1623 lines
36 KiB
C++
1623 lines
36 KiB
C++
/*
|
|
* $Header: /HexenWorld/Siege/mezzoman.hc 8 6/01/98 2:49a Mgummelt $
|
|
*/
|
|
|
|
/*
|
|
==============================================================================
|
|
|
|
Q:\art\models\monsters\mezzoman\FINAL\mezzoman.hc
|
|
MG!!!
|
|
==============================================================================
|
|
*/
|
|
|
|
// For building the model
|
|
$cd Q:\art\models\monsters\mezzoman\FINAL
|
|
$origin 0 0 -2
|
|
$base BASE skin1
|
|
$skin skin1
|
|
$skin Skin2
|
|
$flags 16384
|
|
|
|
//
|
|
$frame block1 block2 block3 block4 block5
|
|
$frame block6
|
|
|
|
//
|
|
$frame charge1 charge2 charge3 charge4 charge5
|
|
$frame charge6 charge7 charge8 charge9 charge10
|
|
$frame charge11 charge12 charge13 charge14 charge15
|
|
$frame charge16 charge17 charge18 charge19 charge20
|
|
$frame charge21 charge22 charge23 charge24 charge25
|
|
|
|
//
|
|
$frame clober1 clober2 clober3 clober4 clober5
|
|
$frame clober6 clober7 clober8 clober9 clober10
|
|
$frame clober11 clober12 clober13 clober14 clober15
|
|
$frame clober16
|
|
|
|
//
|
|
$frame death1 death2 death3 death4 death5
|
|
$frame death6 death7 death8 death9 death10
|
|
$frame death11 death12 death13 death14 death15
|
|
$frame death16
|
|
|
|
//
|
|
$frame dive1 dive2 dive3 dive4 dive5
|
|
$frame dive6 dive7 dive8 dive9 dive10
|
|
$frame dive11 dive12 dive13 dive14 dive15
|
|
$frame dive16 dive17 dive18
|
|
|
|
//
|
|
$frame jump1 jump2 jump3 jump4 jump5
|
|
$frame jump6 jump7 jump8 jump9 jump10
|
|
$frame jump11 jump12 jump13 jump14 jump15
|
|
$frame jump16 jump17 jump18 jump19 jump20
|
|
$frame jump21 jump22
|
|
|
|
//
|
|
$frame pain1 pain2 pain3 pain4 pain5
|
|
$frame pain6 pain7
|
|
|
|
//
|
|
$frame roar1 roar2 roar3 roar4 roar5
|
|
$frame roar6 roar7 roar8 roar9 roar10
|
|
$frame roar11 roar12 roar13 roar14 roar15
|
|
$frame roar16 roar17 roar18 roar19 roar20
|
|
$frame roar21 roar22 roar23 roar24 roar25
|
|
$frame roar26 roar27 roar28 roar29 roar30
|
|
|
|
//
|
|
$frame Roll1 Roll2 Roll3 Roll4 Roll5
|
|
$frame Roll6 Roll7 Roll8 Roll9 Roll10
|
|
$frame Roll11 Roll12 Roll13 Roll14 Roll15
|
|
$frame Roll16 Roll17 Roll18
|
|
|
|
//
|
|
$frame run1 run2 run3 run4 run5
|
|
$frame run6 run7 run8 run9 run10
|
|
$frame run11 run12 run13 run14 run15
|
|
$frame run16 run17 run18 run19 run20
|
|
$frame run21 run22
|
|
|
|
//
|
|
$frame stand1 stand2 stand3 stand4 stand5
|
|
$frame stand6 stand7 stand8 stand9 stand10
|
|
|
|
//
|
|
$frame sword1 sword2 sword3 sword4 sword5
|
|
$frame sword6 sword7 sword8 sword9 sword10
|
|
$frame sword11 sword12 sword13
|
|
|
|
//
|
|
$frame twirl1 twirl2 twirl3 twirl4 twirl5
|
|
$frame twirl6 twirl7 twirl8 twirl9 twirl10
|
|
|
|
//
|
|
$frame walk1 walk2 walk3 walk4 walk5
|
|
$frame walk6 walk7 walk8 walk9 walk10
|
|
$frame walk11 walk12 walk13 walk14 walk15
|
|
$frame walk16 walk17 walk18 walk19 walk20
|
|
$frame walk21 walk22 walk23 walk24 walk25
|
|
$frame walk26 walk27 walk28 walk29 walk30
|
|
|
|
|
|
void() mezzo_skid;
|
|
void() mezzo_block;
|
|
void() mezzo_block_wait;
|
|
void() mezzo_jump;
|
|
void() mezzo_roar;
|
|
void() mezzo_in_air;
|
|
void() mezzo_run_loop;
|
|
void()mezzo_charge;
|
|
|
|
void mezzo_idle_sound ()
|
|
{
|
|
string soundstr;
|
|
if(random()<0.5)
|
|
soundstr="mezzo/snort.wav";
|
|
else
|
|
soundstr="mezzo/growl.wav";
|
|
sound(self,CHAN_VOICE,soundstr,1,ATTN_NORM);
|
|
}
|
|
|
|
/*
|
|
void mezzo_possum_up (void)// [-- $death14..$death1]
|
|
{
|
|
if (cycle_wrapped)
|
|
self.think=self.th_run;
|
|
}
|
|
|
|
void mezzo_playdead (void)
|
|
{
|
|
// self.frame=$death14;
|
|
self.think=mezzo_playdead;
|
|
thinktime self : 0.1;
|
|
ai_stand();
|
|
}
|
|
*/
|
|
|
|
void mezzo_roll_right () [-- $Roll18 .. $Roll1]
|
|
{
|
|
// if(self.shield.velocity!='0 0 0'&&self.shield.model!="models/null.spr")
|
|
// dprint("what the?\n");
|
|
//SOUND?
|
|
vector rollangle;
|
|
makevectors(self.angles);
|
|
rollangle=vectoangles(v_right);
|
|
// if(!walkmove(rollangle_y,7,FALSE)&&self.frame>$Roll5 &&self.flags&FL_ONGROUND)
|
|
// self.frame=$Roll5;
|
|
walkmove(rollangle_y,7,FALSE);
|
|
if(cycle_wrapped)
|
|
{
|
|
thinktime self : 0;
|
|
if(!self.flags&FL_ONGROUND)
|
|
self.think=mezzo_in_air;
|
|
else
|
|
self.think=self.th_run;
|
|
}
|
|
}
|
|
|
|
void mezzo_roll_left () [++ $Roll1 .. $Roll18]
|
|
{
|
|
// if(self.shield.velocity!='0 0 0'&&self.shield.model!="models/null.spr")
|
|
// dprint("what the?\n");
|
|
//SOUND?
|
|
vector rollangle;
|
|
makevectors(self.angles);
|
|
rollangle=vectoangles(v_right);
|
|
// if(!walkmove(rollangle_y,-7,FALSE)&&self.frame<$Roll14 &&self.flags&FL_ONGROUND)
|
|
// self.frame=$Roll14;
|
|
walkmove(rollangle_y,-7,FALSE);
|
|
if(cycle_wrapped)
|
|
{
|
|
thinktime self : 0;
|
|
if(!self.flags&FL_ONGROUND)
|
|
self.think=mezzo_in_air;
|
|
else
|
|
self.think=self.th_run;
|
|
}
|
|
}
|
|
|
|
void mezzo_roll_forward () [++ $dive1 .. $dive18]
|
|
{
|
|
//SOUND?
|
|
//vector rollangle;
|
|
// if(!walkmove(self.angles_y,7,FALSE)&&self.frame<$dive12 &&self.flags&FL_ONGROUND)
|
|
// self.frame=$dive12;
|
|
if(!self.flags&FL_ONGROUND)
|
|
{
|
|
if(!infront(self.enemy))//stay facing enemy so if land behind him, will be facing him
|
|
ai_face();
|
|
}
|
|
else
|
|
{
|
|
if(self.dflags)
|
|
{
|
|
sound(self,CHAN_BODY,"player/land.wav",1,ATTN_NORM);
|
|
self.dflags=FALSE;
|
|
}
|
|
walkmove(self.angles_y,7,FALSE);
|
|
}
|
|
|
|
if(cycle_wrapped)
|
|
{
|
|
thinktime self : 0;
|
|
if(!self.flags&FL_ONGROUND)
|
|
self.think=mezzo_in_air;
|
|
else
|
|
self.think=self.th_run;
|
|
}
|
|
}
|
|
|
|
void mezzo_duck () [++ $jump13 .. $jump22]
|
|
{
|
|
//FIXME: Have him keep checking for befense when staying down for .5 sec
|
|
vector newmaxs;
|
|
if(self.frame==$jump14)
|
|
{
|
|
newmaxs=self.maxs;
|
|
newmaxs_z=self.maxs_z*0.5;
|
|
setsize(self,self.mins,newmaxs);
|
|
}
|
|
else if(self.frame==$jump18)
|
|
{
|
|
newmaxs=self.maxs;
|
|
newmaxs_z=self.maxs_z*2;
|
|
setsize(self,self.mins,newmaxs);
|
|
}
|
|
else if(self.frame==$jump16)
|
|
thinktime self : 0.5;
|
|
else if(cycle_wrapped)
|
|
{
|
|
thinktime self : 0;
|
|
self.think=self.th_run;
|
|
}
|
|
}
|
|
|
|
float mezzo_check_duck (entity proj)
|
|
{
|
|
entity proj_owner;
|
|
vector proj_mins,duck_hite,proj_dir;
|
|
vector temp_f,temp_r,temp_u;
|
|
|
|
duck_hite=self.origin;
|
|
duck_hite_z=self.origin_z + self.maxs_z/2;
|
|
if(proj==self.enemy)
|
|
{
|
|
proj_owner=proj;
|
|
proj_mins=self.enemy.origin+self.enemy.proj_ofs;
|
|
temp_f=v_forward;
|
|
temp_r=v_right;
|
|
temp_u=v_up;
|
|
if(self.enemy.classname=="player")
|
|
makevectors(self.enemy.v_angle);
|
|
else
|
|
makevectors(self.enemy.angles);
|
|
proj_dir=v_forward;
|
|
v_forward=temp_f;
|
|
v_right=temp_r;
|
|
v_up=temp_u;
|
|
}
|
|
else
|
|
{
|
|
proj_owner=proj.owner;
|
|
proj_mins=proj.origin;
|
|
proj_mins_z=proj.origin_z - proj.mins_z;
|
|
proj_dir=normalize(duck_hite-proj_mins);
|
|
}
|
|
if(!proj_owner)
|
|
proj_owner=proj;
|
|
|
|
traceline(proj_mins,duck_hite+proj_dir*8,FALSE,proj_owner);
|
|
|
|
if(trace_ent!=self)//||trace_endpos_z>duck_hite_z)
|
|
{
|
|
dprint(trace_ent.classname);
|
|
dprint(" at end of trace- ok to duck!\n");
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
float mezzo_check_jump (entity proj)
|
|
{
|
|
float impact_hite, jump_hite;
|
|
vector proj_dir, proj_top;
|
|
|
|
if(!self.flags&FL_ONGROUND)
|
|
return FALSE;
|
|
|
|
proj_dir=normalize(proj.velocity);
|
|
proj_top=proj.origin;
|
|
proj_top_z=proj.absmax_z;
|
|
traceline(proj_top,proj_top+proj_dir*1000,FALSE,proj);
|
|
if(trace_ent!=self)
|
|
return FALSE;
|
|
|
|
impact_hite=trace_endpos_z;
|
|
tracearea(self.origin,self.origin+'0 0 256',self.mins,self.maxs,FALSE,self);
|
|
jump_hite=trace_fraction*256;
|
|
if(jump_hite<24)
|
|
return FALSE;
|
|
else if(jump_hite>133)
|
|
jump_hite=133;
|
|
else if(jump_hite<77)
|
|
jump_hite=77;
|
|
|
|
if(self.origin_z+jump_hite/2>impact_hite+proj.maxs_z&&random()<0.7)
|
|
{
|
|
self.velocity_z=jump_hite*3;
|
|
self.flags(-)FL_ONGROUND;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void mezzo_choose_roll (entity proj)
|
|
{
|
|
float proj_dir;
|
|
proj_dir=check_heading_left_or_right(proj);
|
|
if(proj_dir==0)
|
|
{
|
|
if(mezzo_check_duck(proj))
|
|
{
|
|
thinktime self : 0;
|
|
self.think=mezzo_duck;
|
|
}
|
|
else
|
|
{
|
|
thinktime self : 0;
|
|
self.think=mezzo_block;
|
|
}
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
//FIXME: Probably shouldn't try to roll in the other direction
|
|
makevectors(self.angles);
|
|
if(solid_under(self.origin, self.origin+v_right*105*proj_dir))
|
|
tracearea(self.origin, self.origin+v_right*105*proj_dir,self.mins,self.maxs,FALSE,self);
|
|
else
|
|
trace_fraction=FALSE;
|
|
if(trace_fraction==1)
|
|
{
|
|
traceline(trace_endpos, trace_endpos-'0 0 300',TRUE,self);
|
|
if(pointcontents(trace_endpos)!=CONTENT_EMPTY)
|
|
trace_fraction=FALSE;
|
|
else
|
|
trace_fraction=TRUE;
|
|
}
|
|
if(trace_fraction==1)
|
|
{
|
|
if(proj_dir>0)
|
|
{
|
|
thinktime self : 0;
|
|
self.think=mezzo_roll_right;
|
|
}
|
|
else
|
|
{
|
|
thinktime self : 0;
|
|
self.think=mezzo_roll_left;
|
|
}
|
|
return;
|
|
}
|
|
else if(mezzo_check_duck(proj))
|
|
{
|
|
thinktime self : 0;
|
|
self.think=mezzo_duck;
|
|
}
|
|
else
|
|
{
|
|
thinktime self : 0;
|
|
self.think=mezzo_block;
|
|
}
|
|
/* {
|
|
tracearea(self.origin, self.origin+v_right*36*proj_dir*-1,self.mins,self.maxs,FALSE,self);
|
|
if(trace_fraction==1)
|
|
{
|
|
if(proj_dir*-1>0)
|
|
{
|
|
thinktime self : 0;
|
|
self.think=mezzo_roll_right;
|
|
}
|
|
else
|
|
{
|
|
thinktime self : 0;
|
|
self.think=mezzo_roll_left;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
|
|
void mezzo_check_defense ()
|
|
{
|
|
// if(self.shield.velocity!='0 0 0'&&self.shield.model!="models/null.spr")
|
|
// dprint("what the?\n");
|
|
//NOTE: Add random chance of failure based on difficulty level - highest diff means no chance of failure here
|
|
if(skill+self.strength/5<random(6))
|
|
return;
|
|
|
|
if((self.enemy.last_attack+0.5<time&&self.oldenemy.last_attack+0.5<time)||self.aflag)
|
|
return;
|
|
|
|
entity enemy_proj;
|
|
float r;
|
|
enemy_proj=look_projectiles();
|
|
|
|
if(!enemy_proj)
|
|
if(lineofsight(self,self.enemy))
|
|
{
|
|
enemy_proj=self.enemy;
|
|
self.level=vlen(self.enemy.origin-self.origin)/1000;
|
|
}
|
|
else
|
|
return;
|
|
|
|
if(self.flags&FL_ONGROUND)
|
|
self.velocity='0 0 0';//Clear velocity from last jump so he doesn't go nuts
|
|
|
|
r=range(enemy_proj);
|
|
if(self.enemy.weapon==IT_WEAPON1&&r<=RANGE_NEAR&&self.enemy.playerclass!=CLASS_SUCCUBUS)
|
|
{
|
|
thinktime self : 0;
|
|
if(r==RANGE_MELEE)
|
|
{
|
|
if(random()<0.7||self.enemy.v_angle_x>=0)
|
|
self.think=mezzo_duck;
|
|
else if(self.think==mezzo_block_wait)
|
|
{
|
|
self.t_width=time+1;
|
|
return;
|
|
}
|
|
else if(self.think==mezzo_run_loop||random()<0.3)
|
|
self.think=mezzo_charge;
|
|
else
|
|
self.think=mezzo_block;
|
|
return;
|
|
}
|
|
else if(random()<0.5)
|
|
mezzo_choose_roll(enemy_proj);
|
|
else if(random()<0.7||self.enemy.v_angle_x>=0)
|
|
self.think=mezzo_duck;
|
|
else if(self.think==mezzo_block_wait)
|
|
{
|
|
self.t_width=time+1;
|
|
return;
|
|
}
|
|
else if(self.think==mezzo_block_wait)
|
|
{
|
|
self.t_width=time+1;
|
|
return;
|
|
}
|
|
else if(self.think==mezzo_run_loop||random()<0.3)
|
|
self.think=mezzo_charge;
|
|
else
|
|
self.think=mezzo_block;
|
|
return;
|
|
}
|
|
|
|
if(self.level>0.3)//I've got 0.3 seconds before impact
|
|
{
|
|
mezzo_choose_roll(enemy_proj);
|
|
return;
|
|
}
|
|
else if(mezzo_check_duck(enemy_proj))
|
|
{
|
|
thinktime self : 0;
|
|
tracearea(self.origin,self.origin+v_forward*64,self.mins,'16 16 20',FALSE,self);
|
|
if(trace_fraction<1||random()<0.2||!infront(enemy_proj))
|
|
self.think=mezzo_duck;
|
|
else
|
|
self.think=mezzo_roll_forward;
|
|
return;
|
|
}
|
|
else if(mezzo_check_jump(enemy_proj))
|
|
{
|
|
self.think=mezzo_jump;
|
|
enemy_infront=infront(self.enemy);
|
|
enemy_vis=visible(self.enemy);
|
|
trace_fraction=0;
|
|
if((random()<0.3||self.think==mezzo_run_loop)&&enemy_infront&&enemy_vis&&self.enemy!=world)//Jump towards enemy
|
|
{
|
|
vector enemy_dir;
|
|
enemy_dir=normalize(self.enemy.origin-self.origin);
|
|
traceline(self.origin,self.origin+enemy_dir*64+'0 0 56',FALSE,self);
|
|
if(trace_fraction==1)
|
|
{
|
|
traceline(trace_endpos,trace_endpos-'0 0 300',TRUE,self);
|
|
if(pointcontents(trace_endpos)==CONTENT_EMPTY)
|
|
{
|
|
self.velocity_x=self.velocity_y=0;
|
|
self.velocity+=enemy_dir*vlen(self.enemy.origin-self.origin);
|
|
trace_fraction=1;
|
|
if(random()<0.7)
|
|
self.think=mezzo_roll_forward;
|
|
else
|
|
self.think=self.th_jump;
|
|
}
|
|
else
|
|
{
|
|
// dprint("might land in water or lava\n");
|
|
trace_fraction=0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// dprint("not enough room in front \n");
|
|
trace_fraction=0;
|
|
}
|
|
}
|
|
// dprint(ftos(trace_fraction));
|
|
// dprint(" is the trace_fraction\n");
|
|
if(random()<0.5&&trace_fraction<1)//Jump to side
|
|
{
|
|
// dprint("checking to sides\n");
|
|
if(random()<0.5)
|
|
r=1;
|
|
else
|
|
r=-1;
|
|
makevectors(self.angles);
|
|
traceline(self.origin,self.origin+v_right*36*r+'0 0 56',FALSE,self);
|
|
if(trace_fraction<1)
|
|
{
|
|
traceline(self.origin,self.origin-v_right*36*r+'0 0 56',FALSE,self);
|
|
if(trace_fraction<1)
|
|
{
|
|
// dprint("not enough room to jump on that side\n");
|
|
self.think=mezzo_jump;
|
|
}
|
|
else
|
|
{
|
|
traceline(trace_endpos,trace_endpos-'0 0 300',TRUE,self);
|
|
if(pointcontents(trace_endpos)!=CONTENT_EMPTY)
|
|
{
|
|
// dprint("might jump into water or lava\n");
|
|
self.think=mezzo_jump;
|
|
}
|
|
else
|
|
{
|
|
self.velocity-=v_right*r*200;
|
|
if(r*-1>0)
|
|
self.think=mezzo_roll_right;
|
|
else
|
|
self.think=mezzo_roll_left;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
traceline(trace_endpos,trace_endpos-'0 0 300',TRUE,self);
|
|
if(pointcontents(trace_endpos)!=CONTENT_EMPTY)
|
|
{
|
|
// dprint("might jump into water or lava\n");
|
|
self.think=mezzo_jump;
|
|
}
|
|
else
|
|
{
|
|
self.velocity+=v_right*r*200;
|
|
if(r>0)
|
|
self.think=mezzo_roll_right;
|
|
else
|
|
self.think=mezzo_roll_left;
|
|
}
|
|
}
|
|
}
|
|
thinktime self : 0;
|
|
if(self.think!=mezzo_jump&&self.think!=mezzo_roll_right&&self.think!=mezzo_roll_left&&self.think!=mezzo_roll_forward)
|
|
{
|
|
// dprint("What the FUCK!!!\n");
|
|
self.think=mezzo_jump;
|
|
}
|
|
// return;
|
|
}
|
|
else if(infront(enemy_proj)&&random()<0.5)
|
|
{
|
|
thinktime self : 0;
|
|
if(self.think==mezzo_block_wait)
|
|
{
|
|
self.t_width=time+1;
|
|
return;
|
|
}
|
|
else if(self.think==mezzo_run_loop||random()<0.3)
|
|
self.think=mezzo_charge;
|
|
else
|
|
self.think=mezzo_block;
|
|
return;
|
|
}
|
|
}
|
|
|
|
void() mezzo_charge_stop;
|
|
void mezzo_slam ()
|
|
{
|
|
if(!other.movetype||other.mass>100||other.solid==SOLID_BSP)
|
|
return;
|
|
|
|
if(!infront(other)||other.safe_time>time)
|
|
return;
|
|
|
|
if(other.origin_z>self.absmax_z - 6||other.absmax_z<self.origin_z + 6)
|
|
return;
|
|
|
|
sound(self,CHAN_VOICE,"mezzo/slam.wav",1,ATTN_NORM);
|
|
|
|
float inertia;
|
|
if(other.mass<10)
|
|
inertia=1;
|
|
else
|
|
inertia=other.mass/10;
|
|
|
|
vector punchdir;
|
|
makevectors(self.angles);
|
|
punchdir=v_forward*300+'0 0 100';
|
|
T_Damage(other,self,self,5*(self.strength+1)*(self.aflag+1)*2);//(coop + 1));
|
|
other.velocity+=punchdir*(1/inertia);
|
|
other.flags(-)FL_ONGROUND;
|
|
|
|
self.ltime+=1;
|
|
other.safe_time=time+1.25;//So can't kill them instantly if they're moving against him or pinned on a wall
|
|
if(self.think!=mezzo_charge_stop)
|
|
{
|
|
thinktime self : 0;
|
|
self.think=mezzo_charge_stop;
|
|
}
|
|
}
|
|
|
|
void mezzo_reflect_trig_touch ()
|
|
{
|
|
//vector newv;
|
|
vector org, vec, dir;//, endspot,endplane, dif;
|
|
float magnitude;//remainder, reflect_count,
|
|
|
|
if (other.flags & FL_MONSTER || other.flags & FL_CLIENT || !other || other == self) return;
|
|
|
|
if (other.safe_time>time) return;
|
|
|
|
if(!self.owner.flags2&FL_ALIVE||self.owner.frozen>0)
|
|
{
|
|
if(self.owner.movechain==self)
|
|
self.owner.movechain=world;
|
|
remove(self);
|
|
}
|
|
|
|
if(other.classname=="funnal"||other.classname=="tornato")
|
|
return;
|
|
|
|
dir = normalize(other.velocity);
|
|
magnitude=vlen(other.velocity);
|
|
org = other.origin;
|
|
vec = org + dir*100;
|
|
traceline (org, vec, FALSE, other);
|
|
|
|
if(trace_ent!=self.owner)
|
|
return;
|
|
|
|
if(self.owner.classname=="monster_mezzoman")
|
|
sound(self,CHAN_AUTO,"mezzo/slam.wav",1,ATTN_NORM);
|
|
|
|
if(!self.owner.strength&&self.owner.classname=="monster_mezzoman")
|
|
{//Just block it
|
|
if(!other.flags2&FL_ALIVE)
|
|
other.flags2(+)FL_NODAMAGE;
|
|
}
|
|
else
|
|
{//reflect!
|
|
if(self.owner.classname!="monster_mezzoman")
|
|
{
|
|
sound (self, CHAN_WEAPON, "fangel/deflect.wav", 1, ATTN_NORM);
|
|
CreateWhiteFlash(trace_endpos);
|
|
if(self.owner.classname=="monster_fallen_angel")
|
|
{
|
|
dir=dir*-1;
|
|
makevectors(dir);
|
|
dir=v_forward + v_up*random(-0.75,.75) + v_right*random(-0.75,.75);
|
|
dir=normalize(dir);
|
|
}
|
|
else// if(visible(other.owner))
|
|
{
|
|
v_forward=normalize(other.owner.origin+other.owner.view_ofs-other.origin);
|
|
dir+= 2*v_forward;
|
|
dir=normalize(dir);
|
|
}
|
|
// else
|
|
// dir=dir*-1;
|
|
}
|
|
else
|
|
{
|
|
sound(self,CHAN_AUTO,"mezzo/reflect.wav",1,ATTN_NORM);
|
|
starteffect(CE_MEZZO_REFLECT,self.origin);
|
|
makevectors(trace_ent.angles);
|
|
dir+= 2*v_forward;
|
|
dir=normalize(dir);
|
|
}
|
|
|
|
if(other.movedir)
|
|
other.movedir=dir;
|
|
if(other.o_angle)
|
|
other.o_angle=dir;
|
|
|
|
if(magnitude<other.speed)
|
|
{
|
|
// dprintf("Low mag : %s\n",magnitude);
|
|
magnitude=other.speed;
|
|
}
|
|
other.velocity = dir*magnitude;
|
|
other.angles = vectoangles(other.velocity);
|
|
|
|
self.owner.last_attack=time;
|
|
other.safe_time=time+100/magnitude;
|
|
|
|
if(!other.controller)
|
|
other.controller=other.owner;
|
|
if(other.enemy==self.owner)
|
|
other.enemy=other.owner;
|
|
if(other.goalentity==self.owner)
|
|
other.goalentity=other.owner;
|
|
other.owner=self.owner;
|
|
}
|
|
}
|
|
|
|
void reflect_think ()
|
|
{
|
|
makevectors(self.owner.angles);
|
|
setorigin(self,self.owner.origin+ v_forward*48+'0 0 40');
|
|
self.think=reflect_think;
|
|
thinktime self : 0.05;
|
|
}
|
|
|
|
void spawn_reflect ()
|
|
{
|
|
//FIXME: Picks up enemy missile as shield! shield not necc?
|
|
makevectors(self.angles);
|
|
newmis=spawn();
|
|
self.shield=newmis;
|
|
newmis.movetype = MOVETYPE_NOCLIP;
|
|
newmis.solid = SOLID_TRIGGER;
|
|
newmis.owner = self;
|
|
newmis.touch = mezzo_reflect_trig_touch;
|
|
newmis.classname="mezzo_reflect";
|
|
newmis.effects=EF_NODRAW;
|
|
|
|
setmodel(newmis,"models/null.spr");
|
|
if(self.classname=="monster_mezzoman")
|
|
{
|
|
setsize (newmis, '-32 -32 -30','32 32 30');
|
|
setorigin(newmis,self.origin+ v_forward*48+'0 0 40');
|
|
|
|
newmis.think=reflect_think;
|
|
thinktime newmis : 0;
|
|
}
|
|
else
|
|
{
|
|
self.movechain=newmis;
|
|
setsize (newmis, '-48 -48 -64','48 48 50');
|
|
setorigin(newmis,self.origin);
|
|
}
|
|
}
|
|
|
|
void mezzo_clobber() [++ $clober1 .. $clober16]
|
|
{
|
|
float zofs;
|
|
ai_charge(1);
|
|
if(self.frame==$clober7)
|
|
{
|
|
makevectors(self.angles);
|
|
|
|
zofs = self.enemy.origin_z - self.origin_z;
|
|
if(zofs>20)
|
|
zofs=20;
|
|
else if(zofs<-20)
|
|
zofs=-20;
|
|
|
|
traceline(self.origin+'0 0 30',self.origin+'0 0 30'+v_forward*36+v_up*zofs,FALSE,self);
|
|
if(trace_fraction==1)
|
|
return;
|
|
|
|
sound(self,CHAN_VOICE,"mezzo/slam.wav",1,ATTN_NORM);
|
|
|
|
if(trace_ent.movetype&&trace_ent.movetype!=MOVETYPE_PUSH)
|
|
trace_ent.velocity+=v_forward*200-v_right*100+'0 0 100';
|
|
if(trace_ent.takedamage)
|
|
T_Damage(trace_ent,self,self,5*(self.strength+1)*(self.aflag+1)*2);//(coop + 1));
|
|
if(trace_ent.classname=="player")
|
|
if(infront_of_ent(self,trace_ent))
|
|
trace_ent.punchangle_y=4;
|
|
}
|
|
else if(cycle_wrapped)
|
|
{
|
|
self.attack_finished=time+0.5;
|
|
thinktime self : 0;
|
|
self.think=self.th_run;
|
|
}
|
|
else if(self.frame==$clober1)
|
|
{
|
|
self.last_attack=time;
|
|
if(random()<0.5)
|
|
sound(self,CHAN_VOICE,"mezzo/attack.wav",1,ATTN_NORM);
|
|
}
|
|
}
|
|
|
|
/*
|
|
void mezzo_sword() [++ $sword1 .. $sword13]
|
|
{
|
|
ai_face();
|
|
ai_charge(3);
|
|
if(cycle_wrapped)
|
|
{
|
|
self.attack_finished=time+0.3;
|
|
thinktime self : 0;
|
|
self.think=self.th_run;
|
|
}
|
|
else if(self.frame==$sword1)
|
|
{
|
|
self.last_attack=time;
|
|
sound(self,CHAN_WEAPON,"weapons/vorpswng.wav",1,ATTN_NORM);
|
|
if(random()<0.5)
|
|
sound(self,CHAN_VOICE,"mezzo/attack.wav",1,ATTN_NORM);
|
|
}
|
|
else if(self.frame>=$sword6 && self.frame<=$sword10)
|
|
{
|
|
float ofs,zofs;
|
|
vector dir;
|
|
makevectors(self.angles);
|
|
ofs=($sword10 - self.frame)*4;
|
|
dir_z=ofs - 8;
|
|
dir+=v_right*(ofs - 8)+v_forward*(48 - fabs(16 - ofs));
|
|
dir=normalize(dir);
|
|
|
|
zofs = self.enemy.origin_z - self.origin_z;
|
|
if(zofs>20)
|
|
zofs=20;
|
|
else if(zofs<-20)
|
|
zofs=-20;
|
|
|
|
traceline(self.origin+'0 0 37',self.origin+'0 0 37'+dir*48+v_up*zofs,FALSE,self);
|
|
if(trace_fraction==1)
|
|
return;
|
|
|
|
if(self.t_width<time)
|
|
{
|
|
MetalHitSound(trace_ent.thingtype);
|
|
self.t_width=time+1;
|
|
}
|
|
|
|
if(trace_ent.takedamage)
|
|
T_Damage(trace_ent,self,self,2*(self.strength+1)*(self.aflag+1)*2);//(coop + 1));
|
|
if(trace_ent.thingtype==THINGTYPE_FLESH&&self.frame==$sword9)
|
|
{
|
|
MeatChunks (trace_endpos,v_right*random(-100,-300)+'0 0 200', 3,trace_ent);
|
|
sound(self,CHAN_AUTO,"weapons/slash.wav",1,ATTN_NORM);
|
|
}
|
|
SpawnPuff (trace_endpos, '0 0 0', 3,trace_ent);
|
|
}
|
|
}
|
|
*/
|
|
void mezzo_sword() [++ $sword1 .. $sword13]
|
|
{
|
|
ai_face();
|
|
ai_charge(3);
|
|
if(cycle_wrapped)
|
|
{
|
|
if(skill>=4)
|
|
self.attack_finished=0;
|
|
else
|
|
self.attack_finished=time+0.3;
|
|
thinktime self : 0;
|
|
self.think=self.th_run;
|
|
}
|
|
else if(self.frame==$sword1)
|
|
{
|
|
self.last_attack=time;
|
|
sound(self,CHAN_WEAPON,"weapons/vorpswng.wav",1,ATTN_NORM);
|
|
if(random()<0.5)
|
|
sound(self,CHAN_VOICE,"mezzo/attack.wav",1,ATTN_NORM);
|
|
}
|
|
else if(self.frame>=$sword6 && self.frame<=$sword10)
|
|
{
|
|
float ofs,zofs;
|
|
vector dir;
|
|
makevectors(self.angles);
|
|
ofs=($sword10 - self.frame)*4;
|
|
dir=v_right*(ofs - 8)+v_forward*(48 - fabs(16 - ofs))+'0 0 1'*(ofs - 8);
|
|
dir=normalize(dir);
|
|
|
|
zofs = (self.enemy.origin_z+self.enemy.view_ofs_z) - (self.origin_z+37);
|
|
if(zofs>36)
|
|
zofs=36;
|
|
else if(zofs<-36)
|
|
zofs=-36;
|
|
|
|
traceline(self.origin+'0 0 37'+'0 0 1'*zofs,self.origin+'0 0 37'+dir*48+'0 0 1'*zofs,FALSE,self);
|
|
if(trace_fraction==1)
|
|
return;
|
|
|
|
if(self.t_width<time)
|
|
{
|
|
MetalHitSound(trace_ent.thingtype);
|
|
self.t_width=time+1;
|
|
}
|
|
|
|
if(trace_ent.takedamage)
|
|
T_Damage(trace_ent,self,self,(2+skill)*(self.strength+1)*(self.aflag+1)*(coop + 1));
|
|
if(trace_ent.thingtype==THINGTYPE_FLESH&&self.frame==$sword9)
|
|
{
|
|
MeatChunks (trace_endpos,v_right*random(-100,-300)+'0 0 200', 3,trace_ent);
|
|
sound(self,CHAN_AUTO,"weapons/slash.wav",1,ATTN_NORM);
|
|
}
|
|
SpawnPuff (trace_endpos, '0 0 0', 3,trace_ent);
|
|
}
|
|
}
|
|
|
|
void mezzo_melee ()
|
|
{
|
|
if(random()<0.3)
|
|
self.think=mezzo_clobber;
|
|
else
|
|
self.think=mezzo_sword;
|
|
thinktime self : 0;
|
|
}
|
|
|
|
void mezzo_missile ()
|
|
{
|
|
if(vlen(self.enemy.origin-self.origin)<84&&lineofsight(self.enemy,self))
|
|
self.think=mezzo_charge;
|
|
else
|
|
self.think=self.th_run;
|
|
thinktime self : 0;
|
|
}
|
|
|
|
void mezzo_die () [++ $death1 .. $death16]
|
|
{
|
|
if(self.shield)
|
|
remove(self.shield);
|
|
if (self.health < -40)
|
|
{
|
|
chunk_death();
|
|
return;
|
|
}
|
|
if(self.frame==$death1)
|
|
sound(self,CHAN_VOICE,"mezzo/die.wav",1,ATTN_NORM);
|
|
else if(self.frame==$death12)
|
|
sound(self,CHAN_BODY,"player/land.wav",1,ATTN_NORM);
|
|
else if(self.frame==$death16)
|
|
MakeSolidCorpse();
|
|
thinktime self : 0.1;
|
|
}
|
|
|
|
void mezzo_pain_seq () [++ $pain1 .. $pain7]
|
|
{
|
|
ai_back(1);
|
|
if(cycle_wrapped)
|
|
{
|
|
thinktime self : 0;
|
|
if(!self.flags&FL_ONGROUND)
|
|
self.think=mezzo_in_air;
|
|
else
|
|
self.think=self.th_run;
|
|
}
|
|
}
|
|
|
|
void mezzo_pain (entity attacker, float damage)
|
|
{
|
|
if(self.monster_awake)
|
|
if(random(self.health)>damage*3||self.pain_finished>time)//only react to 33 percent of current health damage
|
|
return;
|
|
|
|
self.monster_awake=TRUE;
|
|
|
|
if(self.shield)
|
|
remove(self.shield);
|
|
|
|
if(self.health<=100)
|
|
{
|
|
self.th_pain=SUB_Null;
|
|
if(self.health<=100)
|
|
{
|
|
if(random()<0.5)
|
|
{
|
|
self.oldthink=self.th_run;
|
|
self.think=mezzo_roar;
|
|
self.speed=15;
|
|
self.yaw_speed=20;
|
|
self.aflag=TRUE;//Berzerk!
|
|
}
|
|
else if(!self.flags&FL_ONGROUND)
|
|
self.think=mezzo_in_air;
|
|
else
|
|
self.think=self.th_run;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sound(self,CHAN_VOICE,"mezzo/pain.wav",1,ATTN_NORM);
|
|
if((!self.enemy||!visible(self.enemy))&&attacker.siege_team!=self.siege_team)
|
|
{
|
|
if(self.enemy!=world&&self.enemy!=attacker)
|
|
self.oldenemy=self.enemy;
|
|
self.enemy=attacker;
|
|
}
|
|
self.pain_finished=time+1+self.strength;
|
|
self.think=mezzo_pain_seq;
|
|
}
|
|
thinktime self : 0;
|
|
}
|
|
|
|
void mezzo_land () [++ $jump13 .. $jump22]
|
|
{
|
|
//SOUND?
|
|
// dprint("landing\n");
|
|
if(cycle_wrapped)
|
|
{
|
|
thinktime self : 0;
|
|
self.think=self.th_run;
|
|
}
|
|
else if(self.frame==$jump13)
|
|
sound(self,CHAN_BODY,"player/land.wav",1,ATTN_NORM);
|
|
}
|
|
|
|
void mezzo_in_air ()
|
|
{
|
|
// dprint("in air\n");
|
|
self.frame=$jump12;
|
|
if(self.flags&FL_ONGROUND)
|
|
{
|
|
thinktime self : 0;
|
|
self.think=mezzo_land;
|
|
}
|
|
else
|
|
{
|
|
if(self.velocity=='0 0 0')
|
|
self.velocity='0 0 -60';
|
|
self.think=mezzo_in_air;
|
|
if(vlen(self.velocity)>300)
|
|
{
|
|
if(random()<0.5)
|
|
{
|
|
self.dflags=TRUE;//in air
|
|
self.think=mezzo_roll_forward;
|
|
}
|
|
}
|
|
thinktime self : 0.05;
|
|
}
|
|
}
|
|
|
|
void mezzo_jump () [++ $jump1 .. $jump11]
|
|
{
|
|
//SOUND?
|
|
// dprint("jumping\n");
|
|
ai_face();
|
|
if(self.flags&FL_ONGROUND)
|
|
{
|
|
thinktime self : 0;
|
|
self.think=mezzo_land;
|
|
}
|
|
else if(self.frame==$jump11)
|
|
{
|
|
thinktime self : 0.05;
|
|
self.think=mezzo_in_air;
|
|
}
|
|
}
|
|
|
|
void mezzo_charge_stop () [++ $charge15 .. $charge25]
|
|
{
|
|
if(cycle_wrapped)
|
|
{
|
|
self.touch=obj_push;
|
|
thinktime self : 0;
|
|
self.think=self.th_run;
|
|
}
|
|
if(!walkmove(self.angles_y,$charge25 - self.frame,FALSE))
|
|
{
|
|
if(!self.ltime)
|
|
self.think=mezzo_pain_seq;
|
|
else
|
|
self.think=self.th_run;
|
|
thinktime self : 0;
|
|
}
|
|
}
|
|
|
|
void mezzo_charge_leap () [++ $charge9 .. $charge14]
|
|
{
|
|
//SOUND?
|
|
if(cycle_wrapped)
|
|
{
|
|
thinktime self : 0;
|
|
self.think=mezzo_charge_stop;
|
|
}
|
|
else if(self.frame==$charge9)
|
|
{
|
|
makevectors(self.angles);
|
|
traceline(self.origin+'0 0 25',self.origin+'0 0 25'+v_forward*256,FALSE,self);
|
|
//Used to make him not charge if you stepped aside, now
|
|
//only checks if will fall
|
|
if(!trace_ent.takedamage)
|
|
{
|
|
self.think=mezzo_skid;
|
|
thinktime self : 0;
|
|
}
|
|
else
|
|
{
|
|
traceline(trace_endpos,trace_endpos-'0 0 300',TRUE,self);
|
|
if(pointcontents(trace_endpos)!=CONTENT_EMPTY||trace_fraction==1)
|
|
{
|
|
self.think=mezzo_skid;
|
|
thinktime self : 0;
|
|
}
|
|
else if(self.flags&FL_ONGROUND)
|
|
{
|
|
if(random()<0.5)
|
|
sound(self,CHAN_VOICE,"mezzo/attack.wav",1,ATTN_NORM);
|
|
self.velocity=v_forward*700+'0 0 133';
|
|
self.flags(-)FL_ONGROUND;
|
|
}
|
|
else
|
|
{
|
|
self.think=mezzo_in_air;
|
|
thinktime self : 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void mezzo_charge () [++ $charge1 .. $charge8]
|
|
{
|
|
if(cycle_wrapped)
|
|
{
|
|
thinktime self : 0;
|
|
self.think=mezzo_charge_leap;
|
|
}
|
|
else if(self.frame==$charge1)
|
|
{
|
|
self.last_attack=time;
|
|
self.ltime=0;
|
|
self.touch=mezzo_slam;
|
|
self.attack_finished=time+1.25;
|
|
}
|
|
walkmove(self.angles_y,15,FALSE);
|
|
}
|
|
|
|
void mezzo_block_return () [-- $block6 .. $block1]
|
|
{
|
|
// if(self.shield.velocity!='0 0 0'&&self.shield.model!="models/null.spr")
|
|
// dprint("what the?\n");
|
|
if(cycle_wrapped)
|
|
{
|
|
float r;
|
|
if(self.shield)
|
|
remove(self.shield);
|
|
r=vlen(self.enemy.origin-self.origin);
|
|
if(infront(self.enemy)&&r<100)
|
|
{
|
|
thinktime self : 0;
|
|
self.think=self.th_melee;
|
|
}
|
|
// else if(random()<0.2&&r<177)
|
|
// {
|
|
// thinktime self : 0;
|
|
// self.think=self.th_stand;
|
|
// }
|
|
else
|
|
{
|
|
thinktime self : 0;
|
|
self.think=self.th_run;
|
|
}
|
|
}
|
|
}
|
|
|
|
void mezzo_block_wait ()
|
|
{
|
|
// if(self.shield.velocity!='0 0 0'&&self.shield.model!="models/null.spr")
|
|
// dprint("what the?\n");
|
|
self.think=mezzo_block_wait;
|
|
if(self.t_width<time)
|
|
{
|
|
thinktime self : 0;
|
|
self.think=mezzo_block_return;
|
|
}
|
|
else
|
|
{
|
|
self.frame=$block6;
|
|
ai_face();
|
|
self.think=mezzo_block_wait;
|
|
thinktime self : 0.05;
|
|
}
|
|
if(range(self.enemy)==RANGE_MELEE)
|
|
if(CheckAnyAttack())
|
|
return;
|
|
if(!self.flags&FL_ONGROUND)
|
|
{
|
|
// dprint("what the fuck?! off ground while blocking?!\n");
|
|
if(!self.velocity_x&&!self.velocity_y)
|
|
self.think=mezzo_in_air;
|
|
else
|
|
self.think=mezzo_roll_forward;
|
|
thinktime self : 0;
|
|
}
|
|
self.shield.oldthink=self.shield.think;
|
|
self.shield.think=SUB_Remove;
|
|
thinktime self.shield : 0.2;
|
|
// dprint("checking defense from block\n");
|
|
mezzo_check_defense();
|
|
if(self.think==mezzo_block_wait)
|
|
{
|
|
self.shield.think=self.shield.oldthink;
|
|
thinktime self.shield : 0;
|
|
}
|
|
// else
|
|
// dprint("wigging!\n");
|
|
}
|
|
|
|
void mezzo_block () [++ $block1 .. $block6]
|
|
{
|
|
walkmove(self.angles_y,-1,FALSE);
|
|
// dprint("blocking\n");
|
|
|
|
// if(self.shield.velocity!='0 0 0'&&self.shield.model!="models/null.spr")
|
|
// dprint("what the?\n");
|
|
if(cycle_wrapped)
|
|
{
|
|
if(self.th_pain==SUB_Null&&self.health>77)
|
|
self.th_pain=mezzo_pain;
|
|
self.t_width=time+1;
|
|
thinktime self : 0;
|
|
self.think=mezzo_block_wait;
|
|
}
|
|
else if(self.frame==$block1)
|
|
spawn_reflect();
|
|
}
|
|
|
|
void mezzo_skid () [++ $block1 .. $block6]
|
|
{
|
|
float skidspeed, anim_stretch;
|
|
anim_stretch = 3;
|
|
|
|
skidspeed=$block6 - self.frame + anim_stretch - self.level;
|
|
if(walkmove(self.angles_y,skidspeed*2,FALSE))
|
|
{
|
|
particle(self.origin, '0 0 20'*skidspeed, 344, skidspeed);
|
|
if(random()<0.2)
|
|
CreateWhiteSmoke(self.origin,'0 0 8',HX_FRAME_TIME * 2);
|
|
}
|
|
else
|
|
{
|
|
thinktime self : 0;
|
|
self.think=mezzo_block_return;
|
|
return;
|
|
}
|
|
|
|
if(cycle_wrapped)
|
|
{
|
|
self.attack_finished=time+3;
|
|
thinktime self : 0;
|
|
self.think=mezzo_block_return;
|
|
}
|
|
else if(self.frame==$block1)
|
|
{
|
|
spawn_reflect();
|
|
sound(self,CHAN_AUTO,"mezzo/skid.wav",1,ATTN_NORM);
|
|
}
|
|
else if(self.level<anim_stretch)
|
|
{
|
|
self.frame-=1;
|
|
self.level+=1;
|
|
}
|
|
else
|
|
self.level=0;
|
|
}
|
|
|
|
void mezzo_roar () [++ $roar1 .. $roar30]
|
|
{
|
|
self.health+=1.1;
|
|
|
|
if(self.frame==$roar30)
|
|
{
|
|
if(!self.aflag)
|
|
self.th_pain=mezzo_pain;
|
|
if(!self.takedamage)
|
|
self.takedamage=DAMAGE_YES;
|
|
self.last_attack=time+3;
|
|
thinktime self : 0;
|
|
self.think=self.oldthink;
|
|
}
|
|
else if(self.frame==$roar1)
|
|
{
|
|
self.monster_awake=TRUE;
|
|
if(self.health<100)
|
|
{
|
|
self.th_pain=SUB_Null;
|
|
self.takedamage=DAMAGE_NO;
|
|
}
|
|
sound(self,CHAN_VOICE,"mezzo/roar.wav",1,ATTN_NORM);
|
|
}
|
|
else if(self.frame==$roar19)
|
|
thinktime self : 2;
|
|
|
|
if(self.takedamage)
|
|
mezzo_check_defense();
|
|
}
|
|
|
|
void mezzo_run_think ()
|
|
{
|
|
mezzo_check_defense();
|
|
if(!self.takedamage)
|
|
{
|
|
self.takedamage=DAMAGE_YES;
|
|
}
|
|
|
|
if(!self.enemy.flags2&FL_ALIVE&&self.enemy!=world)
|
|
{
|
|
self.monster_awake=FALSE;
|
|
if(visible(self.enemy)&&infront(self.enemy))
|
|
{
|
|
self.oldthink=self.th_stand;
|
|
self.think=mezzo_roar;
|
|
}
|
|
else
|
|
self.think=self.th_stand;
|
|
if(self.oldenemy.flags2&FL_ALIVE)
|
|
{
|
|
self.enemy=self.oldenemy;
|
|
self.oldenemy=world;
|
|
self.think=self.th_run;
|
|
}
|
|
else
|
|
self.enemy=world;
|
|
thinktime self : 0;
|
|
}
|
|
else if(self.enemy!=world)
|
|
{
|
|
if(visible(self.enemy))
|
|
{
|
|
float dist;
|
|
dist=vlen(self.enemy.origin-self.origin);
|
|
if(dist<177&&dist>33)
|
|
{
|
|
if(random()<0.5&&lineofsight(self.enemy,self))
|
|
{
|
|
thinktime self : 0;
|
|
self.think=mezzo_charge;
|
|
}
|
|
else if(dist>84&&self.last_attack<time&&infront(self.enemy))
|
|
{
|
|
thinktime self : 0;
|
|
self.think=mezzo_skid;
|
|
}
|
|
}
|
|
else if(!infront(self.enemy))
|
|
{
|
|
if(self.last_attack<time&&random()<0.5)
|
|
{
|
|
if(!self.aflag)
|
|
self.yaw_speed=10;
|
|
self.last_attack=time+7;
|
|
thinktime self : 0;
|
|
self.think=mezzo_skid;
|
|
}
|
|
else
|
|
self.yaw_speed=20;
|
|
}
|
|
else if(!self.aflag)
|
|
self.yaw_speed=10;
|
|
}
|
|
else
|
|
self.yaw_speed=10;
|
|
ai_run(self.speed);
|
|
}
|
|
else
|
|
{
|
|
self.think=self.th_stand;
|
|
thinktime self : 0;
|
|
}
|
|
if(self.flags&EF_NODRAW)
|
|
if(self.invisible_time>time)
|
|
dropStep();
|
|
else
|
|
self.effects(-)EF_NODRAW;
|
|
}
|
|
|
|
void mezzo_run_loop () [++ $run1 .. $run22]
|
|
{
|
|
mezzo_run_think();
|
|
}
|
|
|
|
void mezzo_run () [++ $run6 .. $run22]
|
|
{
|
|
mezzo_check_defense();
|
|
self.last_attack=time+0.1;//So won't start running then skid suddenly
|
|
if(!self.monster_awake)
|
|
if(range(self.enemy)>RANGE_NEAR&&random()>0.3)
|
|
{
|
|
self.oldthink=self.th_run;
|
|
self.think=mezzo_roar;
|
|
thinktime self : 0;
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
sound(self,CHAN_VOICE,"mezzo/attack.wav",1,ATTN_NORM);
|
|
self.monster_awake=TRUE;
|
|
}
|
|
|
|
if(cycle_wrapped)
|
|
{
|
|
self.think=mezzo_run_loop;
|
|
thinktime self : 0;
|
|
}
|
|
else
|
|
mezzo_run_think();
|
|
}
|
|
|
|
void mezzo_walk () [++ $walk1 .. $walk30]
|
|
{
|
|
if(self.frame==$stand3 &&random()<0.1)
|
|
mezzo_idle_sound();
|
|
mezzo_check_defense();
|
|
ai_walk(3);
|
|
if(self.enemy)
|
|
if(CheckAnyAttack())
|
|
return;
|
|
}
|
|
|
|
void()mezzo_stand;
|
|
void mezzo_twirl() [++ $twirl1 .. $twirl10]
|
|
{
|
|
mezzo_check_defense();
|
|
if(cycle_wrapped)
|
|
{
|
|
self.think=mezzo_stand;
|
|
thinktime self : 0;
|
|
}
|
|
else if(self.frame==$twirl1)
|
|
{
|
|
sound(self,CHAN_WEAPON,"weapons/vorpswng.wav",0.7,ATTN_NORM);
|
|
if(random()<0.5)
|
|
mezzo_idle_sound();
|
|
}
|
|
ai_stand();
|
|
}
|
|
|
|
void mezzo_stand2 () [-- $stand10 .. $stand1]
|
|
{
|
|
mezzo_check_defense();
|
|
|
|
if(self.level<3&&self.frame<$stand10)
|
|
{
|
|
self.level+=1;
|
|
self.frame+=1;
|
|
}
|
|
else
|
|
self.level=0;
|
|
|
|
if(self.frame==$stand1)
|
|
{
|
|
if(random()<0.1||(self.monster_awake&&random()<0.5))
|
|
self.think=mezzo_twirl;
|
|
else
|
|
self.think=mezzo_stand;
|
|
thinktime self : 0;
|
|
return;
|
|
}
|
|
else if(self.frame==$stand10 &&random()<0.1)
|
|
mezzo_idle_sound();
|
|
|
|
/* if(self.monster_awake)
|
|
{
|
|
float r;
|
|
r=vlen(self.enemy.origin-self.origin);
|
|
if(random()<0.1||r>177)
|
|
{
|
|
if(r>177)
|
|
self.think=self.th_run;
|
|
else if(enemy_infront&&enemy_vis&&r<133)
|
|
self.think=mezzo_charge;
|
|
else if(random()<0.5)
|
|
self.think=self.th_run;
|
|
else
|
|
self.think=self.th_walk;
|
|
thinktime self : 0;
|
|
}
|
|
else
|
|
{
|
|
if(random()<0.8&&r>100)
|
|
self.attack_finished=time+0.1;
|
|
ai_run(0);
|
|
}
|
|
}
|
|
else
|
|
*/ ai_stand();
|
|
}
|
|
|
|
void mezzo_stand () [++ $stand1 .. $stand10]
|
|
{
|
|
if(random()<0.5)
|
|
{
|
|
mezzo_check_defense();
|
|
|
|
if((!self.enemy.flags2&FL_ALIVE&&self.enemy!=world)||self.enemy==world)
|
|
{
|
|
self.monster_awake=FALSE;
|
|
if(self.oldenemy.flags2&FL_ALIVE)
|
|
{
|
|
self.enemy=self.oldenemy;
|
|
self.oldenemy=world;
|
|
}
|
|
else
|
|
self.enemy=world;
|
|
}
|
|
}
|
|
|
|
if(self.level<3&&self.frame>$stand1)
|
|
{
|
|
self.level+=1;
|
|
self.frame-=1;
|
|
}
|
|
else
|
|
self.level=0;
|
|
|
|
if(self.frame==$stand10)
|
|
{
|
|
self.think=mezzo_stand2;
|
|
thinktime self : 0;
|
|
return;
|
|
}
|
|
else if(self.frame==$stand1 &&random()<0.1)
|
|
mezzo_idle_sound();
|
|
|
|
if(random()<0.5)
|
|
ai_stand();
|
|
}
|
|
|
|
|
|
/*QUAKED monster_werejaguar (1 0.3 0) (-16 -16 0) (16 16 56) AMBUSH STUCK JUMP PLAY_DEAD DORMANT
|
|
WereCat with jaguar skin
|
|
If they're targetted by a trigger and used, they'll atack the activator of the target
|
|
If they can't see the activator, they'll roll left or right (in the direction of the activator)
|
|
Their roll is 128 units long, so place the mezzoman 128 units away from where you want the roll to stop
|
|
|
|
My babies!!! - MG
|
|
*/
|
|
//IDEA: Have mezzoman do ai_face while in air or rolling so always faces you when lands/gets up?
|
|
void() monster_werejaguar =
|
|
{
|
|
// if (deathmatch)
|
|
// {
|
|
// remove(self);
|
|
// return;
|
|
// }
|
|
|
|
if (!self.flags2&FL_SUMMONED)
|
|
{
|
|
precache_model2 ("models/mezzoman.mdl");
|
|
precache_model2 ("models/mezzoref.spr");
|
|
precache_model2 ("models/h_mez.mdl");
|
|
precache_sound2 ("mezzo/skid.wav");
|
|
precache_sound2 ("mezzo/roar.wav");
|
|
precache_sound2 ("mezzo/reflect.wav");
|
|
precache_sound2 ("mezzo/slam.wav");
|
|
precache_sound2 ("mezzo/pain.wav");
|
|
precache_sound2 ("mezzo/die.wav");
|
|
precache_sound2 ("mezzo/growl.wav");
|
|
precache_sound2 ("mezzo/snort.wav");
|
|
precache_sound2 ("mezzo/attack.wav");
|
|
}
|
|
self.solid = SOLID_SLIDEBOX;
|
|
self.takedamage=DAMAGE_YES;
|
|
self.thingtype=THINGTYPE_FLESH;
|
|
self.movetype = MOVETYPE_STEP;
|
|
self.view_ofs = '0 0 53';
|
|
self.speed=10;
|
|
self.yaw_speed = 10;
|
|
self.experience_value = 150;
|
|
self.monsterclass = CLASS_HENCHMAN;
|
|
self.mass = 10;
|
|
self.mintel = 15;//Animal sense of smell makes him a good tracker
|
|
if(self.classname=="monster_werepanther")
|
|
{
|
|
self.monsterclass = CLASS_LEADER;
|
|
self.experience_value = 300;
|
|
if(!self.health)
|
|
self.health=400;
|
|
}
|
|
else if(!self.health)
|
|
self.health = 250;
|
|
|
|
self.strength = 1;
|
|
self.classname="monster_mezzoman";
|
|
|
|
self.th_stand=mezzo_stand;
|
|
self.th_walk=mezzo_walk;
|
|
self.th_run=mezzo_run;
|
|
self.th_pain=mezzo_pain;
|
|
self.th_melee=mezzo_melee;
|
|
self.th_missile=mezzo_missile;
|
|
self.th_jump=mezzo_jump;
|
|
self.th_die=mezzo_die;
|
|
self.spawnflags (+) JUMP;
|
|
|
|
setmodel (self, "models/mezzoman.mdl");
|
|
self.headmodel="models/h_mez.mdl";
|
|
|
|
setsize (self, '-16 -16 0', '16 16 56');
|
|
|
|
self.frame=$stand1;
|
|
|
|
walkmonster_start();
|
|
};
|
|
|
|
void monster_mezzoman (void)
|
|
{
|
|
monster_werejaguar();
|
|
}
|
|
|
|
/*QUAKED monster_werepanther (1 0.3 0) (-16 -16 0) (16 16 56) AMBUSH STUCK JUMP PLAY_DEAD DORMANT
|
|
TIGER Skins for siege
|
|
*/
|
|
void monster_werepanther (void)
|
|
{
|
|
monster_werejaguar();
|
|
}
|
|
|