Need help with Making pawns attack pawns.
Posted: Fri Jan 05, 2007 10:38 pm
I have seen this posted before but cannot find the posts now. When I did read them I didnt see any detailed answer that stated that it worked.
I have tried the following to get a robot pawn to attack the pawn group called robot. It didnt work. Can some please tell me why?
{
IDLE [idle] // idle animation
WALK [walk] // walk animation
DIE [die] // die animation
SHOOT [shoot] // shoot animation
MISC1 [slump] // misc1 animation
GROUP [friendly_robot]
HOSTILEPLAYER [false] // hostile to player
HOSTILESAME [false] // hostile to same Pawn group
TargetGroup [false] // hostile to a certain group, true or false doesnt work
HostileDifferent [true] // hostile to different group, true or false doesnt work
HEALTHATTRIBUTE [enemy_health] // name of pawns health attribute
HEALTH [100] // initial pawn health
DAMAGEATTRIBUTE [health] // attribute damaged by attack
ALERTTRIGGER [AlertG] // name of alert trigger
DIEHOLD [15] // time corpse still appears
DIEFADE [10] // fadeout time of corpse
FOV [360] // field of view
SIGHTDIST [700] // max distance pawn can see at idle
ALERTSIGHTDIST [900] // max distance pawn can see when alert
YAWSPEED [90]
WALKSPEED [50]
SHOOTRANGE [300] // max distance to start missile attack
PROJECTILE [10mm_shell] // projectile name
FIREBONE [Joint15] // projectile launch bone
OFFSETX [0] // launch offsets
OFFSETY [0]
OFFSETZ [25]
ATTACKDELAY [0.5] // time between shots
FIREDELAY [0.1] // delay after animation starts before projectile launch
SKILL [5] // skill level 1 to 10
LOSTTIME [15] // time to search for enemy before giving up
POINTRADIUS [20] // radius from point when considered there
RUNFUNC [run_start] // monster run to attack function
SHOOTFUNC [shoot_start] // monster missile function
LOSTFUNC [lost_target_start] // monster lost target function
AS_NONE [0]
AS_SHOOT [2]
AS_STRAIGHT [3]
attack_delay [0]
lost_time [0]
back_up [false]
back_time [0]
left_time [0]
back_flag [false]
fire_delay [0]
skill_time [0]
attack_state [0]
Spawn[ ()
{
//Console(true);
SetFOV(FOV); // set field of view
BoxWidth(40);
SetGroup(GROUP);
HostilePlayer(HOSTILEPLAYER);
HostileSame(HOSTILESAME);
TargetGroup(robot); //added by me, didnt work
HostileDifferent(robot); //added by me, didnt work
// setup orders
AttributeOrder(HEALTHATTRIBUTE, HEALTH, "Death"); // give monster health
FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE); // seen a target to chase
AvoidOrder("Avoidance"); // avoid obstacles
AddPainOrder("PainToAlert", 100); // show pain and trigger alert
AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0); // go to alert when triggered
RotateToPoint(IDLE, YAWSPEED, false, ""); // go to point if any specified
MoveToPoint(WALK, WALKSPEED, ""); // move to starting point
NewOrder("Patrol");
} ]
Idle[ ()
{
// just look around a bit
Rotate(IDLE, YAWSPEED, 0, 100, 0, "");
Delay(IDLE, random(3,5), "");
Rotate(IDLE, YAWSPEED, 0, -200, 0, "");
Delay(IDLE, random(3,5), "");
Align();
NewOrder("Patrol"); // continue to patrol
} ]
Avoidance[()
{
// backup and move sideways sometimes
MoveBackward(WALK, WALKSPEED, (WALKSPEED/2), "");
if(random(1,10)<6)
{
MoveRight(WALK, WALKSPEED, (WALKSPEED/2), "");
}
else
{
MoveLeft(WALK, WALKSPEED, (WALKSPEED/2), "");
}
Return();
}]
Patrol[ ()
{
// patroling from point to point, looking for special orders in each script point (i.e. "Idle")
NextPoint();
NextOrder();
RotateMoveToPoint(WALK, YAWSPEED, WALKSPEED, false, "");
MoveToPoint(WALK, WALKSPEED, "");
RestartOrder();
}]
PainToAlert[()
{
SetEventState(ALERTTRIGGER, true); // set trigger to go to alert
Return();
}]
IdleToAlert[()
{
FindTargetOrder(ALERTSIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE); // increase viewing
distance
AddTimerOrder(1, LOSTTIME, "AlertToIdle"); // go to idle after 10
secs
SetEventState(ALERTTRIGGER, false); // turn off alert
trigger
NewOrder("Alert");
}]
Alert[()
{
// just look around a bit
Rotate(IDLE, YAWSPEED, 0, 150, 0, "");
Delay(IDLE, random(3,5), "");
Rotate(IDLE, YAWSPEED, 0, -150, 0, "");
Delay(IDLE, random(3,5), "");
RestartOrder();
}]
AlertToIdle[()
{
FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE); // decrease viewing distance
AddPainOrder("PainToAlert", 100); // go to alert when pain
AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0); // go to alert when triggered
NewOrder("Idle");
}]
FoundTarget[()
{
DelTimerOrder(1); // get rid of alert timer
LowLevel(RUNFUNC); // attack functions are low level
}]
LostTarget[ ()
{
FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE); // seen a target to chase
AddPainOrder("PainToAlert", 100); // trigger alert when pain
AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0); // go to alert when triggered
FindPointOrder("Patrol");
NewOrder("Idle");
} ]
Death[()
{
DelTimerOrder(1); // remove alert timer
AddPainOrder("PainToAlert", 0); // remove pain order
FindTargetOrder(0, "FoundTarget", DAMAGEATTRIBUTE); // remove target finding
DelTriggerOrder("IdleToAlert"); // remove alert trigger
SetNoCollision(); // remove bounding box so there are no
collisions with corpse
AnimateStop(DIE, DIEHOLD, "");
FadeOut(DIEFADE, 0); // fade out corpse
Remove(true); // remove actor
}]
// Low level routines
run_start[ ()
{
Animate(WALK); // play animation
self.ThinkTime = 0; // start thinking on next frame
self.ideal_yaw = self.enemy_yaw; // set direction to run
self.yaw_speed = YAWSPEED; // set rotation speed
back_up = false; // initialize obsticle avoidance
attack_state = AS_NONE; // not attacking yet
self.think = "run_to_attack"; // go to run attack routine
} ]
run_to_attack[ ()
{
self.ThinkTime = 0.05;
if(self.health<=0)
{
HighLevel("Death"); // dead
return 0;
}
if(EnemyExist(DAMAGEATTRIBUTE) < 3)
{
HighLevel("LostTarget"); // enemy is gone or dead
return 0;
}
if(self.enemy_vis = false)
{
self.think = LOSTFUNC; // lost sight of enemy
lost_time = self.time + LOSTTIME;
return 0;
}
ai_run(random(WALKSPEED-2, WALKSPEED+2)); // run toward enemy
} ]
// start of lost sight of enemy routine
lost_target_start[()
{
Animate(WALK); // play run animation
self.ThinkTime = 0; // start thinking on next frame
self.think = "lost_target";
}]
// go to last known location of enemy
lost_target[()
{
self.ThinkTime = 0.1;
if(lost_time<self.time)
{
HighLevel("LostTarget"); // timed out while looking
return 0;
}
if(self.health<=0)
{
HighLevel("Death"); // died
return 0;
}
if(EnemyExist(DAMAGEATTRIBUTE) < 3)
{
HighLevel("LostTarget"); // enemy died or was removed
return 0;
}
if(self.enemy_vis = true)
{
self.think = "run_start"; // seen again so run to attack
self.ThinkTime = 0;
return 0;
}
if(self.enemy_range>POINTRADIUS) // get close to last known location
{
walk_movetogoal(random(WALKSPEED-2, WALKSPEED+2));
}
else
{
HighLevel("LostTarget"); // can't find at last known location
return 0;
}
}]
// start of shoot attack
shoot_start[()
{
Animate(SHOOT); // play shoot attack animation
SetHoldAtEnd(true);
self.ThinkTime = 0;
fire_delay = self.time + FIREDELAY; // set firing delay
UpdateTarget(); // update target location
skill_time = self.time + (SKILL*0.1); // calculate next update time
attack_delay = self.time + ATTACKDELAY; // delay until next shot
self.think = "shooting";
}]
// attack target with projectile
shooting[()
{
self.ThinkTime = 0.1;
if(self.health<=0)
{
SetHoldAtEnd(false);
HighLevel("Death"); // dead
return 0;
}
exist = EnemyExist(DAMAGEATTRIBUTE);
if(exist < 2)
{
SetHoldAtEnd(false);
HighLevel("LostTarget"); // enemy is dead and gone
return 0;
}
if(exist = 2)
{
SetHoldAtEnd(false);
HighLevel("LostTarget"); // enemy is dead but body remains
return 0;
}
if(self.enemy_vis = false)
{
self.think = LOSTFUNC; // lost sight of enemy
lost_time = self.time + LOSTTIME;
SetHoldAtEnd(false);
return 0;
}
if(self.enemy_range>SHOOTRANGE)
{
self.think = RUNFUNC; // too far away so run toward
SetHoldAtEnd(false);
return 0;
}
if(skill_time<self.time) // update according to skill level
{
UpdateTarget(); // update target location
skill_time = self.time + (SKILL*0.1);
ai_face(); // face enemy while attacking
}
if(fire_delay<self.time) // delay after animation starts before firing
{
FireProjectile(PROJECTILE, FIREBONE, OFFSETX, OFFSETY, OFFSETZ, DAMAGEATTRIBUTE);
fire_delay = self.time + 1000; // set delay well ahead so it is ignored
}
// wait until animation is done before attacking again
// hold animation at end until attack delay is over
if(self.animate_at_end = true)
{
if(attack_delay < self.time)
{
self.think = "shoot_start"; // go back to missile attack
SetHoldAtEnd(false);
self.ThinkTime = 0.1;
}
}
}]
// basic AI routines
ai_run[(dist)
{
if (attack_state = AS_SHOOT) // do shoot attack
{
ai_run_shoot();
return 0;
}
if (CheckAnyAttack()) // check if you can start the actual attack
{
return 0;
}
walk_movetogoal(dist); // else move toward the enemy
}]
// shoot attack setup
ai_run_shoot[()
{
ai_face();
if(FacingIdeal()) // got close enough
{
self.think = SHOOTFUNC; // start shoot attack
attack_state = AS_STRAIGHT;
UpdateTarget();
skill_time = self.time + (SKILL*0.1);
}
}]
ai_face[()
{
self.ideal_yaw = self.enemy_yaw;
ChangeYaw(); // rotate to face enemy
}]
// use walkmove to naviagte to enemy
walk_movetogoal[(dist)
{
if(self.IsFalling = true)
{
return 0; // don't move while falling
}
if(back_up = false)
{
ai_face(); // turn to face enemy
if(FacingIdeal())
{
yaw = self.current_yaw;
if(NearestPoint(10, 500))
{
yaw = GetYawToPoint();
self.ideal_yaw = yaw;
ChangeYaw();
}
if(walkmove(yaw, dist) = true)
{
return 0; // can move in current direction
}
else
{
if(random(1,10)<3) // backup and move sideways
{
back_up = true;
back_time = self.time + 0.5;
back_flag = false;
return 0;
}
else
{
ForceUp(20); // jump up, forward and to side
ForceForward(10);
if(random(1,10)<6)
{
ForceRight(10);
}
else
{
ForceLeft(10);
}
}
}
}
}
else
{
if(back_flag = false) // go backward 1/2 sec
{
if(back_time > self.time)
{
walkmove((self.current_yaw-(3.14159)), dist);
return 0;
}
else
{
back_time = self.time + 0.5;
back_flag = true;
}
}
if(back_time > self.time) // go sideways 1/2 sec
{
walkmove((self.current_yaw-(1.570796)), dist);
return 0;
}
back_up = false;
}
} ]
// check if nearly facing enemy
FacingIdeal[()
{
delta = self.current_yaw - self.ideal_yaw; // difference in directions
if (delta > -0.4 and delta < 0.4) // within ~20 degrees is close enough
{
return true;
}
return false;
}]
// check if ready to do actual attacking
CheckAnyAttack[()
{
if(attack_delay>self.time)
{
return false;
}
if(enemy_range<SHOOTRANGE) // inside missile range
{
attack_state = AS_SHOOT; // do a missile attack
return true;
}
return false;
}]
}
I have tried the following to get a robot pawn to attack the pawn group called robot. It didnt work. Can some please tell me why?
{
IDLE [idle] // idle animation
WALK [walk] // walk animation
DIE [die] // die animation
SHOOT [shoot] // shoot animation
MISC1 [slump] // misc1 animation
GROUP [friendly_robot]
HOSTILEPLAYER [false] // hostile to player
HOSTILESAME [false] // hostile to same Pawn group
TargetGroup [false] // hostile to a certain group, true or false doesnt work
HostileDifferent [true] // hostile to different group, true or false doesnt work
HEALTHATTRIBUTE [enemy_health] // name of pawns health attribute
HEALTH [100] // initial pawn health
DAMAGEATTRIBUTE [health] // attribute damaged by attack
ALERTTRIGGER [AlertG] // name of alert trigger
DIEHOLD [15] // time corpse still appears
DIEFADE [10] // fadeout time of corpse
FOV [360] // field of view
SIGHTDIST [700] // max distance pawn can see at idle
ALERTSIGHTDIST [900] // max distance pawn can see when alert
YAWSPEED [90]
WALKSPEED [50]
SHOOTRANGE [300] // max distance to start missile attack
PROJECTILE [10mm_shell] // projectile name
FIREBONE [Joint15] // projectile launch bone
OFFSETX [0] // launch offsets
OFFSETY [0]
OFFSETZ [25]
ATTACKDELAY [0.5] // time between shots
FIREDELAY [0.1] // delay after animation starts before projectile launch
SKILL [5] // skill level 1 to 10
LOSTTIME [15] // time to search for enemy before giving up
POINTRADIUS [20] // radius from point when considered there
RUNFUNC [run_start] // monster run to attack function
SHOOTFUNC [shoot_start] // monster missile function
LOSTFUNC [lost_target_start] // monster lost target function
AS_NONE [0]
AS_SHOOT [2]
AS_STRAIGHT [3]
attack_delay [0]
lost_time [0]
back_up [false]
back_time [0]
left_time [0]
back_flag [false]
fire_delay [0]
skill_time [0]
attack_state [0]
Spawn[ ()
{
//Console(true);
SetFOV(FOV); // set field of view
BoxWidth(40);
SetGroup(GROUP);
HostilePlayer(HOSTILEPLAYER);
HostileSame(HOSTILESAME);
TargetGroup(robot); //added by me, didnt work
HostileDifferent(robot); //added by me, didnt work
// setup orders
AttributeOrder(HEALTHATTRIBUTE, HEALTH, "Death"); // give monster health
FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE); // seen a target to chase
AvoidOrder("Avoidance"); // avoid obstacles
AddPainOrder("PainToAlert", 100); // show pain and trigger alert
AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0); // go to alert when triggered
RotateToPoint(IDLE, YAWSPEED, false, ""); // go to point if any specified
MoveToPoint(WALK, WALKSPEED, ""); // move to starting point
NewOrder("Patrol");
} ]
Idle[ ()
{
// just look around a bit
Rotate(IDLE, YAWSPEED, 0, 100, 0, "");
Delay(IDLE, random(3,5), "");
Rotate(IDLE, YAWSPEED, 0, -200, 0, "");
Delay(IDLE, random(3,5), "");
Align();
NewOrder("Patrol"); // continue to patrol
} ]
Avoidance[()
{
// backup and move sideways sometimes
MoveBackward(WALK, WALKSPEED, (WALKSPEED/2), "");
if(random(1,10)<6)
{
MoveRight(WALK, WALKSPEED, (WALKSPEED/2), "");
}
else
{
MoveLeft(WALK, WALKSPEED, (WALKSPEED/2), "");
}
Return();
}]
Patrol[ ()
{
// patroling from point to point, looking for special orders in each script point (i.e. "Idle")
NextPoint();
NextOrder();
RotateMoveToPoint(WALK, YAWSPEED, WALKSPEED, false, "");
MoveToPoint(WALK, WALKSPEED, "");
RestartOrder();
}]
PainToAlert[()
{
SetEventState(ALERTTRIGGER, true); // set trigger to go to alert
Return();
}]
IdleToAlert[()
{
FindTargetOrder(ALERTSIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE); // increase viewing
distance
AddTimerOrder(1, LOSTTIME, "AlertToIdle"); // go to idle after 10
secs
SetEventState(ALERTTRIGGER, false); // turn off alert
trigger
NewOrder("Alert");
}]
Alert[()
{
// just look around a bit
Rotate(IDLE, YAWSPEED, 0, 150, 0, "");
Delay(IDLE, random(3,5), "");
Rotate(IDLE, YAWSPEED, 0, -150, 0, "");
Delay(IDLE, random(3,5), "");
RestartOrder();
}]
AlertToIdle[()
{
FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE); // decrease viewing distance
AddPainOrder("PainToAlert", 100); // go to alert when pain
AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0); // go to alert when triggered
NewOrder("Idle");
}]
FoundTarget[()
{
DelTimerOrder(1); // get rid of alert timer
LowLevel(RUNFUNC); // attack functions are low level
}]
LostTarget[ ()
{
FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE); // seen a target to chase
AddPainOrder("PainToAlert", 100); // trigger alert when pain
AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0); // go to alert when triggered
FindPointOrder("Patrol");
NewOrder("Idle");
} ]
Death[()
{
DelTimerOrder(1); // remove alert timer
AddPainOrder("PainToAlert", 0); // remove pain order
FindTargetOrder(0, "FoundTarget", DAMAGEATTRIBUTE); // remove target finding
DelTriggerOrder("IdleToAlert"); // remove alert trigger
SetNoCollision(); // remove bounding box so there are no
collisions with corpse
AnimateStop(DIE, DIEHOLD, "");
FadeOut(DIEFADE, 0); // fade out corpse
Remove(true); // remove actor
}]
// Low level routines
run_start[ ()
{
Animate(WALK); // play animation
self.ThinkTime = 0; // start thinking on next frame
self.ideal_yaw = self.enemy_yaw; // set direction to run
self.yaw_speed = YAWSPEED; // set rotation speed
back_up = false; // initialize obsticle avoidance
attack_state = AS_NONE; // not attacking yet
self.think = "run_to_attack"; // go to run attack routine
} ]
run_to_attack[ ()
{
self.ThinkTime = 0.05;
if(self.health<=0)
{
HighLevel("Death"); // dead
return 0;
}
if(EnemyExist(DAMAGEATTRIBUTE) < 3)
{
HighLevel("LostTarget"); // enemy is gone or dead
return 0;
}
if(self.enemy_vis = false)
{
self.think = LOSTFUNC; // lost sight of enemy
lost_time = self.time + LOSTTIME;
return 0;
}
ai_run(random(WALKSPEED-2, WALKSPEED+2)); // run toward enemy
} ]
// start of lost sight of enemy routine
lost_target_start[()
{
Animate(WALK); // play run animation
self.ThinkTime = 0; // start thinking on next frame
self.think = "lost_target";
}]
// go to last known location of enemy
lost_target[()
{
self.ThinkTime = 0.1;
if(lost_time<self.time)
{
HighLevel("LostTarget"); // timed out while looking
return 0;
}
if(self.health<=0)
{
HighLevel("Death"); // died
return 0;
}
if(EnemyExist(DAMAGEATTRIBUTE) < 3)
{
HighLevel("LostTarget"); // enemy died or was removed
return 0;
}
if(self.enemy_vis = true)
{
self.think = "run_start"; // seen again so run to attack
self.ThinkTime = 0;
return 0;
}
if(self.enemy_range>POINTRADIUS) // get close to last known location
{
walk_movetogoal(random(WALKSPEED-2, WALKSPEED+2));
}
else
{
HighLevel("LostTarget"); // can't find at last known location
return 0;
}
}]
// start of shoot attack
shoot_start[()
{
Animate(SHOOT); // play shoot attack animation
SetHoldAtEnd(true);
self.ThinkTime = 0;
fire_delay = self.time + FIREDELAY; // set firing delay
UpdateTarget(); // update target location
skill_time = self.time + (SKILL*0.1); // calculate next update time
attack_delay = self.time + ATTACKDELAY; // delay until next shot
self.think = "shooting";
}]
// attack target with projectile
shooting[()
{
self.ThinkTime = 0.1;
if(self.health<=0)
{
SetHoldAtEnd(false);
HighLevel("Death"); // dead
return 0;
}
exist = EnemyExist(DAMAGEATTRIBUTE);
if(exist < 2)
{
SetHoldAtEnd(false);
HighLevel("LostTarget"); // enemy is dead and gone
return 0;
}
if(exist = 2)
{
SetHoldAtEnd(false);
HighLevel("LostTarget"); // enemy is dead but body remains
return 0;
}
if(self.enemy_vis = false)
{
self.think = LOSTFUNC; // lost sight of enemy
lost_time = self.time + LOSTTIME;
SetHoldAtEnd(false);
return 0;
}
if(self.enemy_range>SHOOTRANGE)
{
self.think = RUNFUNC; // too far away so run toward
SetHoldAtEnd(false);
return 0;
}
if(skill_time<self.time) // update according to skill level
{
UpdateTarget(); // update target location
skill_time = self.time + (SKILL*0.1);
ai_face(); // face enemy while attacking
}
if(fire_delay<self.time) // delay after animation starts before firing
{
FireProjectile(PROJECTILE, FIREBONE, OFFSETX, OFFSETY, OFFSETZ, DAMAGEATTRIBUTE);
fire_delay = self.time + 1000; // set delay well ahead so it is ignored
}
// wait until animation is done before attacking again
// hold animation at end until attack delay is over
if(self.animate_at_end = true)
{
if(attack_delay < self.time)
{
self.think = "shoot_start"; // go back to missile attack
SetHoldAtEnd(false);
self.ThinkTime = 0.1;
}
}
}]
// basic AI routines
ai_run[(dist)
{
if (attack_state = AS_SHOOT) // do shoot attack
{
ai_run_shoot();
return 0;
}
if (CheckAnyAttack()) // check if you can start the actual attack
{
return 0;
}
walk_movetogoal(dist); // else move toward the enemy
}]
// shoot attack setup
ai_run_shoot[()
{
ai_face();
if(FacingIdeal()) // got close enough
{
self.think = SHOOTFUNC; // start shoot attack
attack_state = AS_STRAIGHT;
UpdateTarget();
skill_time = self.time + (SKILL*0.1);
}
}]
ai_face[()
{
self.ideal_yaw = self.enemy_yaw;
ChangeYaw(); // rotate to face enemy
}]
// use walkmove to naviagte to enemy
walk_movetogoal[(dist)
{
if(self.IsFalling = true)
{
return 0; // don't move while falling
}
if(back_up = false)
{
ai_face(); // turn to face enemy
if(FacingIdeal())
{
yaw = self.current_yaw;
if(NearestPoint(10, 500))
{
yaw = GetYawToPoint();
self.ideal_yaw = yaw;
ChangeYaw();
}
if(walkmove(yaw, dist) = true)
{
return 0; // can move in current direction
}
else
{
if(random(1,10)<3) // backup and move sideways
{
back_up = true;
back_time = self.time + 0.5;
back_flag = false;
return 0;
}
else
{
ForceUp(20); // jump up, forward and to side
ForceForward(10);
if(random(1,10)<6)
{
ForceRight(10);
}
else
{
ForceLeft(10);
}
}
}
}
}
else
{
if(back_flag = false) // go backward 1/2 sec
{
if(back_time > self.time)
{
walkmove((self.current_yaw-(3.14159)), dist);
return 0;
}
else
{
back_time = self.time + 0.5;
back_flag = true;
}
}
if(back_time > self.time) // go sideways 1/2 sec
{
walkmove((self.current_yaw-(1.570796)), dist);
return 0;
}
back_up = false;
}
} ]
// check if nearly facing enemy
FacingIdeal[()
{
delta = self.current_yaw - self.ideal_yaw; // difference in directions
if (delta > -0.4 and delta < 0.4) // within ~20 degrees is close enough
{
return true;
}
return false;
}]
// check if ready to do actual attacking
CheckAnyAttack[()
{
if(attack_delay>self.time)
{
return false;
}
if(enemy_range<SHOOTRANGE) // inside missile range
{
attack_state = AS_SHOOT; // do a missile attack
return true;
}
return false;
}]
}