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

  1. /*
  2. ==============================================================================
  3.  
  4. INFANTRY
  5.  
  6. ==============================================================================
  7. */
  8.  
  9. #include "g_local.h"
  10. #include "m_infantry.h"
  11.  
  12. void InfantryMachineGun (edict_t *self);
  13.  
  14.  
  15. static int    sound_pain1;
  16. static int    sound_pain2;
  17. static int    sound_die1;
  18. static int    sound_die2;
  19.  
  20. static int    sound_gunshot;
  21. static int    sound_weapon_cock;
  22. static int    sound_punch_swing;
  23. static int    sound_punch_hit;
  24. static int    sound_sight;
  25. static int    sound_search;
  26. static int    sound_idle;
  27.  
  28.  
  29. mframe_t infantry_frames_stand [] =
  30. {
  31.     ai_stand, 0, NULL,
  32.     ai_stand, 0, NULL,
  33.     ai_stand, 0, NULL,
  34.     ai_stand, 0, NULL,
  35.     ai_stand, 0, NULL,
  36.     ai_stand, 0, NULL,
  37.     ai_stand, 0, NULL,
  38.     ai_stand, 0, NULL,
  39.     ai_stand, 0, NULL,
  40.     ai_stand, 0, NULL,
  41.     ai_stand, 0, NULL,
  42.     ai_stand, 0, NULL,
  43.     ai_stand, 0, NULL,
  44.     ai_stand, 0, NULL,
  45.     ai_stand, 0, NULL,
  46.     ai_stand, 0, NULL,
  47.     ai_stand, 0, NULL,
  48.     ai_stand, 0, NULL,
  49.     ai_stand, 0, NULL,
  50.     ai_stand, 0, NULL,
  51.     ai_stand, 0, NULL,
  52.     ai_stand, 0, NULL
  53. };
  54. mmove_t infantry_move_stand = {FRAME_stand50, FRAME_stand71, infantry_frames_stand, NULL};
  55.  
  56. void infantry_stand (edict_t *self)
  57. {
  58.     self->monsterinfo.currentmove = &infantry_move_stand;
  59. }
  60.  
  61.  
  62. mframe_t infantry_frames_fidget [] =
  63. {
  64.     ai_stand, 1,  NULL,
  65.     ai_stand, 0,  NULL,
  66.     ai_stand, 1,  NULL,
  67.     ai_stand, 3,  NULL,
  68.     ai_stand, 6,  NULL,
  69.     ai_stand, 3,  NULL,
  70.     ai_stand, 0,  NULL,
  71.     ai_stand, 0,  NULL,
  72.     ai_stand, 0,  NULL,
  73.     ai_stand, 0,  NULL,
  74.     ai_stand, 1,  NULL,
  75.     ai_stand, 0,  NULL,
  76.     ai_stand, 0,  NULL,
  77.     ai_stand, 0,  NULL,
  78.     ai_stand, 0,  NULL,
  79.     ai_stand, 1,  NULL,
  80.     ai_stand, 0,  NULL,
  81.     ai_stand, -1, NULL,
  82.     ai_stand, 0,  NULL,
  83.     ai_stand, 0,  NULL,
  84.     ai_stand, 1,  NULL,
  85.     ai_stand, 0,  NULL,
  86.     ai_stand, -2, NULL,
  87.     ai_stand, 1,  NULL,
  88.     ai_stand, 1,  NULL,
  89.     ai_stand, 1,  NULL,
  90.     ai_stand, -1, NULL,
  91.     ai_stand, 0,  NULL,
  92.     ai_stand, 0,  NULL,
  93.     ai_stand, -1, NULL,
  94.     ai_stand, 0,  NULL,
  95.     ai_stand, 0,  NULL,
  96.     ai_stand, 0,  NULL,
  97.     ai_stand, 0,  NULL,
  98.     ai_stand, 0,  NULL,
  99.     ai_stand, -1, NULL,
  100.     ai_stand, 0,  NULL,
  101.     ai_stand, 0,  NULL,
  102.     ai_stand, 1,  NULL,
  103.     ai_stand, 0,  NULL,
  104.     ai_stand, 0,  NULL,
  105.     ai_stand, -1, NULL,
  106.     ai_stand, -1, NULL,
  107.     ai_stand, 0,  NULL,
  108.     ai_stand, -3, NULL,
  109.     ai_stand, -2, NULL,
  110.     ai_stand, -3, NULL,
  111.     ai_stand, -3, NULL,
  112.     ai_stand, -2, NULL
  113. };
  114. mmove_t infantry_move_fidget = {FRAME_stand01, FRAME_stand49, infantry_frames_fidget, infantry_stand};
  115.  
  116. void infantry_fidget (edict_t *self)
  117. {
  118.     self->monsterinfo.currentmove = &infantry_move_fidget;
  119.     gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
  120. }
  121.  
  122. mframe_t infantry_frames_walk [] =
  123. {
  124.     ai_walk, 5,  NULL,
  125.     ai_walk, 4,  NULL,
  126.     ai_walk, 4,  NULL,
  127.     ai_walk, 5,  NULL,
  128.     ai_walk, 4,  NULL,
  129.     ai_walk, 5,  NULL,
  130.     ai_walk, 6,  NULL,
  131.     ai_walk, 4,  NULL,
  132.     ai_walk, 4,  NULL,
  133.     ai_walk, 4,  NULL,
  134.     ai_walk, 4,  NULL,
  135.     ai_walk, 5,  NULL
  136. };
  137. mmove_t infantry_move_walk = {FRAME_walk03, FRAME_walk14, infantry_frames_walk, NULL};
  138.  
  139. void infantry_walk (edict_t *self)
  140. {
  141.     self->monsterinfo.currentmove = &infantry_move_walk;
  142. }
  143.  
  144. mframe_t infantry_frames_run [] =
  145. {
  146.     ai_run, 10, NULL,
  147.     ai_run, 20, NULL,
  148.     ai_run, 5,  NULL,
  149.     ai_run, 7,  NULL,
  150.     ai_run, 30, NULL,
  151.     ai_run, 35, NULL,
  152.     ai_run, 2,  NULL,
  153.     ai_run, 6,  NULL
  154. };
  155. mmove_t infantry_move_run = {FRAME_run01, FRAME_run08, infantry_frames_run, NULL};
  156.  
  157. void infantry_run (edict_t *self)
  158. {
  159.     if (self->monsterinfo.aiflags & AI_STAND_GROUND)
  160.         self->monsterinfo.currentmove = &infantry_move_stand;
  161.     else
  162.         self->monsterinfo.currentmove = &infantry_move_run;
  163. }
  164.  
  165.  
  166. mframe_t infantry_frames_pain1 [] =
  167. {
  168.     ai_move, -3, NULL,
  169.     ai_move, -2, NULL,
  170.     ai_move, -1, NULL,
  171.     ai_move, -2, NULL,
  172.     ai_move, -1, NULL,
  173.     ai_move, 1,  NULL,
  174.     ai_move, -1, NULL,
  175.     ai_move, 1,  NULL,
  176.     ai_move, 6,  NULL,
  177.     ai_move, 2,  NULL
  178. };
  179. mmove_t infantry_move_pain1 = {FRAME_pain101, FRAME_pain110, infantry_frames_pain1, infantry_run};
  180.  
  181. mframe_t infantry_frames_pain2 [] =
  182. {
  183.     ai_move, -3, NULL,
  184.     ai_move, -3, NULL,
  185.     ai_move, 0,  NULL,
  186.     ai_move, -1, NULL,
  187.     ai_move, -2, NULL,
  188.     ai_move, 0,  NULL,
  189.     ai_move, 0,  NULL,
  190.     ai_move, 2,  NULL,
  191.     ai_move, 5,  NULL,
  192.     ai_move, 2,  NULL
  193. };
  194. mmove_t infantry_move_pain2 = {FRAME_pain201, FRAME_pain210, infantry_frames_pain2, infantry_run};
  195.  
  196. void infantry_pain (edict_t *self, edict_t *other, float kick, int damage)
  197. {
  198.     int        n;
  199.  
  200.     if (self->health < (self->max_health / 2))
  201.         self->s.skinnum = 1;
  202.  
  203.     if (level.time < self->pain_debounce_time)
  204.         return;
  205.  
  206.     self->pain_debounce_time = level.time + 3;
  207.     
  208.  
  209.     n = rand() % 2;
  210.     if (n == 0)
  211.     {
  212.         self->monsterinfo.currentmove = &infantry_move_pain1;
  213.         gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
  214.     }
  215.     else
  216.     {
  217.         self->monsterinfo.currentmove = &infantry_move_pain2;
  218.         gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
  219.     }
  220. }
  221.  
  222.  
  223. vec3_t    aimangles[] =
  224. {
  225.     0.0, 5.0, 0.0,
  226.     10.0, 15.0, 0.0,
  227.     20.0, 25.0, 0.0,
  228.     25.0, 35.0, 0.0,
  229.     30.0, 40.0, 0.0,
  230.     30.0, 45.0, 0.0,
  231.     25.0, 50.0, 0.0,
  232.     20.0, 40.0, 0.0,
  233.     15.0, 35.0, 0.0,
  234.     40.0, 35.0, 0.0,
  235.     70.0, 35.0, 0.0,
  236.     90.0, 35.0, 0.0
  237. };
  238.  
  239. void InfantryMachineGun (edict_t *self)
  240. {
  241.     vec3_t    start, target;
  242.     vec3_t    forward, right;
  243.     vec3_t    vec;
  244.     int        flash_number;
  245.  
  246.     if (self->s.frame == FRAME_attak111)
  247.     {
  248.         flash_number = MZ2_INFANTRY_MACHINEGUN_1;
  249.         AngleVectors (self->s.angles, forward, right, NULL);
  250.         G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start);
  251.  
  252.         if (self->enemy)
  253.         {
  254.             VectorMA (self->enemy->s.origin, -0.2, self->enemy->velocity, target);
  255.             target[2] += self->enemy->viewheight;
  256.             VectorSubtract (target, start, forward);
  257.             VectorNormalize (forward);
  258.         }
  259.         else
  260.         {
  261.             AngleVectors (self->s.angles, forward, right, NULL);
  262.         }
  263.     }
  264.     else
  265.     {
  266.         flash_number = MZ2_INFANTRY_MACHINEGUN_2 + (self->s.frame - FRAME_death211);
  267.  
  268.         AngleVectors (self->s.angles, forward, right, NULL);
  269.         G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start);
  270.  
  271.         VectorSubtract (self->s.angles, aimangles[flash_number-MZ2_INFANTRY_MACHINEGUN_2], vec);
  272.         AngleVectors (vec, forward, NULL, NULL);
  273.     }
  274.  
  275.     monster_fire_bullet (self, start, forward, 3, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, flash_number);
  276. }
  277.  
  278. void infantry_sight (edict_t *self, edict_t *other)
  279. {
  280.     gi.sound (self, CHAN_BODY, sound_sight, 1, ATTN_NORM, 0);
  281. }
  282.  
  283. void infantry_dead (edict_t *self)
  284. {
  285.     VectorSet (self->mins, -16, -16, -24);
  286.     VectorSet (self->maxs, 16, 16, -8);
  287.     self->movetype = MOVETYPE_TOSS;
  288.     gi.linkentity (self);
  289.  
  290.     M_FlyCheck (self);
  291. }
  292.  
  293. mframe_t infantry_frames_death1 [] =
  294. {
  295.     ai_move, -4, NULL,
  296.     ai_move, 0,  NULL,
  297.     ai_move, 0,  NULL,
  298.     ai_move, -1, NULL,
  299.     ai_move, -4, NULL,
  300.     ai_move, 0,  NULL,
  301.     ai_move, 0,  NULL,
  302.     ai_move, 0,  NULL,
  303.     ai_move, -1, NULL,
  304.     ai_move, 3,  NULL,
  305.     ai_move, 1,  NULL,
  306.     ai_move, 1,  NULL,
  307.     ai_move, -2, NULL,
  308.     ai_move, 2,  NULL,
  309.     ai_move, 2,  NULL,
  310.     ai_move, 9,  NULL,
  311.     ai_move, 9,  NULL,
  312.     ai_move, 5,  NULL,
  313.     ai_move, -3, NULL,
  314.     ai_move, -3, NULL
  315. };
  316. mmove_t infantry_move_death1 = {FRAME_death101, FRAME_death120, infantry_frames_death1, infantry_dead};
  317.  
  318. // Off with his head
  319. mframe_t infantry_frames_death2 [] =
  320. {
  321.     ai_move, 0,   NULL,
  322.     ai_move, 1,   NULL,
  323.     ai_move, 5,   NULL,
  324.     ai_move, -1,  NULL,
  325.     ai_move, 0,   NULL,
  326.     ai_move, 1,   NULL,
  327.     ai_move, 1,   NULL,
  328.     ai_move, 4,   NULL,
  329.     ai_move, 3,   NULL,
  330.     ai_move, 0,   NULL,
  331.     ai_move, -2,  InfantryMachineGun,
  332.     ai_move, -2,  InfantryMachineGun,
  333.     ai_move, -3,  InfantryMachineGun,
  334.     ai_move, -1,  InfantryMachineGun,
  335.     ai_move, -2,  InfantryMachineGun,
  336.     ai_move, 0,   InfantryMachineGun,
  337.     ai_move, 2,   InfantryMachineGun,
  338.     ai_move, 2,   InfantryMachineGun,
  339.     ai_move, 3,   InfantryMachineGun,
  340.     ai_move, -10, InfantryMachineGun,
  341.     ai_move, -7,  InfantryMachineGun,
  342.     ai_move, -8,  InfantryMachineGun,
  343.     ai_move, -6,  NULL,
  344.     ai_move, 4,   NULL,
  345.     ai_move, 0,   NULL
  346. };
  347. mmove_t infantry_move_death2 = {FRAME_death201, FRAME_death225, infantry_frames_death2, infantry_dead};
  348.  
  349. mframe_t infantry_frames_death3 [] =
  350. {
  351.     ai_move, 0,   NULL,
  352.     ai_move, 0,   NULL,
  353.     ai_move, 0,   NULL,
  354.     ai_move, -6,  NULL,
  355.     ai_move, -11, NULL,
  356.     ai_move, -3,  NULL,
  357.     ai_move, -11, NULL,
  358.     ai_move, 0,   NULL,
  359.     ai_move, 0,   NULL
  360. };
  361. mmove_t infantry_move_death3 = {FRAME_death301, FRAME_death309, infantry_frames_death3, infantry_dead};
  362.  
  363.  
  364. void infantry_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
  365. {
  366.     int        n;
  367.  
  368. // check for gib
  369.     if (self->health <= self->gib_health)
  370.     {
  371.         gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
  372.         for (n= 0; n < 2; n++)
  373.             ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
  374.         for (n= 0; n < 4; n++)
  375.             ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
  376.         ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
  377.         self->deadflag = DEAD_DEAD;
  378.         return;
  379.     }
  380.  
  381.     if (self->deadflag == DEAD_DEAD)
  382.         return;
  383.  
  384. // regular death
  385.     self->deadflag = DEAD_DEAD;
  386.     self->takedamage = DAMAGE_YES;
  387.  
  388.     n = rand() % 3;
  389.     if (n == 0)
  390.     {
  391.         self->monsterinfo.currentmove = &infantry_move_death1;
  392.         gi.sound (self, CHAN_VOICE, sound_die2, 1, ATTN_NORM, 0);
  393.     }
  394.     else if (n == 1)
  395.     {
  396.         self->monsterinfo.currentmove = &infantry_move_death2;
  397.         gi.sound (self, CHAN_VOICE, sound_die1, 1, ATTN_NORM, 0);
  398.     }
  399.     else
  400.     {
  401.         self->monsterinfo.currentmove = &infantry_move_death3;
  402.         gi.sound (self, CHAN_VOICE, sound_die2, 1, ATTN_NORM, 0);
  403.     }
  404. }
  405.  
  406.  
  407. void infantry_duck_down (edict_t *self)
  408. {
  409.     if (self->monsterinfo.aiflags & AI_DUCKED)
  410.         return;
  411.     self->monsterinfo.aiflags |= AI_DUCKED;
  412.     self->maxs[2] -= 32;
  413.     self->takedamage = DAMAGE_YES;
  414.     self->monsterinfo.pausetime = level.time + 1;
  415.     gi.linkentity (self);
  416. }
  417.  
  418. void infantry_duck_hold (edict_t *self)
  419. {
  420.     if (level.time >= self->monsterinfo.pausetime)
  421.         self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
  422.     else
  423.         self->monsterinfo.aiflags |= AI_HOLD_FRAME;
  424. }
  425.  
  426. void infantry_duck_up (edict_t *self)
  427. {
  428.     self->monsterinfo.aiflags &= ~AI_DUCKED;
  429.     self->maxs[2] += 32;
  430.     self->takedamage = DAMAGE_AIM;
  431.     gi.linkentity (self);
  432. }
  433.  
  434. mframe_t infantry_frames_duck [] =
  435. {
  436.     ai_move, -2, infantry_duck_down,
  437.     ai_move, -5, infantry_duck_hold,
  438.     ai_move, 3,  NULL,
  439.     ai_move, 4,  infantry_duck_up,
  440.     ai_move, 0,  NULL
  441. };
  442. mmove_t infantry_move_duck = {FRAME_duck01, FRAME_duck05, infantry_frames_duck, infantry_run};
  443.  
  444. void infantry_dodge (edict_t *self, edict_t *attacker, float eta)
  445. {
  446.     if (random() > 0.25)
  447.         return;
  448.  
  449.     if (!self->enemy)
  450.         self->enemy = attacker;
  451.  
  452.     self->monsterinfo.currentmove = &infantry_move_duck;
  453. }
  454.  
  455.  
  456. void infantry_cock_gun (edict_t *self)
  457. {
  458.     int        n;
  459.  
  460.     gi.sound (self, CHAN_WEAPON, sound_weapon_cock, 1, ATTN_NORM, 0);
  461.     n = (rand() & 15) + 3 + 7;
  462.     self->monsterinfo.pausetime = level.time + n * FRAMETIME;
  463. }
  464.  
  465. void infantry_fire (edict_t *self)
  466. {
  467.     InfantryMachineGun (self);
  468.  
  469.     if (level.time >= self->monsterinfo.pausetime)
  470.         self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
  471.     else
  472.         self->monsterinfo.aiflags |= AI_HOLD_FRAME;
  473. }
  474.  
  475. mframe_t infantry_frames_attack1 [] =
  476. {
  477.     ai_charge, 4,  NULL,
  478.     ai_charge, -1, NULL,
  479.     ai_charge, -1, NULL,
  480.     ai_charge, 0,  infantry_cock_gun,
  481.     ai_charge, -1, NULL,
  482.     ai_charge, 1,  NULL,
  483.     ai_charge, 1,  NULL,
  484.     ai_charge, 2,  NULL,
  485.     ai_charge, -2, NULL,
  486.     ai_charge, -3, NULL,
  487.     ai_charge, 1,  infantry_fire,
  488.     ai_charge, 5,  NULL,
  489.     ai_charge, -1, NULL,
  490.     ai_charge, -2, NULL,
  491.     ai_charge, -3, NULL
  492. };
  493. mmove_t infantry_move_attack1 = {FRAME_attak101, FRAME_attak115, infantry_frames_attack1, infantry_run};
  494.  
  495.  
  496. void infantry_swing (edict_t *self)
  497. {
  498.     gi.sound (self, CHAN_WEAPON, sound_punch_swing, 1, ATTN_NORM, 0);
  499. }
  500.  
  501. void infantry_smack (edict_t *self)
  502. {
  503.     vec3_t    aim;
  504.  
  505.     VectorSet (aim, MELEE_DISTANCE, 0, 0);
  506.     if (fire_hit (self, aim, (5 + (rand() % 5)), 50))
  507.         gi.sound (self, CHAN_WEAPON, sound_punch_hit, 1, ATTN_NORM, 0);
  508. }
  509.  
  510. mframe_t infantry_frames_attack2 [] =
  511. {
  512.     ai_charge, 3, NULL,
  513.     ai_charge, 6, NULL,
  514.     ai_charge, 0, infantry_swing,
  515.     ai_charge, 8, NULL,
  516.     ai_charge, 5, NULL,
  517.     ai_charge, 8, infantry_smack,
  518.     ai_charge, 6, NULL,
  519.     ai_charge, 3, NULL,
  520. };
  521. mmove_t infantry_move_attack2 = {FRAME_attak201, FRAME_attak208, infantry_frames_attack2, infantry_run};
  522.  
  523. void infantry_attack(edict_t *self)
  524. {
  525.     if (range (self, self->enemy) == RANGE_MELEE)
  526.         self->monsterinfo.currentmove = &infantry_move_attack2;
  527.     else
  528.         self->monsterinfo.currentmove = &infantry_move_attack1;
  529. }
  530.  
  531.  
  532. /*QUAKED monster_infantry (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
  533. */
  534. void SP_monster_infantry (edict_t *self)
  535. {
  536.     if (deathmatch->value)
  537.     {
  538.         G_FreeEdict (self);
  539.         return;
  540.     }
  541.  
  542.     sound_pain1 = gi.soundindex ("infantry/infpain1.wav");
  543.     sound_pain2 = gi.soundindex ("infantry/infpain2.wav");
  544.     sound_die1 = gi.soundindex ("infantry/infdeth1.wav");
  545.     sound_die2 = gi.soundindex ("infantry/infdeth2.wav");
  546.  
  547.     sound_gunshot = gi.soundindex ("infantry/infatck1.wav");
  548.     sound_weapon_cock = gi.soundindex ("infantry/infatck3.wav");
  549.     sound_punch_swing = gi.soundindex ("infantry/infatck2.wav");
  550.     sound_punch_hit = gi.soundindex ("infantry/melee2.wav");
  551.     
  552.     sound_sight = gi.soundindex ("infantry/infsght1.wav");
  553.     sound_search = gi.soundindex ("infantry/infsrch1.wav");
  554.     sound_idle = gi.soundindex ("infantry/infidle1.wav");
  555.     
  556.  
  557.     self->movetype = MOVETYPE_STEP;
  558.     self->solid = SOLID_BBOX;
  559.     self->s.modelindex = gi.modelindex("models/monsters/infantry/tris.md2");
  560.     VectorSet (self->mins, -16, -16, -24);
  561.     VectorSet (self->maxs, 16, 16, 32);
  562.  
  563.     self->health = 100;
  564.     self->gib_health = -40;
  565.     self->mass = 200;
  566.  
  567.     self->pain = infantry_pain;
  568.     self->die = infantry_die;
  569.  
  570.     self->monsterinfo.stand = infantry_stand;
  571.     self->monsterinfo.walk = infantry_walk;
  572.     self->monsterinfo.run = infantry_run;
  573.     self->monsterinfo.dodge = infantry_dodge;
  574.     self->monsterinfo.attack = infantry_attack;
  575.     self->monsterinfo.melee = NULL;
  576.     self->monsterinfo.sight = infantry_sight;
  577.     self->monsterinfo.idle = infantry_fidget;
  578.  
  579.     gi.linkentity (self);
  580.  
  581.     self->monsterinfo.currentmove = &infantry_move_stand;
  582.     self->monsterinfo.scale = MODEL_SCALE;
  583.  
  584.     walkmonster_start (self);
  585. }
  586.