Advertisement
Guest User

Untitled

a guest
May 9th, 2021
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 26.74 KB | None | 0 0
  1. /*==============================================================================
  2. FREDDIE (Edie from Quoth - Kell/Necros/Preach)
  3. ==============================================================================*/
  4. // Run/Walk same animation
  5. $frame run1 run2 run3 run4 run5 run6 run7 run8
  6. $frame run9 run10 run11 run12 run13 run14 run15 run16
  7.  
  8. // Run and fire nail/laser gun at same time
  9. $frame rfire1 rfire2 rfire3 rfire4 rfire5 rfire6 rfire7 rfire8
  10. $frame rfire9 rfire10 rfire11 rfire12 rfire13 rfire14 rfire15 rfire16
  11.  
  12. // Stand and fire nail/laser gun
  13. $frame sfire1 sfire2 sfire3 sfire4 sfire5 sfire6 sfire7 sfire8
  14. $frame sfire9 sfire10 sfire11 sfire12 sfire13 sfire14 sfire15 sfire16
  15. $frame sfire17 sfire18 sfire19 sfire20 sfire21 sfire22 sfire23 sfire24
  16. $frame sfire25 sfire26 sfire27 sfire28
  17.  
  18. // Pain forward
  19. $frame pain1 pain2 pain3 pain4 pain5 pain6 pain7 pain8
  20. $frame pain9 pain10 pain11 pain12
  21.  
  22. // Pain Backward (short)
  23. $frame painb1 painb2 painb3 painb4 painb5
  24.  
  25. // Quick forward swing of chainsaw arm
  26. $frame fswing1 fswing2 fswing3 fswing4 fswing5 fswing6 fswing7 fswing8
  27. $frame fswing9 fswing10 fswing11
  28.  
  29. // Quick smack with elbow of chainsaw arm
  30. $frame fswinge1 fswinge2 fswinge3 fswinge4 fswinge5 fswinge6 fswinge7
  31. $frame fswinge8 fswinge9 fswinge10
  32.  
  33. // Slow back swing of chainsaw arm (left to right)
  34. $frame bswing1 bswing2 bswing3 bswing4 bswing5 bswing6 bswing7 bswing8
  35. $frame bswing9 bswing10 bswing11 bswing12 bswing13 bswing14
  36.  
  37. // Extremely long death animation!
  38. $frame death1 death2 death3 death4 death5 death6 death7 death8
  39. $frame death9 death10 death11 death12 death13 death14 death15 death16
  40. $frame death17 death18 death19 death20 death21 death22 death23 death24
  41. $frame death25 death26 death27 death28 death29 death30 death31 death32
  42. $frame death33 death34 death35
  43.  
  44. // Export frames (ignored)
  45. $frame base1 base2
  46.  
  47. // Standing / idle animation
  48. $frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8
  49.  
  50. float DAMAGE_FREDDIE = 40; // Explosive damage from Freddie
  51. float SPEED_FREDDIEPROJ = 500; // Freddie spike/laser bolt speed
  52. float SPEED_FREDDIESKILL = 150; // 500=easy, 650=normal, 800=hard, 950=nm
  53. float MONAI_MELEEFREDDIE = 100; // Ogre Freddie blade got a long range
  54. float MONAI_RANGEFREDDIE = 300; // Inside range for stand and fire
  55.  
  56. float MON_FREDDIE_LASER = 2; // Fires laser instead of nails
  57.  
  58.  
  59. //============================================================================
  60. void() fred_stand1 =[ $stand1, fred_stand2 ] {sound_idle (self, CHAN_VOICE, "freddie/idle1.wav", 1, ATTN_IDLE); ai_stand();};
  61. void() fred_stand2 =[ $stand2, fred_stand3 ] {ai_stand();};
  62. void() fred_stand3 =[ $stand3, fred_stand4 ] {ai_stand();};
  63. void() fred_stand4 =[ $stand4, fred_stand5 ] {ai_stand();};
  64. void() fred_stand5 =[ $stand5, fred_stand6 ] {ai_stand();};
  65. void() fred_stand6 =[ $stand6, fred_stand7 ] {ai_stand();};
  66. void() fred_stand7 =[ $stand7, fred_stand8 ] {ai_stand();};
  67. void() fred_stand8 =[ $stand8, fred_stand1 ] {ai_stand();};
  68.  
  69. //============================================================================
  70. void() fred_walk1 = [ $run1, fred_walk2 ] {sound_idle (self, CHAN_VOICE, "freddie/idle1.wav", 1, ATTN_IDLE); ai_walk(20);};
  71. void() fred_walk2 = [ $run2, fred_walk3 ] {ai_walk(16);};
  72. void() fred_walk3 = [ $run3, fred_walk4 ] {ai_walk(1);};
  73. void() fred_walk4 = [ $run4, fred_walk5 ] {ai_walk(2);};
  74. void() fred_walk5 = [ $run5, fred_walk6 ] {ai_walk(4);};
  75. void() fred_walk6 = [ $run6, fred_walk7 ] {ai_walk(8);};
  76. void() fred_walk7 = [ $run7, fred_walk8 ] {ai_walk(4);};
  77. void() fred_walk8 = [ $run8, fred_walk9 ] {ai_walk(16);};
  78. void() fred_walk9 = [ $run9, fred_walk10 ] {ai_walk(20);};
  79. void() fred_walk10 = [ $run10, fred_walk11 ] {ai_walk(16);};
  80. void() fred_walk11 = [ $run11, fred_walk12 ] {ai_walk(1);};
  81. void() fred_walk12 = [ $run12, fred_walk13 ] {ai_walk(2);};
  82. void() fred_walk13 = [ $run13, fred_walk14 ] {ai_walk(4);};
  83. void() fred_walk14 = [ $run14, fred_walk15 ] {ai_walk(8);};
  84. void() fred_walk15 = [ $run15, fred_walk16 ] {ai_walk(4);};
  85. void() fred_walk16 = [ $run16, fred_walk1 ] {ai_walk(16);};
  86.  
  87. void fred_projtouch ()
  88. {
  89. if (other == self.owner)
  90. return;
  91. if (other.solid == SOLID_TRIGGER)
  92. return; // trigger field, do nothing
  93. if (pointcontents(self.origin) == CONTENT_SKY)
  94. {
  95. remove(self);
  96. return;
  97. }
  98.  
  99. if (self.aflag)
  100. sound_hit (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC);
  101.  
  102. if (other.takedamage) {
  103. spawn_touchblood (self.dmg);
  104. T_Damage (other, self, self.owner, self.dmg);
  105. }
  106. else {
  107. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  108. WriteByte (MSG_BROADCAST, TE_SPIKE);
  109. WriteCoord (MSG_BROADCAST, self.origin_x);
  110. WriteCoord (MSG_BROADCAST, self.origin_y);
  111. WriteCoord (MSG_BROADCAST, self.origin_z);
  112. }
  113. remove(self);
  114. }
  115.  
  116. //===========================================================================
  117. // RANGE ATTACK - Fires spikes or laser bolts
  118. //===========================================================================
  119. void(vector weapofs) fred_fireweapon =
  120. {
  121. local vector org, dir, vec;
  122.  
  123. // Check for death?
  124. if (self.health < 1) return;
  125.  
  126. // Lit up that barrel
  127. self.effects = self.effects | EF_MUZZLEFLASH;
  128. // Nail and laser use the same firing speed
  129. float attack_speed = SPEED_FREDDIEPROJ + (skill * SPEED_FREDDIESKILL);
  130. // turn and face your enemy!
  131. makevectors (self.angles);
  132. org = self.origin + attack_vector(weapofs);
  133.  
  134. // The mini burst mode (run+fire) can do tracking
  135. if (self.attack_timer && skill > 1) {
  136. // More precise fire, track player velocity
  137. // Reset the tracking on first shot, get better over time
  138. if (self.cnt == 1)
  139. self.attack_track = SUB_Tracking(self.enemy.origin, weapofs, self.enemy, attack_speed);
  140. else self.attack_track = SUB_Tracking(self.attack_track, weapofs, self.enemy, attack_speed);
  141. dir = normalize(self.attack_track - org);
  142. }
  143. else {
  144. // Standard mode spray bullets at player
  145. vec = v_right*(crandom()*(20+random()*50));
  146. dir = normalize((self.enemy.origin + vec) - org);
  147. }
  148.  
  149. entity newmis;
  150. newmis = spawn ();
  151. newmis.owner = self;
  152.  
  153. // Switch projectile type based on spawnflag
  154. if (self.spawnflags & MON_FREDDIE_LASER) {
  155. sound (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
  156. //launch_projectile(org, dir, CT_PROJ_LASER, self.attack_speed);
  157. setmodel (newmis, "progs/proj_laz.mdl");
  158. newmis.movetype = MOVETYPE_FLY;
  159. newmis.effects = EF_DIMLIGHT;
  160. newmis.dmg = 15;
  161. newmis.aflag = TRUE;
  162. }
  163. else {
  164. sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
  165. //launch_projectile(org, dir, CT_PROJ_MONNG, self.attack_speed);
  166. setmodel (newmis, "progs/proj_ngred.mdl");
  167. newmis.movetype = MOVETYPE_FLYMISSILE;
  168. newmis.dmg = 9;
  169. }
  170.  
  171. newmis.solid = SOLID_BBOX;
  172. newmis.touch = fred_projtouch; //Touch_Projectile;
  173. newmis.nextthink = time + 6;
  174. newmis.think = SUB_Remove;
  175.  
  176. newmis.velocity = dir * attack_speed;
  177. newmis.angles = vectoangles(dir);
  178. setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
  179. setorigin (newmis, org);
  180. };
  181.  
  182. // Start the initial wind up of the weapon first
  183. //----------------------------------------------------------------------
  184. void() fred_sfire1 = [ $sfire1, fred_sfire2 ] {ai_face();
  185. self.pain_finished = time + 0.5 + (skill*0.5);
  186. sound (self, CHAN_WEAPON, "freddie/stfire.wav", 1, ATTN_NORM);};
  187. void() fred_sfire2 = [ $sfire2, fred_sfire3 ] {ai_face();};
  188. void() fred_sfire3 = [ $sfire3, fred_sfire4 ] {ai_face();};
  189. void() fred_sfire4 = [ $sfire4, fred_sfire5 ] {ai_face();};
  190. void() fred_sfire5 = [ $sfire5, fred_sfire6 ] {ai_face();};
  191. void() fred_sfire6 = [ $sfire6, fred_sfire7 ] {ai_face();};
  192. void() fred_sfire7 = [ $sfire7, fred_sfire8 ] {ai_face();};
  193. void() fred_sfire8 = [ $sfire8, fred_sfire9 ] {ai_face();
  194. self.cnt = 0;
  195. };
  196.  
  197. // Fire the weapon in bursts
  198. //----------------------------------------------------------------------
  199. void(vector weapofs) fred_standfire =
  200. {
  201. // Always check AI health before locking in function
  202. if (self.health < 1) return;
  203.  
  204. // Turn before offset check
  205. ai_face();
  206.  
  207. // If no enemy or enemy dead then stop attack
  208. if (!self.enemy || self.enemy.health < 1) self.cnt = 10;
  209. // Check if can see enemy? (use weapon offset)
  210. else if (visxray(self.enemy, weapofs, '0 0 0', FALSE))
  211. self.cnt = self.cnt + 1;
  212. // Reset counter and keep firing
  213. else self.cnt = 0;
  214.  
  215. // If fired a burst of bullets at enemy, stop loop
  216. if (self.cnt > 4 + skill*2) // Vary bullet burst based on skill
  217. self.think = self.th_charge;
  218. else
  219. fred_fireweapon(weapofs);
  220. };
  221.  
  222. // Cycle through barrel firing
  223. // Easy = 7 shots, Normal = 11 shots, Hard/NM = 15 shots
  224. //----------------------------------------------------------------------
  225. void() fred_sfire9 = [ $sfire9, fred_sfire10 ] {fred_standfire('45 -10 20');};
  226. void() fred_sfire10 = [ $sfire10, fred_sfire11 ] {fred_standfire('45 -10 20');};
  227. void() fred_sfire11 = [ $sfire11, fred_sfire12 ] {fred_standfire('45 -10 22');};
  228. void() fred_sfire12 = [ $sfire12, fred_sfire13 ] {fred_standfire('45 -10 22');};
  229. void() fred_sfire13 = [ $sfire13, fred_sfire14 ] {fred_standfire('45 -12 23');};
  230. void() fred_sfire14 = [ $sfire14, fred_sfire15 ] {fred_standfire('42 -12 25');};
  231. void() fred_sfire15 = [ $sfire15, fred_sfire16 ] {fred_standfire('42 -14 23');
  232. // Always double check health before changing think
  233. if (self.health > 0 && skill == 0) self.think = self.th_charge;};
  234. void() fred_sfire16 = [ $sfire16, fred_sfire17 ] {fred_standfire('38 -14 27');};
  235. void() fred_sfire17 = [ $sfire17, fred_sfire18 ] {fred_standfire('38 -17 26');};
  236. void() fred_sfire18 = [ $sfire18, fred_sfire19 ] {fred_standfire('36 -17 28');};
  237. void() fred_sfire19 = [ $sfire19, fred_sfire20 ] {fred_standfire('36 -17 26');
  238. // Always double check health before changing think
  239. if (self.health > 0 && skill == 1) self.think = self.th_charge;};
  240. void() fred_sfire20 = [ $sfire20, fred_sfire21 ] {fred_standfire('30 -17 28');};
  241. void() fred_sfire21 = [ $sfire21, fred_sfire22 ] {fred_standfire('30 -18 25');};
  242. void() fred_sfire22 = [ $sfire22, fred_sfire23 ] {fred_standfire('25 -18 27');};
  243. void() fred_sfire23 = [ $sfire23, fred_sfire24 ] {fred_standfire('25 -18 27');};
  244.  
  245. // Finish the wind down of weapon
  246. void() fred_sfire24 = [ $sfire24, fred_sfire25 ] {};
  247. void() fred_sfire25 = [ $sfire25, fred_sfire26 ] {};
  248. void() fred_sfire26 = [ $sfire26, fred_sfire27 ] {};
  249. void() fred_sfire27 = [ $sfire27, fred_run ] {};
  250.  
  251. //============================================================================
  252. // freddie has a run while firing and can switch seamless
  253. // between the two if the player is within sight
  254. //============================================================================
  255. void() fred_runframe =
  256. {
  257. // If dead, no more updates
  258. if (self.health < 1) return;
  259. // If enemy is dead or missing no firing
  260. if (!self.enemy || self.enemy.health < 1) self.attack_timer = FALSE;
  261.  
  262. if (self.attack_timer) self.frame = $rfire1 + self.walkframe;
  263. else self.frame = $run1 + self.walkframe;
  264.  
  265. // Beginning of animation block
  266. if (self.walkframe == 0)
  267. sound_idle (self, CHAN_VOICE, "freddie/idle1.wav", 1, ATTN_IDLE);
  268.  
  269. if (self.walkframe == 0) {self.distance = 24;self.attack_offset = '50 -20 32';}
  270. else if (self.walkframe == 1) {self.distance = 19;self.attack_offset = '43 -18 33';}
  271. else if (self.walkframe == 2) {self.distance = 1;self.attack_offset = '53 -20 27';}
  272. else if (self.walkframe == 3) {self.distance = 2;self.attack_offset = '47 -19 31';}
  273. else if (self.walkframe == 4) {self.distance = 5;self.attack_offset = '54 -17 29';}
  274. else if (self.walkframe == 5) {self.distance = 10;self.attack_offset = '47 -17 35';}
  275. else if (self.walkframe == 6) {self.distance = 5;self.attack_offset = '53 -15 32';}
  276. else if (self.walkframe == 7) {self.distance = 5;self.attack_offset = '47 -15 36';}
  277. else if (self.walkframe == 8) {self.distance = 24;self.attack_offset = '50 -13 32';}
  278. else if (self.walkframe == 9) {self.distance = 19;self.attack_offset = '46 -15 33';}
  279. else if (self.walkframe == 10) {self.distance = 1;self.attack_offset = '51 -14 33';}
  280. else if (self.walkframe == 11) {self.distance = 2;self.attack_offset = '47 -14 32';}
  281. else if (self.walkframe == 12) {self.distance = 5;self.attack_offset = '52 -14 33';}
  282. else if (self.walkframe == 13) {self.distance = 10;self.attack_offset = '47 -14 36';}
  283. else if (self.walkframe == 14) {self.distance = 5;self.attack_offset = '49 -14 35';}
  284. else if (self.walkframe == 15) {self.distance = 5;self.attack_offset = '45 -15 34';}
  285.  
  286. // Run + Fire time?
  287. if (self.attack_timer) {
  288. // Keep turning towards the enemy
  289. ai_face();
  290. // Fire a small burst at the enemy
  291. self.cnt = self.cnt + 1;
  292. if (self.cnt > 2) self.attack_timer = FALSE;
  293. else fred_fireweapon(self.attack_offset);
  294. }
  295.  
  296. // Move frame forward, check for conditions
  297. self.walkframe = self.walkframe + 1;
  298. if (self.walkframe > 15) self.walkframe = 0;
  299. self.nextthink = time + 0.1;
  300. self.think = fred_runframe;
  301.  
  302. ai_run(self.distance * (1 + self.speed_mod));
  303. };
  304.  
  305. //----------------------------------------------------------------------
  306. void() fred_run = { self.walkframe = 0; fred_runframe(); };
  307.  
  308. //===========================================================================
  309. // MELEE ATTACK - Various back and forth blade arm attacks
  310. //===========================================================================
  311. void(float side) fred_blade =
  312. {
  313. local float ldmg;
  314.  
  315. if (!self.enemy) return;
  316. if (self.health < 1) return;
  317.  
  318. ai_damagebreakable(20); // Damage any breakables
  319. if (!ai_checkmelee(MONAI_MELEEFREDDIE, MONAI_MELEEZTALL)) return; // Too far away
  320.  
  321. // Can the target bleed? - generate blood
  322. if (!CanDamage (self.enemy, self)) return;
  323.  
  324. sound (self, CHAN_WEAPON, "freddie/mangle.wav", 1, ATTN_NORM);
  325. // 1-45 (3x15) damage
  326. ldmg = (random() + random() + random()) * 15;
  327. if (ldmg < 1) ldmg = 1;
  328. T_Damage (self.enemy, self, self, ldmg);
  329. makevectors(self.angles);
  330. SpawnMeatSpray (trace_endpos, side * v_right);
  331. SpawnMeatSpray (trace_endpos, side * v_right);
  332. };
  333.  
  334. // Alternative ending of melee attack (chance of extra damage)
  335. //----------------------------------------------------------------------
  336. void() fred_bswing1 = [ $bswing1, fred_bswing2 ] {ai_faceforward(20);
  337. sound (self, CHAN_WEAPON, "freddie/sawstart.wav", 1, ATTN_NORM);};
  338. void() fred_bswing2 = [ $bswing2, fred_bswing3 ] {ai_faceforward(12);};
  339. void() fred_bswing3 = [ $bswing3, fred_bswing4 ] {ai_faceforward(4);};
  340. void() fred_bswing4 = [ $bswing4, fred_bswing5 ] {ai_faceforward(2);};
  341. void() fred_bswing5 = [ $bswing5, fred_bswing6 ] {ai_faceforward(6);fred_blade(200);};
  342. void() fred_bswing6 = [ $bswing6, fred_bswing7 ] {ai_faceforward(4);};
  343. void() fred_bswing7 = [ $bswing7, fred_bswing8 ] {ai_faceforward(4);};
  344. void() fred_bswing8 = [ $bswing8, fred_bswing9 ] {ai_faceforward(8);};
  345. void() fred_bswing9 = [ $bswing9, fred_bswing10 ] {ai_faceforward(8);};
  346. void() fred_bswing10 = [ $bswing10, fred_bswing11 ] {ai_faceforward(8);};
  347. void() fred_bswing11 = [ $bswing11, fred_bswing12 ] {ai_faceforward(8);};
  348. void() fred_bswing12 = [ $bswing12, fred_bswing13 ] {ai_faceforward(12);};
  349. void() fred_bswing13 = [ $bswing13, fred_bswing14 ] {ai_faceforward(10);};
  350. void() fred_bswing14 = [ $bswing14, fred_run ] {ai_faceforward(10);};
  351.  
  352. // Start of melee attack
  353. //----------------------------------------------------------------------
  354. void() fred_fswing1 = [ $fswing1, fred_fswing2 ] {ai_faceforward(8);
  355. sound (self, CHAN_WEAPON, "freddie/sawstart.wav", 1, ATTN_NORM);};
  356. void() fred_fswing2 = [ $fswing2, fred_fswing3 ] {ai_faceforward(16); };
  357. void() fred_fswing3 = [ $fswing3, fred_fswing4 ] {ai_faceforward(10);
  358. self.nextthink = time + 0.09;};
  359. void() fred_fswing4 = [ $fswing4, fred_fswing5 ] {ai_faceforward(4);
  360. self.nextthink = time + 0.08;};
  361. void() fred_fswing5 = [ $fswing5, fred_fswing6 ] {ai_faceforward(2);
  362. self.nextthink = time + 0.07;};
  363. void() fred_fswing6 = [ $fswing6, fred_fswing7 ] {ai_faceforward(1);
  364. self.nextthink = time + 0.07;};
  365. void() fred_fswing7 = [ $fswing7, fred_fswing8 ] {ai_faceforward(1);
  366. self.nextthink = time + 0.06;};
  367. void() fred_fswing8 = [ $fswing8, fred_fswing9 ] {ai_faceforward(2);fred_blade(-200);
  368. self.nextthink = time + 0.05;};
  369. void() fred_fswing9 = [ $fswing9, fred_fswing10 ] {ai_faceforward(2);};
  370. void() fred_fswing10 = [ $fswing10, fred_fswing11 ] {ai_faceforward(2);};
  371. void() fred_fswing11 = [ $fswing11, fred_fswinge1 ] {
  372. // Always check for enemy and health before changing think
  373. if (self.enemy && self.enemy.health > 1 && self.health > 0) {
  374. // Check if within range to do a second (back) swing attack
  375. if (ai_checkmelee(MONAI_MELEEFREDDIE, MONAI_MELEEZTALL)) self.think = fred_bswing1;
  376. }
  377. };
  378.  
  379. // End of melee attack
  380. //----------------------------------------------------------------------
  381. void() fred_fswinge1 = [ $fswinge1, fred_fswinge2 ] {ai_faceforward(2);};
  382. void() fred_fswinge2 = [ $fswinge2, fred_fswinge3 ] {ai_faceforward(2);};
  383. void() fred_fswinge3 = [ $fswinge3, fred_fswinge4 ] {ai_faceforward(3);};
  384. void() fred_fswinge4 = [ $fswinge4, fred_fswinge5 ] {ai_faceforward(4);};
  385. void() fred_fswinge5 = [ $fswinge5, fred_fswinge6 ] {ai_faceforward(8);};
  386. void() fred_fswinge6 = [ $fswinge6, fred_fswinge7 ] {ai_faceforward(12);};
  387. void() fred_fswinge7 = [ $fswinge7, fred_fswinge8 ] {ai_faceforward(16);};
  388. void() fred_fswinge8 = [ $fswinge8, fred_fswinge9 ] {ai_faceforward(12);};
  389. void() fred_fswinge9 = [ $fswinge9, fred_fswinge10 ] {ai_faceforward(16);};
  390. void() fred_fswinge10 = [ $fswinge10, fred_run ] {
  391. ai_faceforward(16);};
  392.  
  393. //============================================================================
  394. void() fred_pain1 = [ $pain1, fred_pain2 ] {};
  395. void() fred_pain2 = [ $pain2, fred_pain3 ] {ai_pain(10);};
  396. void() fred_pain3 = [ $pain3, fred_pain4 ] {ai_pain(9);};
  397. void() fred_pain4 = [ $pain4, fred_pain5 ] {ai_pain(4);};
  398. void() fred_pain5 = [ $pain5, fred_pain6 ] {};
  399. void() fred_pain6 = [ $pain6, fred_pain7 ] {};
  400. void() fred_pain7 = [ $pain7, fred_pain8 ] {};
  401. void() fred_pain8 = [ $pain8, fred_pain9 ] {};
  402. void() fred_pain9 = [ $pain9, fred_pain10 ] {};
  403. void() fred_pain10 = [ $pain10, fred_pain11 ] {};
  404. void() fred_pain11 = [ $pain11, fred_pain12 ] {};
  405. void() fred_pain12 = [ $pain12, fred_run ] {};
  406.  
  407. //----------------------------------------------------------------------
  408. void() fred_painb1 = [ $painb1, fred_painb2 ] {};
  409. void() fred_painb2 = [ $painb2, fred_painb3 ] {};
  410. void() fred_painb3 = [ $painb3, fred_painb4 ] {};
  411. void() fred_painb4 = [ $painb4, fred_painb5 ] {};
  412. void() fred_painb5 = [ $painb5, fred_run ] {};
  413.  
  414. //----------------------------------------------------------------------
  415. void(entity attacker, float damage) fred_pain =
  416. {
  417. float pain_check;
  418. // already dying, don't go into pain frame
  419. if (self.health < 1) pain_check = 0;
  420. // Dangerous liquids should kill the monster and keeping them in constant pain animations which makes them look better than doing nothing!
  421. else if (self.watertype == CONTENT_SLIME || self.watertype == CONTENT_LAVA) pain_check = 1;
  422. // If being attacked by a world object (shooter, electricity, bmodel) in pain
  423. else if (attacker == world) pain_check = 1;
  424. // Random chance to flinch and not ignore the pain (play sound only)
  425. else if (random()* 100 > damage ) pain_check = 3;
  426. // DEFAULT : long pain animation + sound (last condition)
  427. else pain_check = 2;
  428.  
  429. // Any pain animation/sound required?
  430. if (pain_check > 0) {
  431. // Random pain sounds
  432. if (random() < 0.5)
  433. sound_pain (self, CHAN_VOICE, "freddie/pain.wav", 1, ATTN_NORM);
  434. else
  435. sound_misc3 (self, CHAN_VOICE, "freddie/painshrt.wav", 1, ATTN_NORM);
  436.  
  437. if (pain_check == 1) {
  438. self.pain_finished = time + 2 + random()*2;
  439. // Really short 5 frame re-coil
  440. fred_painb1();
  441. }
  442. else if (pain_check == 2) {
  443. self.pain_finished = time + 3 + random()*2;
  444. // Long classic pain animation
  445. fred_pain1();
  446. }
  447. }
  448. };
  449.  
  450. //============================================================================
  451. void() fred_death1 = [ $death1, fred_death2 ] {};
  452. void() fred_death2 = [ $death2, fred_death3 ] {};
  453. void() fred_death3 = [ $death3, fred_death4 ] {self.solid = SOLID_NOT;};
  454. void() fred_death4 = [ $death4, fred_death5 ] {};
  455. void() fred_death5 = [ $death5, fred_death6 ] {};
  456. void() fred_death6 = [ $death6, fred_death7 ] {};
  457. void() fred_death7 = [ $death7, fred_death8 ] {};
  458. void() fred_death8 = [ $death8, fred_death9 ] {};
  459. void() fred_death9 = [ $death9, fred_death10 ] {};
  460. void() fred_death10 = [ $death10, fred_death11 ] {};
  461. void() fred_death11 = [ $death11, fred_death12 ] {};
  462. void() fred_death12 = [ $death12, fred_death13 ] {};
  463. void() fred_death13 = [ $death13, fred_death14 ] {};
  464. void() fred_death14 = [ $death14, fred_death15 ] {};
  465. void() fred_death15 = [ $death15, fred_death16 ] {};
  466. void() fred_death16 = [ $death16, fred_death17 ] {};
  467. void() fred_death17 = [ $death17, fred_death18 ] {};
  468. void() fred_death18 = [ $death18, fred_death19 ] {};
  469. void() fred_death19 = [ $death19, fred_death20 ] {};
  470. void() fred_death20 = [ $death20, fred_death21 ] {};
  471. void() fred_death21 = [ $death21, fred_death22 ] {};
  472. void() fred_death22 = [ $death22, fred_death23 ] {};
  473. void() fred_death23 = [ $death23, fred_death24 ] {};
  474. void() fred_death24 = [ $death24, fred_death25 ] {};
  475. void() fred_death25 = [ $death25, fred_death26 ] {};
  476. void() fred_death26 = [ $death26, fred_death27 ] {};
  477. void() fred_death27 = [ $death27, fred_death28 ] {};
  478. void() fred_death28 = [ $death28, fred_death29 ] {};
  479. void() fred_death29 = [ $death29, fred_death30 ] {};
  480. void() fred_death30 = [ $death30, fred_death31 ] {};
  481. void() fred_death31 = [ $death31, fred_death32 ] {};
  482. void() fred_death32 = [ $death32, fred_death33 ] {};
  483. void() fred_death33 = [ $death33, fred_death34 ] {};
  484. void() fred_death34 = [ $death34, fred_death35 ] {};
  485. void() fred_death35 = [ $death35, fred_death35 ] {self.nextthink = -1;};
  486.  
  487. //----------------------------------------------------------------------
  488. /*
  489. void() fred_explode =
  490. {
  491. // no more FREDDIE!
  492. entity_hide (self);
  493. // Make sure gibs go flying up
  494. self.max_health = MON_GIBFOUNTAIN;
  495. self.health = -100;
  496.  
  497. // ID style explosion
  498. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  499. WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  500. WriteCoord (MSG_BROADCAST, self.origin_x);
  501. WriteCoord (MSG_BROADCAST, self.origin_y);
  502. WriteCoord (MSG_BROADCAST, self.origin_z);
  503. T_RadiusDamage (self, self, DAMAGE_FREDDIE, world, DAMAGEALL);
  504.  
  505. // Sprite + Dust (+ explosion death sound)
  506. SpawnExplosion(EXPLODE_BIG, self.origin, self.death_sound2);
  507. SpawnProjectileSmoke(self.origin, 200, 250, 100);
  508. SpawnProjectileSmoke(self.origin, 200, 250, 100);
  509.  
  510. // Regular blood like gibs
  511. ThrowGib(4, 2 + rint(random()*4));
  512. ThrowGib(5, 2 + rint(random()*4));
  513. ThrowGib(25, 1);
  514. // Metal and custom body parts
  515. self.gibtype = GIBTYPE_METAL;
  516. ThrowGib(11, 1 + rint(random()*2));
  517. ThrowGib(12, 2 + rint(random()*2));
  518. ThrowGib(13, 2 + rint(random()*2));
  519. };
  520. */
  521.  
  522. //----------------------------------------------------------------------
  523. void() fred_die =
  524. {
  525. // check for gib
  526. if (self.health < -80)
  527. {
  528. if (self.snd_misc && self.snd_misc != "")
  529. sound (self, CHAN_VOICE, self.snd_misc, 1, ATTN_NORM);
  530. else
  531. sound (self, CHAN_VOICE, "freddie/explode_major.wav", 1, ATTN_NORM);
  532.  
  533. if (self.mdl_head != "") //dumptruck_ds custom_mdls
  534. ThrowHead (self.mdl_head, self.health);
  535. else
  536. ThrowHead ("progs/h_ogre.mdl", self.health);
  537.  
  538. if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
  539. ThrowGib (self.mdl_gib1, self.health);
  540. else
  541. ThrowGib ("progs/gib1.mdl", self.health);
  542. if (self.mdl_gib2 != "")
  543. ThrowGib (self.mdl_gib2, self.health);
  544. else
  545. ThrowGib ("progs/gib2.mdl", self.health);
  546. if (self.mdl_gib3 != "")
  547. ThrowGib (self.mdl_gib3, self.health);
  548. else
  549. ThrowGib ("progs/gib3.mdl", self.health);
  550.  
  551. ThrowGib ("progs/gib_freddiejunk.mdl", self.health);
  552. ThrowGib ("progs/gib_metal1.mdl", self.health);
  553. ThrowGib ("progs/gib_metal3.mdl", self.health);
  554.  
  555. WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  556. WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  557. WriteCoord (MSG_BROADCAST, self.origin_x);
  558. WriteCoord (MSG_BROADCAST, self.origin_y);
  559. WriteCoord (MSG_BROADCAST, self.origin_z);
  560. T_RadiusDamage (self, self, DAMAGE_FREDDIE, world);
  561.  
  562. DropStuff();
  563. remove(self);
  564. return;
  565. }
  566.  
  567. // regular death
  568. sound_death (self, CHAN_VOICE, "freddie/death.wav", 1, ATTN_NORM);
  569. DropStuff();
  570. fred_death1 ();
  571. };
  572.  
  573. /*======================================================================
  574. QUAKED monster_freddie (1 0 0) (-32 -32 -24) (32 32 64) Ambush
  575. ======================================================================*/
  576. void() monster_freddie =
  577. {
  578. if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
  579. return;
  580.  
  581. precache_body_model2 ("progs/mon_freddie.mdl"); // custom_mdls function -- dumptruck_ds
  582. precache_head_model2 ("progs/h_ogre.mdl");
  583. precache_gib1 ("progs/gib1.mdl");
  584. precache_gib2 ("progs/gib2.mdl");
  585. precache_gib3 ("progs/gib3.mdl");
  586. precache_model ("progs/gib_freddiejunk.mdl");
  587. precache_model ("progs/gib_metal1.mdl");
  588. precache_model ("progs/gib_metal3.mdl");
  589.  
  590. precache_sound2_idle ("freddie/idle1.wav");
  591.  
  592. // Melee sounds, swing and impact
  593. precache_sound("freddie/sawstart.wav");
  594. precache_sound("freddie/mangle.wav");
  595.  
  596. // Default attack - red glowing nails
  597. precache_model ("progs/proj_ngred.mdl");
  598. precache_sound ("freddie/stfire.wav");
  599.  
  600. // Alternative attack - lasers!?!
  601. if (self.spawnflags & MON_FREDDIE_LASER) {
  602. precache_model ("progs/proj_laz.mdl");
  603. precache_sound ("seeker/range_laser.wav");
  604. precache_sound ("enforcer/enfire.wav");
  605. precache_sound ("enforcer/enfstop.wav");
  606. }
  607.  
  608. precache_sound2_death ("freddie/death.wav");
  609. precache_sound2_misc ("freddie/explode_major.wav");
  610. precache_sound2_pain ("freddie/pain.wav");
  611. precache_sound2_misc3 ("freddie/painshrt.wav");
  612. precache_sound2_sight ("freddie/sight.wav");
  613.  
  614. body_model ("progs/mon_freddie.mdl");
  615.  
  616. //self.solid = SOLID_NOT; // No interaction with world
  617. //self.movetype = MOVETYPE_NONE; // Static item, no movement
  618. self.solid = SOLID_SLIDEBOX;
  619. self.movetype = MOVETYPE_STEP;
  620. setsize(self, '-24 -24 -24', '24 24 64');
  621. if (self.health < 1)
  622. self.health = 500;
  623. self.attack_offset = '0 0 0'; // Run + Gun vector
  624. if (!self.obit_method || self.obit_method=="")
  625. self.obit_method = "exterminated";
  626. if (!self.obit_name || self.obit_name=="")
  627. self.obit_name = "Freddie";
  628.  
  629. //self.th_checkattack = FreddieCheckAttack;
  630. self.th_stand = fred_stand1;
  631. self.th_walk = fred_walk1;
  632. self.th_run = fred_run;
  633. self.th_melee = fred_fswing1; // Blade arm
  634. self.th_missile = fred_sfire1; // Spike/Laser bolts
  635. self.th_charge = fred_sfire24; // End of barrel weapon
  636. if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
  637. self.th_pain = fred_pain;
  638. else
  639. self.th_pain = SUB_NullPain;
  640. self.th_die = fred_die;
  641.  
  642. walkmonster_start();
  643. };
  644.  
  645. // Re-direct all Quoth Edie requests to Freddie!
  646. void() monster_edie = { self.classname = "monster_freddie"; monster_freddie(); }
  647.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement