What's new
  • Visit Rebornbuddy
  • Visit Resources
  • Visit API Documentation
  • Visit Downloads
  • Visit Portal
  • Visit Panda Profiles
  • Visit LLamamMagic

Problem beim Schreiben einer Combat Routine

Nubi

New Member
Joined
Jul 29, 2014
Messages
24
Reaction score
0
Guten Tag :)
Ich weiß ,dass es ein extra Forum dafür gibt,der aber auf Englisch ist :(
Ich versuchs deswegen mal wieder hier :)

Ich habe das Problem ,dass mein Pet zwei mal (sofort hintereinander) beschwört wird.
Das heißt, der Bot merkt nicht sofort ,dass das Pet schon da ist.
Wie kann ich mein Code dahingehend verbessern,dass nur einmal beschworen wird?

PHP:
 private Composite CreatePreCombatBuff()
        {
            return (
                new Decorator(ret => !Me.Mounted && !Me.IsDead && !Me.Combat && !Me.IsFlying && !Me.IsOnTransport
                                     && !Me.HasAura("Essen") && !Me.HasAura("Trinken") && Me.CurrentTarget.IsAlive,
                    new PrioritySelector(
                        new Decorator(ret => !Me.GotAlivePet,
                            SpellCast.Cast(SB.SummonPet, ret => !Me.GotAlivePet && !Me.Combat, "Summon Pet"))
                        )));
        }
 
probier mal !Me.IsCasting einzufügen, bin mir zwar nicht sicher, hab bisher nur eine routine für eine klasse ohne pet geschrieben XD
 
probier mal !Me.IsCasting einzufügen, bin mir zwar nicht sicher, hab bisher nur eine routine für eine klasse ohne pet geschrieben XD
Hat tatsächlich geholfen!! Komischerweise:) Hätte ich ja nicht gedacht.ist ja auch eher unlogisch,da er ja garnicht casten kann, bevor er nicht für das erste pet zu ende gecastet hat.Wie auch immer.Vielen Dank!

Vlt könntest du mir auch gleich beim nächsten Problem helfen :)

Wie eröffne ich ein Kampf automatisch?
Das habe ich als Code

PHP:
        public override Composite PullBehavior
        {
            get { return CreatePull(); }
        }
 private Composite CreatePull()
        {
            return (
                (new Decorator(ret => !Me.Combat,
                    new PrioritySelector(
                        SpellCast.Cast(SB.Verderbnis, ret => true, "Pull ")))));
        }

aber der will einfach nicht den Kampf selber eröffnen :) Welcher Behavior ist dafür verantwortlich?
 
oh das kann ich dir nicht sagen ^^ meine CC ist ne reine raidroutine :P

probiers mal mit

Code:
        public override void Pull()
        {
  

        }

100% sicher bin ich mir da aber auch nicht
 
Last edited:
Hat tatsächlich geholfen!! Komischerweise:) Hätte ich ja nicht gedacht.ist ja auch eher unlogisch,da er ja garnicht casten kann, bevor er nicht für das erste pet zu ende gecastet hat.Wie auch immer.Vielen Dank!

das ist auch nicht wirklich die richtige lösung sondern eher zufall
Hintergrund zu deinem Problem ist folgender
Dein Pet erscheint NICHT sofort nach Beendigung des Casts
Deine LagToleranz ist größer als 0ms

Beides zusammen ergibt das Me.GotAlivePet false ist beim beenden des casts und er erneut das Pet beschwört
Dein Pet verschwindet sofort (ja das ist blizzard logik) nach beenden der zweiten Beschwörung und taucht dann erst 0,xxx sekunden später auf
währrend dessen hat HB aber bereits erkannt "hey wir haben kein pet, lasst uns doch mal eins beschwören", das ganze ist dann eine Endlosschleife.

die richtigere und vermutlich für jeden geltende Lösung(en) wären hier eher
a) Füge einen PetTimer (500-2000ms) hinzu (diese variante ist zu bevorzugen da dich das problem öfter treffen wird!), den du direkt nach dem beschwören zurücksetzt, im Castteil ret=>!Me.GotAlivePet fügst du die Prüfung hinzu ob dieser Timer abgelaufen ist ret=> !Me.GotAlivePet && PetTimer.isFinished
den Decorator(ret=>!Me.GotAlivePet, castxxxxxx) kannst übrigens raus nehmen, wozu zweimal prüfen ob das pet vorhanden ist? (einmal im decorator und einmal im spell cast)

b) füge in deiner Cast Methode eine Variable hinzu um dort zu speichern welchen Zauber du zuletzt gecastet hast (würde bei diesem Problem kurzfristig helfen, ist jedoch keine dauerlösung da die Problematik mit dem Pet erscheinen mehrfach abzufangen ist), und führe den aktuellen Cast nur dann aus wenn der letzte Cast nicht der gleiche war/ist

Warum hat nun eigentlich !Me.isCasting geholfen?
Ganze einfach HB ist wahnsinnig schnell, und prüft per CanCast ob ein Spruch gezaubert werden kann (soweit so gut, das wollen wir !), kurz bevor der Cast zuende ist wird CanCast true, da deine Latenz eben größer als 0 ms und von CanCast berücksichtigt wird. CanCast liefert also true zurück während evtl noch ca 20-120ms vergehen bevor der neue cast gestartet wird, da du aber nun Me.IsCasting prüfst läuft er gar nicht in dieses Problem rein, da der Cast nicht mehr aufgerufen wird (weil du noch castest)

