746 lines
16 KiB
C++
746 lines
16 KiB
C++
|
|
||
|
//**************************************************************************
|
||
|
//**
|
||
|
//** scorpion.hc
|
||
|
//** bgokey
|
||
|
//**
|
||
|
//** $Header: /HexenWorld/HCode/scorpion.hc 1 2/04/98 1:59p Rjohnson $
|
||
|
//**
|
||
|
//**************************************************************************
|
||
|
|
||
|
// FRAMES ------------------------------------------------------------------
|
||
|
|
||
|
// Attack 1 (claw and tail)
|
||
|
$frame ScAttA1 ScAttA2 ScAttA3 ScAttA4 ScAttA5
|
||
|
$frame ScAttA6 ScAttA7 ScAttA8 ScAttA9 ScAttA10
|
||
|
$frame ScAttA11 ScAttA12 ScAttA13 ScAttA14 ScAttA15
|
||
|
$frame ScAttA16 ScAttA17 ScAttA18 ScAttA19 ScAttA20
|
||
|
$frame ScAttA21 ScAttA22 ScAttA23 ScAttA24 ScAttA25
|
||
|
|
||
|
// Attack 2 (claw only)
|
||
|
$frame ScAttB1 ScAttB2 ScAttB3 ScAttB4 ScAttB5
|
||
|
$frame ScAttB6 ScAttB7 ScAttB8 ScAttB9 ScAttB10
|
||
|
$frame ScAttB11 ScAttB12 ScAttB13 ScAttB14 ScAttB15
|
||
|
$frame ScAttB16 ScAttB17 ScAttB18 ScAttB19 ScAttB20
|
||
|
$frame ScAttB21 ScAttB22 ScAttB23 ScAttB24 ScAttB25
|
||
|
$frame ScAttB26 ScAttB27
|
||
|
|
||
|
// Attack 3 (tail only)
|
||
|
$frame ScAttC1 ScAttC2 ScAttC3 ScAttC4 ScAttC5
|
||
|
$frame ScAttC6 ScAttC7 ScAttC8 ScAttC9 ScAttC10
|
||
|
$frame ScAttC11 ScAttC12 ScAttC13 ScAttC14 ScAttC15
|
||
|
$frame ScAttC16 ScAttC17 ScAttC18 ScAttC19 ScAttC20
|
||
|
$frame ScAttC21 ScAttC22
|
||
|
|
||
|
// Death
|
||
|
$frame SCDead1 SCDead2 SCDead3 SCDead4 SCDead5
|
||
|
$frame SCDead6 SCDead7 SCDead8 SCDead9 SCDead10
|
||
|
$frame SCDead11 SCDead12 SCDead13 SCDead14 SCDead15
|
||
|
$frame SCDead16 SCDead17 SCDead18 SCDead19 SCDead20
|
||
|
$frame SCDead21
|
||
|
|
||
|
// Pain
|
||
|
$frame ScPain1 ScPain2 ScPain3 ScPain4 ScPain5
|
||
|
$frame ScPain6 ScPain7 ScPain8 ScPain9 ScPain10
|
||
|
|
||
|
// Transition from standing to attack pose
|
||
|
$frame ScRedy1 ScRedy2 ScRedy3 ScRedy4 ScRedy5
|
||
|
$frame ScRedy6 ScRedy7 ScRedy8 ScRedy9 ScRedy10
|
||
|
$frame ScRedy11
|
||
|
|
||
|
// Transition from standing to walk
|
||
|
$frame ScStep1 ScStep2 ScStep3 ScStep4
|
||
|
|
||
|
// Transition from walk to standing
|
||
|
$frame ScStop1 ScStop2 ScStop3 ScStop4 ScStop5
|
||
|
$frame ScStop6 ScStop7 ScStop8 ScStop9
|
||
|
|
||
|
// Wake from resting (ScWake1 = resting)
|
||
|
$frame ScWake1 ScWake2 ScWake3 ScWake4 ScWake5
|
||
|
$frame ScWake6 ScWake7 ScWake8 ScWake9 ScWake10
|
||
|
$frame ScWake11 ScWake12 ScWake13 ScWake14 ScWake15
|
||
|
$frame ScWake16 ScWake17 ScWake18 ScWake19 ScWake20
|
||
|
$frame ScWake21 ScWake22 ScWake23 ScWake24 ScWake25
|
||
|
$frame ScWake26 ScWake27 ScWake28 ScWake29 ScWake30
|
||
|
|
||
|
// Walk
|
||
|
$frame ScWalk1 ScWalk2 ScWalk3 ScWalk4 ScWalk5
|
||
|
$frame ScWalk6 ScWalk7 ScWalk8 ScWalk9 ScWalk10
|
||
|
$frame ScWalk11 ScWalk12 ScWalk13 ScWalk14 ScWalk15
|
||
|
$frame ScWalk16
|
||
|
|
||
|
// CONSTANTS ---------------------------------------------------------------
|
||
|
|
||
|
float SCORPION_YELLOW = 0;
|
||
|
float SCORPION_BLACK = 1;
|
||
|
|
||
|
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||
|
|
||
|
void ScorpionInit(float type);
|
||
|
void ScorpionStand(void);
|
||
|
void ScorpionWake(void);
|
||
|
void ScorpionWalk(void);
|
||
|
void ScorpionRun(void);
|
||
|
void ScorpionRunBlack(void);
|
||
|
void ScorpionPainDecide(void);
|
||
|
void ScorpionPain(void);
|
||
|
void ScorpionMeleeDecide(void);
|
||
|
void ScorpionMelee1(void);
|
||
|
void ScorpionMelee2(void);
|
||
|
void ScorpionMelee3(void);
|
||
|
void ScorpionMelee4(void);
|
||
|
void ScorpionDie(void);
|
||
|
void ScorpionDieInit(void);
|
||
|
entity ScorpionLookProjectiles(void);
|
||
|
float ScorpionCheckDefense(void);
|
||
|
void ScorpionStrafeDefense(void);
|
||
|
|
||
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||
|
|
||
|
float ScorpionStandFrames[6] =
|
||
|
{
|
||
|
$scwake1, $scwake2, $scwake3, $scwake4, $scwake3, $scwake2
|
||
|
};
|
||
|
|
||
|
// CODE --------------------------------------------------------------------
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// monster_scorpion_yellow
|
||
|
//
|
||
|
//==========================================================================
|
||
|
/*QUAKED monster_scorpion_yellow (1 0.3 0) (-10 -10 0) (10 10 64) AMBUSH
|
||
|
Yellow scorpion.
|
||
|
------- key / value ----------------------------
|
||
|
health = 100
|
||
|
experience_value = 60
|
||
|
------- spawnflags -----------------------------
|
||
|
AMBUSH
|
||
|
*/
|
||
|
|
||
|
void monster_scorpion_yellow(void)
|
||
|
{
|
||
|
ScorpionInit(SCORPION_YELLOW);
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// monster_scorpion_black
|
||
|
//
|
||
|
//==========================================================================
|
||
|
/*QUAKED monster_scorpion_black (1 0.3 0) (-10 -10 0) (10 10 64) AMBUSH
|
||
|
Black scorpion.
|
||
|
------- key / value ----------------------------
|
||
|
health = 200
|
||
|
experience_value = 150
|
||
|
------- spawnflags -----------------------------
|
||
|
AMBUSH
|
||
|
*/
|
||
|
|
||
|
void monster_scorpion_black(void)
|
||
|
{
|
||
|
ScorpionInit(SCORPION_BLACK);
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionInit
|
||
|
//
|
||
|
//==========================================================================
|
||
|
|
||
|
void ScorpionInit(float type)
|
||
|
{
|
||
|
if(deathmatch)
|
||
|
{
|
||
|
remove(self);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if not(self.flags2&FL_SUMMONED)
|
||
|
{
|
||
|
precache_model2("models/scorpion.mdl");
|
||
|
|
||
|
precache_sound2("scorpion/awaken.wav");
|
||
|
precache_sound2("scorpion/walk.wav");
|
||
|
precache_sound2("scorpion/clawsnap.wav");
|
||
|
precache_sound2("scorpion/tailwhip.wav");
|
||
|
precache_sound2("scorpion/pain.wav");
|
||
|
precache_sound2("scorpion/death.wav");
|
||
|
}
|
||
|
setmodel(self, "models/scorpion.mdl");
|
||
|
|
||
|
self.solid = SOLID_SLIDEBOX;
|
||
|
self.movetype = MOVETYPE_STEP;
|
||
|
self.thingtype = THINGTYPE_FLESH;
|
||
|
|
||
|
if (type == SCORPION_YELLOW)
|
||
|
self.yaw_speed = 8;
|
||
|
else
|
||
|
self.yaw_speed = 10;
|
||
|
|
||
|
self.mass = 9;
|
||
|
self.mintel = 4;
|
||
|
|
||
|
//self.touch = SUB_Null;
|
||
|
//self.use = SUB_Null;
|
||
|
setsize(self, '-16 -16 0', '16 16 64');
|
||
|
|
||
|
if(type == SCORPION_YELLOW)
|
||
|
{
|
||
|
self.health = 100;
|
||
|
self.experience_value = 60;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
self.health = 200;
|
||
|
self.experience_value = 150;
|
||
|
}
|
||
|
|
||
|
self.takedamage = DAMAGE_YES;
|
||
|
|
||
|
self.th_stand = ScorpionStand;
|
||
|
self.th_walk = ScorpionWalk;
|
||
|
|
||
|
if(type == SCORPION_BLACK)
|
||
|
self.th_run = ScorpionRunBlack;
|
||
|
else
|
||
|
self.th_run = ScorpionRun;
|
||
|
|
||
|
self.th_melee = ScorpionMeleeDecide;
|
||
|
self.th_pain = ScorpionPainDecide;
|
||
|
self.th_die = ScorpionDieInit;
|
||
|
|
||
|
self.view_ofs = '0 0 12';
|
||
|
|
||
|
self.scorpionType = type;
|
||
|
if(type == SCORPION_BLACK)
|
||
|
{
|
||
|
self.skin = 1;
|
||
|
}
|
||
|
walkmonster_start();
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionStand
|
||
|
//
|
||
|
//==========================================================================
|
||
|
|
||
|
void ScorpionStand(void)
|
||
|
{
|
||
|
self.think = ScorpionStand;
|
||
|
self.nextthink = time + 0.2;
|
||
|
self.scorpionRest += 2;
|
||
|
if(self.scorpionRest < 0 || self.scorpionRest > 5)
|
||
|
{
|
||
|
self.scorpionRest = 0;
|
||
|
}
|
||
|
self.frame = ScorpionStandFrames[self.scorpionRest];
|
||
|
ai_stand();
|
||
|
if(self.think != ScorpionStand)
|
||
|
{ // Wake up
|
||
|
self.th_save = self.think;
|
||
|
self.think = ScorpionWake;
|
||
|
sound(self, CHAN_VOICE, "scorpion/awaken.wav", 1, ATTN_NORM);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionWake
|
||
|
//
|
||
|
//==========================================================================
|
||
|
|
||
|
void ScorpionWake(void) [++ $scwake1..$scwake30]
|
||
|
{
|
||
|
if(cycle_wrapped)
|
||
|
{
|
||
|
self.cnt = time;
|
||
|
self.think = self.th_save;
|
||
|
self.think();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionWalk
|
||
|
//
|
||
|
//==========================================================================
|
||
|
|
||
|
void ScorpionWalk(void) [++ $scwalk1..$scwalk16]
|
||
|
{
|
||
|
if(((self.scorpionWalkCount += 1)&3) == 0)
|
||
|
{
|
||
|
sound(self, CHAN_BODY, "scorpion/walk.wav", random(0.9, 1), ATTN_NORM);
|
||
|
}
|
||
|
ai_walk(2);
|
||
|
if(random()<0.1)
|
||
|
pitch_roll_for_slope('0 0 0');
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionRunBlack
|
||
|
//
|
||
|
//==========================================================================
|
||
|
|
||
|
void ScorpionRunBlack(void) [++ $scwalk1..$scwalk16]
|
||
|
{
|
||
|
float enemy_dist;
|
||
|
|
||
|
if(((self.scorpionWalkCount += 1)&3) == 0)
|
||
|
{
|
||
|
sound(self, CHAN_BODY, "scorpion/walk.wav", random(0.9, 1), ATTN_NORM);
|
||
|
}
|
||
|
|
||
|
if ((self.enemy.last_attack > time - 1) && (fov(self, self.enemy, 45)))
|
||
|
{
|
||
|
if (ScorpionCheckDefense())
|
||
|
{
|
||
|
ScorpionStrafeDefense();
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (self.attack_state == AS_SLIDING)
|
||
|
if ((random() < 0.8) && (self.cnt <= time))
|
||
|
{
|
||
|
self.cnt = time + random(0.5, 1.0);
|
||
|
self.attack_state = AS_STRAIGHT;
|
||
|
ScorpionMelee4();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
enemy_dist = vlen(self.enemy.origin - self.origin);
|
||
|
|
||
|
if (enemy_dist < 120)
|
||
|
{
|
||
|
if ((random() < 0.33) && (infront(self.enemy)) && (self.cnt <= time))
|
||
|
{
|
||
|
self.attack_state = AS_SLIDING;
|
||
|
|
||
|
self.cnt = time + random(0.5, 1.0);
|
||
|
self.lefty = random(0,1);
|
||
|
if (self.lefty < 0.5) self.lefty = 0;
|
||
|
else self.lefty = 1;
|
||
|
|
||
|
ai_run(10);
|
||
|
return;
|
||
|
}
|
||
|
else if (!infront(self.enemy))
|
||
|
self.attack_state = AS_STRAIGHT;
|
||
|
}
|
||
|
else self.attack_state = AS_STRAIGHT;
|
||
|
|
||
|
ai_run(8);
|
||
|
if(random()<0.1)
|
||
|
pitch_roll_for_slope('0 0 0');
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionRun
|
||
|
//
|
||
|
//==========================================================================
|
||
|
|
||
|
void ScorpionRun(void) [++ $scwalk1..$scwalk16]
|
||
|
{
|
||
|
float enemy_dist;
|
||
|
|
||
|
if(((self.scorpionWalkCount += 1)&3) == 0)
|
||
|
{
|
||
|
sound(self, CHAN_BODY, "scorpion/walk.wav", random(0.9, 1), ATTN_NORM);
|
||
|
}
|
||
|
|
||
|
|
||
|
if ((self.enemy.last_attack > time - 1) && (fov(self, self.enemy, 45)))
|
||
|
{
|
||
|
if (ScorpionCheckDefense())
|
||
|
{
|
||
|
ScorpionStrafeDefense();
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (self.attack_state == AS_SLIDING)
|
||
|
if ((random() < 0.5) && (self.cnt <= time))
|
||
|
{
|
||
|
self.cnt = time + random(0.5, 1.0);
|
||
|
self.attack_state = AS_STRAIGHT;
|
||
|
ScorpionMelee4();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
enemy_dist = vlen(self.enemy.origin - self.origin);
|
||
|
|
||
|
if (enemy_dist < 120)
|
||
|
{
|
||
|
if ((random() < 0.33) && (infront(self.enemy)) && (self.cnt <= time))
|
||
|
{
|
||
|
self.attack_state = AS_SLIDING;
|
||
|
|
||
|
self.cnt = time + random(0.5, 1.0);
|
||
|
self.lefty = random(0,1);
|
||
|
if (self.lefty < 0.5) self.lefty = 0;
|
||
|
else self.lefty = 1;
|
||
|
|
||
|
ai_run(10);
|
||
|
return;
|
||
|
}
|
||
|
else if (!infront(self.enemy))
|
||
|
self.attack_state = AS_STRAIGHT;
|
||
|
}
|
||
|
else self.attack_state = AS_STRAIGHT;
|
||
|
|
||
|
ai_run(6);
|
||
|
if(random()<0.1)
|
||
|
pitch_roll_for_slope('0 0 0');
|
||
|
}
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionPainDecide
|
||
|
//
|
||
|
//==========================================================================
|
||
|
|
||
|
void ScorpionPainDecide(void)
|
||
|
{
|
||
|
if(random() < 0.3)
|
||
|
{
|
||
|
ScorpionPain();
|
||
|
sound(self, CHAN_VOICE, "scorpion/pain.wav", 1, ATTN_NORM);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionPain
|
||
|
//
|
||
|
//==========================================================================
|
||
|
|
||
|
void ScorpionPain(void) [++ $scpain1..$scpain10]
|
||
|
{
|
||
|
if(cycle_wrapped)
|
||
|
{
|
||
|
self.th_run();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionMelee
|
||
|
//
|
||
|
//==========================================================================
|
||
|
void ScorpionMelee(float damage)
|
||
|
{
|
||
|
vector source;
|
||
|
|
||
|
makevectors (self.angles);
|
||
|
source = self.origin;
|
||
|
traceline (source, source + v_forward*60, FALSE, self);
|
||
|
|
||
|
if (trace_ent != self.enemy) return;
|
||
|
|
||
|
damage += random(0.1, 1);
|
||
|
T_Damage (self.enemy, self, self, damage);
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionMeleeDecide
|
||
|
//
|
||
|
//==========================================================================
|
||
|
|
||
|
void ScorpionMeleeDecide(void)
|
||
|
{
|
||
|
float r;
|
||
|
|
||
|
r = random();
|
||
|
self.last_attack=time;
|
||
|
if (self.classname == "monster_scorpion_black")
|
||
|
{
|
||
|
if(r < 0.2)
|
||
|
{
|
||
|
ScorpionMelee1();
|
||
|
}
|
||
|
else if(r < 0.4)
|
||
|
{
|
||
|
ScorpionMelee2();
|
||
|
}
|
||
|
else if (r < 0.6)
|
||
|
{
|
||
|
ScorpionMelee3();
|
||
|
}
|
||
|
else
|
||
|
ScorpionMelee4();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(r < 0.3)
|
||
|
{
|
||
|
ScorpionMelee1();
|
||
|
}
|
||
|
else if(r < 0.6)
|
||
|
{
|
||
|
ScorpionMelee2();
|
||
|
}
|
||
|
else if (r < 0.9)
|
||
|
{
|
||
|
ScorpionMelee3();
|
||
|
}
|
||
|
else
|
||
|
ScorpionMelee4();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionMelee1
|
||
|
//
|
||
|
//==========================================================================
|
||
|
|
||
|
void ScorpionMelee1(void) [++ $scatta1..$scatta25]
|
||
|
{
|
||
|
if(self.frame == $scatta4 || self.frame == $scatta9)
|
||
|
{
|
||
|
sound(self, CHAN_VOICE, "scorpion/clawsnap.wav", 1, ATTN_NORM);
|
||
|
ScorpionMelee(1);
|
||
|
}
|
||
|
else if(self.frame == $scatta14)
|
||
|
{
|
||
|
sound(self, CHAN_BODY, "scorpion/tailwhip.wav", 1, ATTN_NORM);
|
||
|
ScorpionMelee(1);
|
||
|
}
|
||
|
|
||
|
if(self.frame > $scatta16 && self.frame < $scatta20)
|
||
|
{
|
||
|
ai_charge(4);
|
||
|
if (self.classname == "monster_scorpion_yellow")
|
||
|
ScorpionMelee(2);
|
||
|
else
|
||
|
ScorpionMelee(3);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ai_charge(2);
|
||
|
}
|
||
|
|
||
|
if(cycle_wrapped)
|
||
|
self.think = self.th_run;
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionMelee2
|
||
|
//
|
||
|
//==========================================================================
|
||
|
|
||
|
void ScorpionMelee2(void) [++ $scattb1..$scattb27]
|
||
|
{
|
||
|
if(self.frame == $scattb4 || self.frame == $scattb8
|
||
|
|| self.frame == $scattb13)
|
||
|
{
|
||
|
sound(self, CHAN_VOICE, "scorpion/clawsnap.wav", 1, ATTN_NORM);
|
||
|
ScorpionMelee(1);
|
||
|
}
|
||
|
|
||
|
if(self.frame > $scattb16 && self.frame < $scattb20)
|
||
|
{
|
||
|
ai_charge(4);
|
||
|
if (self.classname == "monster_scorpion_yellow")
|
||
|
ScorpionMelee(2);
|
||
|
else
|
||
|
ScorpionMelee(3);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ai_charge(2);
|
||
|
}
|
||
|
if(cycle_wrapped)
|
||
|
self.think = self.th_run;
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionMelee3
|
||
|
//
|
||
|
//==========================================================================
|
||
|
|
||
|
void ScorpionMelee3(void) [++ $scattc1..$scattc22]
|
||
|
{
|
||
|
if(self.frame == $scattc9)
|
||
|
{
|
||
|
sound(self, CHAN_BODY, "scorpion/tailwhip.wav", 1, ATTN_NORM);
|
||
|
ScorpionMelee(1);
|
||
|
}
|
||
|
|
||
|
if(self.frame > $scattc16 && self.frame < $scattc20)
|
||
|
{
|
||
|
ai_charge(4);
|
||
|
if (self.classname == "monster_scorpion_yellow")
|
||
|
ScorpionMelee(2);
|
||
|
else
|
||
|
ScorpionMelee(3);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ai_charge(2);
|
||
|
}
|
||
|
if(cycle_wrapped)
|
||
|
self.think = self.th_run;
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionMelee4
|
||
|
//
|
||
|
//==========================================================================
|
||
|
|
||
|
void ScorpionMelee4(void) [++ $scatta1..$scatta25]
|
||
|
{
|
||
|
if (self.frame == $scatta4 || self.frame == $scatta9)
|
||
|
{
|
||
|
sound(self, CHAN_VOICE, "scorpion/clawsnap.wav", 1, ATTN_NORM);
|
||
|
ScorpionMelee(1);
|
||
|
}
|
||
|
else if(self.frame == $scatta14)
|
||
|
{
|
||
|
sound(self, CHAN_BODY, "scorpion/tailwhip.wav", 1, ATTN_NORM);
|
||
|
if (self.classname == "monster_scorpion_yellow")
|
||
|
ScorpionMelee(2);
|
||
|
else
|
||
|
ScorpionMelee(3);
|
||
|
}
|
||
|
|
||
|
if(self.frame > $scatta16 && self.frame < $scatta20)
|
||
|
{
|
||
|
ai_charge(16);
|
||
|
if (self.classname == "monster_scorpion_yellow")
|
||
|
ScorpionMelee(2);
|
||
|
else
|
||
|
ScorpionMelee(4);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ai_charge(12);
|
||
|
}
|
||
|
if(cycle_wrapped)
|
||
|
self.think = self.th_run;
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionStrafeDefense
|
||
|
//
|
||
|
//==========================================================================
|
||
|
|
||
|
void ScorpionStrafeDefense(void) [++ $scwalk1..$scwalk8]
|
||
|
{
|
||
|
float ofs;
|
||
|
|
||
|
if (cycle_wrapped)
|
||
|
{
|
||
|
thinktime self : 0.1;
|
||
|
self.think = self.th_run;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
makevectors(self.v_angle);
|
||
|
|
||
|
if (self.lefty == -1)
|
||
|
ofs = 90;
|
||
|
else
|
||
|
ofs = -90;
|
||
|
|
||
|
if (walkmove (self.ideal_yaw + ofs, 10, FALSE))
|
||
|
return;
|
||
|
|
||
|
walkmove (self.ideal_yaw - ofs, 10, FALSE);
|
||
|
if (self.lefty == -1)
|
||
|
self.lefty = 1;
|
||
|
else self.lefty = -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionCheckDefense
|
||
|
//
|
||
|
//==========================================================================
|
||
|
|
||
|
float ScorpionCheckDefense()
|
||
|
{
|
||
|
entity enemy_proj;
|
||
|
float r;
|
||
|
|
||
|
enemy_proj=ScorpionLookProjectiles();
|
||
|
|
||
|
if (!enemy_proj) return 0;
|
||
|
|
||
|
r=range(enemy_proj);
|
||
|
|
||
|
self.lefty=check_heading_left_or_right(enemy_proj);
|
||
|
|
||
|
if(r==RANGE_NEAR)
|
||
|
{
|
||
|
if (random() < 0.2)
|
||
|
return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionLookProjectiles
|
||
|
//
|
||
|
//==========================================================================
|
||
|
entity ScorpionLookProjectiles ()
|
||
|
{
|
||
|
entity found, enemy_proj;
|
||
|
|
||
|
found=findradius(self.origin,1000);
|
||
|
while(found)
|
||
|
{
|
||
|
if(found.movetype==MOVETYPE_FLYMISSILE||found.movetype==MOVETYPE_BOUNCE||found.movetype==MOVETYPE_BOUNCEMISSILE)
|
||
|
if(visible(found))
|
||
|
{
|
||
|
if(heading(self,found,0.9))
|
||
|
enemy_proj=found;
|
||
|
}
|
||
|
found=found.chain;
|
||
|
}
|
||
|
if(enemy_proj)
|
||
|
return enemy_proj;
|
||
|
else
|
||
|
return world;
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// ScorpionDie
|
||
|
//
|
||
|
//==========================================================================
|
||
|
|
||
|
|
||
|
void ScorpionDie(void)
|
||
|
{
|
||
|
if(self.frame == $scdead21)
|
||
|
{
|
||
|
MakeSolidCorpse();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
if(self.health < -30)
|
||
|
{
|
||
|
chunk_death();
|
||
|
}
|
||
|
|
||
|
self.frame += 1;
|
||
|
thinktime self : HX_FRAME_TIME;
|
||
|
}
|
||
|
|
||
|
void ScorpionDieInit(void) [$scdead1 ScorpionDie]
|
||
|
{
|
||
|
sound(self, CHAN_VOICE, "scorpion/death.wav", 1, ATTN_NORM);
|
||
|
}
|