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

Help with CC errors

Joker76

Member
Joined
Feb 8, 2010
Messages
835
Reaction score
9
I made a simple CC yesterday, for use with Combat Bot and just noticed that the debug log has some spam. See full log attached.

It's complaining about line 181, which is;

Code:
   if (Me.CurrentTarget.MaxHealth > 1000000 && Me.CurrentTarget.HealthPercent < 90)
            {
                BerserkerRage();
                Deathwish();
                Recklessness();
            }

It might not be proper, but I'm trying to make it use the cooldowns on bosses with more than 1mil HP. Any ideas?

I'm also having trouble getting it to use AoE abilities on adds. I don't think it's detecting them properly. If anyone can take a look and help me out, I'd really appreciate it. I'm very new to this and just trying to gain some knowledge.

Thanks in advance.
 

Attachments

Do u really have a target?
System.Null.Reference looks like you perform or query something to an object that doesn't exists
maybe you should check if you have a target.
The logs spams multiple times per second Bloodthirst and all the other Spells ... don't know if needed, but at this points you should check if you have cooldown (global cooldown and spellcooldown)

should look like this
Code:
if ( SpellManager.CanCast("Bloodthirst")){ 
// do it
}

At this time i haven'T written any CC for HB, but i think this two things (Check spells if u can cast, check if u have a target) are needed

The problem with AE-abilitys and finding all the mobs is a little bit tricky
method 1: query objectmanager for creatures which r targetting u (possible way but not efficient, while tanks bind the mobs)
method 2: query objectmanager for creatures which are attackable and in range of xx yards, if count > 0 -> attack them

i haven't any samples, but there r samples in this forum :)
 
Do u really have a target?
System.Null.Reference looks like you perform or query something to an object that doesn't exists
maybe you should check if you have a target.
The logs spams multiple times per second Bloodthirst and all the other Spells ... don't know if needed, but at this points you should check if you have cooldown (global cooldown and spellcooldown)

should look like this
Code:
if ( SpellManager.CanCast("Bloodthirst")){ 
// do it
}

At this time i haven'T written any CC for HB, but i think this two things (Check spells if u can cast, check if u have a target) are needed

The problem with AE-abilitys and finding all the mobs is a little bit tricky
method 1: query objectmanager for creatures which r targetting u (possible way but not efficient, while tanks bind the mobs)
method 2: query objectmanager for creatures which are attackable and in range of xx yards, if count > 0 -> attack them

i haven't any samples, but there r samples in this forum :)

Sorry, I forgot to post the CC. I've used SpellManager.CanCast in the Combat routine for each ability, so it should be waiting for global cooldown as far as I can tell.

I'm not sure how the Combat Bot itself handles targetting, but I purposely omitted any targeting, movement and range checks from the CC because I wanted that all to be handled by the user (me).

I've tried to define adds as;
Code:
if (thing.IsTargetingMyPartyMember || thing.IsTargetingMyRaidMember || thing.IsTargetingMeOrPet)

Again, not sure if that's proper but I referenced some other CCs and posts here to come up with the method.
 

Attachments

Last edited:
your whole combat section needs to be wrapped in a check if Me.CurrentTarget is null. Me.CurrentTarget always has a chance to return null. so you always need to wrap it.
Code:
        public override void Combat()
        {
            if (Me.CurrentTarget != null)
            {
                if (Me.CurrentTarget.HealthPercent < 20)
                {
                    if (SpellManager.CanCast("Execute"))
                    {
                        Execute();
                    }
                }

                if (SpellManager.CanCast("Bloodthirst"))
                {
                    Bloodthirst();
                }

                if (SpellManager.CanCast("Colossus Smash"))
                {
                    ColossusSmash();
                }

                if (SpellManager.CanCast("Raging Blow"))
                {
                    RagingBlow();
                }

                if (Me.ActiveAuras.ContainsKey("Bloodsurge"))
                {
                    Slam();
                }

                if (Me.RagePercent > 60 && SpellManager.CanCast("Heroic Strike"))
                {
                    HeroicStrike();
                }

                if (Me.CurrentTarget.MaxHealth > 1000000 && Me.CurrentTarget.HealthPercent < 90)
                {
                    BerserkerRage();
                    Deathwish();
                    Recklessness();
                }
            }
        }
also in combat you use.
Code:
                if (SpellManager.CanCast("Raging Blow"))
                {
                    RagingBlow();
                }


            private void RagingBlow()
            {
                SpellManager.Cast("Raging Blow");

                slog("-==- Raging Blow -==-");
            }
what you should think about doing is.
Code:
Combat()
{
RagingBlow();
}
            private void RagingBlow()
            {
                if(SpellManager.CanCast("RagingBlow"))
                {
                SpellManager.Cast("Raging Blow");

                slog("-==- Raging Blow -==-");
                }
            }
or even better make a wrapper so you dont have to keep retyping If spellmanager.can cast, spellmananger cast. for each spell, if you need help with this let me know.

hopefully this will fix it for you.
 
your add detection is a little wacky.

