AI Taking cover

Rivo

7014
Ok, so i've spent the last few days working on my ai system using different states to tell the enemy what to do, and I am reasonable happy with it so far. Especially considering that i'm completely new to it.

What i'm not so happy about is how the enemy will get way too close and risk it's life to try and kill me D:
So what I'm trying to do make the enemy take cover whenever a solid is near. Here is the code I tried

Code:
//when cover is in range, and player is in sight go to cover.
if collision_line(x, y, oPlayer.x, oPlayer.y, oSolid, false, false){
    if distance_to_object(oSolid) <= 20{
        if distance_to_object(oPlayer) >= radius - 100{
        path_end();
            if mp_grid_path(pathfinder_grid, path, x, y, oSolid.x, oSolid.y, true){
                path_start(path, spd, path_action_stop, false);
            }
        }
    }
}
but I have a feeling that this may be a bit more complex than I know (bear in mind this code was purely just trial and error)

Any help at all would be great, thank you!
 

Yal

šŸ§ *penguin noises*
GMC Elder
I'd use different states for this to make it easier to manage... if you don't keep things like this separated, the code will be a nightmare to adapt. Enemies would use different AI for tracking you down, attacking you, and running into cover... and probably for attacking you from inside cover as well. Using a state machine approach would let you write several easier AIs and only use one at a time.
 

Phil Strahl

Member
I'd use different states for this to make it easier to manage... if you don't keep things like this separated, the code will be a nightmare to adapt. Enemies would use different AI for tracking you down, attacking you, and running into cover... and probably for attacking you from inside cover as well. Using a state machine approach would let you write several easier AIs and only use one at a time.
Yal is right, a state machine would make your code more maintainable. What I'd also suggest is to have your AI select different behaviors based on some variables, e.g. if it has significantly more HP than the player and/or better gear, it tends to attack more risky, or if it is low on health, it will try to avoid damage. Based on a few variables like that, the AI could choose from a number of options. E.g. "avoid damage" would first prioritize "find cover", if that fails "run away", and if the unit is cornered it could mean "make a desperate move"...
 
S

Snail Man

Guest
As to the actual code, the issue appears to be that you used collision_line to mean 'can see the player'. Collision_line tells whether there are blocks in the way, so you should be using !collision_line
 
It seems like you might run into problems where cover is nearby but the bath to get to it is absurdly long, like you have to go around a long wall. And in that case the AI will behave in a way which I'm sure is undesirable.
 

Rivo

7014
Well, I do have a set of scripts (states) my enemy follows e.g. idle state - check state- attack state's- etc. And it switches between them, and from reading what you said, I could create a defense state to put this into and have the enemy fire at me whilst it moves into cover (plz correct me if this isn't a state machine).

But how would I go about coding the enemy to hide behind the nearest wall instead of being so brave and getting to near me. Especially since I plan on having the enemy die in one shot. Because I can't tell it to go to 'oSolid.x and oSolid.y' since that would move it inside the wall. I would like it to move the enemy on the other side of the wall to the player which is why i used 'collision_line'(Also, cool idea about making the enemy more risky dependent upon health)


Here is how my little work in progress looks http://prntscr.com/bpl3on
(I couldn't be bothered drawing a sprite for the enemy :p and I haven't fixed the depth of the enemy just yet either)

Sorry about the late reply.
 

Phil Strahl

Member
But how would I go about coding the enemy to hide behind the nearest wall instead of being so brave and getting to near me. Especially since I plan on having the enemy die in one shot. Because I can't tell it to go to 'oSolid.x and oSolid.y' since that would move it inside the wall. I would like it to move the enemy on the other side of the wall to the player which is why i used 'collision_line'
Sorry about the late reply.
How about having "safe tiles" the AI surrounding each cover object. If they in the "find cover" state, i'd do something like this:
  1. Find the nearest cover
  2. from all if its surrounding "safe tiles" cast a line from its center to the player
  3. store all "safe tiles" whose line to the player collides with the cover
  4. find the closest "safe tile" for the AI
  5. Regularily update which tiles are safe, based on player movement
 
Top