|
|
1.1 root 1: /*
2: ==============================================================================
3:
4: GLADIATOR
5:
6: ==============================================================================
7: */
8:
9: #include "g_local.h"
10: #include "m_gladiator.h"
11:
12:
13: static int sound_pain1;
14: static int sound_pain2;
15: static int sound_die;
16: static int sound_gun;
17: static int sound_cleaver_swing;
18: static int sound_cleaver_hit;
19: static int sound_cleaver_miss;
20: static int sound_idle;
21: static int sound_search;
22: static int sound_sight;
23:
24:
25: void gladiator_idle (edict_t *self)
26: {
27: gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
28: }
29:
30: void gladiator_sight (edict_t *self, edict_t *other)
31: {
32: gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
33: }
34:
35: void gladiator_search (edict_t *self)
36: {
37: gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
38: }
39:
40: void gladiator_cleaver_swing (edict_t *self)
41: {
42: gi.sound (self, CHAN_WEAPON, sound_cleaver_swing, 1, ATTN_NORM, 0);
43: }
44:
45: mframe_t gladiator_frames_stand [] =
46: {
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: ai_stand, 0, NULL
54: };
55: mmove_t gladiator_move_stand = {FRAME_stand1, FRAME_stand7, gladiator_frames_stand, NULL};
56:
57: void gladiator_stand (edict_t *self)
58: {
59: self->monsterinfo.currentmove = &gladiator_move_stand;
60: }
61:
62:
63: mframe_t gladiator_frames_walk [] =
64: {
65: ai_walk, 15, NULL,
66: ai_walk, 7, NULL,
67: ai_walk, 6, NULL,
68: ai_walk, 5, NULL,
69: ai_walk, 2, NULL,
70: ai_walk, 0, NULL,
71: ai_walk, 2, NULL,
72: ai_walk, 8, NULL,
73: ai_walk, 12, NULL,
74: ai_walk, 8, NULL,
75: ai_walk, 5, NULL,
76: ai_walk, 5, NULL,
77: ai_walk, 2, NULL,
78: ai_walk, 2, NULL,
79: ai_walk, 1, NULL,
80: ai_walk, 8, NULL
81: };
82: mmove_t gladiator_move_walk = {FRAME_walk1, FRAME_walk16, gladiator_frames_walk, NULL};
83:
84: void gladiator_walk (edict_t *self)
85: {
86: self->monsterinfo.currentmove = &gladiator_move_walk;
87: }
88:
89:
90: mframe_t gladiator_frames_run [] =
91: {
92: ai_run, 23, NULL,
93: ai_run, 14, NULL,
94: ai_run, 14, NULL,
95: ai_run, 21, NULL,
96: ai_run, 12, NULL,
97: ai_run, 13, NULL
98: };
99: mmove_t gladiator_move_run = {FRAME_run1, FRAME_run6, gladiator_frames_run, NULL};
100:
101: void gladiator_run (edict_t *self)
102: {
103: if (self->monsterinfo.aiflags & AI_STAND_GROUND)
104: self->monsterinfo.currentmove = &gladiator_move_stand;
105: else
106: self->monsterinfo.currentmove = &gladiator_move_run;
107: }
108:
109:
110: void GaldiatorMelee (edict_t *self)
111: {
112: vec3_t aim;
113:
114: VectorSet (aim, MELEE_DISTANCE, self->mins[0], -4);
115: if (fire_hit (self, aim, (20 + (rand() %5)), 300))
116: gi.sound (self, CHAN_AUTO, sound_cleaver_hit, 1, ATTN_NORM, 0);
117: else
118: gi.sound (self, CHAN_AUTO, sound_cleaver_miss, 1, ATTN_NORM, 0);
119: }
120:
121: mframe_t gladiator_frames_attack_melee [] =
122: {
123: ai_charge, 0, NULL,
124: ai_charge, 0, NULL,
125: ai_charge, 0, NULL,
126: ai_charge, 0, NULL,
127: ai_charge, 0, gladiator_cleaver_swing,
128: ai_charge, 0, NULL,
129: ai_charge, 0, GaldiatorMelee,
130: ai_charge, 0, NULL,
131: ai_charge, 0, NULL,
132: ai_charge, 0, NULL,
133: ai_charge, 0, gladiator_cleaver_swing,
134: ai_charge, 0, NULL,
135: ai_charge, 0, NULL,
136: ai_charge, 0, GaldiatorMelee,
137: ai_charge, 0, NULL,
138: ai_charge, 0, NULL,
139: ai_charge, 0, NULL
140: };
141: mmove_t gladiator_move_attack_melee = {FRAME_melee1, FRAME_melee17, gladiator_frames_attack_melee, gladiator_run};
142:
143: void gladiator_melee(edict_t *self)
144: {
145: self->monsterinfo.currentmove = &gladiator_move_attack_melee;
146: }
147:
148:
149: void GladiatorGun (edict_t *self)
150: {
151: vec3_t start;
152: vec3_t dir;
153: vec3_t forward, right;
154:
155: AngleVectors (self->s.angles, forward, right, NULL);
156: G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_GLADIATOR_RAILGUN_1], forward, right, start);
157:
158: // calc direction to where we targted
159: VectorSubtract (self->pos1, start, dir);
160: VectorNormalize (dir);
161:
162: monster_fire_railgun (self, start, dir, 50, 100, MZ2_GLADIATOR_RAILGUN_1);
163: }
164:
165: mframe_t gladiator_frames_attack_gun [] =
166: {
167: ai_charge, 0, NULL,
168: ai_charge, 0, NULL,
169: ai_charge, 0, NULL,
170: ai_charge, 0, GladiatorGun,
171: ai_charge, 0, NULL,
172: ai_charge, 0, NULL,
173: ai_charge, 0, NULL,
174: ai_charge, 0, NULL,
175: ai_charge, 0, NULL
176: };
177: mmove_t gladiator_move_attack_gun = {FRAME_attack1, FRAME_attack9, gladiator_frames_attack_gun, gladiator_run};
178:
179: void gladiator_attack(edict_t *self)
180: {
181: float range;
182: vec3_t v;
183:
184: // a small safe zone
185: VectorSubtract (self->s.origin, self->enemy->s.origin, v);
186: range = VectorLength(v);
187: if (range <= (MELEE_DISTANCE + 32))
188: return;
189:
190: // charge up the railgun
191: gi.sound (self, CHAN_WEAPON, sound_gun, 1, ATTN_NORM, 0);
192: VectorCopy (self->enemy->s.origin, self->pos1); //save for aiming the shot
193: self->pos1[2] += self->enemy->viewheight;
194: self->monsterinfo.currentmove = &gladiator_move_attack_gun;
195: }
196:
197:
198: mframe_t gladiator_frames_pain [] =
199: {
200: ai_move, 0, NULL,
201: ai_move, 0, NULL,
202: ai_move, 0, NULL,
203: ai_move, 0, NULL,
204: ai_move, 0, NULL,
205: ai_move, 0, NULL
206: };
207: mmove_t gladiator_move_pain = {FRAME_pain1, FRAME_pain6, gladiator_frames_pain, gladiator_run};
208:
209: mframe_t gladiator_frames_pain_air [] =
210: {
211: ai_move, 0, NULL,
212: ai_move, 0, NULL,
213: ai_move, 0, NULL,
214: ai_move, 0, NULL,
215: ai_move, 0, NULL,
216: ai_move, 0, NULL,
217: ai_move, 0, NULL
218: };
219: mmove_t gladiator_move_pain_air = {FRAME_painup1, FRAME_painup7, gladiator_frames_pain_air, gladiator_run};
220:
221: void gladiator_pain (edict_t *self, edict_t *other, float kick, int damage)
222: {
223:
224: if (self->health < (self->max_health / 2))
225: self->s.skinnum = 1;
226:
227: if (level.time < self->pain_debounce_time)
228: {
229: if ((self->velocity[2] > 100) && (self->monsterinfo.currentmove == &gladiator_move_pain))
230: self->monsterinfo.currentmove = &gladiator_move_pain_air;
231: return;
232: }
233:
234: self->pain_debounce_time = level.time + 3;
235:
236: if (random() < 0.5)
237: gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
238: else
239: gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
240:
241: if (skill->value == 3)
242: return; // no pain anims in nightmare
243:
244: if (self->velocity[2] > 100)
245: self->monsterinfo.currentmove = &gladiator_move_pain_air;
246: else
247: self->monsterinfo.currentmove = &gladiator_move_pain;
248:
249: }
250:
251:
252: void gladiator_dead (edict_t *self)
253: {
254: VectorSet (self->mins, -16, -16, -24);
255: VectorSet (self->maxs, 16, 16, -8);
256: self->movetype = MOVETYPE_TOSS;
257: self->svflags |= SVF_DEADMONSTER;
258: self->nextthink = 0;
259: gi.linkentity (self);
260: }
261:
262: mframe_t gladiator_frames_death [] =
263: {
264: ai_move, 0, NULL,
265: ai_move, 0, NULL,
266: ai_move, 0, NULL,
267: ai_move, 0, NULL,
268: ai_move, 0, NULL,
269: ai_move, 0, NULL,
270: ai_move, 0, NULL,
271: ai_move, 0, NULL,
272: ai_move, 0, NULL,
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: };
287: mmove_t gladiator_move_death = {FRAME_death1, FRAME_death22, gladiator_frames_death, gladiator_dead};
288:
289: void gladiator_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
290: {
291: int n;
292:
293: // check for gib
294: if (self->health <= self->gib_health)
295: {
296: gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
297: for (n= 0; n < 2; n++)
298: ThrowGib (self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
299: for (n= 0; n < 4; n++)
300: ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
301: ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
302: self->deadflag = DEAD_DEAD;
303: return;
304: }
305:
306: if (self->deadflag == DEAD_DEAD)
307: return;
308:
309: // regular death
310: gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0);
311: self->deadflag = DEAD_DEAD;
312: self->takedamage = DAMAGE_YES;
313:
314: self->monsterinfo.currentmove = &gladiator_move_death;
315: }
316:
317:
318: /*QUAKED monster_gladiator (1 .5 0) (-32 -32 -24) (32 32 64) Ambush Trigger_Spawn Sight
319: */
320: void SP_monster_gladiator (edict_t *self)
321: {
322: if (deathmatch->value)
323: {
324: G_FreeEdict (self);
325: return;
326: }
327:
328:
329: sound_pain1 = gi.soundindex ("gladiator/pain.wav");
330: sound_pain2 = gi.soundindex ("gladiator/gldpain2.wav");
331: sound_die = gi.soundindex ("gladiator/glddeth2.wav");
332: sound_gun = gi.soundindex ("gladiator/railgun.wav");
333: sound_cleaver_swing = gi.soundindex ("gladiator/melee1.wav");
334: sound_cleaver_hit = gi.soundindex ("gladiator/melee2.wav");
335: sound_cleaver_miss = gi.soundindex ("gladiator/melee3.wav");
336: sound_idle = gi.soundindex ("gladiator/gldidle1.wav");
337: sound_search = gi.soundindex ("gladiator/gldsrch1.wav");
338: sound_sight = gi.soundindex ("gladiator/sight.wav");
339:
340: self->movetype = MOVETYPE_STEP;
341: self->solid = SOLID_BBOX;
342: self->s.modelindex = gi.modelindex ("models/monsters/gladiatr/tris.md2");
343: VectorSet (self->mins, -32, -32, -24);
344: VectorSet (self->maxs, 32, 32, 64);
345:
346: self->health = 400;
347: self->gib_health = -175;
348: self->mass = 400;
349:
350: self->pain = gladiator_pain;
351: self->die = gladiator_die;
352:
353: self->monsterinfo.stand = gladiator_stand;
354: self->monsterinfo.walk = gladiator_walk;
355: self->monsterinfo.run = gladiator_run;
356: self->monsterinfo.dodge = NULL;
357: self->monsterinfo.attack = gladiator_attack;
358: self->monsterinfo.melee = gladiator_melee;
359: self->monsterinfo.sight = gladiator_sight;
360: self->monsterinfo.idle = gladiator_idle;
361: self->monsterinfo.search = gladiator_search;
362:
363: gi.linkentity (self);
364: self->monsterinfo.currentmove = &gladiator_move_stand;
365: self->monsterinfo.scale = MODEL_SCALE;
366:
367: walkmonster_start (self);
368: }
369:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.