you have.
Code:
        private List<WoWUnit> detectAdds()
        {

            List<WoWUnit> enemyMobList = new List<WoWUnit>();

            List<WoWUnit> mobList = ObjectManager.GetObjectsOfType<WoWUnit>(false);
 
            foreach (WoWUnit thing in mobList)
            {

                if (thing.Distance < 40 && thing.IsAlive)
                {
                    continue;
                }

                if (thing.IsTargetingMyPartyMember || thing.IsTargetingMyRaidMember || thing.IsTargetingMeOrPet)
                {
 
                    enemyMobList.Add(thing);
                }
            }
            {
                if (enemyMobList.Count > 1)
                {
                    slog("-=Detected=- " + enemyMobList.Count.ToString() + " hostiles, using AoE=-");
                }
                return enemyMobList;
            }
        }
and it looks like its fine, except you instead of returning what you want, you keep returning enemyMobList and your not clearing it, so each time it pulses its going to go up and up.
Code:
        private List<WoWUnit> detectAdds()
        {

            List<WoWUnit> AddList = ObjectManager.GetObjectsOfType<WoWUnit>(false).FindAll(unit =>
unit.Guid != Me.Guid &&
(unit.IsTargetingMyPartyMember || unit.IsTargetingMyRaidMember || unit.IsTargetingMeOrPet) &&
!unit.IsFriendly &&
!unit.IsPet &&
unit != Me.CurrentTarget &&
!Styx.Logic.Blacklist.Contains(unit.Guid));

                if (AddList.Count > 1)
                {
                    slog("-=Detected=- " + AddList.Count.ToString() + " hostiles, using AoE=-");
                }
                return Addslist;
            
        }
instead of having the foreach loop, to weed things out this time we have a piece of linq that does the same thing, except its a lot more compact. and because we weeded out everything from the list except what we wanted. you can just pass the list without passing things to another list first.
theres also a check for unit != Me.CurrentTarget. so this is checking for true adds. all the mobs attacking minus the one your currently targeting.

anyway, hope that helps.
 
Thanks for the adds detection code, it works great.

Log spam is still there after adding the !=null wrapper and it's still complaining about the line 183 regarding the MaxHealth target.

I am going to work on revamping the combat section, I'm just a little unsure about how to add the wrapper as you mentioned to prevent redundancy in writing SpellManager.CanCast and SpellManager.Cast. If you could post a quick example, I'd appreciate it.

I'm also trying to figure out if it's possible to check if hostiles in ranged are CCed, to avoid breaking CC during dungeon runs. I haven't seen anything similar used in other CCs. I was thinking the below might work. Any ideas?

