• Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • Internal CombatBehaviour switches

    Discussion in 'Archives' started by wownerds, Aug 12, 2011.

    1. wownerds

      wownerds New Member

      Joined:
      Feb 15, 2011
      Messages:
      1,385
      Likes Received:
      30
      Trophy Points:
      0
      Hey there,

      while coding my CC, I just came across the following problem: How can I switch between 3 internal behaviours, depending on the add count?

      As an intro, here are the relevant code snippets:

      Code:
              private List<WoWUnit> adds = new List<WoWUnit>();
      
              private List<WoWUnit> detectAdds()
              {
                  List<WoWUnit> addList = ObjectManager.GetObjectsOfType<WoWUnit>(false).FindAll(unit =>
                              unit.Guid != Me.Guid &&
                              unit.Distance < 10.00 &&
                              (unit.IsTargetingMyPartyMember || unit.IsTargetingMyRaidMember || unit.IsTargetingMeOrPet) &&
                              !unit.IsFriendly &&
                              !unit.IsPet &&
                              !Styx.Logic.Blacklist.Contains(unit.Guid));
      
                  return addList;
              }
      From which I am able to retrieve the number of adds by calling
      Code:
      adds.Count
      When the CombatBehaviour looks like this:

      Code:
              protected Composite CreateBossBehavior()
              {
                  adds = detectAdds();
      
                  return new Switch(bool) (ret => adds.Count == 1,
                      CreateBossTankingBehavior(),
                      new SwitchArgument(bool) (adds.Count > 1,
                      CreateAoetankingBehavior()));
              }
      When using that script, the CC will always use "CreateAoetankingBehavior()".

      I tried adding the switch command into "CreateAoetankingBehavior()" and the "CreateBossTankingBehavior()" to determine whether ot not to switch after executing a PrioritySelector. This ended up crashing HB on startup.

      My original idea would have looked like this:

      Code:
              protected Composite CreateBossBehavior()
              {
                  adds = detectAdds();
                  
                  return new Switch(int) (ret => adds.Count == 1,
                      CreateBossTankingBehavior(),
                      new SwitchArgument(int) (adds.Count > 1,
                      CreateAoetankingBehavior())
                      new SwitchArgument(int) (adds.Count > 1 && adds.Count < 6,
                      CreateMegaAoetankingBehavior())
                      );
              }
      Which does not work, because Switch(T) does not accept "int" as a switch argument. But that would not have changed the problem I'm currently experiencing anyway.

      All in all, my question is: How can I make the CC evaluate a Switch argument each time a PrioritySelector was run through?

      I already tried workaraound like adding
      Code:
      => ret adds.Count >= 6
      to all decorators in the PrioritySelector, but they seem to be ignored.

      Thank you very much in advance.
       
    2. CodenameG

      CodenameG New Member

      Joined:
      Jan 15, 2010
      Messages:
      38,369
      Likes Received:
      231
      Trophy Points:
      0
      heres what i use for zerfall for switching rotations.

      Code:
                    //PVP SpecSwitch
                      new Decorator(ret => IsBattleGround(),
                                new Switch<WarlockTalentSpec>(r => _talentManager.Spec,
                                         new SwitchArgument<WarlockTalentSpec>(Low_rotation(), WarlockTalentSpec.Lowbie),
                                         new SwitchArgument<WarlockTalentSpec>(Affliction_PVP(), WarlockTalentSpec.Affliction),
                                         new SwitchArgument<WarlockTalentSpec>(Demo_PVP(), WarlockTalentSpec.Demonology),
                                         new SwitchArgument<WarlockTalentSpec>(Destro_PVP(), WarlockTalentSpec.Destruction)
                                         )),
                      //Instance SpecSwitch
                      new Decorator(ret => Me.IsInInstance && Me.IsInParty,
                                new Switch<WarlockTalentSpec>(r => _talentManager.Spec,
                                         new SwitchArgument<WarlockTalentSpec>(Low_rotation(), WarlockTalentSpec.Lowbie),
                                         new SwitchArgument<WarlockTalentSpec>(Affliction_Instance(), WarlockTalentSpec.Affliction),
                                         new SwitchArgument<WarlockTalentSpec>(Demo_Instance(), WarlockTalentSpec.Demonology),
                                         new SwitchArgument<WarlockTalentSpec>(Destro_Instance(), WarlockTalentSpec.Destruction)
                                         )),
                      //PVE SpecSwitch if other two fail to be used. 
                      new Switch<WarlockTalentSpec>(r => _talentManager.Spec,
                                         new SwitchArgument<WarlockTalentSpec>(Low_rotation(), WarlockTalentSpec.Lowbie),
                                         new SwitchArgument<WarlockTalentSpec>(Affliction_PVE(), WarlockTalentSpec.Affliction),
                                         new SwitchArgument<WarlockTalentSpec>(Demo_PVE(), WarlockTalentSpec.Demonology),
                                         new SwitchArgument<WarlockTalentSpec>(Destro_PVE(), WarlockTalentSpec.Destruction)
                                         )
      
      i have the most likely first so if im in battlegrounds it will go into that tree first, untill it hits the pve switch the PVE switch is Always going to be used if it dost get sidetracked first.

      instead of IsBattleground() ,you can always DetectAdds().Count > 2,
       
    3. wownerds

      wownerds New Member

      Joined:
      Feb 15, 2011
      Messages:
      1,385
      Likes Received:
      30
      Trophy Points:
      0
      Thank you, I'll give it a try :)

      Unfortunately, this does not solve my problem of the switch argument only being called once, when the Behaviour is first created.
       
    4. wownerds

      wownerds New Member

      Joined:
      Feb 15, 2011
      Messages:
      1,385
      Likes Received:
      30
      Trophy Points:
      0
      Finally got the opportunity to test this.

      The code looks like this:

      Code:
              private Composite _combatBehavior;
      
              public override Composite CombatBehavior
              {
                  get 
                  { 
                      if (_combatBehavior == null) 
                      {
                          slog("Creating an awesome Combat behavior");
                          _combatBehavior = CreateCombatBehavior(); 
                      }
                      _combatBehavior = CreateCombatBehavior(); 
                      return _combatBehavior;
                  }
              }
      
              private Composite CreateCombatBehavior()
              {
                  return CreateCombat();
              }
              #endregion
      
      #region behaveswitch
              public Composite CreateCombat()
              {
      
                    return new Decorator(ret => Me.IsInInstance && Me.IsInParty,
                    new Switch<TalentSpec>(r => TalentManager.CurrentSpec,
                                         new SwitchArgument<TalentSpec>(CreateFuryBehavior(), TalentSpec.FuryWarrior),
                                         new SwitchArgument<TalentSpec>(CreateBossBehavior(), TalentSpec.ProtectionWarrior)
                                         ));
              }
      Unfortunately, the CC now does nothing at all. Both behaviours work when using them without any switch.

      Any ideas?
       
    5. CodenameG

      CodenameG New Member

      Joined:
      Jan 15, 2010
      Messages:
      38,369
      Likes Received:
      231
      Trophy Points:
      0
      are you sure

      Me.IsInInstance && Me.IsInParty

      Are returning true? try replacing those with Me.IsAlive or something simple and see if it runs then.
      </pre>
       
    6. wownerds

      wownerds New Member

      Joined:
      Feb 15, 2011
      Messages:
      1,385
      Likes Received:
      30
      Trophy Points:
      0
      Yep, figured that out seconds before you replied :/

      works perfectly, thanks :)

      Have you got any idea how to check for specc intelligently?

      I put it in pulse, which seems to cause WoW lags.
       
    7. wownerds

      wownerds New Member

      Joined:
      Feb 15, 2011
      Messages:
      1,385
      Likes Received:
      30
      Trophy Points:
      0
      New problem: after switching speccs the CC does not seem to use any behaviour at all.
       
    8. CodenameG

      CodenameG New Member

      Joined:
      Jan 15, 2010
      Messages:
      38,369
      Likes Received:
      231
      Trophy Points:
      0
      the problem is the BT is Cached, so it on the fly settings and spec changes wont work. theres no way around it.
       
    9. wownerds

      wownerds New Member

      Joined:
      Feb 15, 2011
      Messages:
      1,385
      Likes Received:
      30
      Trophy Points:
      0
      Thank you :) Great to know - won't waste my time with trying then.
       
    10. fiftypence

      fiftypence New Member

      Joined:
      Jul 28, 2011
      Messages:
      235
      Likes Received:
      13
      Trophy Points:
      0
      You should only need to build the behaviours once -- having them built every pulse is a bad way of doing things. A better way of doing things would be to have a global variable (called CurrentSpec, for example) and check CurrentSpec against TalentManager.CurrentSpec -- if they match, you're the same spec, and if they do not, the spec has changed since the last pulse, so you should rebuild the BehaviorTree with the new spec in mind.

      e.g:

      Code:
      (declare CurrentSpec here)
      
      private Composite _CombatBehavior;
      
      public override Composite CombatBehavior()
      {
          get 
          {
              if (_CombatBehavior == null)
              {
      	    (enter your code to build your behavior tree for the first time)
      	    CurrentSpec = TalentManager.CurrentSpec;
              }
      
              return _CombatBehavior; 
      }
      
      public override Pulse()
      {
          if (CurrentSpec != TalentManager.CurrentSpec)
          {
              CurrentSpec = TalentManager.CurrentSpec;
              _CombatBehavior = null;
          }
      }
      Something like that should only rebuild the behaviortree if your spec changes.

      edit: Didn't see above posts before posting, so I suppose my suggestion won't work. Ah well!
       
    11. wownerds

      wownerds New Member

      Joined:
      Feb 15, 2011
      Messages:
      1,385
      Likes Received:
      30
      Trophy Points:
      0
      Now that I've taken the specccheck out of the pulse, it does not seems to detect speccs at all and therefore does not build any CombatBehaviour :/
       

    Share This Page