/* * $Header: /HexenWorld/HCode/medusa.hc 2 3/27/98 1:34p Mgummelt $ */ /* ============================================================================== Q:\art\models\monsters\medusa\medusa.hc MG ============================================================================== */ // For building the model $cd Q:\art\models\monsters\medusa $origin 0 0 0 $base BASE-F skin $skin skin $skin SKIN2 $flags 0 //MEDUSA.MDL // $frame looklf1 looklf2 looklf3 looklf4 looklf5 $frame looklf6 looklf7 looklf8 looklf9 looklf10 $frame looklf11 looklf12 looklf13 looklf14 looklf15 $frame looklf16 looklf17 looklf18 looklf19 looklf20 $frame looklf21 looklf22 looklf23 looklf24 looklf25 $frame looklf26 looklf27 looklf28 looklf29 // $frame lookrt1 lookrt2 lookrt3 lookrt4 lookrt5 $frame lookrt6 lookrt7 lookrt8 lookrt9 lookrt10 $frame lookrt11 lookrt12 lookrt13 lookrt14 lookrt15 $frame lookrt16 lookrt17 lookrt18 lookrt19 lookrt20 $frame lookrt21 lookrt22 lookrt23 lookrt24 lookrt25 $frame lookrt26 lookrt27 lookrt28 lookrt29 // $frame medusa1 medusa2 medusa3 medusa4 medusa5 $frame medusa6 medusa7 medusa8 medusa9 medusa10 $frame medusa11 medusa12 medusa13 medusa14 medusa15 $frame medusa16 medusa17 medusa18 medusa19 medusa20 $frame medusa21 medusa22 medusa23 medusa24 medusa25 $frame medusa26 medusa27 medusa28 medusa29 // $frame ratatt1 ratatt2 ratatt3 ratatt4 ratatt5 $frame ratatt6 ratatt7 ratatt8 ratatt9 ratatt10 $frame ratatt11 ratatt12 ratatt13 ratatt14 ratatt15 $frame ratatt16 ratatt17 ratatt18 ratatt19 ratatt20 $frame ratatt21 ratatt22 ratatt23 ratatt24 ratatt25 $frame ratatt26 ratatt27 ratatt28 ratatt29 // $frame ratlft1 ratlft2 ratlft3 ratlft4 ratlft5 $frame ratlft6 ratlft7 ratlft8 ratlft9 ratlft10 $frame ratlft11 ratlft12 ratlft13 ratlft14 ratlft15 $frame ratlft16 ratlft17 ratlft18 ratlft19 ratlft20 $frame ratlft21 ratlft22 ratlft23 ratlft24 ratlft25 $frame ratlft26 ratlft27 ratlft28 ratlft29 // $frame ratrit1 ratrit2 ratrit3 ratrit4 ratrit5 $frame ratrit6 ratrit7 ratrit8 ratrit9 ratrit10 $frame ratrit11 ratrit12 ratrit13 ratrit14 ratrit15 $frame ratrit16 ratrit17 ratrit18 ratrit19 ratrit20 $frame ratrit21 ratrit22 ratrit23 ratrit24 ratrit25 $frame ratrit26 ratrit27 ratrit28 ratrit29 // $frame stand1 stand2 stand3 stand4 stand5 $frame stand6 stand7 stand8 stand9 stand10 $frame stand11 stand12 stand13 stand14 stand15 $frame stand16 stand17 stand18 stand19 stand20 $frame stand21 stand22 stand23 stand24 stand25 $frame stand26 stand27 stand28 stand29 // $frame swipe1 swipe2 swipe3 swipe4 swipe5 $frame swipe6 swipe7 swipe8 swipe9 swipe10 $frame swipe11 swipe12 swipe13 swipe14 swipe15 $frame swipe16 swipe17 swipe18 swipe19 swipe20 $frame swipe21 swipe22 swipe23 swipe24 swipe25 $frame swipe26 swipe27 swipe28 swipe29 //MEDUSA2.MDL $framevalue 0 // $frame adecap1 adecap2 adecap3 adecap4 adecap5 $frame adecap6 adecap7 adecap8 adecap9 adecap10 $frame adecap11 adecap12 adecap13 adecap14 adecap15 $frame adecap16 adecap17 adecap18 adecap19 adecap20 $frame adecap21 adecap22 adecap23 adecap24 adecap25 $frame adecap26 adecap27 adecap28 adecap29 adecap30 $frame adecap31 adecap32 adecap33 adecap34 adecap35 $frame adecap36 adecap37 adecap38 adecap39 adecap40 $frame adecap41 adecap42 adecap43 adecap44 adecap45 $frame adecap46 adecap47 adecap48 adecap49 adecap50 $frame adecap51 adecap52 adecap53 adecap54 adecap55 $frame adecap56 adecap57 adecap58 adecap59 adecap60 $frame adecap61 adecap62 adecap63 adecap64 adecap65 $frame adecap66 adecap67 adecap68 adecap69 adecap70 $frame adecap71 adecap72 adecap73 adecap74 adecap75 $frame adecap76 adecap77 adecap78 adecap79 adecap80 $frame adecap81 adecap82 adecap83 adecap84 adecap85 $frame adecap86 adecap87 adecap88 // $frame bdecap1 bdecap2 bdecap3 bdecap4 bdecap5 $frame bdecap6 bdecap7 bdecap8 bdecap9 bdecap10 $frame bdecap11 bdecap12 bdecap13 bdecap14 bdecap15 $frame bdecap16 bdecap17 bdecap18 bdecap19 bdecap20 $frame bdecap21 bdecap22 bdecap23 bdecap24 bdecap25 // $frame death01 death02 death03 death04 death05 $frame death06 death07 death08 death09 death10 $frame death11 death12 death13 death14 death15 $frame death16 death17 death18 death19 death20 // $frame pain1 pain2 pain3 pain4 pain5 $frame pain6 pain7 pain8 pain9 pain10 $frame pain11 // $frame rnatlf1 rnatlf2 rnatlf3 rnatlf4 rnatlf5 $frame rnatlf6 rnatlf7 rnatlf8 rnatlf9 rnatlf10 $frame rnatlf11 rnatlf12 rnatlf13 rnatlf14 rnatlf15 $frame rnatlf16 rnatlf17 rnatlf18 rnatlf19 rnatlf20 $frame rnatlf21 // $frame rnatrt1 rnatrt2 rnatrt3 rnatrt4 rnatrt5 $frame rnatrt6 rnatrt7 rnatrt8 rnatrt9 rnatrt10 $frame rnatrt11 rnatrt12 rnatrt13 rnatrt14 rnatrt15 $frame rnatrt16 rnatrt17 rnatrt18 rnatrt19 rnatrt20 $frame rnatrt21 // $frame runatt1 runatt2 runatt3 runatt4 runatt5 $frame runatt6 runatt7 runatt8 runatt9 runatt10 $frame runatt11 runatt12 runatt13 runatt14 runatt15 $frame runatt16 runatt17 runatt18 runatt19 runatt20 $frame runatt21 runatt22 runatt23 runatt24 runatt25 $frame runatt26 runatt27 runatt28 runatt29 //==================================================================== float MEDUSA_LOOK = 0; float MEDUSA_RATTLE = 1; float MEDUSA_HEADBUTT = 2; float MEDUSA_SNAKES = 3; void(entity attacker,float total_damage)medusa_pain; void()medusa_attack_right; void()medusa_attack_left; void()medusa_attack; void(float action)MedusaSelectDir; void medusa_check_use_model (string modelstring) { if(self.model!=modelstring) { setmodel(self,modelstring); setsize(self,'-16 -16 0','16 16 56'); } } void snake_remove () { particleexplosion(self.origin,random(176,192),30,20); remove(self); } void() SnakeHit = { if(other==self.owner||(other.owner==self.owner&&other.classname=="snakearrow")) return; starteffect(CE_MEDUSA_HIT,self.origin); sound(other,CHAN_AUTO,"medusa/hitplayr.wav",1,ATTN_NORM); if(other.takedamage) { other.bloodloss=other.bloodloss+1; SpawnPuff(other.origin,'0 0 0',self.dmg,other); //Snakehit sprite T_Damage(other,self,self.owner,self.dmg); } snake_remove(); }; void snake_fly () { particle4(self.origin,10,256+random(176,192),PARTICLETYPE_GRAV,3); if(random()<0.1) CreateGreenSmoke(self.origin,'0 0 0',HX_FRAME_TIME); HomeThink(); self.think=snake_fly; thinktime self : 0.05; } void FireSnakeArrow (vector offset) { //FIXME: add a greenish particle trail? self.last_attack=time; makevectors(self.angles); //identity newmis=spawn(); newmis.owner=self; newmis.classname="snakearrow"; //Movement and solidity newmis.movetype=MOVETYPE_FLYMISSILE; newmis.solid=SOLID_BBOX; //rendering newmis.abslight=0.3; newmis.drawflags(+)MLS_ABSLIGHT; //velocity newmis.speed=500; newmis.o_angle=normalize((self.goalentity.origin+self.goalentity.view_ofs) - (self.origin+self.view_ofs+offset)); newmis.velocity=newmis.o_angle*newmis.speed; newmis.angles=vectoangles(newmis.velocity); //impact newmis.touch=SnakeHit; newmis.dmg=3; //behaviour newmis.lockentity=newmis.enemy=self.enemy;//lockentity means it will never track any other ent newmis.veer=50; //slight veering, random course modifications newmis.th_die=snake_remove; newmis.think=snake_fly; newmis.hoverz=TRUE; //slow down on turns thinktime newmis : 0; //appearance,size, and position, always in this order!!! setmodel(newmis,"models/snakearr.mdl"); setsize(newmis,'0 0 0','0 0 0'); setorigin(newmis,self.origin+self.view_ofs+v_forward*8+offset); } void MedusaAttacks (void) { vector source, org; float damg; if(self.monster_stage==MEDUSA_SNAKES) { self.attack_finished=time+2; sound (self,CHAN_WEAPON,"medusa/attack2.wav",1,ATTN_NORM); FireSnakeArrow(v_up*12); FireSnakeArrow(v_right*12); FireSnakeArrow(v_right*-12); } else { self.attack_finished=time+1; makevectors (self.angles+self.angle_ofs); source = self.origin+self.view_ofs; traceline (source, source + v_forward*48, FALSE, self); if (trace_fraction == 1.0) return; org = trace_endpos + (v_forward * 4); sound (self, CHAN_WEAPON, "weapons/gauntht1.wav", 1, ATTN_NORM); if (trace_ent.takedamage) { damg = random(10,18); SpawnPuff (org, '0 0 0', 20,trace_ent); T_Damage (trace_ent, self, self, damg); //punchangle // if(other.classname=="player") // other.punchangle=??? } else { // hit wall SpawnPuff (trace_endpos, '0 0 0', 20,self); medusa_pain(self,0); } } } void()medusa_attack_left = [++ $rnatlf1 .. $rnatlf21] { medusa_check_use_model("models/medusa2.mdl"); if(self.frame==$rnatlf21) self.think=self.th_run; else if(self.frame==$rnatlf4) MedusaAttacks(); }; void()medusa_attack_right = [++ $rnatrt1 .. $rnatrt21] { medusa_check_use_model("models/medusa2.mdl"); if(self.frame==$rnatrt21) self.think=self.th_run; else if(self.frame==$rnatrt4) MedusaAttacks(); }; void()medusa_attack = [++ $runatt1 .. $runatt29] { medusa_check_use_model("models/medusa2.mdl"); if(self.frame==$runatt29) self.think= self.th_run; else if(self.frame==$runatt12) MedusaAttacks(); }; void()MedusaGazeLoop; void MedusaGaze (vector org, vector destiny, entity loser) [++ $medusa1 .. $medusa29] { //Anim? //sound, temp ent self.last_attack=time; if(!self.aflag) { sound (self,CHAN_WEAPON,"medusa/attack1.wav",1,ATTN_NORM); self.aflag=TRUE; } medusa_check_use_model("models/medusa.mdl"); ai_face(); WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); WriteByte (MSG_BROADCAST, TE_STREAM_GAZE); WriteByte (MSG_BROADCAST, 1+STREAM_ATTACHED); WriteByte (MSG_BROADCAST, 4); WriteEntity (MSG_BROADCAST, self); WriteCoord (MSG_BROADCAST, org_x); WriteCoord (MSG_BROADCAST, org_y); WriteCoord (MSG_BROADCAST, org_z); WriteCoord (MSG_BROADCAST, destiny_x); WriteCoord (MSG_BROADCAST, destiny_y); WriteCoord (MSG_BROADCAST, destiny_z); if(loser.health<=10&&!loser.artifact_active&ART_INVINCIBILITY) { sound(loser,CHAN_BODY,"medusa/stoned.wav",1,ATTN_NORM); self.attack_finished=time+7; loser.skin = GLOBAL_SKIN_STONE; loser.think=loser.th_pain=loser.th_run=SUB_Null; loser.attack_finished=loser.teleport_time=loser.pausetime = time+10000000000; loser.nextthink=-1; loser.th_die = chunk_death; loser.thingtype = THINGTYPE_GREYSTONE; loser.health = 10; loser.touch = obj_push; loser.flags(-)FL_FLY; loser.flags(-)FL_SWIM; if(loser.classname!="player") loser.movetype = MOVETYPE_STEP;//step? else loser.o_angle=loser.v_angle; loser.solid = SOLID_BBOX; loser.artifact_active(+)ARTFLAG_STONED; //Greying palette effect } else { T_Damage(loser,self,self,3); if(loser.classname=="player"&&random()<0.2+skill/10+self.skin/5) { loser.o_angle=loser.v_angle; loser.pausetime=time+random(0.05,0.3); if(random()<0.5) { loser.attack_finished=time+random(0.05,0.3); if(random()<0.5) thinktime loser : 0.2; } } } if(lineofsight(self,loser)&&!loser.artifact_active&ARTFLAG_STONED) { self.goalentity=loser; self.think=MedusaGazeLoop; thinktime self : 0.1; } else { self.aflag=FALSE; stopSound(self,CHAN_WEAPON); //sound (self,CHAN_WEAPON,"misc/null.wav",1,ATTN_NORM); self.attack_finished=time+2; self.think=self.th_run; thinktime self : 0; } } void MedusaGazeLoop() { MedusaGaze(self.origin+self.view_ofs,self.goalentity.origin+self.goalentity.view_ofs,self.goalentity); } void MedusaSwipe () [++ $swipe1 .. $swipe29] { self.last_attack=time; if(cycle_wrapped) { self.attack_finished=time+1; self.think=self.th_run; thinktime self : 0; } else if(self.frame==$swipe1) { sound(self,CHAN_VOICE,"medusa/sight.wav",1,ATTN_NORM); sound(self,CHAN_BODY,"weapons/vorpswng.wav",1,ATTN_NORM); } else if(self.frame>=$swipe6 &&self.frame<=$swipe10) { makevectors(self.angles); traceline(self.origin+'0 0 23',self.origin+'0 0 23'-v_forward*72+v_right*($swipe7 - self.frame)*10,FALSE,self); if(trace_ent.takedamage) { T_Damage(trace_ent,self,self,7); sound(trace_ent,CHAN_BODY,"weapons/met2flsh.wav",1,ATTN_NORM); SpawnPuff(trace_endpos,'0 0 0',7,trace_ent); trace_ent.velocity+=v_right*-200; trace_ent.velocity_z+=100; trace_ent.flags(-)FL_ONGROUND; } } else if(self.frame>$swipe10) ai_face(); } float MedusaCheckAttack (void) { vector org,dir,destiny; float r, loscheck1,loscheck2; if(random()<0.5 - skill/10 - self.skin/5||self.enemy==world) return FALSE; org=self.origin+self.view_ofs; if (time < self.attack_finished) return FALSE; if (!enemy_vis) { if(self.goalentity.classname=="waypoint") { if(visible2ent(self.enemy,self.goalentity)) { MedusaSelectDir(MEDUSA_SNAKES); return TRUE; } } return FALSE; } if(!enemy_infront) { if(enemy_range==RANGE_MELEE) { MedusaSwipe(); return TRUE; } } if (enemy_range == RANGE_FAR) { if (self.attack_state != AS_STRAIGHT) self.attack_state = AS_STRAIGHT; return FALSE; } // see if any entities are in the way of the shot dir = self.enemy.origin + self.enemy.view_ofs; traceline (org, dir, FALSE, self); if (trace_ent != self.enemy) { // don't have a clear shot, so move to a side if (self.attack_state != AS_SLIDING) self.attack_state == AS_SLIDING; return FALSE; } else self.attack_state == AS_STRAIGHT; destiny = self.enemy.origin+self.enemy.view_ofs; //FIXME: account for z difference loscheck1=lineofsight(self.enemy,self); loscheck2=lineofsight(self,self.enemy); r=random(); if(!self.enemy.artifact_active&ARTFLAG_STONED&&loscheck1&& (loscheck2|| (r<0.1&&infront_of_ent(self,self.enemy)) ) ) { MedusaGaze(org,destiny,self.enemy); return TRUE; } if (enemy_range == RANGE_MELEE) { MedusaSelectDir(MEDUSA_HEADBUTT); return TRUE; } else if (enemy_range == RANGE_NEAR) r = 0.2; else if (enemy_range == RANGE_MID) r = 0.3; if (random () < r) { MedusaSelectDir(MEDUSA_SNAKES); return TRUE; } return FALSE; } //==================================================================== void()medusa_look_right; void MedusaHeadTouch () { if(self.velocity!='0 0 0'&&!other.flags2&FL_ALIVE) sound(self,CHAN_AUTO,"weapons/hithurt2.wav",1,ATTN_NORM); } void()MedusaHeadDying; void MedusaHeadDead () [++ 0 .. 45] { thinktime self : 0.1; ai_face(); if(self.frame==20) sound(self,CHAN_VOICE,"medusa/sight.wav",0.5,ATTN_NORM); else if(self.frame==45) { self.aflag=TRUE; self.think=MedusaHeadDying; } } void MedusaHeadDying () [++ 46 .. 105] { if(pointcontents(self.origin)==CONTENT_SOLID) { chunk_death(); return; } if(self.velocity=='0 0 0') if(!self.aflag) { if(self.angles_x<-10||self.angles_x>10) self.angles_x=0; if(self.angles_z<-10||self.angles_z>10) self.angles_z=0; self.solid = SOLID_BBOX; self.think=MedusaHeadDead; thinktime self : 0; } else if(self.frame==105) { self.skin=1; self.think=init_corpseblink; thinktime self : 5; } } void MedusaThrowHead () { newmis = spawn(); newmis.owner=self; newmis.enemy=newmis.goalentity=self.enemy; newmis.yaw_speed=3; setmodel (newmis, self.headmodel); self.headmodel=""; setsize (newmis, '-3 -3 -3', '3 3 3'); setorigin(newmis,self.absmax - '0 0 15'); newmis.velocity = randomv('-200 -200 200','200 200 600'); newmis.movetype = MOVETYPE_BOUNCE; if(pointcontents(newmis.origin)==CONTENT_SOLID) newmis.solid = SOLID_NOT; else newmis.solid = SOLID_BBOX; newmis.takedamage=DAMAGE_YES; newmis.thingtype=self.thingtype; newmis.th_die=chunk_death; newmis.touch=MedusaHeadTouch; newmis.health=25; newmis.scale=2; newmis.avelocity_x = random(600); newmis.avelocity_y = random(600); newmis.avelocity_z = random(600); newmis.think=MedusaHeadDying; thinktime newmis : 0; } void medusa_decap_drop ()[++ $bdecap1 .. $bdecap25] { if(self.frame==$bdecap9) sound(self,CHAN_BODY,"player/land.wav",1,ATTN_NORM); else if(self.frame==$bdecap25) MakeSolidCorpse(); } void medusa_decap_loop ()[++ $adecap1..$adecap88] { if(random()<0.5) self.angles_y+=random(-3,3); walkmove(self.angles_y,self.speed*random(),FALSE); if(random()<0.2) { sound (self, CHAN_VOICE, "misc/decomp.wav", 0.3, ATTN_NORM); SpawnPuff (self.origin+'0 0 56', '0 0 35',5,self); } if(self.frame==$adecap48) sound(self,CHAN_BODY,"medusa/rattle.wav",1,ATTN_NORM); if(cycle_wrapped) { self.think=medusa_decap_drop; thinktime self : 0; } } void medusa_decap_init () { float throwdist; throwdist=self.health; ThrowGib("models/medsnake.mdl",throwdist); ThrowGib("models/medsnake.mdl",throwdist); ThrowGib("models/medsnake.mdl",throwdist); sound(self,CHAN_VOICE,"player/gib2.wav",1,ATTN_NORM); MedusaThrowHead(); SpawnPuff (self.origin+'0 0 56', '0 0 35',5,self); medusa_decap_loop(); } void medusa_die (void) [++ $death01..$death20] { medusa_check_use_model("models/medusa2.mdl"); if(self.decap) medusa_decap_init(); else if(self.health<=-80) { MedusaThrowHead(); chunk_death(); } else { if(self.frame==$death20) MakeSolidCorpse(); else if(self.frame==$death01) sound(self,CHAN_VOICE,"medusa/death.wav",1,ATTN_NORM); } } void medusa_pain_anim () [++ $pain1 .. $pain11] { //sound medusa_check_use_model("models/medusa2.mdl"); if (cycle_wrapped) { thinktime self : 0; self.think=self.th_run; } else if(self.frame==$pain1) sound(self,CHAN_VOICE,"medusa/pain.wav",1,ATTN_NORM); } void medusa_pain (entity attacker,float total_damage) { if(random()<0.6&&total_damage<50&&attacker!=self) return; medusa_pain_anim(); } void()medusa_look_left = [++ $looklf1 .. $looklf29] { medusa_check_use_model("models/medusa.mdl"); if(self.oldthink==self.th_run) ai_run(self.speed); else { if(self.oldthink==self.th_stand) ai_stand(); else if(self.oldthink==self.th_walk) ai_walk(5); } if(cycle_wrapped) { self.think=self.oldthink; if(self.think!=self.th_run) if(random()<0.2) self.think=medusa_look_right; thinktime self : 0; } }; void()medusa_look_right = [++ $lookrt1 .. $lookrt29] { medusa_check_use_model("models/medusa.mdl"); if(self.oldthink==self.th_run) ai_run(self.speed); else { if(self.oldthink==self.th_stand) ai_stand(); else if(self.oldthink==self.th_walk) ai_walk(5); } if(cycle_wrapped) { self.think=self.oldthink; if(self.think!=self.th_run) if(random()<0.2) self.think=medusa_look_left; thinktime self : 0; } }; void()medusa_rattle_left = [++ $ratlft1 .. $ratlft29] { //sound medusa_check_use_model("models/medusa.mdl"); if(cycle_wrapped) { thinktime self : 0; self.think=self.th_run; } }; void()medusa_rattle_right = [++ $ratrit1 .. $ratrit29] { //sound medusa_check_use_model("models/medusa.mdl"); if(cycle_wrapped) { thinktime self : 0; self.think=self.th_run; } }; void()medusa_rattle = [++ $ratatt1 .. $ratatt29] { //sound medusa_check_use_model("models/medusa.mdl"); if(cycle_wrapped) { thinktime self : 0; self.think=self.th_run; } }; void MedusaSelectDir (float action) { vector enemy_dir; float dot; medusa_check_use_model("models/medusa.mdl"); self.monster_stage=action; if(action>=MEDUSA_HEADBUTT) { self.last_attack=time; sound (self,CHAN_VOICE,"medusa/hiss.wav",1,ATTN_NORM); medusa_check_use_model("models/medusa2.mdl"); } else if(action==MEDUSA_RATTLE) sound(self,CHAN_BODY,"medusa/rattle.wav",1,ATTN_NORM); makevectors(self.angles); enemy_dir=normalize(self.enemy.origin-self.origin); dot=v_right*enemy_dir; if(dot>0.3) { self.angle_ofs_y=-90; if(action>=MEDUSA_HEADBUTT) self.think=medusa_attack_right; else if(action==MEDUSA_RATTLE) self.think=medusa_rattle_right; else self.think=medusa_look_right; } else if(dot<-0.3) { self.angle_ofs_y=-90; if(action>=MEDUSA_HEADBUTT) self.think=medusa_attack_left; else if(action==MEDUSA_RATTLE) self.think=medusa_rattle_left; else self.think=medusa_look_left; } else { self.angle_ofs_y=0; if(action>=MEDUSA_HEADBUTT) self.think=medusa_attack; else if(action==MEDUSA_RATTLE) self.think=medusa_rattle; else return; } thinktime self : 0; } void medusa_hunt () [++ $medusa1 .. $medusa29] { medusa_check_use_model("models/medusa.mdl"); if(random()<0.1) ai_run(0); else ai_run(self.speed); if(!enemy_vis) if(random()<0.1&&random()<0.5) if(random()<0.5) MedusaSelectDir(MEDUSA_RATTLE); else { self.oldthink=self.th_run; MedusaSelectDir(MEDUSA_LOOK); } } void medusa_walk () [++ $medusa1 .. $medusa29] { medusa_check_use_model("models/medusa.mdl"); self.monster_awake=FALSE; if(random()<0.1) ai_walk(0); else ai_walk(5); if(cycle_wrapped) { if(random()<0.3) { self.oldthink=self.th_walk; if(random()<0.5) { thinktime self : 0; self.think=medusa_look_left; } else { thinktime self : 0; self.think=medusa_look_right; } } } // MedusaCheckAttack(); if(random()<0.1&&random()<0.5) sound(self,CHAN_VOICE,"medusa/hiss.wav",1,ATTN_NORM); } void medusa_stand () [++$stand1..$stand29] { medusa_check_use_model("models/medusa.mdl"); self.monster_awake=FALSE; ai_stand(); if(random()<0.1) { self.oldthink=self.th_stand; if(random()<0.5) { thinktime self : 0; self.think=medusa_look_left; } else { thinktime self : 0; self.think=medusa_look_right; } } if(random()<0.1&&random()<0.3) sound(self,CHAN_VOICE,"medusa/hiss.wav",1,ATTN_NORM); } /*QUAKED monster_medusa_green (1 0.3 0) (-16 -16 0) (16 16 56) AMBUSH STUCK JUMP PLAY_DEAD DORMANT The medusa monster with its nasty sharp pointy teeth -------------------------FIELDS------------------------- -------------------------------------------------------- */ void monster_medusa_green (void) { if (deathmatch) { remove(self); return; } precache_model2("models/medusa.mdl"); precache_model2("models/medusa2.mdl"); precache_model2("models/snakearr.mdl"); precache_model2("models/medhit.spr"); precache_model2("models/medhead.mdl"); precache_model2("models/medsnake.mdl"); precache_sound2("medusa/rattle.wav"); precache_sound2("medusa/hiss.wav"); precache_sound2("medusa/sight.wav"); precache_sound2("medusa/attack1.wav"); precache_sound2("medusa/attack2.wav"); precache_sound2("medusa/pain.wav"); precache_sound2("medusa/death.wav"); precache_sound2("medusa/stoned.wav"); precache_sound2("medusa/hitplayr.wav"); // if(random()<0.5) // self.skin=1; self.headmodel="models/medhead.mdl"; self.solid = SOLID_SLIDEBOX; self.movetype = MOVETYPE_STEP; self.takedamage=DAMAGE_YES; self.thingtype=THINGTYPE_FLESH; self.monsterclass=CLASS_LEADER; self.mintel = 20;//Very smart- excellent tracker self.mass = 15; self.view_ofs = '0 0 53'; self.speed=5; self.yaw_speed = 5; self.classname="monster_medusa"; self.health = 700; self.experience_value = 500; self.th_stand=medusa_stand; self.th_run=medusa_hunt; self.th_walk=medusa_walk; self.th_die=medusa_die; self.th_pain=medusa_pain; self.th_missile=medusa_rattle; self.th_melee=medusa_attack; setmodel (self, "models/medusa.mdl"); setsize(self, '-28 -28 0', '28 28 56'); self.hull=HULL_PLAYER; walkmonster_start(); } void monster_medusa (void) { monster_medusa_green(); } /*QUAKED monster_medusa_red (1 0.3 0) (-16 -16 0) (16 16 56) AMBUSH STUCK JUMP PLAY_DEAD DORMANT The medusa monster with its nasty sharp pointy teeth -------------------------FIELDS------------------------- -------------------------------------------------------- */ void monster_medusa_red (void) { // self.skin=1; monster_medusa_green(); self.health = 250; self.experience_value = 125; }