home *** CD-ROM | disk | FTP | other *** search
/ Gambler 19 / GAMBLERCD19.BIN / UTILS / 3D / BRONIE / DUAL_LAU.ZIP / src / m_parasite.c < prev    next >
C/C++ Source or Header  |  1997-11-24  |  13KB  |  526 lines

  1. /*
  2. ==============================================================================
  3.  
  4. parasite
  5.  
  6. ==============================================================================
  7. */
  8.  
  9. #include "g_local.h"
  10. #include "m_parasite.h"
  11.  
  12.  
  13. static int    sound_pain1;
  14. static int    sound_pain2;
  15. static int    sound_die;
  16. static int    sound_launch;
  17. static int    sound_impact;
  18. static int    sound_suck;
  19. static int    sound_reelin;
  20. static int    sound_sight;
  21. static int    sound_tap;
  22. static int    sound_scratch;
  23. static int    sound_search;
  24.  
  25.  
  26. void parasite_stand (edict_t *self);
  27. void parasite_start_run (edict_t *self);
  28. void parasite_run (edict_t *self);
  29. void parasite_walk (edict_t *self);
  30. void parasite_start_walk (edict_t *self);
  31. void parasite_end_fidget (edict_t *self);
  32. void parasite_do_fidget (edict_t *self);
  33. void parasite_refidget (edict_t *self);
  34.  
  35.  
  36. void parasite_launch (edict_t *self)
  37. {
  38.     gi.sound (self, CHAN_WEAPON, sound_launch, 1, ATTN_NORM, 0);
  39. }
  40.  
  41. void parasite_reel_in (edict_t *self)
  42. {
  43.     gi.sound (self, CHAN_WEAPON, sound_reelin, 1, ATTN_NORM, 0);
  44. }
  45.  
  46. void parasite_sight (edict_t *self, edict_t *other)
  47. {
  48.     gi.sound (self, CHAN_WEAPON, sound_sight, 1, ATTN_NORM, 0);
  49. }
  50.  
  51. void parasite_tap (edict_t *self)
  52. {
  53.     gi.sound (self, CHAN_WEAPON, sound_tap, 1, ATTN_IDLE, 0);
  54. }
  55.  
  56. void parasite_scratch (edict_t *self)
  57. {
  58.     gi.sound (self, CHAN_WEAPON, sound_scratch, 1, ATTN_IDLE, 0);
  59. }
  60.  
  61. void parasite_search (edict_t *self)
  62. {
  63.     gi.sound (self, CHAN_WEAPON, sound_search, 1, ATTN_IDLE, 0);
  64. }
  65.  
  66.  
  67. mframe_t parasite_frames_start_fidget [] =
  68. {
  69.     ai_stand, 0, NULL,
  70.     ai_stand, 0, NULL,
  71.     ai_stand, 0, NULL,
  72.     ai_stand, 0, NULL
  73. };
  74. mmove_t parasite_move_start_fidget = {FRAME_stand18, FRAME_stand21, parasite_frames_start_fidget, parasite_do_fidget};
  75.  
  76. mframe_t parasite_frames_fidget [] =
  77. {    
  78.     ai_stand, 0, parasite_scratch,
  79.     ai_stand, 0, NULL,
  80.     ai_stand, 0, NULL,
  81.     ai_stand, 0, parasite_scratch,
  82.     ai_stand, 0, NULL,
  83.     ai_stand, 0, NULL
  84. };
  85. mmove_t parasite_move_fidget = {FRAME_stand22, FRAME_stand27, parasite_frames_fidget, parasite_refidget};
  86.  
  87. mframe_t parasite_frames_end_fidget [] =
  88. {
  89.     ai_stand, 0, parasite_scratch,
  90.     ai_stand, 0, NULL,
  91.     ai_stand, 0, NULL,
  92.     ai_stand, 0, NULL,
  93.     ai_stand, 0, NULL,
  94.     ai_stand, 0, NULL,
  95.     ai_stand, 0, NULL,
  96.     ai_stand, 0, NULL
  97. };
  98. mmove_t parasite_move_end_fidget = {FRAME_stand28, FRAME_stand35, parasite_frames_end_fidget, parasite_stand};
  99.  
  100. void parasite_end_fidget (edict_t *self)
  101. {
  102.     self->monsterinfo.currentmove = ¶site_move_end_fidget;
  103. }
  104.  
  105. void parasite_do_fidget (edict_t *self)
  106. {
  107.     self->monsterinfo.currentmove = ¶site_move_fidget;
  108. }
  109.  
  110. void parasite_refidget (edict_t *self)
  111.     if (random() <= 0.8)
  112.         self->monsterinfo.currentmove = ¶site_move_fidget;
  113.     else
  114.         self->monsterinfo.currentmove = ¶site_move_end_fidget;
  115. }
  116.  
  117. void parasite_idle (edict_t *self)
  118.     self->monsterinfo.currentmove = ¶site_move_start_fidget;
  119. }
  120.  
  121.  
  122. mframe_t parasite_frames_stand [] =
  123. {
  124.     ai_stand, 0, NULL,
  125.     ai_stand, 0, NULL,
  126.     ai_stand, 0, parasite_tap,
  127.     ai_stand, 0, NULL,
  128.     ai_stand, 0, parasite_tap,
  129.     ai_stand, 0, NULL,
  130.     ai_stand, 0, NULL,
  131.     ai_stand, 0, NULL,
  132.     ai_stand, 0, parasite_tap,
  133.     ai_stand, 0, NULL,
  134.     ai_stand, 0, parasite_tap,
  135.     ai_stand, 0, NULL,
  136.     ai_stand, 0, NULL,
  137.     ai_stand, 0, NULL,
  138.     ai_stand, 0, parasite_tap,
  139.     ai_stand, 0, NULL,
  140.     ai_stand, 0, parasite_tap
  141. };
  142. mmove_t    parasite_move_stand = {FRAME_stand01, FRAME_stand17, parasite_frames_stand, parasite_stand};
  143.  
  144. void parasite_stand (edict_t *self)
  145. {
  146.     self->monsterinfo.currentmove = ¶site_move_stand;
  147. }
  148.  
  149.  
  150. mframe_t parasite_frames_run [] =
  151. {
  152.     ai_run, 30, NULL,
  153.     ai_run, 30, NULL,
  154.     ai_run, 22, NULL,
  155.     ai_run, 19, NULL,
  156.     ai_run, 24, NULL,
  157.     ai_run, 28, NULL,
  158.     ai_run, 25, NULL
  159. };
  160. mmove_t parasite_move_run = {FRAME_run03, FRAME_run09, parasite_frames_run, NULL};
  161.  
  162. mframe_t parasite_frames_start_run [] =
  163. {
  164.     ai_run, 0,    NULL,
  165.     ai_run, 30, NULL,
  166. };
  167. mmove_t parasite_move_start_run = {FRAME_run01, FRAME_run02, parasite_frames_start_run, parasite_run};
  168.  
  169. mframe_t parasite_frames_stop_run [] =
  170. {    
  171.     ai_run, 20, NULL,
  172.     ai_run, 20,    NULL,
  173.     ai_run, 12, NULL,
  174.     ai_run, 10, NULL,
  175.     ai_run, 0,  NULL,
  176.     ai_run, 0,  NULL
  177. };
  178. mmove_t parasite_move_stop_run = {FRAME_run10, FRAME_run15, parasite_frames_stop_run, NULL};
  179.  
  180. void parasite_start_run (edict_t *self)
  181. {    
  182.     self->monsterinfo.currentmove = ¶site_move_start_run;
  183. }
  184.  
  185. void parasite_run (edict_t *self)
  186. {
  187.     if (self->monsterinfo.aiflags & AI_STAND_GROUND)
  188.         self->monsterinfo.currentmove = ¶site_move_stand;
  189.     else
  190.         self->monsterinfo.currentmove = ¶site_move_run;
  191. }
  192.  
  193.  
  194. mframe_t parasite_frames_walk [] =
  195. {
  196.     ai_walk, 30, NULL,
  197.     ai_walk, 30, NULL,
  198.     ai_walk, 22, NULL,
  199.     ai_walk, 19, NULL,
  200.     ai_walk, 24, NULL,
  201.     ai_walk, 28, NULL,
  202.     ai_walk, 25, NULL
  203. };
  204. mmove_t parasite_move_walk = {FRAME_run03, FRAME_run09, parasite_frames_walk, parasite_walk};
  205.  
  206. mframe_t parasite_frames_start_walk [] =
  207. {
  208.     ai_walk, 0,    NULL,
  209.     ai_walk, 30, parasite_walk
  210. };
  211. mmove_t parasite_move_start_walk = {FRAME_run01, FRAME_run02, parasite_frames_start_walk, NULL};
  212.  
  213. mframe_t parasite_frames_stop_walk [] =
  214. {    
  215.     ai_walk, 20, NULL,
  216.     ai_walk, 20,    NULL,
  217.     ai_walk, 12, NULL,
  218.     ai_walk, 10, NULL,
  219.     ai_walk, 0,  NULL,
  220.     ai_walk, 0,  NULL
  221. };
  222. mmove_t parasite_move_stop_walk = {FRAME_run10, FRAME_run15, parasite_frames_stop_walk, NULL};
  223.  
  224. void parasite_start_walk (edict_t *self)
  225. {    
  226.     self->monsterinfo.currentmove = ¶site_move_start_walk;
  227. }
  228.  
  229. void parasite_walk (edict_t *self)
  230. {
  231.     self->monsterinfo.currentmove = ¶site_move_walk;
  232. }
  233.  
  234.  
  235. mframe_t parasite_frames_pain1 [] =
  236. {
  237.     ai_move, 0, NULL,
  238.     ai_move, 0, NULL,
  239.     ai_move, 0,    NULL,
  240.     ai_move, 0,    NULL,
  241.     ai_move, 0,    NULL,
  242.     ai_move, 0,    NULL,
  243.     ai_move, 6,    NULL,
  244.     ai_move, 16, NULL,
  245.     ai_move, -6, NULL,
  246.     ai_move, -7, NULL,
  247.     ai_move, 0, NULL
  248. };
  249. mmove_t parasite_move_pain1 = {FRAME_pain101, FRAME_pain111, parasite_frames_pain1, parasite_start_run};
  250.  
  251. void parasite_pain (edict_t *self, edict_t *other, float kick, int damage)
  252. {
  253.     if (self->health < (self->max_health / 2))
  254.         self->s.skinnum = 1;
  255.  
  256.     if (level.time < self->pain_debounce_time)
  257.         return;
  258.  
  259.     self->pain_debounce_time = level.time + 3;
  260.     if (random() < 0.5)
  261.         gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
  262.     else
  263.         gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
  264.  
  265.     self->monsterinfo.currentmove = ¶site_move_pain1;
  266. }
  267.  
  268.  
  269. static qboolean parasite_drain_attack_ok (vec3_t start, vec3_t end)
  270. {
  271.     vec3_t    dir, angles;
  272.  
  273.     // check for max distance
  274.     VectorSubtract (start, end, dir);
  275.     if (VectorLength(dir) > 256)
  276.         return false;
  277.  
  278.     // check for min/max pitch
  279.     vectoangles (dir, angles);
  280.     if (angles[0] < -180)
  281.         angles[0] += 360;
  282.     if (fabs(angles[0]) > 30)
  283.         return false;
  284.  
  285.     return true;
  286. }
  287.  
  288. void parasite_drain_attack (edict_t *self)
  289. {
  290.     vec3_t    offset, start, f, r, end, dir;
  291.     trace_t    tr;
  292.     int damage;
  293.  
  294.     AngleVectors (self->s.angles, f, r, NULL);
  295.     VectorSet (offset, 24, 0, 6);
  296.     G_ProjectSource (self->s.origin, offset, f, r, start);
  297.  
  298.     VectorCopy (self->enemy->s.origin, end);
  299.     if (!parasite_drain_attack_ok(start, end))
  300.     {
  301.         end[2] = self->enemy->s.origin[2] + self->enemy->maxs[2] - 8;
  302.         if (!parasite_drain_attack_ok(start, end))
  303.         {
  304.             end[2] = self->enemy->s.origin[2] + self->enemy->mins[2] + 8;
  305.             if (!parasite_drain_attack_ok(start, end))
  306.                 return;
  307.         }
  308.     }
  309.     VectorCopy (self->enemy->s.origin, end);
  310.  
  311.     tr = gi.trace (start, NULL, NULL, end, self, MASK_SHOT);
  312.     if (tr.ent != self->enemy)
  313.         return;
  314.  
  315.     if (self->s.frame == FRAME_drain03)
  316.     {
  317.         damage = 5;
  318.         gi.sound (self->enemy, CHAN_AUTO, sound_impact, 1, ATTN_NORM, 0);
  319.     }
  320.     else
  321.     {
  322.         if (self->s.frame == FRAME_drain04)
  323.             gi.sound (self, CHAN_WEAPON, sound_suck, 1, ATTN_NORM, 0);
  324.         damage = 2;
  325.     }
  326.  
  327.     gi.WriteByte (svc_temp_entity);
  328.     gi.WriteByte (TE_PARASITE_ATTACK);
  329.     gi.WriteShort (self - g_edicts);
  330.     gi.WritePosition (start);
  331.     gi.WritePosition (end);
  332.     gi.multicast (self->s.origin, MULTICAST_PVS);
  333.  
  334.     VectorSubtract (start, end, dir);
  335.     T_Damage (self->enemy, self, self, dir, self->enemy->s.origin, vec3_origin, damage, 0, DAMAGE_NO_KNOCKBACK);
  336. }
  337.  
  338. mframe_t parasite_frames_drain [] =
  339. {
  340.     ai_charge, 0,    parasite_launch,
  341.     ai_charge, 0,    NULL,
  342.     ai_charge, 15,    parasite_drain_attack,            // Target hits
  343.     ai_charge, 0,    parasite_drain_attack,            // drain
  344.     ai_charge, 0,    parasite_drain_attack,            // drain
  345.     ai_charge, 0,    parasite_drain_attack,            // drain
  346.     ai_charge, 0,    parasite_drain_attack,            // drain
  347.     ai_charge, -2,  parasite_drain_attack,            // drain
  348.     ai_charge, -2,    parasite_drain_attack,            // drain
  349.     ai_charge, -3,    parasite_drain_attack,            // drain
  350.     ai_charge, -2,    parasite_drain_attack,            // drain
  351.     ai_charge, 0,    parasite_drain_attack,            // drain
  352.     ai_charge, -1,  parasite_drain_attack,            // drain
  353.     ai_charge, 0,    parasite_reel_in,                // let go
  354.     ai_charge, -2,    NULL,
  355.     ai_charge, -2,    NULL,
  356.     ai_charge, -3,    NULL,
  357.     ai_charge, 0,    NULL
  358. };
  359. mmove_t parasite_move_drain = {FRAME_drain01, FRAME_drain18, parasite_frames_drain, parasite_start_run};
  360.  
  361.  
  362. mframe_t parasite_frames_break [] =
  363. {
  364.     ai_charge, 0,    NULL,
  365.     ai_charge, -3,    NULL,
  366.     ai_charge, 1,    NULL,
  367.     ai_charge, 2,    NULL,
  368.     ai_charge, -3,    NULL,
  369.     ai_charge, 1,    NULL,
  370.     ai_charge, 1,    NULL,
  371.     ai_charge, 3,    NULL,
  372.     ai_charge, 0,    NULL,
  373.     ai_charge, -18,    NULL,
  374.     ai_charge, 3,    NULL,
  375.     ai_charge, 9,    NULL,
  376.     ai_charge, 6,    NULL,
  377.     ai_charge, 0,    NULL,
  378.     ai_charge, -18,    NULL,
  379.     ai_charge, 0,    NULL,
  380.     ai_charge, 8,    NULL,
  381.     ai_charge, 9,    NULL,
  382.     ai_charge, 0,    NULL,
  383.     ai_charge, -18,    NULL,
  384.     ai_charge, 0,    NULL,
  385.     ai_charge, 0,    NULL,        // airborne
  386.     ai_charge, 0,    NULL,        // airborne
  387.     ai_charge, 0,    NULL,        // slides
  388.     ai_charge, 0,    NULL,        // slides
  389.     ai_charge, 0,    NULL,        // slides
  390.     ai_charge, 0,    NULL,        // slides
  391.     ai_charge, 4,    NULL,
  392.     ai_charge, 11,    NULL,        
  393.     ai_charge, -2,    NULL,
  394.     ai_charge, -5,    NULL,
  395.     ai_charge, 1,    NULL
  396. };
  397. mmove_t parasite_move_break = {FRAME_break01, FRAME_break32, parasite_frames_break, parasite_start_run};
  398.  
  399. /*
  400. === 
  401. Break Stuff Ends
  402. ===
  403. */
  404.  
  405. void parasite_attack (edict_t *self)
  406. {
  407. //    if (random() <= 0.2)
  408. //        self->monsterinfo.currentmove = ¶site_move_break;
  409. //    else
  410.         self->monsterinfo.currentmove = ¶site_move_drain;
  411. }
  412.  
  413.  
  414.  
  415. /*
  416. ===
  417. Death Stuff Starts
  418. ===
  419. */
  420.  
  421. void parasite_dead (edict_t *self)
  422. {
  423.     VectorSet (self->mins, -16, -16, -24);
  424.     VectorSet (self->maxs, 16, 16, -8);
  425.     self->movetype = MOVETYPE_TOSS;
  426.     self->nextthink = 0;
  427.     gi.linkentity (self);
  428. }
  429.  
  430. mframe_t parasite_frames_death [] =
  431. {
  432.     ai_move, 0,     NULL,
  433.     ai_move, 0,     NULL,
  434.     ai_move, 0,     NULL,
  435.     ai_move, 0,     NULL,
  436.     ai_move, 0,     NULL,
  437.     ai_move, 0,     NULL,
  438.     ai_move, 0,     NULL
  439. };
  440. mmove_t parasite_move_death = {FRAME_death101, FRAME_death107, parasite_frames_death, parasite_dead};
  441.  
  442. void parasite_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
  443. {
  444.     int        n;
  445.  
  446. // check for gib
  447.     if (self->health <= self->gib_health)
  448.     {
  449.         gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
  450.         for (n= 0; n < 2; n++)
  451.             ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
  452.         for (n= 0; n < 4; n++)
  453.             ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
  454.         ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
  455.         self->deadflag = DEAD_DEAD;
  456.         return;
  457.     }
  458.  
  459.     if (self->deadflag == DEAD_DEAD)
  460.         return;
  461.  
  462. // regular death
  463.     gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0);
  464.     self->deadflag = DEAD_DEAD;
  465.     self->takedamage = DAMAGE_YES;
  466.     self->monsterinfo.currentmove = ¶site_move_death;
  467. }
  468.  
  469. /*
  470. ===
  471. End Death Stuff
  472. ===
  473. */
  474.  
  475. /*QUAKED monster_parasite (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
  476. */
  477. void SP_monster_parasite (edict_t *self)
  478. {
  479.     if (deathmatch->value)
  480.     {
  481.         G_FreeEdict (self);
  482.         return;
  483.     }
  484.  
  485.     sound_pain1 = gi.soundindex ("parasite/parpain1.wav");    
  486.     sound_pain2 = gi.soundindex ("parasite/parpain2.wav");    
  487.     sound_die = gi.soundindex ("parasite/pardeth1.wav");    
  488.     sound_launch = gi.soundindex("parasite/paratck1.wav");
  489.     sound_impact = gi.soundindex("parasite/paratck2.wav");
  490.     sound_suck = gi.soundindex("parasite/paratck3.wav");
  491.     sound_reelin = gi.soundindex("parasite/paratck4.wav");
  492.     sound_sight = gi.soundindex("parasite/parsght1.wav");
  493.     sound_tap = gi.soundindex("parasite/paridle1.wav");
  494.     sound_scratch = gi.soundindex("parasite/paridle2.wav");
  495.     sound_search = gi.soundindex("parasite/parsrch1.wav");
  496.  
  497.     self->s.modelindex = gi.modelindex ("models/monsters/parasite/tris.md2");
  498.     VectorSet (self->mins, -16, -16, -24);
  499.     VectorSet (self->maxs, 16, 16, 24);
  500.     self->movetype = MOVETYPE_STEP;
  501.     self->solid = SOLID_BBOX;
  502.  
  503.     self->health = 175;
  504.     self->gib_health = -50;
  505.     self->mass = 250;
  506.  
  507.     self->pain = parasite_pain;
  508.     self->die = parasite_die;
  509.  
  510.     self->monsterinfo.stand = parasite_stand;
  511.     self->monsterinfo.walk = parasite_start_walk;
  512.     self->monsterinfo.run = parasite_start_run;
  513.     self->monsterinfo.attack = parasite_attack;
  514.     self->monsterinfo.sight = parasite_sight;
  515.     self->monsterinfo.idle = parasite_idle;
  516.  
  517.     gi.linkentity (self);
  518.  
  519.     self->monsterinfo.currentmove = ¶site_move_stand;    
  520.     self->monsterinfo.scale = MODEL_SCALE;
  521.  
  522.     walkmonster_start (self);
  523. }
  524.