/* ============================================================================== Captain coded by Michael Rogers a.k.a Xsniper http://xsniper.virtualave.net/ some code done by iD software ============================================================================== */ $cd /models/enemies $origin 0 0 24 $base base $skin base $frame idle101 idle102 idle103 idle104 idle105 idle106 idle107 idle108 idle109 idle110 $frame idle111 idle112 idle113 idle114 idle115 idle116 idle117 idle118 idle119 idle120 $frame idle121 idle122 idle123 idle124 idle125 idle126 idle127 idle128 idle129 idle130 $frame idle131 idle132 idle133 idle134 idle135 idle136 idle137 idle138 idle139 idle140 $frame idle141 idle142 $frame run01 run02 run03 run04 run05 run06 $frame walk01 walk02 walk03 walk04 walk05 walk06 walk07 walk08 walk09 walk10 $frame walk11 walk12 $frame attack101 attack102 attack103 attack104 attack105 attack106 attack107 $frame attack201 attack202 attack203 attack204 attack205 attack206 attack207 attack208 attack209 $frame attack301 attack302 attack303 attack304 attack305 attack306 attack307 attack308 attack309 attack310 $frame attack311 attack312 attack313 attack314 $frame pain101 pain102 pain103 pain104 $frame pain201 pain202 pain203 pain204 $frame pain301 pain302 pain303 pain304 pain305 pain306 pain307 pain308 pain309 pain310 $frame pain311 pain312 $frame death101 death102 death103 death104 death105 death106 death107 death108 death109 $frame death201 death202 death203 death204 death205 death206 $frame throw101 throw102 throw103 throw104 throw105 throw106 throw107 throw108 throw109 throw110 $frame throw111 throw112 $frame throw201 throw202 throw203 throw204 throw205 throw206 throw207 throw208 throw209 throw210 $frame throw211 $frame throw301 throw302 throw303 throw304 throw305 throw306 throw307 throw308 throw309 throw310 $frame block101 block102 block103 block104 block105 block106 $frame dodge101 dodge102 dodge103 dodge104 dodge105 $frame duck101 duck102 duck103 duck104 duck105 duck106 //=========================================================================== void() captain_char_a1; void() captain_run1; void() captain_step; void() CaptainCheckForCharge = { // check for mad charge if (!enemy_vis) return; if (time < self.attack_finished) return; if ( fabs(self.origin_z - self.enemy.origin_z) > 20) return; // too much height change if ( vlen (self.origin - self.enemy.origin) < 80) return; // use regular attack // charge SUB_AttackFinished (2); captain_char_a1 (); }; void() CaptainCheckContinueCharge = { if (time > self.attack_finished) { SUB_AttackFinished (3); captain_run1 (); return; // done charging } if (random() > 0.5) sound (self, CHAN_WEAPON, "enemy/captain/attack1miss.wav", 1, ATTN_NORM); else sound (self, CHAN_WEAPON, "enemy/captain/attack2miss.wav", 1, ATTN_NORM); }; void() FlaskExplode = { T_RadiusDamage (self, self.owner, 40, world); sound (self, CHAN_VOICE, "weapons/flaskexplode.wav", 1, ATTN_NORM); WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); WriteByte (MSG_BROADCAST, TE_EXPLOSION); WriteCoord (MSG_BROADCAST, self.origin_x); WriteCoord (MSG_BROADCAST, self.origin_y); WriteCoord (MSG_BROADCAST, self.origin_z); BecomeExplosion(); }; void() FlaskTouch = { if (other == self.owner) return; // don't explode on owner if (other.takedamage == DAMAGE_AIM) { FlaskExplode(); return; } sound (self, CHAN_VOICE, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound if (self.velocity == '0 0 0') self.avelocity = '0 0 0'; }; /* ================ ThrowFlask This code is used by multiple monsters in ew. ================ */ void() ThrowFlask = { local entity missile; self.effects = self.effects | EF_MUZZLEFLASH; missile = spawn (); missile.owner = self; missile.movetype = MOVETYPE_BOUNCE; missile.solid = SOLID_BBOX; // set missile speed makevectors (self.v_angle); missile.velocity = normalize(self.enemy.origin - self.origin); missile.velocity = missile.velocity * 500; missile.velocity_z = missile.velocity_z + 200; missile.avelocity = '300 300 300'; missile.angles = vectoangles(missile.velocity); missile.touch = FlaskTouch; // set missile duration missile.nextthink = time + 2.5; missile.think = FlaskExplode; setmodel (missile, "models/holy/g_flask.md2"); setsize (missile, '0 0 0', '0 0 0'); setorigin (missile, self.origin); }; void(vector spot) create_hhoundbot; void(vector spot) create_dwellerbot; void(vector spot) create_mercabot; /* ==================== captain_check_summon Check to see if we can summon ==================== */ float() captain_check_summon = { local vector start, end; //set up angles stuff self.v_angle = self.angles; makevectors (self.angles); //we need to check for walls so that we don't summon monsters inside them // Check in front of the captain for a wall start = self.origin; end = (start + (v_forward * 80) + '0 0 5'); // Check 80 Quake units infront and 5 units up traceline (start, end, TRUE, self); // If there is a wall or obstacle then return NOSUMMON if (trace_fraction != 1.0) return (0); //NOSUMMON return (1); //SUMMON }; /* ==================== captain_summom The Captain will call monsters to aid him ==================== */ void() captain_summon = { local float r; //set up angles stuff self.v_angle = self.angles; makevectors (self.angles); create_mercabot((self.origin + (v_forward * 80)) + '0 0 5'); //create axe mercenary infront of him }; //=========================================================================== void() captain_stand1 =[ $idle101, captain_stand2 ] {ai_stand();}; void() captain_stand2 =[ $idle102, captain_stand3 ] {ai_stand();}; void() captain_stand3 =[ $idle103, captain_stand4 ] {ai_stand();}; void() captain_stand4 =[ $idle104, captain_stand5 ] {ai_stand();}; void() captain_stand5 =[ $idle105, captain_stand6 ] {ai_stand();}; void() captain_stand6 =[ $idle106, captain_stand7 ] {ai_stand();}; void() captain_stand7 =[ $idle107, captain_stand8 ] {ai_stand();}; void() captain_stand8 =[ $idle108, captain_stand9 ] {ai_stand();}; void() captain_stand9 =[ $idle109, captain_stand10 ] {ai_stand();}; void() captain_stand10 =[ $idle110, captain_stand11 ] {ai_stand();}; void() captain_stand11 =[ $idle111, captain_stand12 ] {ai_stand();}; void() captain_stand12 =[ $idle112, captain_stand13 ] {ai_stand();}; void() captain_stand13 =[ $idle113, captain_stand14 ] {ai_stand();}; void() captain_stand14 =[ $idle114, captain_stand15 ] {ai_stand();}; void() captain_stand15 =[ $idle115, captain_stand16 ] {ai_stand();}; void() captain_stand16 =[ $idle116, captain_stand17 ] {ai_stand();}; void() captain_stand17 =[ $idle117, captain_stand18 ] {ai_stand();}; void() captain_stand18 =[ $idle118, captain_stand19 ] {ai_stand();}; void() captain_stand19 =[ $idle119, captain_stand20 ] {ai_stand();}; void() captain_stand20 =[ $idle120, captain_stand21 ] {ai_stand();}; void() captain_stand21 =[ $idle121, captain_stand22 ] {ai_stand();}; void() captain_stand22 =[ $idle122, captain_stand23 ] {ai_stand();}; void() captain_stand23 =[ $idle123, captain_stand24 ] {ai_stand();}; void() captain_stand24 =[ $idle124, captain_stand25 ] {ai_stand();}; void() captain_stand25 =[ $idle125, captain_stand26 ] {ai_stand();}; void() captain_stand26 =[ $idle126, captain_stand27 ] {ai_stand();}; void() captain_stand27 =[ $idle127, captain_stand28 ] {ai_stand();}; void() captain_stand28 =[ $idle128, captain_stand29 ] {ai_stand();}; void() captain_stand29 =[ $idle129, captain_stand30 ] {ai_stand();}; void() captain_stand30 =[ $idle130, captain_stand31 ] {ai_stand();}; void() captain_stand31 =[ $idle131, captain_stand32 ] {ai_stand();}; void() captain_stand32 =[ $idle132, captain_stand33 ] {ai_stand();}; void() captain_stand33 =[ $idle133, captain_stand34 ] {ai_stand();}; void() captain_stand34 =[ $idle134, captain_stand35 ] {ai_stand();}; void() captain_stand35 =[ $idle135, captain_stand36 ] {ai_stand();}; void() captain_stand36 =[ $idle136, captain_stand37 ] {ai_stand();}; void() captain_stand37 =[ $idle137, captain_stand38 ] {ai_stand();}; void() captain_stand38 =[ $idle138, captain_stand39 ] {ai_stand();}; void() captain_stand39 =[ $idle139, captain_stand40 ] {ai_stand();}; void() captain_stand40 =[ $idle140, captain_stand41 ] {ai_stand();}; void() captain_stand41 =[ $idle141, captain_stand42 ] {ai_stand();}; void() captain_stand42 =[ $idle142, captain_stand1 ] {ai_stand();}; //=========================================================================== void() captain_walk1 =[ $walk01, captain_walk2 ] {captain_step();ai_walk(2);}; void() captain_walk2 =[ $walk02, captain_walk3 ] {ai_walk(5);}; void() captain_walk3 =[ $walk03, captain_walk4 ] {ai_walk(5);}; void() captain_walk4 =[ $walk04, captain_walk5 ] {ai_walk(4);}; void() captain_walk5 =[ $walk05, captain_walk6 ] {ai_walk(4);}; void() captain_walk6 =[ $walk06, captain_walk7 ] {ai_walk(2);}; void() captain_walk7 =[ $walk07, captain_walk8 ] {captain_step();ai_walk(2);}; void() captain_walk8 =[ $walk08, captain_walk9 ] {ai_walk(3);}; void() captain_walk9 =[ $walk09, captain_walk10 ] {ai_walk(3);}; void() captain_walk10 =[ $walk10, captain_walk11 ] {ai_walk(4);}; void() captain_walk11 =[ $walk11, captain_walk12 ] {ai_walk(3);}; void() captain_walk12 =[ $walk12, captain_walk1 ] {ai_walk(2);}; //=========================================================================== void() captain_run1 =[ $run01, captain_run2 ] { captain_step(); ai_run(20); CaptainCheckForCharge(); }; void() captain_run2 =[ $run02, captain_run3 ] {ai_run(25);}; void() captain_run3 =[ $run03, captain_run4 ] {ai_run(18);}; void() captain_run4 =[ $run04, captain_run5 ] {ai_run(16);}; void() captain_run5 =[ $run05, captain_run6 ] {ai_run(14);}; void() captain_run6 =[ $run06, captain_run1 ] {ai_run(13);}; //============================================================================ void() captain_pain1 =[ $pain101, captain_pain2 ] {}; void() captain_pain2 =[ $pain102, captain_pain3 ] {}; void() captain_pain3 =[ $pain103, captain_pain4 ] {}; void() captain_pain4 =[ $pain104, captain_run1 ] {}; //============================================================================ void() captain_die1 =[ $death101, captain_die2 ] {}; void() captain_die2 =[ $death102, captain_die3 ] {}; void() captain_die3 =[ $death103, captain_die4 ] {self.solid = SOLID_NOT;}; void() captain_die4 =[ $death104, captain_die5 ] {}; void() captain_die5 =[ $death105, captain_die6 ] {}; void() captain_die6 =[ $death106, captain_die7 ] {}; void() captain_die7 =[ $death107, captain_die8 ] {}; void() captain_die8 =[ $death108, captain_die9 ] {}; void() captain_die9 =[ $death109, captain_die9 ] {banish_monster();}; void() captain_dieb1 =[ $death201, captain_dieb2 ] {}; void() captain_dieb2 =[ $death202, captain_dieb3 ] {}; void() captain_dieb3 =[ $death203, captain_dieb4 ] {self.solid = SOLID_NOT;}; void() captain_dieb4 =[ $death204, captain_dieb5 ] {}; void() captain_dieb5 =[ $death205, captain_dieb6 ] {}; void() captain_dieb6 =[ $death206, captain_dieb6 ] {banish_monster();}; void() captain_die = { // regular death sound (self, CHAN_VOICE, "enemy/captain/death1.wav", 1, ATTN_NORM); if (random() > 0.5) captain_die1 (); else captain_dieb1 (); }; void() captain_char_a1 =[ $run01, captain_char_a2 ] {captain_step();ai_charge(20);}; void() captain_char_a2 =[ $run02, captain_char_a3 ] {ai_charge(20);}; void() captain_char_a3 =[ $run03, captain_char_a4 ] {ai_charge(21);}; void() captain_char_a4 =[ $run04, captain_char_a5 ] {ai_charge(13);}; void() captain_char_a5 =[ $run05, captain_char_a6 ] {ai_charge(20);}; void() captain_char_a6 =[ $run06, captain_run1 ] {ai_charge(13);}; //=========================================================================== void() captain_char_b1 =[ $run01, captain_char_b2 ] {CaptainCheckContinueCharge();ai_charge(23);captain_step();}; void() captain_char_b2 =[ $run02, captain_char_b3 ] {ai_charge(17);}; void() captain_char_b3 =[ $run03, captain_char_b4 ] {ai_charge(12);}; void() captain_char_b4 =[ $run04, captain_char_b5 ] {ai_charge(22);}; void() captain_char_b5 =[ $run05, captain_char_b6 ] {ai_charge(18);}; void() captain_char_b6 =[ $run06, captain_char_b1 ] {ai_charge(8);}; //=========================================================================== void() captain_watk1 =[ $attack101, captain_watk2 ] {ai_charge(9);}; void() captain_watk2 =[ $attack102, captain_watk3 ] {ai_charge(7);}; void() captain_watk3 =[ $attack103, captain_watk4 ] {ai_charge(15);ai_melee();}; void() captain_watk4 =[ $attack104, captain_watk5 ] {ai_charge(8);ai_melee();}; void() captain_watk5 =[ $attack105, captain_watk6 ] {ai_charge(2);ai_melee();}; void() captain_watk6 =[ $attack106, captain_watk7 ] {ai_face();ai_melee();}; void() captain_watk7 =[ $attack107, captain_run1 ] {ai_face();}; //=========================================================================== void() captain_slice1 =[ $attack201, captain_slice2 ] {ai_charge(9);}; void() captain_slice2 =[ $attack202, captain_slice3 ] {ai_charge(6);}; void() captain_slice3 =[ $attack203, captain_slice4 ] {ai_charge(13);}; void() captain_slice4 =[ $attack204, captain_slice5 ] {ai_charge(7);ai_melee();}; void() captain_slice5 =[ $attack205, captain_slice6 ] {ai_charge(15); ai_melee();}; void() captain_slice6 =[ $attack206, captain_slice7 ] {ai_charge(8); ai_melee();}; void() captain_slice7 =[ $attack207, captain_slice8 ] {ai_face();ai_melee();}; void() captain_slice8 =[ $attack208, captain_slice9 ] {ai_face();}; void() captain_slice9 =[ $attack209, captain_run1 ] {ai_face();}; //=========================================================================== void() captain_smash1 =[ $attack301, captain_smash2 ] {ai_charge(15);}; void() captain_smash2 =[ $attack302, captain_smash3 ] {ai_charge(18);}; void() captain_smash3 =[ $attack303, captain_smash4 ] {ai_charge(14);}; void() captain_smash4 =[ $attack304, captain_smash5 ] {ai_charge(16);}; void() captain_smash5 =[ $attack305, captain_smash6 ] {ai_charge(18);}; void() captain_smash6 =[ $attack306, captain_smash7 ] {ai_charge(14);ai_melee();}; void() captain_smash7 =[ $attack307, captain_smash8 ] {ai_charge(16);ai_melee();}; void() captain_smash8 =[ $attack308, captain_smash9 ] {ai_charge(15);ai_melee();}; void() captain_smash9 =[ $attack309, captain_smash10 ] {ai_charge(12);ai_melee();}; void() captain_smash10 =[ $attack310, captain_smash11 ] {ai_charge(17);ai_melee();}; void() captain_smash11 =[ $attack311, captain_smash12 ] {ai_face();ai_melee();}; void() captain_smash12 =[ $attack312, captain_smash13 ] {ai_face();}; void() captain_smash13 =[ $attack313, captain_smash14 ] {ai_face();}; void() captain_smash14 =[ $attack314, captain_run1 ] {ai_face();}; //=========================================================================== void() captain_throw1 =[ $throw101, captain_throw2 ] {ai_face();}; void() captain_throw2 =[ $throw102, captain_throw3 ] {ai_face();}; void() captain_throw3 =[ $throw103, captain_throw4 ] {ai_face();}; void() captain_throw4 =[ $throw104, captain_throw5 ] {ai_face();}; void() captain_throw5 =[ $throw105, captain_throw6 ] {ai_face();}; void() captain_throw6 =[ $throw106, captain_throw7 ] {ai_face();}; void() captain_throw7 =[ $throw107, captain_throw8 ] {ai_face();}; void() captain_throw8 =[ $throw108, captain_throw9 ] {ai_face();}; void() captain_throw9 =[ $throw109, captain_throw10 ] {ai_face();}; void() captain_throw10 =[ $throw110, captain_throw11 ] {ai_face();}; void() captain_throw11 =[ $throw111, captain_throw12 ] {ai_face();}; void() captain_throw12 =[ $throw112, captain_throw13 ] {ai_face();}; void() captain_throw13 =[ $throw201, captain_throw14 ] {ai_face();}; void() captain_throw14 =[ $throw202, captain_throw15 ] {ai_face();}; void() captain_throw15 =[ $throw203, captain_throw16 ] {ai_face();}; void() captain_throw16 =[ $throw204, captain_throw17 ] {ai_face();}; void() captain_throw17 =[ $throw205, captain_throw18 ] {ai_face();}; void() captain_throw18 =[ $throw206, captain_throw19 ] {ai_face();}; void() captain_throw19 =[ $throw207, captain_throw20 ] { ai_face(); ThrowFlask(); }; void() captain_throw20 =[ $throw208, captain_throw21 ] {ai_face();}; void() captain_throw21 =[ $throw209, captain_throw22 ] {ai_face();}; void() captain_throw22 =[ $throw210, captain_throw23 ] {ai_face();}; void() captain_throw23 =[ $throw211, captain_throw24 ] {ai_face();}; void() captain_throw24 =[ $throw301, captain_throw25 ] {ai_face();}; void() captain_throw25 =[ $throw302, captain_throw26 ] {ai_face();}; void() captain_throw26 =[ $throw303, captain_throw27 ] {ai_face();}; void() captain_throw27 =[ $throw304, captain_throw28 ] {ai_face();}; void() captain_throw28 =[ $throw305, captain_throw29 ] {ai_face();}; void() captain_throw29 =[ $throw306, captain_throw30 ] {ai_face();}; void() captain_throw30 =[ $throw307, captain_throw31 ] {ai_face();}; void() captain_throw31 =[ $throw308, captain_throw32 ] {ai_face();}; void() captain_throw32 =[ $throw309, captain_throw33 ] {ai_face();}; void() captain_throw33 =[ $throw310, captain_run1 ] {ai_face();}; //=========================================================================== void() captain_summon1 =[ $attack301, captain_summon2 ] {ai_face();}; void() captain_summon2 =[ $attack302, captain_summon3 ] {}; void() captain_summon3 =[ $attack303, captain_summon4 ] {}; void() captain_summon4 =[ $attack304, captain_run1 ] {captain_summon();}; //=========================================================================== void(entity attacker, float damage) captain_pain = { if (self.pain_finished > time) return; if (time - self.pain_finished > 5) { // allways go into pain frame if it has been a while sound (self, CHAN_VOICE, "enemy/captain/pain2.wav", 1, ATTN_NORM); captain_pain1 (); self.pain_finished = time + 1; return; } if ((random()*30 > damage) ) { sound (self, CHAN_VOICE, "enemy/captain/pain1.wav", 1, ATTN_NORM); return; // didn't flinch } sound (self, CHAN_VOICE, "enemy/captain/pain2.wav", 1, ATTN_NORM); self.pain_finished = time + 1; captain_pain1 (); }; float captain_type; void() captain_melee = { captain_type = captain_type + 1; if (captain_type == 1) { sound (self, CHAN_WEAPON, "enemy/captain/attack1hit.wav", 1, ATTN_NORM); captain_slice1 (); } else if (captain_type == 2) { sound (self, CHAN_WEAPON, "enemy/captain/attack2hit.wav", 1, ATTN_NORM); captain_smash1 (); } else if (captain_type == 3) { sound (self, CHAN_WEAPON, "enemy/captain/attack3.wav", 1, ATTN_NORM); captain_watk1 (); captain_type = 0; } }; void() captain_missile = { //missile attacks, choose between summoning or throwing a flask //will usually throw flask but sometimes he doesnt do a missile attack local float r; r = random(); if (r >= 0.90) { if (captain_check_summon() == 1) captain_summon1(); } else if (r >= 0.35) captain_throw1(); } float captain_stepsound; void() captain_step = { //play step sounds in sequence, step1, step2, step1, step2, etc captain_stepsound = captain_stepsound + 1; if (captain_stepsound == 1) sound (self, CHAN_WEAPON, "enemy/captain/step1.wav", 1, ATTN_NORM); else { sound (self, CHAN_WEAPON, "enemy/captain/step2.wav", 1, ATTN_NORM); captain_stepsound = 0; } }; void() captain_precache = { //captain precaches precache_model ("models/enemies/captain.md2"); precache_model ("models/holy/g_flask.md2"); precache_sound ("weapons/flaskexplode.wav"); precache_sound ("enemy/captain/alert1.wav"); precache_sound ("enemy/captain/alert2.wav"); precache_sound ("enemy/captain/attack1hit.wav"); precache_sound ("enemy/captain/attack1miss.wav"); precache_sound ("enemy/captain/attack2hit.wav"); precache_sound ("enemy/captain/attack2miss.wav"); precache_sound ("enemy/captain/attack3.wav"); precache_sound ("enemy/captain/death1.wav"); precache_sound ("enemy/captain/pain1.wav"); precache_sound ("enemy/captain/pain2.wav"); precache_sound ("enemy/captain/step1.wav"); precache_sound ("enemy/captain/step2.wav"); //axe mercenary precaches precache_model ("models/enemies/merc_a.md2"); precache_sound ("enemy/mercenary/alert1.wav"); precache_sound ("enemy/mercenary/alert2.wav"); precache_sound ("enemy/mercenary/chatter1.wav"); precache_sound ("enemy/mercenary/chatter2.wav"); precache_sound ("enemy/mercenary/chatter3.wav"); precache_sound ("enemy/mercenary/chop1.wav"); precache_sound ("enemy/mercenary/chop2.wav"); precache_sound ("enemy/mercenary/chop3.wav"); precache_sound ("enemy/mercenary/chop4.wav"); precache_sound ("enemy/mercenary/death1.wav"); precache_sound ("enemy/mercenary/death4.wav"); precache_sound ("enemy/mercenary/death5.wav"); precache_sound ("enemy/mercenary/pain1.wav"); precache_sound ("enemy/mercenary/pain2.wav"); precache_sound ("enemy/mercenary/pain3.wav"); precache_sound ("enemy/mercenary/step1.wav"); precache_sound ("enemy/mercenary/step2.wav"); precache_sound ("enemy/mercenary/taunt1.wav"); }; /*EWED monster_captain (1 0 0) (-16 -16 -24) (16 16 40) Ambush */ void() monster_captain = { if (deathmatch) { remove(self); return; } //if we are put in the level directly then call captain_precache if (self.classname != "monster_hell_knight") captain_precache(); self.solid = SOLID_SLIDEBOX; self.movetype = MOVETYPE_STEP; setmodel (self, "models/enemies/captain.md2"); setsize (self, '-16 -16 -24', '16 16 40'); // setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX); self.health = set_health(250); self.speed = set_speed(300); self.dtype = 2; //dodge type forward_strafe self.alpha = 1; //we aren't transparent self.th_stand = captain_stand1; self.th_walk = captain_walk1; self.th_run = captain_run1; self.th_melee = captain_melee; self.th_missile = captain_missile; self.th_pain = captain_pain; self.th_die = captain_die; //my new classname is? self.classname = "monster_captain"; //set up our monflag self.monflag = "TRUE"; walkmonster_start (); };