figuring enemy auto target and attack.

I’ve spent all morning trying to figure this out and I just cant seem to get it.

I have 4 hero characters on the screen at once. Enemies randomly spawn and pick a hero to attack, I have that part down.

The issue is when an enemy kills a hero, I am trying to get the enemy to pick a random hero and start to move towards and attack the new hero.

this is what I thought would work

 function setRandomTarget (self, event) newTarget = math.random( 1, 4 ) setTarget = none if activeParty[newTarget].dead == false then if newTarget == 1 then setTarget = Hero1 elseif newTarget == 2 then setTarget = Hero2 elseif newTarget == 3 then setTarget = Hero3 elseif newTarget == 4 then setTarget = Hero4 end elseif activeParty[newTarget].dead == true then setRandomTarget() end return setTarget end

The idea is this, I have a table that tracks the active hero’s. there is a value “dead” within that table that is turned to true whenever a hero’s health has dropped to 0.

How I thought this function would work would be it picks a random number between 1 - 4. it then checks the activeParty table to see if that character is dead or alive.

if it is alive, the function further looks into the number to specify what the new target would be.

if the character is dead, the function simply triggers again and this is repeated until an alive character is found to be the new target.

after this function I have a trigger when the enemy kills a hero to set self.target = setRandomTarget()

Issue im getting with this is that it states “target” is a nil value… That would be due to the rest of my enemy code involves tracking the target spot etc…

But if Im getting that error it must mean that my function to pick a new target is faulty. Does anyone have any insight on this?

Hi.

Are you explicitly initializing all your entries’ dead fields to false when you start out? If not they’ll be nil and, since you’re comparing against false specifically, that will silently fail. What you can do instead is

if not activeParty[newTarget].dead then

which will handle either nil or false. (And then the true test could simply become an else.)

Also, more generally, you’ll want to use locals and, in a case like this, should probably prefer a loop to recursion. So something like:

function setRandomTarget (self, event) while true do local newTarget = math.random( 1, 4 ) -- assign to local, so we don't stop on stuff with same names elsewhere local setTarget = nil -- note: not "none" (that would have been nil accidentally, in your case) if not activeParty[newTarget].dead then if newTarget == 1 then setTarget = Hero1 elseif newTarget == 2 then setTarget = Hero2 elseif newTarget == 3 then setTarget = Hero3 elseif newTarget == 4 then setTarget = Hero4 end return setTarget end end end

yes, I am defining the dead values as false prior. I’m on the way out of the house right now and did not get to fully read your response, but wanted to give you that info to see if it changes your suggestion any.

Thanks

Hmm. In that case all I can guess (given the information presented) is that maybe your Hero* variables are missing.

What do you see if you put some print() statements in your if cases?

Hi.

Are you explicitly initializing all your entries’ dead fields to false when you start out? If not they’ll be nil and, since you’re comparing against false specifically, that will silently fail. What you can do instead is

if not activeParty[newTarget].dead then

which will handle either nil or false. (And then the true test could simply become an else.)

Also, more generally, you’ll want to use locals and, in a case like this, should probably prefer a loop to recursion. So something like:

function setRandomTarget (self, event) while true do local newTarget = math.random( 1, 4 ) -- assign to local, so we don't stop on stuff with same names elsewhere local setTarget = nil -- note: not "none" (that would have been nil accidentally, in your case) if not activeParty[newTarget].dead then if newTarget == 1 then setTarget = Hero1 elseif newTarget == 2 then setTarget = Hero2 elseif newTarget == 3 then setTarget = Hero3 elseif newTarget == 4 then setTarget = Hero4 end return setTarget end end end

yes, I am defining the dead values as false prior. I’m on the way out of the house right now and did not get to fully read your response, but wanted to give you that info to see if it changes your suggestion any.

Thanks

Hmm. In that case all I can guess (given the information presented) is that maybe your Hero* variables are missing.

What do you see if you put some print() statements in your if cases?