Wann wird dich das Problem wieder treffen trotzdes !Me.IsCasting?
Bei einem Zonenwechsel mit ladebildschirm (dungeon,szenario,sonstiges) wird das pet wieder beschworen da es für den Zeitpunkt des ladeschirms (bzw einige ms danach) noch nicht erschienen ist, die routine sieht als "hey kein pet, lasst es uns holen", obwohl eigentlich ein pet da ist. Es wäre also ratsam das ganze über einen Timer zu steuern der
1.) nach dem beschwören zurück gesetzt wird
2.) nach einem Ladescreen direkt zurück gesetzt wird (lieber warten wir 0,5 sekunden ob ein pet da ist, als eins sinnlos zu beschwören)

zu deinem zweiten Problem ist es ein wenig schwierig, fertz hat dir bereits einen Tipp gegeben, allerdings ist seine Routine vermutlich über das Pulsing von HB gesteuert und nicht über den BehaviorTree, normalerweise hast du die absolut richtigen sachen überschrieben.
Es liegt nun also eher daran wie du es testest (BotBases wie Tyrael,Raidbot,CombatBot führen weder void Pull noch composite PullBehavior aus), somit wäre es egal wie du es schreibst, wenn du mit den genannten Botbases testest, es wird niemals zu einem Pull kommen.

Verwendest du eine andere BotBase, so wäre es sinnvoll zu prüfen ob die Botbase das anvisieren übernimmt oder nicht, tut sie dies ... prüfe die pulleinstellungen, tut sie dies nicht, implementiere einen Vorgang zum anvisieren.
Warum anvisieren?
Es wird kein pull initiert wenn wir kein Ziel haben, es wäre also sinnvoll ein Ziel zu setzen ;)
 
Vielen Dank für diese ausführliche Antwort! Ich werde die Timer-Methode in Angriff nehmen! Ich vermute mal Klasse "WaitTimer" sollte dafür richtig sein.

Auch beim zweiten Problem habe ich die Schwierigkeit, nun dank dir ,erkannt! Ich benutze tatsächlich Tyrael als BotBase.Nun muss ich mal schauen was ich für meine Zwecke benutzen kann und wie ich überprüfen kann, was die Botbase übernimmt und was nicht.

den Decorator(ret=>!Me.GotAlivePet, castxxxxxx) kannst übrigens raus nehmen, wozu zweimal prüfen ob das pet vorhanden ist? (einmal im decorator und einmal im spell cast)
Das habe ich mich auch gefragt, nur ist das so ziemlich in allen CR's, die ich mir so angesehen habe, so.Und da ich das Prinzip des BehaviorTree's noch nicht wirklich verstanden habe und die Wiki leider down ist, versuche ich erstmal so zu machen wie "alle" :)

Was ich zB nicht verstehe- warum wird "RunStatus" selten zurückgegeben und wenn der nicht explizit zurückgegeben wird,kommt dann automatisch ein RunStatus.Success ? und was passiert wenn der Status Success und was wenn Failure..
Vlt hat jemand ja eine Kopie auf der Platte von Wiki für mich?

Vielen Dank nochmals für die ausführliche Antwort, die hat mir sehr geholfen!
 
Der Runstatus wird durch die Composites immer zurückgegeben
Wird eine Aktion erfolgreich ausgeführt wird, wenn nicht anders angegeben, immer Success zurückgeliefert
Wird keine Aktion ausgeführt, wird Failure zurückgegeben
In manchen fällen muss/sollte man jedoch Failure statt success zurück gegeben
Bsp:
Zauber ausführen welche keinen GCD auslösen, hier ist es unnötig Success zurück zu geben, da der Baum/Tree dann wieder von anfang durchlaufen wird, man gibt hier also explizit Failure zurück damit das programm den baum danach weiter nach unten steigt und die nächste aktion durchführt ... dies KANN man machen, muss man aber nicht (die meisten machen es jedoch)
das gleiche gilt für aktionen des Pets, hier wird selten das eigene Zaubern beeinflußt, man liefert also Failure zurück damit es weiter im baum geht und die eigenen Zauber geprüft werden zum ausführen.

Der Baum/Tree ist relativ simple, es handelt sich um nichts weiter als eine ewig lange verschachtelung von IF anweisungen (vereinfach ausgedrückt)
wenn du etwas in einem Decorator abprüfst, musst du es in der regel nicht mehr in den Argumenten der aufrufenden methode angeben
umgekehrt das gleiche... wenn du etwas in der aufrufenden methode prüfst, musst du keinen decorator mehr drum packen... du führst die IF bedingung also zwei mal aus statt des notwendigen einen mal

Der Waittimer ist im übrigen richtig :)
public static readonly WaitTimer PetSummonAfterDismountTimer = new WaitTimer(TimeSpan.FromSeconds(2)); //aus singular kopiert
 
Perfekt erklärt!Danke!
Nun weiss ich auch wieder, wo ich den WaitTimer gesehen habe :)
 
Back
Top