Ok, so this is the full script. The problem is that I didn't take any damage from the zombie's attack. I'm sick of the inventory. Every time I need to use the armor, I must go to the inventory and activate it. It is very annoying. I want the armor to be activated all the the time. I think this is the easiest way to do it
Code: Select all
{
// Generic Melee Ambush Monster
// Definitions used to customize monster
GROUP [Zombie] // name of monster group
BOXWIDTH [80] // width and depth of bounding box
HOSTILEPLAYER [true] // hostile to player
HOSTILEDIFFERENT [true] // hostile to different Pawn group
HOSTILESAME [false] // hostile to same Pawn group
HEALTHATTRIBUTE [enemy_health] // name of health attribute
HEALTH [500] // initial amount of health
SIGHTDIST [1000] // max distance monster can see at idle
ALERTSIGHTDIST [1100] // max distance monster can see when alert
FOV [500] // field of view in degrees
YAWSPEED [200] // speed of rotation in deg/sec
DAMAGEATTRIBUTE [health] // attribute damaged by attack
DAMAGEATTRIBUTE1 [power_vest armor]
ALERTTRIGGER [Alert] // triggername used to go to alert mode
// Animations and variables associated with them
STAND [IdleZ] // idle animation
TURNL [TurnL] // turn left animation
TURNR [TurnR] // turn right animation
PAIN [IDLE] // pain animations
PAINPERCENT [50] // percentage of time pain is shown
DIE [Die2] // dying animations
DIEHOLD [2] // time corpse still appears
DIEFADE [1] // fadeout time of corpse
RUN [walk2] // running animation
RUNSPEED [100] // average run speed
MELEEATTACK [Attack2] // melee attacking animation
MELEERANGE [70] // max distance to start melee attack
MELEEDAMAGE [25] // maximum amount of damage per melee attack
MELEEDELAY [1] // number of seconds between melee damages
OFFSETX [0] // launch offsets
OFFSETY [0]
OFFSETZ [17]
LOSTTIME [15] // time to search for enemy before giving up
POINTRADIUS [20] // radius from point when considered at point
// local variables - do not change
RUNFUNC [monster_run_start] // monster run to attack function
MELEEFUNC [monster_melee_start] // monster melee function
LOSTFUNC [monster_lost_target_start] // monster lost target function
AS_NONE [0]
AS_MELEE [2]
AS_STRAIGHT [3]
melee_time [0]
lost_time [0]
back_up [true]
back_time [0]
left_time [0]
back_flag [false]
attack_state [0]
// spawn pawn and do setup work
Spawn[ ()
{
Console(true);
BoxWidth(BOXWIDTH); // set bounding box width/depth
AttributeOrder(HEALTHATTRIBUTE, HEALTH, "Death"); // give monster health
HostilePlayer(HOSTILEPLAYER); // set who monster is hostile to
HostileSame(HOSTILESAME);
HostileDifferent(HOSTILEDIFFERENT);
SetFOV(FOV); // set field of view
SetGroup(GROUP); // assign a group to belong to
FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE); // seen a target to chase
AddPainOrder("IdlePain", 100); // show pain and trigger alert
AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0); // go to alert when triggered
NewOrder("Idle");
} ]
// idle in place waiting for something to happen
Idle[ ()
{
PlayAnimation(STAND, true, "zombie groan 1.wav",""); // stand at idle
if(random(1,10)>6) // turn side to side sometimes
{
if(random(1,10)>5) // turn to left 90 degrees and turn back
{
Rotate(TURNL, 102, 0, 90, 0, "");
PlayAnimation(STAND, true, "");
Rotate(TURNR, 108, 0, -90, 0, "");
}
else // turn to right 90 degrees and turn back
{
Rotate(TURNR, 108, 0, -90, 0, "");
PlayAnimation(STAND, true, "");
Rotate(TURNL, 102, 0, 90, 0, "");
}
}
RestartOrder();
} ]
// show pain at idle then trigger to alert
IdlePain[ ()
{
PlayAnimate(PAIN, true, "");
AddExplosion("Bullet_ActorExplosion", "Bip01", OFFSETX, OFFSETY, OFFSETZ, DAMAGEATTRIBUTE);
SetEventState(ALERTTRIGGER, true); // set trigger to go to alert
Return();
} ]
// start shifting from idle to alert
IdleToAlert[ ()
{
FindTargetOrder(ALERTSIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE); // increase viewing distance
AddPainOrder("AlertPain", PAINPERCENT); // show pain
AddTimerOrder(1, 10, "AlertToIdle"); // go to idle after 10 secs
SetEventState(ALERTTRIGGER, false); // turn off alert trigger
NewOrder("Alert");
} ]
// look around at alert looking for enemy
Alert[ ()
{
PlayAnimation(STAND, true, "");
if(random(1,10)>3) // turn around once in awhile
{
if(random(1,10)>5) // turn around to left
{
Rotate(TURNL, 102, 0, 90, 0, "");
Rotate(TURNL, 102, 0, 90, 0, "");
Rotate(TURNL, 102, 0, 90, 0, "");
Rotate(TURNL, 102, 0, 90, 0, "");
}
else // turn around to right
{
Rotate(TURNR, 108, 0, -90, 0, "");
Rotate(TURNR, 108, 0, -90, 0, "");
Rotate(TURNR, 108, 0, -90, 0, "");
Rotate(TURNR, 108, 0, -90, 0, "");
}
}
RestartOrder();
} ]
// show pain at alert
AlertPain[ ()
PlayAnimation(PAIN, true, "");
AddExplosion("Bullet_ActorExplosion", "Bip01", OFFSETX, OFFSETY, OFFSETZ, DAMAGEATTRIBUTE);
Return();
} ]
// timed out at alert so go to idle
AlertToIdle[ ()
{
FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE); // decrease viewing distance
AddPainOrder("IdlePain", 100); // show pain
AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0); // go to alert when triggered
NewOrder("Idle");
} ]
// found a target to attack
FoundTarget[ ()
{
DelTimerOrder(1); // get rid of alert timer
LowLevel(RUNFUNC); // attack functions are low level
} ]
// lost target while attacking so go back to idle again
LostTarget[ ()
{
FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE); // seen a target to chase
AddPainOrder("IdlePain", 100); // show pain and trigger alert
AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0); // go to alert when triggered
NewOrder("Idle");
} ]
// killed target so back to idle
DeadTarget[ ()
{
FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE); // seen a target to chase
AddPainOrder("IdlePain", 100); // show pain and trigger alert
AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0); // go to alert when triggered
NewOrder("Idle");
} ]
// you died
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 attack routines
// Start of run to attack
monster_run_start[ ()
{
Animate(RUN); // play run animation
self.ThinkTime = 0; // start thinking on next frame
self.think = "monster_run"; // go to run attack routine
self.ideal_yaw = enemy_yaw;
attack_state = AS_NONE; // not attacking yet
self.yaw_speed = YAWSPEED; // set rotation speed
melee_time = time;
back_up = true; // setup obsticle avoidance
} ]
// run to enemy to attack
monster_run[ ()
{
self.ThinkTime = 0.1; // think every 1/10 sec
if(self.health<=0)
{
HighLevel("Death"); // dead
return 0;
}
if((self.in_pain = true) and (random(1,100)<PAINPERCENT))
{
self.think = "monster_run_pain_start"; // in pain
return 0;
}
if(EnemyExist(DAMAGEATTRIBUTE) < 3)
{
HighLevel("LostTarget"); // enemy is gone or dead
return 0;
}
if(enemy_vis = false)
{
self.think = LOSTFUNC; // lost sight of enemy
lost_time = time + LOSTTIME;
return 0;
}
ai_run(random(RUNSPEED-2,RUNSPEED+2)); // run toward enemy
} ]
// start of pain while running
monster_run_pain_start[ ()
{
Animate(RUN); // play pain animation
AddExplosion("Bullet_ActorExplosion", "Bip01", OFFSETX, OFFSETY, OFFSETZ, DAMAGEATTRIBUTE);
SetHoldAtEnd(true); // set to stop at end
SetHoldAtEnd(false); // set to stop at animation end
self.ThinkTime = 0.05;
self.think = "monster_run_pain";
} ]
// wait for animation to stop
monster_run_pain[ ()
{
self.ThinkTime = 0.05;
if(self.animate_at_end = true) // wait for end of animation
{
self.think = "monster_run_start"; // start running again
SetHoldAtEnd(false); // remove animation stop
self.ThinkTime = 0;
}
} ]
// start of lost sight of enemy routine
monster_lost_target_start[ ()
{
Animate(RUN);
self.ThinkTime = 0.1;
self.think = "monster_lost_target";
} ]
// go to last known location of enemy
monster_lost_target[ ()
{
self.ThinkTime = 0.1;
if(lost_time<time)
{
HighLevel("LostTarget");
return 0;
}
if(self.health<=0)
{
HighLevel("Death"); // died
return 0;
}
if(EnemyExist(DAMAGEATTRIBUTE) < 3)
{
HighLevel("LostTarget");
return 0;
}
if(enemy_vis = true)
{
self.think = "monster_run_start";
self.ThinkTime = 0;
return 0;
}
if(enemy_range>POINTRADIUS)
{
walk_movetogoal(random(RUNSPEED-2,RUNSPEED+2));
}
else
{
HighLevel("LostTarget");
return 0;
}
} ]
// start of melee attack
monster_melee_start[ ()
{
Animate(MELEEATTACK, "zombie groan 1.wav", "");
self.ThinkTime = 0;
self.think = "monster_melee";
} ]
// melee attack
monster_melee[ ()
{
self.ThinkTime = 0.1;
if(self.health<=0)
{
HighLevel("Death");
return 0;
}
exist = EnemyExist(DAMAGEATTRIBUTE);
if(exist < 2)
{
HighLevel("LostTarget");
return 0;
}
if(exist = 2)
{
HighLevel("DeadTarget");
return 0;
}
if(enemy_vis = false)
{
self.think = LOSTFUNC;
lost_time = time + LOSTTIME;
return 0;
}
if(enemy_range>MELEERANGE)
{
self.think = RUNFUNC;
return 0;
}
ai_face();
if(time > melee_time)
{
damage = (MELEEDAMAGE); // get damage amount
damage1 = (MELEEDAMAGE - (MELEEDAMAGE * 0.80));
damage2 = (MELEEDAMAGE - (MELEEDAMAGE * 0.50));
damage3 = (MELEEDAMAGE - (MELEEDAMAGE * 0.70));
if (DAMAGEATTRIBUTE1 = 0)
{
Damage(damage, DAMAGEATTRIBUTE);
}
else
{
if (DAMAGEATTRIBUTE1 <= damage2)
{
Damage(damage3, DAMAGEATTRIBUTE);
Damage(damage2, DAMAGEATTRIBUTE1);
}
else
{
Damage(damage1, DAMAGEATTRIBUTE);
Damage(damage2, DAMAGEATTRIBUTE1);
}
}
melee_time = time + MELEEDELAY; // reset time until next damage
}
} ]
// basic AI routines
// run toward enemy and see if you are ready to attack
ai_run[ (dist)
{
if (attack_state = AS_MELEE) // do melee attack
{
ai_run_melee();
return 0;
}
if (CheckAnyAttack()) // check if you can start the actual attack
{
return 0;
}
walk_movetogoal(dist); // move toward the enemy
} ]
// melee attack setup
ai_run_melee[ ()
{
ai_face(); // turn to face target
if(FacingIdeal()) // got close enough
{
self.think = MELEEFUNC; // start melee attack
self.attack_state = AS_STRAIGHT;
}
} ]
// face enemy
ai_face[ ()
{
self.ideal_yaw = enemy_yaw;
ChangeYaw(); // rotate to face enemy
} ]
// use walkmove to navigate to enemy
walk_movetogoal[ (dist)
{
if(IsFalling = true)
{
return 0; // don't move while falling
}
if(back_up = false)
{
ai_face(); // turn to face enemy
if(FacingIdeal())
{
if(walkmove(self.current_yaw, dist) = true)
{
return 0; // can move in current direction
}
else // blocked
{
if(random(1,10)<3) // backup and move sideways sometimes
{
back_up = true;
back_time = time + 0.5;
back_flag = false;
return 0;
}
else
{
ForceUp(30); // jump up, forward and to side
ForceForward(30);
if(random(1,10)<6)
{
ForceRight(30);
}
else
{
ForceLeft(30);
}
}
}
}
}
else
{
if(back_flag = false) // go backward 1/2 sec
{
if(back_time > time)
{
walkmove((self.current_yaw-(180*0.0174532925199433)), dist);
return 0;
}
else
{
back_time = time + 0.5;
back_flag = true;
}
}
if(back_time > time) // go sideways 1/2 sec
{
walkmove((self.current_yaw-(90*0.0174532925199433)), dist);
return 0;
}
back_up = false;
}
} ]
// check if nearly facing enemy
FacingIdeal[ ()
{
selfangle = self.current_yaw/0.0174532925199433; // your direction in degrees
idealangle = self.ideal_yaw/0.0174532925199433; // his direction in degrees
delta = selfangle - idealangle; // difference in directions
if (delta > -20 and delta < 20) // within 20 degrees is close enough
{
return true;
}
return false;
} ]
// check if ready to do actual attacking
CheckAnyAttack[ ()
{
if(enemy_range<MELEERANGE) // inside melee range
{
attack_state = AS_MELEE; // do a melee attack
return true;
}
return false;
} ]
}