Code:
        private List<WoWUnit> detectCC()
        {
            List<WoWUnit> ccList = ObjectManager.GetObjectsOfType<WoWUnit>(false).FindAll(unit =>
            unit.Guid != Me.Guid &&
            (unit.IsTargetingMyPartyMember || unit.IsTargetingMyRaidMember || unit.IsTargetingMeOrPet) &&
            (unit.ActiveAuras.ContainsKey("Polymorphed") || unit.ActiveAuras.ContainsKey("Stunned")) &&
            !unit.IsFriendly &&
            !unit.IsPet &&
            !Styx.Logic.Blacklist.Contains(unit.Guid));

            if (ccList.Count > 0);
            {
                slog("-=Mob(s) crowd controlled, disable AoE")
            }
            return ccList;

Thanks again!
 

Attachments

Thanks for the adds detection code, it works great.

Log spam is still there after adding the !=null wrapper and it's still complaining about the line 183 regarding the MaxHealth target.

I am going to work on revamping the combat section, I'm just a little unsure about how to add the wrapper as you mentioned to prevent redundancy in writing SpellManager.CanCast and SpellManager.Cast. If you could post a quick example, I'd appreciate it.

I'm also trying to figure out if it's possible to check if hostiles in ranged are CCed, to avoid breaking CC during dungeon runs. I haven't seen anything similar used in other CCs. I was thinking the below might work. Any ideas?

Code:
        private List<WoWUnit> detectCC()
        {
            List<WoWUnit> ccList = ObjectManager.GetObjectsOfType<WoWUnit>(false).FindAll(unit =>
            unit.Guid != Me.Guid &&
            (unit.IsTargetingMyPartyMember || unit.IsTargetingMyRaidMember || unit.IsTargetingMeOrPet) &&
            (unit.ActiveAuras.ContainsKey("Polymorphed") || unit.ActiveAuras.ContainsKey("Stunned")) &&
            !unit.IsFriendly &&
            !unit.IsPet &&
            !Styx.Logic.Blacklist.Contains(unit.Guid));

            if (ccList.Count > 0);
            {
                slog("-=Mob(s) crowd controlled, disable AoE")
            }
            return ccList;

Thanks again!
ok so the CC code looks ok, im sure theres a way of doing it automatically but you might wanna look at, WoWunit.IsStunned. and i sure there's a few others. unfortunately i don't have them off the top of my head. and i would double check the buff, for Polymorphed. im not sure thats correct. it might be, if you took it from amplify then it probably is.
Code:
[4:29:51 PM:682] -==- Execute -==-
[4:29:52 PM:681] System.NullReferenceException: Object reference not set to an instance of an object.
   at Lionheart.Classname.Combat() in c:\Users\JoKer\Desktop\Honorbuddy 2.0.0.3804\CustomClasses\Lionheart.cs:line 183
   at Styx.Bot.CustomBots.CombatBot.<CreateCombatBehavior>b__1e(Object ret) in c:\Users\JoKer\Desktop\Honorbuddy 2.0.0.3804\Bots\CombatBot.cs:line 223
   at TreeSharp.Action.RunAction(Object context)
   at TreeSharp.Action.a.a()
   at TreeSharp.Composite.Tick(Object context)
   at TreeSharp.Sequence.a.b()
   at TreeSharp.Composite.Tick(Object context)
   at TreeSharp.PrioritySelector.a.b()
   at TreeSharp.Composite.Tick(Object context)
   at TreeSharp.PrioritySelector.a.b()
   at TreeSharp.Composite.Tick(Object context)
   at TreeSharp.Decorator.a.a()
   at TreeSharp.Composite.Tick(Object context)
   at TreeSharp.PrioritySelector.a.b()
   at TreeSharp.Composite.Tick(Object context)
   at TreeSharp.PrioritySelector.a.b()
   at TreeSharp.Composite.Tick(Object context)
   at Styx.Logic.BehaviorTree.TreeRoot.b()
[4:29:52 PM:681] Cleared POI
so what looks like happened in your log is that popped up as soon as the current target died. and that's fine it happens. because once it happens Me.CurrentTarget becomes null, in the middle of checking your code. so at the end of combat is fine, as long as its not spamming it, i wouldn't worry about it.

Code:
SPELL WRAPPER

Public Void CastSpell(string SpellName)
{
if(SpellManager.CanCast(SpellName))
{
slog("Casting - {0}", SpellName);
SpellManager.CastSpell(SpellName);
}
}

so to call the above code just do
Code:
CastSpell("Raging Blow");
and there you go, basicly what you did is invoked the CastSpell Method, with that string, and that method takes that string and uses it like a variable to execute your code.

there's more advanced things like having more then 1 variable, and that sort of thing, but that should get you started.
 
Keep in mind that CnGs stuff may cause more issues than it fixes.

If you can cast Raging Blow, Deathwish, AND Recklessness, it will simply try to cast each one, one after the other, in the same pulse. This may be the wanted behavior; but I highly suggest checking each one specifically. A simple way to do that is;

(Sorry for bad formatting, writing it in the browser)
Code:
public bool CastSpell(string spellName)
{ 
if (SpellManager.CanCast(spellName) 
{ 
SpellManager.Cast(spellName); 
// We managed to cast the spell, so return true, saying we were able to cast it.
return true; 
} 
// Can't cast the spell right now, so return false.
return false; 
}
 
Guys, thanks a ton for your help. I'm going to do some rewrites this weekend, will post an update with the new code.

Appreciate it.
 
Ok, quick question.

If I have a list (let's use the adds list from above)
Code:
private List<WoWUnit> detectAdds()
        {
            List<WoWUnit> addList = ObjectManager.GetObjectsOfType<WoWUnit>(false).FindAll(unit =>
                        unit.Guid != Me.Guid &&
                        (unit.IsTargetingMyPartyMember || unit.IsTargetingMyRaidMember || unit.IsTargetingMeOrPet) &&
                        !unit.IsFriendly &&
                        !unit.IsPet &&
                        !Styx.Logic.Blacklist.Contains(unit.Guid));

            if (addList.Count > 1)
            {
                slog(Color.DarkBlue, "<< Detected " + addList.Count.ToString() + " mobs, using AoE >>");
            }
            return addList;
        }

How would I go about selecting a target from that list of adds?
 
Ok, quick question.

If I have a list (let's use the adds list from above)
Code:
private List<WoWUnit> detectAdds()
        {
            List<WoWUnit> addList = ObjectManager.GetObjectsOfType<WoWUnit>(false).FindAll(unit =>
                        unit.Guid != Me.Guid &&
                        (unit.IsTargetingMyPartyMember || unit.IsTargetingMyRaidMember || unit.IsTargetingMeOrPet) &&
                        !unit.IsFriendly &&
                        !unit.IsPet &&
                        !Styx.Logic.Blacklist.Contains(unit.Guid));

            if (addList.Count > 1)
            {
                slog(Color.DarkBlue, "<< Detected " + addList.Count.ToString() + " mobs, using AoE >>");
            }
            return addList;
        }

How would I go about selecting a target from that list of adds?

Code:
 addList[0].target()
will target the first thing on the list,
 
Code:
 addList[0].target()
will target the first thing on the list,

For some reason, when I tried that before VS was complaining about something but it seems to be working now. I may have just been tired.

So, I completed the caster detection and Pummel support by using a similar list generation and selection. Is it possible to select the target randomly from the list, or does it always have to be an integer?
 
Back
Top