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

  1. /*
  2. ==============================================================================
  3.  
  4. BERSERK
  5.  
  6. ==============================================================================
  7. */
  8.  
  9. #include "g_local.h"
  10. #include "m_berserk.h"
  11.  
  12.  
  13. static int sound_pain;
  14. static int sound_die;
  15. static int sound_idle;
  16. static int sound_punch;
  17. static int sound_sight;
  18. static int sound_search;
  19.  
  20. void berserk_sight (edict_t *self, edict_t *other)
  21. {
  22.     gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
  23. }
  24.  
  25. void berserk_search (edict_t *self)
  26. {
  27.     gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
  28. }
  29.  
  30.  
  31. void berserk_fidget (edict_t *self);
  32. mframe_t berserk_frames_stand [] =
  33. {
  34.     ai_stand, 0, berserk_fidget,
  35.     ai_stand, 0, NULL,
  36.     ai_stand, 0, NULL,
  37.     ai_stand, 0, NULL,
  38.     ai_stand, 0, NULL
  39. };
  40. mmove_t berserk_move_stand = {FRAME_stand1, FRAME_stand5, berserk_frames_stand, NULL};
  41.  
  42. void berserk_stand (edict_t *self)
  43. {
  44.     self->monsterinfo.currentmove = &berserk_move_stand;
  45. }
  46.  
  47. mframe_t berserk_frames_stand_fidget [] =
  48. {
  49.     ai_stand, 0, NULL,
  50.     ai_stand, 0, NULL,
  51.     ai_stand, 0, NULL,
  52.     ai_stand, 0, NULL,
  53.     ai_stand, 0, NULL,
  54.     ai_stand, 0, NULL,
  55.     ai_stand, 0, NULL,
  56.     ai_stand, 0, NULL,
  57.     ai_stand, 0, NULL,
  58.     ai_stand, 0, NULL,
  59.     ai_stand, 0, NULL,
  60.     ai_stand, 0, NULL,
  61.     ai_stand, 0, NULL,
  62.     ai_stand, 0, NULL,
  63.     ai_stand, 0, NULL,
  64.     ai_stand, 0, NULL,
  65.     ai_stand, 0, NULL,
  66.     ai_stand, 0, NULL,
  67.     ai_stand, 0, NULL,
  68.     ai_stand, 0, NULL
  69. };
  70. mmove_t berserk_move_stand_fidget = {FRAME_standb1, FRAME_standb20, berserk_frames_stand_fidget, berserk_stand};
  71.  
  72. void berserk_fidget (edict_t *self)
  73. {
  74.     if (self->monsterinfo.aiflags & AI_STAND_GROUND)
  75.         return;
  76.     if (random() > 0.15)
  77.         return;
  78.  
  79.     self->monsterinfo.currentmove = &berserk_move_stand_fidget;
  80.     gi.sound (self, CHAN_WEAPON, sound_idle, 1, ATTN_IDLE, 0);
  81. }
  82.  
  83.  
  84. mframe_t berserk_frames_walk [] =
  85. {
  86.     ai_walk, 9.1, NULL,
  87.     ai_walk, 6.3, NULL,
  88.     ai_walk, 4.9, NULL,
  89.     ai_walk, 6.7, NULL,
  90.     ai_walk, 6.0, NULL,
  91.     ai_walk, 8.2, NULL,
  92.     ai_walk, 7.2, NULL,
  93.     ai_walk, 6.1, NULL,
  94.     ai_walk, 4.9, NULL,
  95.     ai_walk, 4.7, NULL,
  96.     ai_walk, 4.7, NULL,
  97.     ai_walk, 4.8, NULL
  98. };
  99. mmove_t berserk_move_walk = {FRAME_walkc1, FRAME_walkc11, berserk_frames_walk, NULL};
  100.  
  101. void berserk_walk (edict_t *self)
  102. {
  103.     self->monsterinfo.currentmove = &berserk_move_walk;
  104. }
  105.  
  106. /*
  107.  
  108.   *****************************
  109.   SKIPPED THIS FOR NOW!
  110.   *****************************
  111.  
  112.    Running -> Arm raised in air
  113.  
  114. void()    berserk_runb1    =[    $r_att1 ,    berserk_runb2    ] {ai_run(21);};
  115. void()    berserk_runb2    =[    $r_att2 ,    berserk_runb3    ] {ai_run(11);};
  116. void()    berserk_runb3    =[    $r_att3 ,    berserk_runb4    ] {ai_run(21);};
  117. void()    berserk_runb4    =[    $r_att4 ,    berserk_runb5    ] {ai_run(25);};
  118. void()    berserk_runb5    =[    $r_att5 ,    berserk_runb6    ] {ai_run(18);};
  119. void()    berserk_runb6    =[    $r_att6 ,    berserk_runb7    ] {ai_run(19);};
  120. // running with arm in air : start loop
  121. void()    berserk_runb7    =[    $r_att7 ,    berserk_runb8    ] {ai_run(21);};
  122. void()    berserk_runb8    =[    $r_att8 ,    berserk_runb9    ] {ai_run(11);};
  123. void()    berserk_runb9    =[    $r_att9 ,    berserk_runb10    ] {ai_run(21);};
  124. void()    berserk_runb10    =[    $r_att10 ,    berserk_runb11    ] {ai_run(25);};
  125. void()    berserk_runb11    =[    $r_att11 ,    berserk_runb12    ] {ai_run(18);};
  126. void()    berserk_runb12    =[    $r_att12 ,    berserk_runb7    ] {ai_run(19);};
  127. // running with arm in air : end loop
  128. */
  129.  
  130.  
  131. mframe_t berserk_frames_run1 [] =
  132. {
  133.     ai_run, 21, NULL,
  134.     ai_run, 11, NULL,
  135.     ai_run, 21, NULL,
  136.     ai_run, 25, NULL,
  137.     ai_run, 18, NULL,
  138.     ai_run, 19, NULL
  139. };
  140. mmove_t berserk_move_run1 = {FRAME_run1, FRAME_run6, berserk_frames_run1, NULL};
  141.  
  142. void berserk_run (edict_t *self)
  143. {
  144.     if (self->monsterinfo.aiflags & AI_STAND_GROUND)
  145.         self->monsterinfo.currentmove = &berserk_move_stand;
  146.     else
  147.         self->monsterinfo.currentmove = &berserk_move_run1;
  148. }
  149.  
  150.  
  151. void berserk_attack_spike (edict_t *self)
  152. {
  153.     static    vec3_t    aim = {MELEE_DISTANCE, 0, -24};
  154.     fire_hit (self, aim, (15 + (rand() % 6)), 400);        //    Faster attack -- upwards and backwards
  155. }
  156.  
  157.  
  158. void berserk_swing (edict_t *self)
  159. {
  160.     gi.sound (self, CHAN_WEAPON, sound_punch, 1, ATTN_NORM, 0);
  161. }
  162.  
  163. mframe_t berserk_frames_attack_spike [] =
  164. {
  165.         ai_charge, 0, NULL,
  166.         ai_charge, 0, NULL,
  167.         ai_charge, 0, berserk_swing,
  168.         ai_charge, 0, berserk_attack_spike,
  169.         ai_charge, 0, NULL,
  170.         ai_charge, 0, NULL,
  171.         ai_charge, 0, NULL,
  172.         ai_charge, 0, NULL
  173. };
  174. mmove_t berserk_move_attack_spike = {FRAME_att_c1, FRAME_att_c8, berserk_frames_attack_spike, berserk_run};
  175.  
  176.  
  177. void berserk_attack_club (edict_t *self)
  178. {
  179.     vec3_t    aim;
  180.  
  181.     VectorSet (aim, MELEE_DISTANCE, self->mins[0], -4);
  182.     fire_hit (self, aim, (5 + (rand() % 6)), 400);        // Slower attack
  183. }
  184.  
  185. mframe_t berserk_frames_attack_club [] =
  186. {    
  187.     ai_charge, 0, NULL,
  188.     ai_charge, 0, NULL,
  189.     ai_charge, 0, NULL,
  190.     ai_charge, 0, NULL,
  191.     ai_charge, 0, berserk_swing,
  192.     ai_charge, 0, NULL,
  193.     ai_charge, 0, NULL,
  194.     ai_charge, 0, NULL,
  195.     ai_charge, 0, berserk_attack_club,
  196.     ai_charge, 0, NULL,
  197.     ai_charge, 0, NULL,
  198.     ai_charge, 0, NULL
  199. };
  200. mmove_t berserk_move_attack_club = {FRAME_att_c9, FRAME_att_c20, berserk_frames_attack_club, berserk_run};
  201.  
  202.  
  203. void berserk_strike (edict_t *self)
  204. {
  205.     //FIXME play impact sound
  206. }
  207.  
  208.  
  209. mframe_t berserk_frames_attack_strike [] =
  210. {
  211.     ai_move, 0, NULL,
  212.     ai_move, 0, NULL,
  213.     ai_move, 0, NULL,
  214.     ai_move, 0, berserk_swing,
  215.     ai_move, 0, NULL,
  216.     ai_move, 0, NULL,
  217.     ai_move, 0, NULL,
  218.     ai_move, 0, berserk_strike,
  219.     ai_move, 0, NULL,
  220.     ai_move, 0, NULL,
  221.     ai_move, 0, NULL,
  222.     ai_move, 0, NULL,
  223.     ai_move, 9.7, NULL,
  224.     ai_move, 13.6, NULL
  225. };
  226.     
  227. mmove_t berserk_move_attack_strike = {FRAME_att_c21, FRAME_att_c34, berserk_frames_attack_strike, berserk_run};
  228.  
  229.  
  230. void berserk_melee (edict_t *self)
  231. {
  232.     if ((rand() % 2) == 0)
  233.         self->monsterinfo.currentmove = &berserk_move_attack_spike;
  234.     else
  235.         self->monsterinfo.currentmove = &berserk_move_attack_club;
  236. }
  237.  
  238.  
  239. /*
  240. void()     berserk_atke1    =[    $r_attb1,    berserk_atke2    ] {ai_run(9);};
  241. void()     berserk_atke2    =[    $r_attb2,    berserk_atke3    ] {ai_run(6);};
  242. void()     berserk_atke3    =[    $r_attb3,    berserk_atke4    ] {ai_run(18.4);};
  243. void()     berserk_atke4    =[    $r_attb4,    berserk_atke5    ] {ai_run(25);};
  244. void()     berserk_atke5    =[    $r_attb5,    berserk_atke6    ] {ai_run(14);};
  245. void()     berserk_atke6    =[    $r_attb6,    berserk_atke7    ] {ai_run(20);};
  246. void()     berserk_atke7    =[    $r_attb7,    berserk_atke8    ] {ai_run(8.5);};
  247. void()     berserk_atke8    =[    $r_attb8,    berserk_atke9    ] {ai_run(3);};
  248. void()     berserk_atke9    =[    $r_attb9,    berserk_atke10    ] {ai_run(17.5);};
  249. void()     berserk_atke10    =[    $r_attb10,    berserk_atke11    ] {ai_run(17);};
  250. void()     berserk_atke11    =[    $r_attb11,    berserk_atke12    ] {ai_run(9);};
  251. void()     berserk_atke12    =[    $r_attb12,    berserk_atke13    ] {ai_run(25);};
  252. void()     berserk_atke13    =[    $r_attb13,    berserk_atke14    ] {ai_run(3.7);};
  253. void()     berserk_atke14    =[    $r_attb14,    berserk_atke15    ] {ai_run(2.6);};
  254. void()     berserk_atke15    =[    $r_attb15,    berserk_atke16    ] {ai_run(19);};
  255. void()     berserk_atke16    =[    $r_attb16,    berserk_atke17    ] {ai_run(25);};
  256. void()     berserk_atke17    =[    $r_attb17,    berserk_atke18    ] {ai_run(19.6);};
  257. void()     berserk_atke18    =[    $r_attb18,    berserk_run1    ] {ai_run(7.8);};
  258. */
  259.  
  260.  
  261. mframe_t berserk_frames_pain1 [] =
  262. {
  263.     ai_move, 0, NULL,
  264.     ai_move, 0, NULL,
  265.     ai_move, 0, NULL,
  266.     ai_move, 0, NULL
  267. };
  268. mmove_t berserk_move_pain1 = {FRAME_painc1, FRAME_painc4, berserk_frames_pain1, berserk_run};
  269.  
  270.  
  271. mframe_t berserk_frames_pain2 [] =
  272. {
  273.     ai_move, 0, NULL,
  274.     ai_move, 0, NULL,
  275.     ai_move, 0, NULL,
  276.     ai_move, 0, NULL,
  277.     ai_move, 0, NULL,
  278.     ai_move, 0, NULL,
  279.     ai_move, 0, NULL,
  280.     ai_move, 0, NULL,
  281.     ai_move, 0, NULL,
  282.     ai_move, 0, NULL,
  283.     ai_move, 0, NULL,
  284.     ai_move, 0, NULL,
  285.     ai_move, 0, NULL,
  286.     ai_move, 0, NULL,
  287.     ai_move, 0, NULL,
  288.     ai_move, 0, NULL,
  289.     ai_move, 0, NULL,
  290.     ai_move, 0, NULL,
  291.     ai_move, 0, NULL,
  292.     ai_move, 0, NULL
  293. };
  294. mmove_t berserk_move_pain2 = {FRAME_painb1, FRAME_painb20, berserk_frames_pain2, berserk_run};
  295.  
  296. void berserk_pain (edict_t *self, edict_t *other, float kick, int damage)
  297. {
  298.     if (self->health < (self->max_health / 2))
  299.         self->s.skinnum = 1;
  300.  
  301.     if (level.time < self->pain_debounce_time)
  302.         return;
  303.  
  304.     self->pain_debounce_time = level.time + 3;
  305.     gi.sound (self, CHAN_VOICE, sound_pain, 1, ATTN_NORM, 0);
  306.  
  307.     if ((damage < 20) || (random() < 0.5))
  308.         self->monsterinfo.currentmove = &berserk_move_pain1;
  309.     else
  310.         self->monsterinfo.currentmove = &berserk_move_pain2;
  311. }
  312.  
  313.  
  314. void berserk_dead (edict_t *self)
  315. {
  316.     VectorSet (self->mins, -16, -16, -24);
  317.     VectorSet (self->maxs, 16, 16, -8);
  318.     self->movetype = MOVETYPE_TOSS;
  319.     self->nextthink = 0;
  320.     gi.linkentity (self);
  321. }
  322.  
  323.  
  324. mframe_t berserk_frames_death1 [] =
  325. {
  326.     ai_move, 0, NULL,
  327.     ai_move, 0, NULL,
  328.     ai_move, 0, NULL,
  329.     ai_move, 0, NULL,
  330.     ai_move, 0, NULL,
  331.     ai_move, 0, NULL,
  332.     ai_move, 0, NULL,
  333.     ai_move, 0, NULL,
  334.     ai_move, 0, NULL,
  335.     ai_move, 0, NULL,
  336.     ai_move, 0, NULL,
  337.     ai_move, 0, NULL,
  338.     ai_move, 0, NULL
  339.     
  340. };
  341. mmove_t berserk_move_death1 = {FRAME_death1, FRAME_death13, berserk_frames_death1, berserk_dead};
  342.  
  343.  
  344. mframe_t berserk_frames_death2 [] =
  345. {
  346.     ai_move, 0, NULL,
  347.     ai_move, 0, NULL,
  348.     ai_move, 0, NULL,
  349.     ai_move, 0, NULL,
  350.     ai_move, 0, NULL,
  351.     ai_move, 0, NULL,
  352.     ai_move, 0, NULL,
  353.     ai_move, 0, NULL
  354. };
  355. mmove_t berserk_move_death2 = {FRAME_deathc1, FRAME_deathc8, berserk_frames_death2, berserk_dead};
  356.  
  357.  
  358. void berserk_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
  359. {
  360.     int        n;
  361.  
  362.     if (self->health <= self->gib_health)
  363.     {
  364.         gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
  365.         for (n= 0; n < 2; n++)
  366.             ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
  367.         for (n= 0; n < 4; n++)
  368.             ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
  369.         ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
  370.         self->deadflag = DEAD_DEAD;
  371.         return;
  372.     }
  373.  
  374.     if (self->deadflag == DEAD_DEAD)
  375.         return;
  376.  
  377.     gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0);
  378.     self->deadflag = DEAD_DEAD;
  379.     self->takedamage = DAMAGE_YES;
  380.  
  381.     if (damage >= 50)
  382.         self->monsterinfo.currentmove = &berserk_move_death1;
  383.     else
  384.         self->monsterinfo.currentmove = &berserk_move_death2;
  385. }
  386.  
  387.  
  388. /*QUAKED monster_berserk (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
  389. */
  390. void SP_monster_berserk (edict_t *self)
  391. {
  392.     if (deathmatch->value)
  393.     {
  394.         G_FreeEdict (self);
  395.         return;
  396.     }
  397.  
  398.     // pre-caches
  399.     sound_pain  = gi.soundindex ("berserk/berpain2.wav");
  400.     sound_die   = gi.soundindex ("berserk/berdeth2.wav");
  401.     sound_idle  = gi.soundindex ("berserk/beridle1.wav");
  402.     sound_punch = gi.soundindex ("berserk/attack.wav");
  403.     sound_search = gi.soundindex ("berserk/bersrch1.wav");
  404.     sound_sight = gi.soundindex ("berserk/sight.wav");
  405.  
  406.     self->s.modelindex = gi.modelindex("models/monsters/berserk/tris.md2");
  407.     VectorSet (self->mins, -16, -16, -24);
  408.     VectorSet (self->maxs, 16, 16, 32);
  409.     self->movetype = MOVETYPE_STEP;
  410.     self->solid = SOLID_BBOX;
  411.  
  412.     self->health = 240;
  413.     self->gib_health = -60;
  414.     self->mass = 250;
  415.  
  416.     self->pain = berserk_pain;
  417.     self->die = berserk_die;
  418.  
  419.     self->monsterinfo.stand = berserk_stand;
  420.     self->monsterinfo.walk = berserk_walk;
  421.     self->monsterinfo.run = berserk_run;
  422.     self->monsterinfo.dodge = NULL;
  423.     self->monsterinfo.attack = NULL;
  424.     self->monsterinfo.melee = berserk_melee;
  425.     self->monsterinfo.sight = berserk_sight;
  426.     self->monsterinfo.search = berserk_search;
  427.  
  428.     self->monsterinfo.currentmove = &berserk_move_stand;
  429.     self->monsterinfo.scale = MODEL_SCALE;
  430.  
  431.     gi.linkentity (self);
  432.  
  433.     walkmonster_start (self);
  434. }
  435.