game: sync all rogue monsters to game

This commit is contained in:
Denis Pauk 2023-10-22 14:46:26 +03:00
parent 5c87db6e88
commit a46d6a2d83
50 changed files with 2844 additions and 17743 deletions

View file

@ -1492,33 +1492,33 @@ ROGUE_OBJS_ = \
src/game/dm/ball.o \
src/game/dm/tag.o \
src/game/monster/berserker/berserker.o \
src/rogue/monster/boss2/boss2.o \
src/game/monster/boss2/boss2.o \
src/game/monster/boss3/boss3.o \
src/game/monster/boss3/boss31.o \
src/game/monster/boss3/boss32.o \
src/game/monster/boss5/boss5.o \
src/rogue/monster/brain/brain.o \
src/game/monster/brain/brain.o \
src/game/monster/carrier/carrier.o \
src/game/monster/chick/chick.o \
src/rogue/monster/flipper/flipper.o \
src/rogue/monster/float/float.o \
src/game/monster/flipper/flipper.o \
src/game/monster/float/float.o \
src/game/monster/flyer/flyer.o \
src/rogue/monster/gladiator/gladiator.o \
src/game/monster/gladiator/gladiator.o \
src/game/monster/gladiator/gladb.o \
src/game/monster/gekk/gekk.o \
src/rogue/monster/gunner/gunner.o \
src/rogue/monster/hover/hover.o \
src/game/monster/gunner/gunner.o \
src/game/monster/hover/hover.o \
src/game/monster/infantry/infantry.o \
src/rogue/monster/insane/insane.o \
src/game/monster/insane/insane.o \
src/game/monster/fixbot/fixbot.o \
src/rogue/monster/medic/medic.o \
src/rogue/monster/misc/move.o \
src/rogue/monster/mutant/mutant.o \
src/rogue/monster/parasite/parasite.o \
src/game/monster/medic/medic.o \
src/game/monster/misc/move.o \
src/game/monster/mutant/mutant.o \
src/game/monster/parasite/parasite.o \
src/game/monster/soldier/soldier.o \
src/game/monster/stalker/stalker.o \
src/rogue/monster/supertank/supertank.o \
src/rogue/monster/tank/tank.o \
src/game/monster/supertank/supertank.o \
src/game/monster/tank/tank.o \
src/game/monster/turret/turret.o \
src/game/monster/widow/widow.o \
src/game/monster/widow/widow2.o \

View file

@ -143,36 +143,42 @@ Boss2Rocket(edict_t *self)
AngleVectors(self->s.angles, forward, right, NULL);
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_1],
forward, right, start);
//1
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_1], forward, right, start);
VectorCopy(self->enemy->s.origin, vec);
vec[2] += self->enemy->viewheight;
vec[2] -= 15;
VectorSubtract(vec, start, dir);
VectorNormalize(dir);
VectorMA(dir, 0.4, right, dir);
VectorNormalize(dir);
monster_fire_rocket(self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_1);
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_2],
forward, right, start);
//2
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_2], forward, right, start);
VectorCopy(self->enemy->s.origin, vec);
vec[2] += self->enemy->viewheight;
VectorSubtract(vec, start, dir);
VectorNormalize(dir);
VectorMA(dir, 0.025, right, dir);
VectorNormalize(dir);
monster_fire_rocket(self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_2);
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_3],
forward, right, start);
//3
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_3], forward, right, start);
VectorCopy(self->enemy->s.origin, vec);
vec[2] += self->enemy->viewheight;
VectorSubtract(vec, start, dir);
VectorNormalize(dir);
VectorMA(dir, -0.025, right, dir);
VectorNormalize(dir);
monster_fire_rocket(self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_3);
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_4],
forward, right, start);
//4
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_4], forward, right, start);
VectorCopy(self->enemy->s.origin, vec);
vec[2] += self->enemy->viewheight;
vec[2] -= 15;
VectorSubtract(vec, start, dir);
VectorNormalize(dir);
VectorMA(dir, -0.4, right, dir);
VectorNormalize(dir);
monster_fire_rocket(self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_4);
}
@ -313,26 +319,26 @@ mmove_t boss2_move_fidget =
};
static mframe_t boss2_frames_walk[] = {
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL},
{ai_walk, 8, NULL}
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL}
};
mmove_t boss2_move_walk = {
@ -343,26 +349,26 @@ mmove_t boss2_move_walk = {
};
static mframe_t boss2_frames_run[] = {
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL}
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL}
};
mmove_t boss2_move_run = {
@ -373,15 +379,15 @@ mmove_t boss2_move_run = {
};
static mframe_t boss2_frames_attack_pre_mg[] = {
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, boss2_attack_mg}
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, boss2_attack_mg}
};
mmove_t boss2_move_attack_pre_mg =
@ -394,12 +400,12 @@ mmove_t boss2_move_attack_pre_mg =
/* Loop this */
static mframe_t boss2_frames_attack_mg[] = {
{ai_charge, 1, Boss2MachineGun},
{ai_charge, 1, Boss2MachineGun},
{ai_charge, 1, Boss2MachineGun},
{ai_charge, 1, Boss2MachineGun},
{ai_charge, 1, Boss2MachineGun},
{ai_charge, 1, boss2_reattack_mg}
{ai_charge, 2, Boss2MachineGun},
{ai_charge, 2, Boss2MachineGun},
{ai_charge, 2, Boss2MachineGun},
{ai_charge, 2, Boss2MachineGun},
{ai_charge, 2, Boss2MachineGun},
{ai_charge, 2, boss2_reattack_mg}
};
mmove_t boss2_move_attack_mg =
@ -411,10 +417,10 @@ mmove_t boss2_move_attack_mg =
};
static mframe_t boss2_frames_attack_post_mg[] = {
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL}
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL}
};
mmove_t boss2_move_attack_post_mg =
@ -426,27 +432,27 @@ mmove_t boss2_move_attack_post_mg =
};
static mframe_t boss2_frames_attack_rocket[] = {
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_move, -20, Boss2Rocket},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL}
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_move, -5, Boss2Rocket},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL}
};
mmove_t boss2_move_attack_rocket =

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View file

@ -42,6 +42,7 @@ static int sound_search;
static int sound_melee1;
static int sound_melee2;
static int sound_melee3;
void brain_run(edict_t *self);
void brain_dead(edict_t *self);

View file

@ -23,6 +23,7 @@
* Brain animations.
*
* =======================================================================
*
*/
#define FRAME_walk101 0

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -73,7 +74,7 @@ floater_fire_blaster(edict_t *self)
vec3_t dir;
int effect;
if (!self)
if (!self || !self->enemy || !self->enemy->inuse)
{
return;
}
@ -308,6 +309,33 @@ mmove_t floater_move_attack1 =
floater_run
};
/* circle strafe frames */
static mframe_t floater_frames_attack1a[] =
{
{ai_charge, 10, NULL}, // Blaster attack
{ai_charge, 10, NULL},
{ai_charge, 10, NULL},
{ai_charge, 10, floater_fire_blaster}, // BOOM (0, -25.8, 32.5) -- LOOP Starts
{ai_charge, 10, floater_fire_blaster},
{ai_charge, 10, floater_fire_blaster},
{ai_charge, 10, floater_fire_blaster},
{ai_charge, 10, floater_fire_blaster},
{ai_charge, 10, floater_fire_blaster},
{ai_charge, 10, floater_fire_blaster},
{ai_charge, 10, NULL},
{ai_charge, 10, NULL},
{ai_charge, 10, NULL},
{ai_charge, 10, NULL} // -- LOOP Ends
};
mmove_t floater_move_attack1a =
{
FRAME_attak101,
FRAME_attak114,
floater_frames_attack1a,
floater_run
};
static mframe_t floater_frames_attack2[] = {
{ai_charge, 0, NULL}, /* Claws */
{ai_charge, 0, NULL},
@ -683,12 +711,41 @@ floater_zap(edict_t *self)
void
floater_attack(edict_t *self)
{
float chance;
if (!self)
{
return;
}
self->monsterinfo.currentmove = &floater_move_attack1;
// 0% chance of circle in easy
// 50% chance in normal
// 75% chance in hard
// 86.67% chance in nightmare
if (skill->value == SKILL_EASY)
{
chance = 0;
}
else
{
chance = 1.0 - (0.5/(float)(skill->value));
}
if (random() > chance)
{
self->monsterinfo.attack_state = AS_STRAIGHT;
self->monsterinfo.currentmove = &floater_move_attack1;
}
else // circle strafe
{
if (random () <= 0.5) // switch directions
{
self->monsterinfo.lefty = 1 - self->monsterinfo.lefty;
}
self->monsterinfo.attack_state = AS_SLIDING;
self->monsterinfo.currentmove = &floater_move_attack1a;
}
}
void
@ -780,6 +837,12 @@ floater_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /*
BecomeExplosion1(self);
}
qboolean
floater_blocked(edict_t *self, float dist)
{
return false;
}
/*
* QUAKED monster_floater (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
*/

View file

@ -533,6 +533,22 @@ gladiator_die(edict_t *self, edict_t *inflictor /* unused */,
self->monsterinfo.currentmove = &gladiator_move_death;
}
qboolean
gladiator_blocked(edict_t *self, float dist)
{
if (!self)
{
return false;
}
if (blocked_checkplat(self, dist))
{
return true;
}
return false;
}
/*
* QUAKED monster_gladiator (1 .5 0) (-32 -32 -24) (32 32 64) Ambush Trigger_Spawn Sight
*/
@ -588,6 +604,7 @@ SP_monster_gladiator(edict_t *self)
self->monsterinfo.sight = gladiator_sight;
self->monsterinfo.idle = gladiator_idle;
self->monsterinfo.search = gladiator_search;
self->monsterinfo.blocked = gladiator_blocked;
gi.linkentity(self);
self->monsterinfo.currentmove = &gladiator_move_stand;

View file

@ -284,7 +284,7 @@ static mframe_t gunner_frames_run[] = {
{ai_run, 26, NULL},
{ai_run, 9, gunner_footstep},
{ai_run, 9, NULL},
{ai_run, 9, NULL},
{ai_run, 9, monster_done_dodge},
{ai_run, 15, NULL},
{ai_run, 10, gunner_footstep},
{ai_run, 13, NULL},
@ -307,6 +307,8 @@ gunner_run(edict_t *self)
return;
}
monster_done_dodge(self);
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
{
self->monsterinfo.currentmove = &gunner_move_stand;
@ -423,6 +425,13 @@ gunner_pain(edict_t *self, edict_t *other /* unused */,
self->s.skinnum = 1;
}
monster_done_dodge(self);
if (!self->groundentity)
{
return;
}
if (level.time < self->pain_debounce_time)
{
return;
@ -456,6 +465,13 @@ gunner_pain(edict_t *self, edict_t *other /* unused */,
{
self->monsterinfo.currentmove = &gunner_move_pain1;
}
self->monsterinfo.aiflags &= ~AI_MANUAL_STEERING;
if (self->monsterinfo.aiflags & AI_DUCKED)
{
monster_duck_up(self);
}
}
void
@ -568,9 +584,15 @@ gunner_duck_down(edict_t *self)
}
}
self->maxs[2] -= 32;
self->maxs[2] = self->monsterinfo.base_height - 32;
self->takedamage = DAMAGE_YES;
self->monsterinfo.pausetime = level.time + 1;
if (self->monsterinfo.duck_wait_time < level.time)
{
self->monsterinfo.duck_wait_time = level.time + 1;
}
gi.linkentity(self);
}
@ -606,8 +628,23 @@ gunner_duck_up(edict_t *self)
gi.linkentity(self);
}
static void
gunner_duck_down_think(edict_t *self)
{
gunner_duck_down(self);
/* rogue code calls duck_down twice, so move this here */
if (skill->value >= SKILL_HARD)
{
if (random() > 0.5)
{
GunnerGrenade(self);
}
}
}
static mframe_t gunner_frames_duck[] = {
{ai_move, 1, gunner_duck_down},
{ai_move, 1, gunner_duck_down_think},
{ai_move, 1, NULL},
{ai_move, 1, gunner_duck_hold},
{ai_move, 0, NULL},
@ -648,6 +685,7 @@ gunner_dodge(edict_t *self, edict_t *attacker, float eta /* unused */,
self->monsterinfo.currentmove = &gunner_move_duck;
}
/* gunner dodge moved below so I know about attack sequences */
void
gunner_opengun(edict_t *self)
{
@ -673,6 +711,11 @@ GunnerFire(edict_t *self)
return;
}
if (!self->enemy || !self->enemy->inuse)
{
return;
}
flash_number = MZ2_GUNNER_MACHINEGUN_1 + (self->s.frame - FRAME_attak216);
AngleVectors(self->s.angles, forward, right, NULL);
@ -691,41 +734,171 @@ GunnerFire(edict_t *self)
flash_number);
}
qboolean
gunner_grenade_check(edict_t *self)
{
vec3_t start;
vec3_t forward, right;
trace_t tr;
vec3_t target, dir;
if (!self)
{
return false;
}
if (!self->enemy)
{
return false;
}
/* if the player is above my head, use machinegun. */
/* check for flag telling us that we're blindfiring */
if (self->monsterinfo.aiflags & AI_MANUAL_STEERING)
{
if (self->s.origin[2] + self->viewheight <
self->monsterinfo.blind_fire_target[2])
{
return false;
}
}
else if (self->absmax[2] <= self->enemy->absmin[2])
{
return false;
}
/* check to see that we can trace to the player
before we start tossing grenades around. */
AngleVectors(self->s.angles, forward, right, NULL);
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_GUNNER_GRENADE_1],
forward, right, start);
/* check for blindfire flag */
if (self->monsterinfo.aiflags & AI_MANUAL_STEERING)
{
VectorCopy(self->monsterinfo.blind_fire_target, target);
}
else
{
VectorCopy(self->enemy->s.origin, target);
}
/* see if we're too close */
VectorSubtract(self->s.origin, target, dir);
if (VectorLength(dir) < 100)
{
return false;
}
tr = gi.trace(start, vec3_origin, vec3_origin, target, self, MASK_SHOT);
if ((tr.ent == self->enemy) || (tr.fraction == 1))
{
return true;
}
return false;
}
void
GunnerGrenade(edict_t *self)
{
vec3_t start;
vec3_t forward, right;
vec3_t forward, right, up;
vec3_t aim;
int flash_number;
float spread;
float pitch = 0;
vec3_t target;
qboolean blindfire = false;
if (!self)
{
return;
}
if (!self->enemy || !self->enemy->inuse)
{
return;
}
if (self->monsterinfo.aiflags & AI_MANUAL_STEERING)
{
blindfire = true;
}
if (self->s.frame == FRAME_attak105)
{
spread = .02;
flash_number = MZ2_GUNNER_GRENADE_1;
}
else if (self->s.frame == FRAME_attak108)
{
spread = .05;
flash_number = MZ2_GUNNER_GRENADE_2;
}
else if (self->s.frame == FRAME_attak111)
{
spread = .08;
flash_number = MZ2_GUNNER_GRENADE_3;
}
else
{
self->monsterinfo.aiflags &= ~AI_MANUAL_STEERING;
spread = .11;
flash_number = MZ2_GUNNER_GRENADE_4;
}
AngleVectors(self->s.angles, forward, right, NULL);
/* if we're shooting blind and we still can't see our enemy */
if ((blindfire) && (!visible(self, self->enemy)))
{
/* and we have a valid blind_fire_target */
if (VectorCompare(self->monsterinfo.blind_fire_target, vec3_origin))
{
return;
}
VectorCopy(self->monsterinfo.blind_fire_target, target);
}
else
{
VectorCopy(self->s.origin, target);
}
AngleVectors(self->s.angles, forward, right, up);
G_ProjectSource(self->s.origin, monster_flash_offset[flash_number],
forward, right, start);
VectorCopy(forward, aim);
if (self->enemy)
{
float dist;
VectorSubtract(target, self->s.origin, aim);
dist = VectorLength(aim);
/* aim up if they're on the same level as me and far away. */
if ((dist > 512) && (aim[2] < 64) && (aim[2] > -64))
{
aim[2] += (dist - 512);
}
VectorNormalize(aim);
pitch = aim[2];
if (pitch > 0.4)
{
pitch = 0.4;
}
else if (pitch < -0.5)
{
pitch = -0.5;
}
}
VectorMA(forward, spread, right, aim);
VectorMA(aim, pitch, up, aim);
monster_fire_grenade(self, start, aim, 50, 600, flash_number);
}
@ -785,6 +958,24 @@ mmove_t gunner_move_endfire_chain =
gunner_run
};
void
gunner_blind_check(edict_t *self)
{
vec3_t aim;
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_MANUAL_STEERING)
{
VectorSubtract(self->monsterinfo.blind_fire_target, self->s.origin,
aim);
self->ideal_yaw = vectoyaw(aim);
}
}
static mframe_t gunner_frames_attack_grenade[] = {
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
@ -820,18 +1011,71 @@ mmove_t gunner_move_attack_grenade =
void
gunner_attack(edict_t *self)
{
float chance, r;
if (!self)
{
return;
}
if (range(self, self->enemy) == RANGE_MELEE)
monster_done_dodge(self);
if (self->monsterinfo.attack_state == AS_BLIND)
{
/* setup shot probabilities */
if (self->monsterinfo.blind_fire_delay < 1.0)
{
chance = 1.0;
}
else if (self->monsterinfo.blind_fire_delay < 7.5)
{
chance = 0.4;
}
else
{
chance = 0.1;
}
r = random();
/* minimum of 2 seconds, plus 0-3, after the shots are done */
self->monsterinfo.blind_fire_delay += 2.1 + 2.0 + random() * 3.0;
/* don't shoot at the origin */
if (VectorCompare(self->monsterinfo.blind_fire_target, vec3_origin))
{
return;
}
/* don't shoot if the dice say not to */
if (r > chance)
{
return;
}
/* turn on manual steering to signal both manual steering and blindfire */
self->monsterinfo.aiflags |= AI_MANUAL_STEERING;
if (gunner_grenade_check(self))
{
/* if the check passes, go for the attack */
self->monsterinfo.currentmove = &gunner_move_attack_grenade;
self->monsterinfo.attack_finished = level.time + 2 * random();
}
/* turn off blindfire flag */
self->monsterinfo.aiflags &= ~AI_MANUAL_STEERING;
return;
}
/* gunner needs to use his chaingun if he's being attacked by a tesla. */
if ((range(self, self->enemy) == RANGE_MELEE) || self->bad_area)
{
self->monsterinfo.currentmove = &gunner_move_attack_chain;
}
else
{
if (random() <= 0.5)
if ((random() <= 0.5) && gunner_grenade_check(self))
{
self->monsterinfo.currentmove = &gunner_move_attack_grenade;
}
@ -876,6 +1120,229 @@ gunner_refire_chain(edict_t *self)
self->monsterinfo.currentmove = &gunner_move_endfire_chain;
}
void
gunner_jump_now(edict_t *self)
{
vec3_t forward, up;
if (!self)
{
return;
}
monster_jump_start(self);
AngleVectors(self->s.angles, forward, NULL, up);
VectorMA(self->velocity, 100, forward, self->velocity);
VectorMA(self->velocity, 300, up, self->velocity);
}
void
gunner_jump2_now(edict_t *self)
{
vec3_t forward, up;
if (!self)
{
return;
}
monster_jump_start(self);
AngleVectors(self->s.angles, forward, NULL, up);
VectorMA(self->velocity, 150, forward, self->velocity);
VectorMA(self->velocity, 400, up, self->velocity);
}
void
gunner_jump_wait_land(edict_t *self)
{
if (!self)
{
return;
}
if (self->groundentity == NULL)
{
self->monsterinfo.nextframe = self->s.frame;
if (monster_jump_finished(self))
{
self->monsterinfo.nextframe = self->s.frame + 1;
}
}
else
{
self->monsterinfo.nextframe = self->s.frame + 1;
}
}
static mframe_t gunner_frames_jump[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, gunner_jump_now},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, gunner_jump_wait_land},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t gunner_move_jump = {
FRAME_jump01,
FRAME_jump10,
gunner_frames_jump,
gunner_run
};
static mframe_t gunner_frames_jump2[] = {
{ai_move, -8, NULL},
{ai_move, -4, NULL},
{ai_move, -4, NULL},
{ai_move, 0, gunner_jump2_now},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, gunner_jump_wait_land},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t gunner_move_jump2 = {
FRAME_jump01,
FRAME_jump10,
gunner_frames_jump2,
gunner_run
};
void
gunner_jump(edict_t *self)
{
if (!self)
{
return;
}
if (!self->enemy)
{
return;
}
monster_done_dodge(self);
if (self->enemy->absmin[2] > self->absmin[2])
{
self->monsterinfo.currentmove = &gunner_move_jump2;
}
else
{
self->monsterinfo.currentmove = &gunner_move_jump;
}
}
qboolean
gunner_blocked(edict_t *self, float dist)
{
if (!self)
{
return false;
}
if (blocked_checkplat(self, dist))
{
return true;
}
if (blocked_checkjump(self, dist, 192, 40))
{
gunner_jump(self);
return true;
}
return false;
}
/* new duck code */
void
gunner_duck(edict_t *self, float eta)
{
if (!self)
{
return;
}
if ((self->monsterinfo.currentmove == &gunner_move_jump2) ||
(self->monsterinfo.currentmove == &gunner_move_jump))
{
return;
}
if ((self->monsterinfo.currentmove == &gunner_move_attack_chain) ||
(self->monsterinfo.currentmove == &gunner_move_fire_chain) ||
(self->monsterinfo.currentmove == &gunner_move_attack_grenade)
)
{
/* if we're shooting, and not on easy, don't dodge */
if (skill->value > SKILL_EASY)
{
self->monsterinfo.aiflags &= ~AI_DUCKED;
return;
}
}
if (skill->value == SKILL_EASY)
{
/* stupid dodge */
self->monsterinfo.duck_wait_time = level.time + eta + 1;
}
else
{
self->monsterinfo.duck_wait_time = level.time + eta + (0.1 * (3 - skill->value));
}
/* has to be done immediately otherwise he can get stuck */
gunner_duck_down(self);
self->monsterinfo.nextframe = FRAME_duck01;
self->monsterinfo.currentmove = &gunner_move_duck;
return;
}
void
gunner_sidestep(edict_t *self)
{
if (!self)
{
return;
}
if ((self->monsterinfo.currentmove == &gunner_move_jump2) ||
(self->monsterinfo.currentmove == &gunner_move_jump))
{
return;
}
if ((self->monsterinfo.currentmove == &gunner_move_attack_chain) ||
(self->monsterinfo.currentmove == &gunner_move_fire_chain) ||
(self->monsterinfo.currentmove == &gunner_move_attack_grenade)
)
{
/* if we're shooting, and not on easy, don't dodge */
if (skill->value > SKILL_EASY)
{
self->monsterinfo.aiflags &= ~AI_DODGING;
return;
}
}
if (self->monsterinfo.currentmove != &gunner_move_run)
{
self->monsterinfo.currentmove = &gunner_move_run;
}
}
/*
* QUAKED monster_gunner (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
*/
@ -926,15 +1393,20 @@ SP_monster_gunner(edict_t *self)
self->monsterinfo.walk = gunner_walk;
self->monsterinfo.run = gunner_run;
self->monsterinfo.dodge = gunner_dodge;
self->monsterinfo.duck = gunner_duck;
self->monsterinfo.unduck = monster_duck_up;
self->monsterinfo.sidestep = gunner_sidestep;
self->monsterinfo.attack = gunner_attack;
self->monsterinfo.melee = NULL;
self->monsterinfo.sight = gunner_sight;
self->monsterinfo.search = gunner_search;
self->monsterinfo.blocked = gunner_blocked;
gi.linkentity(self);
self->monsterinfo.currentmove = &gunner_move_stand;
self->monsterinfo.scale = MODEL_SCALE;
self->monsterinfo.blindfire = true;
walkmonster_start(self);
}

View file

@ -234,5 +234,15 @@
#define FRAME_duck06 206
#define FRAME_duck07 207
#define FRAME_duck08 208
#define FRAME_jump01 209
#define FRAME_jump02 210
#define FRAME_jump03 211
#define FRAME_jump04 212
#define FRAME_jump05 213
#define FRAME_jump06 214
#define FRAME_jump07 215
#define FRAME_jump08 216
#define FRAME_jump09 217
#define FRAME_jump10 218
#define MODEL_SCALE 1.150000

View file

@ -20,7 +20,7 @@
*
* =======================================================================
*
* Icarus.
* Icarus and Daedalus.
*
* =======================================================================
*/
@ -29,15 +29,6 @@
#include "hover.h"
qboolean visible(edict_t *self, edict_t *other);
static int sound_pain1;
static int sound_pain2;
static int sound_death1;
static int sound_death2;
static int sound_sight;
static int sound_search1;
static int sound_search2;
void hover_run(edict_t *self);
void hover_stand(edict_t *self);
void hover_dead(edict_t *self);
@ -47,6 +38,23 @@ void hover_fire_blaster(edict_t *self);
void hover_die(edict_t *self, edict_t *inflictor, edict_t *attacker,
int damage, vec3_t point);
static int sound_pain1;
static int sound_pain2;
static int sound_death1;
static int sound_death2;
static int sound_sight;
static int sound_search1;
static int sound_search2;
/* daedalus sounds */
static int daed_sound_pain1;
static int daed_sound_pain2;
static int daed_sound_death1;
static int daed_sound_death2;
static int daed_sound_sight;
static int daed_sound_search1;
static int daed_sound_search2;
void
hover_sight(edict_t *self, edict_t *other /* unused */)
{
@ -55,7 +63,14 @@ hover_sight(edict_t *self, edict_t *other /* unused */)
return;
}
gi.sound(self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
if (self->mass < 225)
{
gi.sound(self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, daed_sound_sight, 1, ATTN_NORM, 0);
}
}
void
@ -66,13 +81,27 @@ hover_search(edict_t *self)
return;
}
if (random() < 0.5)
if (self->mass < 225)
{
gi.sound(self, CHAN_VOICE, sound_search1, 1, ATTN_NORM, 0);
if (random() < 0.5)
{
gi.sound(self, CHAN_VOICE, sound_search1, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, sound_search2, 1, ATTN_NORM, 0);
}
}
else
{
gi.sound(self, CHAN_VOICE, sound_search2, 1, ATTN_NORM, 0);
if (random() < 0.5)
{
gi.sound(self, CHAN_VOICE, daed_sound_search1, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, daed_sound_search2, 1, ATTN_NORM, 0);
}
}
}
@ -527,6 +556,44 @@ mmove_t hover_move_end_attack =
hover_run
};
static mframe_t hover_frames_start_attack2[] = {
{ai_charge, 15, NULL},
{ai_charge, 15, NULL},
{ai_charge, 15, NULL}
};
mmove_t hover_move_start_attack2 = {
FRAME_attak101,
FRAME_attak103,
hover_frames_start_attack2,
hover_attack
};
static mframe_t hover_frames_attack2[] = {
{ai_charge, 10, hover_fire_blaster},
{ai_charge, 10, hover_fire_blaster},
{ai_charge, 10, hover_reattack},
};
mmove_t hover_move_attack2 = {
FRAME_attak104,
FRAME_attak106,
hover_frames_attack2,
NULL
};
static mframe_t hover_frames_end_attack2[] = {
{ai_charge, 15, NULL},
{ai_charge, 15, NULL}
};
mmove_t hover_move_end_attack2 = {
FRAME_attak107,
FRAME_attak108,
hover_frames_end_attack2,
hover_run
};
void
hover_reattack(edict_t *self)
{
@ -541,8 +608,20 @@ hover_reattack(edict_t *self)
{
if (random() <= 0.6)
{
self->monsterinfo.currentmove = &hover_move_attack1;
return;
if (self->monsterinfo.attack_state == AS_STRAIGHT)
{
self->monsterinfo.currentmove = &hover_move_attack1;
return;
}
else if (self->monsterinfo.attack_state == AS_SLIDING)
{
self->monsterinfo.currentmove = &hover_move_attack2;
return;
}
else
{
gi.dprintf("hover_reattack: unexpected state %d\n", self->monsterinfo.attack_state);
}
}
}
}
@ -564,6 +643,11 @@ hover_fire_blaster(edict_t *self)
return;
}
if (!self->enemy || !self->enemy->inuse)
{
return;
}
if (self->s.frame == FRAME_attak104)
{
effect = EF_HYPERBLASTER;
@ -581,7 +665,16 @@ hover_fire_blaster(edict_t *self)
end[2] += self->enemy->viewheight;
VectorSubtract(end, start, dir);
monster_fire_blaster(self, start, dir, 1, 1000, MZ2_HOVER_BLASTER_1, effect);
if (self->mass < 200)
{
monster_fire_blaster(self, start, dir, 1,
1000, MZ2_HOVER_BLASTER_1, effect);
}
else
{
monster_fire_blaster2(self, start, dir, 1, 1000,
MZ2_DAEDALUS_BLASTER, EF_BLASTER);
}
}
void
@ -638,12 +731,42 @@ hover_start_attack(edict_t *self)
void
hover_attack(edict_t *self)
{
float chance;
if (!self)
{
return;
}
self->monsterinfo.currentmove = &hover_move_attack1;
if (skill->value == SKILL_EASY)
{
chance = 0;
}
else
{
chance = 1.0 - (0.5 / (float)(skill->value));
}
if (self->mass > 150) /* the daedalus strafes more */
{
chance += 0.1;
}
if (random() > chance)
{
self->monsterinfo.currentmove = &hover_move_attack1;
self->monsterinfo.attack_state = AS_STRAIGHT;
}
else /* circle strafe */
{
if (random() <= 0.5) /* switch directions */
{
self->monsterinfo.lefty = 1 - self->monsterinfo.lefty;
}
self->monsterinfo.currentmove = &hover_move_attack2;
self->monsterinfo.attack_state = AS_SLIDING;
}
}
void
@ -657,7 +780,7 @@ hover_pain(edict_t *self, edict_t *other /* unused */,
if (self->health < (self->max_health / 2))
{
self->s.skinnum = 1;
self->s.skinnum |= 1; /* support for skins 2 & 3. */
}
if (level.time < self->pain_debounce_time)
@ -676,19 +799,63 @@ hover_pain(edict_t *self, edict_t *other /* unused */,
{
if (random() < 0.5)
{
gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
/* daedalus sounds */
if (self->mass < 225)
{
gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, daed_sound_pain1, 1, ATTN_NORM, 0);
}
self->monsterinfo.currentmove = &hover_move_pain3;
}
else
{
gi.sound(self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
/* daedalus sounds */
if (self->mass < 225)
{
gi.sound(self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, daed_sound_pain2, 1, ATTN_NORM, 0);
}
self->monsterinfo.currentmove = &hover_move_pain2;
}
}
else
{
gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &hover_move_pain1;
if (random() < (0.45 - (0.1 * skill->value)))
{
/* daedalus sounds */
if (self->mass < 225)
{
gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, daed_sound_pain1, 1, ATTN_NORM, 0);
}
self->monsterinfo.currentmove = &hover_move_pain1;
}
else
{
/* daedalus sounds */
if (self->mass < 225)
{
gi.sound(self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, daed_sound_pain2, 1, ATTN_NORM, 0);
}
self->monsterinfo.currentmove = &hover_move_pain2;
}
}
}
@ -738,6 +905,9 @@ hover_die(edict_t *self, edict_t *inflictor /* unused */,
return;
}
self->s.effects = 0;
self->monsterinfo.power_armor_type = POWER_ARMOR_NONE;
/* check for gib */
if (self->health <= self->gib_health)
{
@ -774,13 +944,27 @@ hover_die(edict_t *self, edict_t *inflictor /* unused */,
}
/* regular death */
if (random() < 0.5)
if (self->mass < 225)
{
gi.sound(self, CHAN_VOICE, sound_death1, 1, ATTN_NORM, 0);
if (random() < 0.5)
{
gi.sound(self, CHAN_VOICE, sound_death1, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, sound_death2, 1, ATTN_NORM, 0);
}
}
else
{
gi.sound(self, CHAN_VOICE, sound_death2, 1, ATTN_NORM, 0);
if (random() < 0.5)
{
gi.sound(self, CHAN_VOICE, daed_sound_death1, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, daed_sound_death2, 1, ATTN_NORM, 0);
}
}
self->deadflag = DEAD_DEAD;
@ -788,8 +972,18 @@ hover_die(edict_t *self, edict_t *inflictor /* unused */,
self->monsterinfo.currentmove = &hover_move_death1;
}
qboolean
hover_blocked(edict_t *self, float dist)
{
return false;
}
/*
* QUAKED monster_hover (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
*
* QUAKED monster_daedalus (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
* This is the improved icarus monster.
*/
void
SP_monster_hover(edict_t *self)
@ -836,6 +1030,38 @@ SP_monster_hover(edict_t *self)
self->monsterinfo.attack = hover_start_attack;
self->monsterinfo.sight = hover_sight;
self->monsterinfo.search = hover_search;
self->monsterinfo.blocked = hover_blocked;
if (strcmp(self->classname, "monster_daedalus") == 0)
{
self->health = 450;
self->mass = 225;
self->yaw_speed = 25;
self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN;
self->monsterinfo.power_armor_power = 100;
self->s.sound = gi.soundindex("daedalus/daedidle1.wav");
daed_sound_pain1 = gi.soundindex("daedalus/daedpain1.wav");
daed_sound_pain2 = gi.soundindex("daedalus/daedpain2.wav");
daed_sound_death1 = gi.soundindex("daedalus/daeddeth1.wav");
daed_sound_death2 = gi.soundindex("daedalus/daeddeth2.wav");
daed_sound_sight = gi.soundindex("daedalus/daedsght1.wav");
daed_sound_search1 = gi.soundindex("daedalus/daedsrch1.wav");
daed_sound_search2 = gi.soundindex("daedalus/daedsrch2.wav");
gi.soundindex("tank/tnkatck3.wav");
}
else
{
sound_pain1 = gi.soundindex("hover/hovpain1.wav");
sound_pain2 = gi.soundindex("hover/hovpain2.wav");
sound_death1 = gi.soundindex("hover/hovdeth1.wav");
sound_death2 = gi.soundindex("hover/hovdeth2.wav");
sound_sight = gi.soundindex("hover/hovsght1.wav");
sound_search1 = gi.soundindex("hover/hovsrch1.wav");
sound_search2 = gi.soundindex("hover/hovsrch2.wav");
gi.soundindex("hover/hovatck1.wav");
self->s.sound = gi.soundindex("hover/hovidle1.wav");
}
gi.linkentity(self);
@ -843,4 +1069,9 @@ SP_monster_hover(edict_t *self)
self->monsterinfo.scale = MODEL_SCALE;
flymonster_start(self);
if (strcmp(self->classname, "monster_daedalus") == 0)
{
self->s.skinnum = 2;
}
}

View file

@ -20,7 +20,7 @@
*
* =======================================================================
*
* Icarus animations.
* Icarus and Daedalus animations.
*
* =======================================================================
*/

View file

@ -890,7 +890,8 @@ insane_die(edict_t *self, edict_t *inflictor /* unused */,
if (self->health <= self->gib_health)
{
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_IDLE, 0);
gi.sound(self, CHAN_VOICE, gi.soundindex(
"misc/udeath.wav"), 1, ATTN_IDLE, 0);
for (n = 0; n < 2; n++)
{

File diff suppressed because it is too large Load diff

View file

@ -20,7 +20,7 @@
*
* =======================================================================
*
* Medic animations.
* Medic and Medic Commander animations.
*
* =======================================================================
*/

View file

@ -32,11 +32,16 @@
int c_yes, c_no;
/* this is used for communications out of
* sv_movestep to say what entity is blocking us */
edict_t *new_bad;
/*
* Returns false if any part of the
* bottom of the entity is off an edge
* that is not a staircase.
*/
qboolean
M_CheckBottom(edict_t *ent)
{
@ -58,6 +63,11 @@ M_CheckBottom(edict_t *ent)
the corners must be within 16 of the midpoint */
start[2] = mins[2] - 1;
if (ent->gravityVector[2] > 0)
{
start[2] = maxs[2] + 1;
}
for (x = 0; x <= 1; x++)
{
for (y = 0; y <= 1; y++)
@ -84,7 +94,18 @@ realcheck:
/* the midpoint must be within 16 of the bottom */
start[0] = stop[0] = (mins[0] + maxs[0]) * 0.5;
start[1] = stop[1] = (mins[1] + maxs[1]) * 0.5;
stop[2] = start[2] - 2 * STEPSIZE;
if (ent->gravityVector[2] < 0)
{
start[2] = mins[2];
stop[2] = start[2] - STEPSIZE - STEPSIZE;
}
else
{
start[2] = maxs[2];
stop[2] = start[2] + STEPSIZE + STEPSIZE;
}
trace = gi.trace(start, vec3_origin, vec3_origin,
stop, ent, MASK_MONSTERSOLID);
@ -106,14 +127,31 @@ realcheck:
trace = gi.trace(start, vec3_origin, vec3_origin,
stop, ent, MASK_MONSTERSOLID);
if ((trace.fraction != 1.0) && (trace.endpos[2] > bottom))
if (ent->gravityVector[2] > 0)
{
bottom = trace.endpos[2];
}
if ((trace.fraction != 1.0) && (trace.endpos[2] < bottom))
{
bottom = trace.endpos[2];
}
if ((trace.fraction == 1.0) || (mid - trace.endpos[2] > STEPSIZE))
if ((trace.fraction == 1.0) ||
(trace.endpos[2] - mid > STEPSIZE))
{
return false;
}
}
else
{
return false;
if ((trace.fraction != 1.0) && (trace.endpos[2] > bottom))
{
bottom = trace.endpos[2];
}
if ((trace.fraction == 1.0) ||
(mid - trace.endpos[2] > STEPSIZE))
{
return false;
}
}
}
}
@ -122,6 +160,43 @@ realcheck:
return true;
}
qboolean
IsBadAhead(edict_t *self, edict_t *bad, vec3_t move)
{
vec3_t dir;
vec3_t forward;
float dp_bad, dp_move;
vec3_t move_copy;
if (!self || !bad)
{
return false;
}
VectorCopy(move, move_copy);
VectorSubtract(bad->s.origin, self->s.origin, dir);
VectorNormalize(dir);
AngleVectors(self->s.angles, forward, NULL, NULL);
dp_bad = DotProduct(forward, dir);
VectorNormalize(move_copy);
AngleVectors(self->s.angles, forward, NULL, NULL);
dp_move = DotProduct(forward, move_copy);
if ((dp_bad < 0) && (dp_move < 0))
{
return true;
}
if ((dp_bad > 0) && (dp_move > 0))
{
return true;
}
return false;
}
/*
* Called by monster program code.
* The move will be adjusted for slopes
@ -140,12 +215,46 @@ SV_movestep(edict_t *ent, vec3_t move, qboolean relink)
float stepsize;
vec3_t test;
int contents;
edict_t *current_bad = NULL;
float minheight;
if (!ent)
{
return false;
}
if (ent->health > 0)
{
current_bad = CheckForBadArea(ent);
if (current_bad)
{
ent->bad_area = current_bad;
if (ent->enemy && !strcmp(ent->enemy->classname, "tesla"))
{
/* if the tesla is in front of us, back up... */
if (IsBadAhead(ent, current_bad, move))
{
VectorScale(move, -1, move);
}
}
}
else if (ent->bad_area)
{
/* if we're no longer in a bad area, get back to business. */
ent->bad_area = NULL;
if (ent->oldenemy)
{
ent->enemy = ent->oldenemy;
ent->goalentity = ent->oldenemy;
FoundTarget(ent);
return true;
}
}
}
/* try the move */
VectorCopy(ent->s.origin, oldorg);
VectorAdd(ent->s.origin, move, neworg);
@ -169,14 +278,25 @@ SV_movestep(edict_t *ent, vec3_t move, qboolean relink)
if (ent->goalentity->client)
{
if (dz > 40)
/* we want the carrier to stay a certain distance off the ground,
to help prevent him from shooting his fliers, who spawn in below him */
if (!strcmp(ent->classname, "monster_carrier"))
{
minheight = 104;
}
else
{
minheight = 40;
}
if (dz > minheight)
{
neworg[2] -= 8;
}
if (!((ent->flags & FL_SWIM) && (ent->waterlevel < 2)))
{
if (dz < 30)
if (dz < (minheight - 10))
{
neworg[2] += 8;
}
@ -279,17 +399,24 @@ SV_movestep(edict_t *ent, vec3_t move, qboolean relink)
}
}
if (trace.fraction == 1)
if ((trace.fraction == 1) && (!trace.allsolid) && (!trace.startsolid))
{
VectorCopy(trace.endpos, ent->s.origin);
if (relink)
if (!current_bad && CheckForBadArea(ent))
{
gi.linkentity(ent);
G_TouchTriggers(ent);
VectorCopy(oldorg, ent->s.origin);
}
else
{
if (relink)
{
gi.linkentity(ent);
G_TouchTriggers(ent);
}
return true;
return true;
}
}
if (!ent->enemy)
@ -311,9 +438,9 @@ SV_movestep(edict_t *ent, vec3_t move, qboolean relink)
stepsize = 1;
}
neworg[2] += stepsize;
VectorCopy(neworg, end);
end[2] -= stepsize * 2;
/* trace from 1 stepsize gravityUp to 2 stepsize gravityDown. */
VectorMA(neworg, -1 * stepsize, ent->gravityVector, neworg);
VectorMA(neworg, 2 * stepsize, ent->gravityVector, end);
trace = gi.trace(neworg, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID);
@ -339,7 +466,16 @@ SV_movestep(edict_t *ent, vec3_t move, qboolean relink)
{
test[0] = trace.endpos[0];
test[1] = trace.endpos[1];
test[2] = trace.endpos[2] + ent->mins[2] + 1;
if (ent->gravityVector[2] > 0)
{
test[2] = trace.endpos[2] + ent->maxs[2] - 1;
}
else
{
test[2] = trace.endpos[2] + ent->mins[2] + 1;
}
contents = gi.pointcontents(test);
if (contents & MASK_WATER)
@ -362,6 +498,7 @@ SV_movestep(edict_t *ent, vec3_t move, qboolean relink)
}
ent->groundentity = NULL;
return true;
}
@ -371,6 +508,28 @@ SV_movestep(edict_t *ent, vec3_t move, qboolean relink)
/* check point traces down for dangling corners */
VectorCopy(trace.endpos, ent->s.origin);
if (ent->health > 0)
{
/* use AI_BLOCKED to tell the calling layer that we're now mad at a tesla */
new_bad = CheckForBadArea(ent);
if (!current_bad && new_bad)
{
if (new_bad->owner && !strcmp(new_bad->owner->classname, "tesla"))
{
if (!ent->enemy || !ent->enemy->inuse ||
!ent->enemy->client || !visible(ent, ent->enemy))
{
TargetTesla(ent, new_bad->owner);
ent->monsterinfo.aiflags |= AI_BLOCKED;
}
}
VectorCopy(oldorg, ent->s.origin);
return false;
}
}
if (!M_CheckBottom(ent))
{
if (ent->flags & FL_PARTIALGROUND)
@ -483,6 +642,11 @@ SV_StepDirection(edict_t *ent, float yaw, float dist)
return false;
}
if (!ent->inuse)
{
return true;
}
ent->ideal_yaw = yaw;
M_ChangeYaw(ent);
@ -495,12 +659,22 @@ SV_StepDirection(edict_t *ent, float yaw, float dist)
if (SV_movestep(ent, move, false))
{
ent->monsterinfo.aiflags &= ~AI_BLOCKED;
if (!ent->inuse)
{
return true;
}
delta = ent->s.angles[YAW] - ent->ideal_yaw;
if ((delta > 45) && (delta < 315))
if (strncmp(ent->classname, "monster_widow", 13))
{
/* not turned far enough, so don't take the step */
VectorCopy(oldorigin, ent->s.origin);
if ((delta > 45) && (delta < 315))
{
/* not turned far enough, so don't take the step */
VectorCopy(oldorigin, ent->s.origin);
}
}
gi.linkentity(ent);
@ -606,6 +780,17 @@ SV_NewChaseDir(edict_t *actor, edict_t *enemy, float dist)
return;
}
if (actor->monsterinfo.blocked)
{
if ((actor->inuse) && (actor->health > 0))
{
if ((actor->monsterinfo.blocked)(actor, dist))
{
return;
}
}
}
/* there is no direct path to the player, so pick another direction */
if ((olddir != DI_NODIR) && SV_StepDirection(actor, olddir, dist))
{
@ -699,8 +884,16 @@ M_MoveToGoal(edict_t *ent, float dist)
}
/* bump around... */
if (((randk() & 3) == 1) || !SV_StepDirection(ent, ent->ideal_yaw, dist))
if ((((randk() & 3) == 1) &&
!(ent->monsterinfo.aiflags & AI_CHARGING)) ||
!SV_StepDirection(ent, ent->ideal_yaw, dist))
{
if (ent->monsterinfo.aiflags & AI_BLOCKED)
{
ent->monsterinfo.aiflags &= ~AI_BLOCKED;
return;
}
if (ent->inuse)
{
SV_NewChaseDir(ent, goal, dist);
@ -712,6 +905,7 @@ qboolean
M_walkmove(edict_t *ent, float yaw, float dist)
{
vec3_t move;
qboolean retval;
if (!ent)
{
@ -729,5 +923,7 @@ M_walkmove(edict_t *ent, float yaw, float dist)
move[1] = sin(yaw) * dist;
move[2] = 0;
return SV_movestep(ent, move, true);
retval = SV_movestep(ent, move, true);
ent->monsterinfo.aiflags &= ~AI_BLOCKED;
return retval;
}

View file

@ -423,7 +423,7 @@ void
mutant_jump_touch(edict_t *self, edict_t *other,
cplane_t *plane /* unused */, csurface_t *surf /* unused */)
{
if (!self)
if (!self || !other)
{
return;
}
@ -842,6 +842,117 @@ mutant_die(edict_t *self, edict_t *inflictor /* unused */,
}
}
void
mutant_jump_down(edict_t *self)
{
vec3_t forward, up;
if (!self)
{
return;
}
AngleVectors(self->s.angles, forward, NULL, up);
VectorMA(self->velocity, 100, forward, self->velocity);
VectorMA(self->velocity, 300, up, self->velocity);
}
void
mutant_jump_up(edict_t *self)
{
vec3_t forward, up;
if (!self)
{
return;
}
AngleVectors(self->s.angles, forward, NULL, up);
VectorMA(self->velocity, 200, forward, self->velocity);
VectorMA(self->velocity, 450, up, self->velocity);
}
void
mutant_jump_wait_land(edict_t *self)
{
if (self->groundentity == NULL)
{
self->monsterinfo.nextframe = self->s.frame;
}
else
{
self->monsterinfo.nextframe = self->s.frame + 1;
}
}
static mframe_t mutant_frames_jump_up[] = {
{ai_move, -8, NULL},
{ai_move, -8, mutant_jump_up},
{ai_move, 0, mutant_jump_wait_land},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t mutant_move_jump_up = {
FRAME_jump01,
FRAME_jump05,
mutant_frames_jump_up,
mutant_run
};
static mframe_t mutant_frames_jump_down[] = {
{ai_move, 0, NULL},
{ai_move, 0, mutant_jump_down},
{ai_move, 0, mutant_jump_wait_land},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t mutant_move_jump_down = {
FRAME_jump01,
FRAME_jump05,
mutant_frames_jump_down,
mutant_run
};
void
mutant_jump_updown(edict_t *self)
{
if (!self || !self->enemy)
{
return;
}
if (self->enemy->absmin[2] > self->absmin[2])
{
self->monsterinfo.currentmove = &mutant_move_jump_up;
}
else
{
self->monsterinfo.currentmove = &mutant_move_jump_down;
}
}
qboolean
mutant_blocked(edict_t *self, float dist)
{
if (!self)
{
return false;
}
if (blocked_checkjump(self, dist, 256, 68))
{
mutant_jump_updown(self);
return true;
}
if (blocked_checkplat(self, dist))
return true;
return false;
}
/*
* QUAKED monster_mutant (1 .5 0) (-32 -32 -24) (32 32 32) Ambush Trigger_Spawn Sight
*/
@ -896,6 +1007,7 @@ SP_monster_mutant(edict_t *self)
self->monsterinfo.search = mutant_search;
self->monsterinfo.idle = mutant_idle;
self->monsterinfo.checkattack = mutant_checkattack;
self->monsterinfo.blocked = mutant_blocked;
gi.linkentity(self);

View file

@ -174,5 +174,10 @@
#define FRAME_walk21 146
#define FRAME_walk22 147
#define FRAME_walk23 148
#define FRAME_jump01 149
#define FRAME_jump02 150
#define FRAME_jump03 151
#define FRAME_jump04 152
#define FRAME_jump05 153
#define MODEL_SCALE 1.000000

View file

@ -511,7 +511,7 @@ parasite_drain_attack_ok(vec3_t start, vec3_t end)
void
parasite_drain_attack(edict_t *self)
{
vec3_t offset, start, f, r, end, dir;
vec3_t offset, start, origStart, f, r, end, dir;
trace_t tr;
int damage;
@ -525,6 +525,19 @@ parasite_drain_attack(edict_t *self)
G_ProjectSource(self->s.origin, offset, f, r, start);
VectorCopy(self->enemy->s.origin, end);
VectorSubtract(end, start, dir);
{
// will use the original startPoint for the actual effect etc,
// the modified start is just for the traces
VectorCopy(start, origStart);
vec3_t dir2; // need normalized dir for offset
VectorCopy(dir, dir2);
VectorNormalize(dir2);
// start = start - 8*dir => move start back a bit
// so trace doesn't start in wall in case parasite is too close to wall
VectorMA(start, -8.0f, dir2, start);
}
if (!parasite_drain_attack_ok(start, end))
{
@ -568,11 +581,10 @@ parasite_drain_attack(edict_t *self)
gi.WriteByte(svc_temp_entity);
gi.WriteByte(TE_PARASITE_ATTACK);
gi.WriteShort(self - g_edicts);
gi.WritePosition(start);
gi.WritePosition(origStart);
gi.WritePosition(end);
gi.multicast(self->s.origin, MULTICAST_PVS);
VectorSubtract(start, end, dir);
T_Damage(self->enemy, self, self, dir, self->enemy->s.origin,
vec3_origin, damage, 0, DAMAGE_NO_KNOCKBACK, MOD_UNKNOWN);
}
@ -660,6 +672,238 @@ parasite_attack(edict_t *self)
self->monsterinfo.currentmove = &parasite_move_drain;
}
void
parasite_jump_down(edict_t *self)
{
vec3_t forward, up;
if (!self)
{
return;
}
monster_jump_start(self);
AngleVectors(self->s.angles, forward, NULL, up);
VectorMA(self->velocity, 100, forward, self->velocity);
VectorMA(self->velocity, 300, up, self->velocity);
}
void
parasite_jump_up(edict_t *self)
{
vec3_t forward, up;
if (!self)
{
return;
}
monster_jump_start(self);
AngleVectors(self->s.angles, forward, NULL, up);
VectorMA(self->velocity, 200, forward, self->velocity);
VectorMA(self->velocity, 450, up, self->velocity);
}
void
parasite_jump_wait_land(edict_t *self)
{
if (!self)
{
return;
}
if (self->groundentity == NULL)
{
self->monsterinfo.nextframe = self->s.frame;
if (monster_jump_finished(self))
{
self->monsterinfo.nextframe = self->s.frame + 1;
}
}
else
{
self->monsterinfo.nextframe = self->s.frame + 1;
}
}
static mframe_t parasite_frames_jump_up[] = {
{ai_move, -8, NULL},
{ai_move, -8, NULL},
{ai_move, -8, NULL},
{ai_move, -8, parasite_jump_up},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, parasite_jump_wait_land},
{ai_move, 0, NULL}
};
mmove_t parasite_move_jump_up = {
FRAME_jump01,
FRAME_jump08,
parasite_frames_jump_up,
parasite_run
};
static mframe_t parasite_frames_jump_down[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, parasite_jump_down},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, parasite_jump_wait_land},
{ai_move, 0, NULL}
};
mmove_t parasite_move_jump_down = {
FRAME_jump01,
FRAME_jump08,
parasite_frames_jump_down,
parasite_run
};
void
parasite_jump(edict_t *self)
{
if (!self)
{
return;
}
if (!self->enemy)
{
return;
}
if (self->enemy->absmin[2] > self->absmin[2])
{
self->monsterinfo.currentmove = &parasite_move_jump_up;
}
else
{
self->monsterinfo.currentmove = &parasite_move_jump_down;
}
}
qboolean
parasite_blocked(edict_t *self, float dist)
{
if (!self)
{
return false;
}
if (self->enemy && self->enemy->client && random() >= (0.25 + (0.05 * skill->value)))
{
vec3_t f, r, offset, start, end;
AngleVectors(self->s.angles, f, r, NULL);
VectorSet(offset, 24, 0, 6);
G_ProjectSource(self->s.origin, offset, f, r, start);
VectorCopy(self->enemy->s.origin, end);
if (!parasite_drain_attack_ok(start, end))
{
end[2] = self->enemy->s.origin[2] + self->enemy->maxs[2] - 8;
if (!parasite_drain_attack_ok(start, end))
{
end[2] = self->enemy->s.origin[2] + self->enemy->mins[2] + 8;
if (!parasite_drain_attack_ok(start, end))
{
return false;
}
}
}
VectorCopy(self->enemy->s.origin, end);
if (visible(self, self->enemy))
{
parasite_attack(self);
return true;
}
}
if (blocked_checkjump(self, dist, 256, 68))
{
parasite_jump(self);
return true;
}
if (blocked_checkplat(self, dist))
{
return true;
}
return false;
}
qboolean
parasite_checkattack(edict_t *self)
{
vec3_t f, r, offset, start, end;
trace_t tr;
qboolean retval;
if (!self)
{
return false;
}
retval = M_CheckAttack(self);
if (!retval)
{
return false;
}
AngleVectors(self->s.angles, f, r, NULL);
VectorSet(offset, 24, 0, 6);
G_ProjectSource(self->s.origin, offset, f, r, start);
VectorCopy(self->enemy->s.origin, end);
if (!parasite_drain_attack_ok(start, end))
{
end[2] = self->enemy->s.origin[2] + self->enemy->maxs[2] - 8;
if (!parasite_drain_attack_ok(start, end))
{
end[2] = self->enemy->s.origin[2] + self->enemy->mins[2] + 8;
if (!parasite_drain_attack_ok(start, end))
{
return false;
}
}
}
VectorCopy(self->enemy->s.origin, end);
tr = gi.trace(start, NULL, NULL, end, self, MASK_SHOT);
if (tr.ent != self->enemy)
{
self->monsterinfo.aiflags |= AI_BLOCKED;
if (self->monsterinfo.attack)
{
self->monsterinfo.attack(self);
}
self->monsterinfo.aiflags &= ~AI_BLOCKED;
return true;
}
return true;
}
void
parasite_dead(edict_t *self)
{
@ -790,6 +1034,8 @@ SP_monster_parasite(edict_t *self)
self->monsterinfo.attack = parasite_attack;
self->monsterinfo.sight = parasite_sight;
self->monsterinfo.idle = parasite_idle;
self->monsterinfo.blocked = parasite_blocked;
self->monsterinfo.checkattack = parasite_checkattack;
gi.linkentity(self);

View file

@ -143,5 +143,13 @@
#define FRAME_stand33 115
#define FRAME_stand34 116
#define FRAME_stand35 117
#define FRAME_jump01 118
#define FRAME_jump02 119
#define FRAME_jump03 120
#define FRAME_jump04 121
#define FRAME_jump05 122
#define FRAME_jump06 123
#define FRAME_jump07 124
#define FRAME_jump08 125
#define MODEL_SCALE 1.000000

View file

@ -30,6 +30,7 @@
#include "supertank.h"
qboolean visible(edict_t *self, edict_t *other);
static int sound_pain1;
static int sound_pain2;
static int sound_pain3;
@ -652,7 +653,7 @@ supertankRocket(edict_t *self)
vec3_t vec;
int flash_number;
if (!self)
if (!self || !self->enemy || !self->enemy->inuse)
{
return;
}
@ -696,7 +697,13 @@ supertankMachineGun(edict_t *self)
return;
}
flash_number = MZ2_SUPERTANK_MACHINEGUN_1 + (self->s.frame - FRAME_attak1_1);
if (!self->enemy || !self->enemy->inuse)
{
return;
}
flash_number = MZ2_SUPERTANK_MACHINEGUN_1 +
(self->s.frame - FRAME_attak1_1);
dir[0] = 0;
dir[1] = self->s.angles[1];
@ -865,6 +872,22 @@ supertank_die(edict_t *self, edict_t *inflictor /* unused */,
self->monsterinfo.currentmove = &supertank_move_death;
}
qboolean
supertank_blocked(edict_t *self, float dist)
{
if (!self)
{
return false;
}
if (blocked_checkplat(self, dist))
{
return true;
}
return false;
}
/*
* QUAKED monster_supertank (1 .5 0) (-64 -64 0) (64 64 72) Ambush Trigger_Spawn Sight Powershield
*/
@ -911,6 +934,7 @@ SP_monster_supertank(edict_t *self)
self->monsterinfo.search = supertank_search;
self->monsterinfo.melee = NULL;
self->monsterinfo.sight = NULL;
self->monsterinfo.blocked = supertank_blocked;
gi.linkentity(self);
@ -924,4 +948,6 @@ SP_monster_supertank(edict_t *self)
}
walkmonster_start(self);
self->monsterinfo.aiflags |= AI_IGNORE_SHOTS;
}

View file

@ -425,6 +425,8 @@ tank_pain(edict_t *self, edict_t *other /* other */,
return; /* no pain anims in nightmare */
}
self->monsterinfo.aiflags &= ~AI_MANUAL_STEERING;
if (damage <= 30)
{
self->monsterinfo.currentmove = &tank_move_pain1;
@ -496,12 +498,25 @@ TankRocket(edict_t *self)
vec3_t dir;
vec3_t vec;
int flash_number;
trace_t trace;
int rocketSpeed;
vec3_t target;
qboolean blindfire = false;
if (!self)
if (!self || !self->enemy || !self->enemy->inuse)
{
return;
}
if (self->monsterinfo.aiflags & AI_MANUAL_STEERING)
{
blindfire = true;
}
else
{
blindfire = false;
}
if (self->s.frame == FRAME_attak324)
{
flash_number = MZ2_TANK_ROCKET_1;
@ -519,12 +534,71 @@ TankRocket(edict_t *self)
G_ProjectSource(self->s.origin, monster_flash_offset[flash_number],
forward, right, start);
VectorCopy(self->enemy->s.origin, vec);
vec[2] += self->enemy->viewheight;
VectorSubtract(vec, start, dir);
rocketSpeed = 500 + (100 * skill->value);
if (blindfire)
{
VectorCopy (self->monsterinfo.blind_fire_target, target);
}
else
{
VectorCopy (self->enemy->s.origin, target);
}
if (blindfire)
{
VectorCopy(target, vec);
VectorSubtract(vec, start, dir);
}
else if(random() < 0.66 || (start[2] < self->enemy->absmin[2]))
{
// Don't shoot at the feed if enemy is above.
VectorCopy(self->enemy->s.origin, vec);
vec[2] += self->enemy->viewheight;
VectorSubtract(vec, start, dir);
}
else
{
// Shoot at the feed.
VectorCopy(self->enemy->s.origin, vec);
vec[2] = self->enemy->absmin[2];
VectorSubtract(vec, start, dir);
}
// Lead target: 20, 35, 50, 65 chance of leading.
if ((!blindfire) && ((random() < (0.2 + ((3 - skill->value) * 0.15)))))
{
float dist;
float time;
dist = VectorLength(dir);
time = dist/rocketSpeed;
VectorMA(vec, time, self->enemy->velocity, vec);
VectorSubtract(vec, start, dir);
}
VectorNormalize(dir);
monster_fire_rocket(self, start, dir, 50, 550, flash_number);
if (blindfire)
{
/* blindfire has different fail criteria for the trace */
if (!blind_rocket_ok(self, start, right, target, 20.0f, dir))
{
return;
}
}
else
{
trace = gi.trace(start, vec3_origin, vec3_origin, vec, self, MASK_SHOT);
if (((trace.ent != self->enemy) && (trace.ent != world)) ||
((trace.fraction <= 0.5f) && !trace.ent->client))
{
return;
}
}
monster_fire_rocket(self, start, dir, 50, rocketSpeed, flash_number);
}
void
@ -536,7 +610,7 @@ TankMachineGun(edict_t *self)
vec3_t forward, right;
int flash_number;
if (!self)
if (!self || !self->enemy || !self->enemy->inuse)
{
return;
}
@ -864,6 +938,13 @@ tank_refire_rocket(edict_t *self)
return;
}
if (self->monsterinfo.aiflags & AI_MANUAL_STEERING)
{
self->monsterinfo.aiflags &= ~AI_MANUAL_STEERING;
self->monsterinfo.currentmove = &tank_move_attack_post_rocket;
return;
}
/* Only on hard or nightmare */
if (skill->value >= SKILL_HARD)
{
@ -901,8 +982,9 @@ tank_attack(edict_t *self)
vec3_t vec;
float range;
float r;
float chance;
if (!self)
if (!self || !self->enemy || !self->enemy->inuse)
{
return;
}
@ -914,6 +996,45 @@ tank_attack(edict_t *self)
return;
}
if (self->monsterinfo.attack_state == AS_BLIND)
{
if (self->monsterinfo.blind_fire_delay < 1.0)
{
chance = 1.0;
}
else if (self->monsterinfo.blind_fire_delay < 7.5)
{
chance = 0.4;
}
else
{
chance = 0.1;
}
r = random();
self->monsterinfo.blind_fire_delay += 3.2 + 2.0 + random() * 3.0;
// Don't shoot at the origin.
if (VectorCompare (self->monsterinfo.blind_fire_target, vec3_origin))
{
return;
}
// Don't shoot if the dice say not to.
if (r > chance)
{
return;
}
// turn on manual steering to signal both manual steering and blindfire
self->monsterinfo.aiflags |= AI_MANUAL_STEERING;
self->monsterinfo.currentmove = &tank_move_attack_fire_rocket;
self->monsterinfo.attack_finished = level.time + 3.0 + 2*random();
self->pain_debounce_time = level.time + 5.0; // no pain for a while
return;
}
VectorSubtract(self->enemy->s.origin, self->s.origin, vec);
range = VectorLength(vec);
@ -1068,8 +1189,27 @@ tank_die(edict_t *self, edict_t *inflictor /* unused */,
self->monsterinfo.currentmove = &tank_move_death;
}
qboolean
tank_blocked(edict_t *self, float dist)
{
if (!self)
{
return false;
}
if (blocked_checkplat(self, dist))
{
return true;
}
return false;
}
/*
* QUAKED monster_tank (1 .5 0) (-32 -32 -16) (32 32 72) Ambush Trigger_Spawn Sight
*/
/*
* QUAKED monster_tank_commander (1 .5 0) (-32 -32 -16) (32 32 72) Ambush Trigger_Spawn Sight
*/
void
@ -1132,6 +1272,7 @@ SP_monster_tank(edict_t *self)
self->monsterinfo.melee = NULL;
self->monsterinfo.sight = tank_sight;
self->monsterinfo.idle = tank_idle;
self->monsterinfo.blocked = tank_blocked;
gi.linkentity(self);
@ -1140,6 +1281,9 @@ SP_monster_tank(edict_t *self)
walkmonster_start(self);
self->monsterinfo.aiflags |= AI_IGNORE_SHOTS;
self->monsterinfo.blindfire = true;
if (strcmp(self->classname, "monster_tank_commander") == 0)
{
self->s.skinnum = 2;

View file

@ -1,905 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Boss 2 aka Hornet. Found in biggun and inner hangar.
*
* =======================================================================
*/
#include "../../header/local.h"
#include "boss2.h"
#define BOSS2_ROCKET_SPEED 750
qboolean infront(edict_t *self, edict_t *other);
void BossExplode(edict_t *self);
void boss2_run(edict_t *self);
void boss2_stand(edict_t *self);
void boss2_dead(edict_t *self);
void boss2_attack(edict_t *self);
void boss2_attack_mg(edict_t *self);
void boss2_reattack_mg(edict_t *self);
void boss2_die(edict_t *self, edict_t *inflictor, edict_t *attacker,
int damage, vec3_t point);
static int sound_pain1;
static int sound_pain2;
static int sound_pain3;
static int sound_death;
static int sound_search1;
void
boss2_search(edict_t *self)
{
if (!self)
{
return;
}
if (random() < 0.5)
{
gi.sound(self, CHAN_VOICE, sound_search1, 1, ATTN_NONE, 0);
}
}
void
Boss2PredictiveRocket(edict_t *self)
{
vec3_t forward, right;
vec3_t start;
vec3_t dir;
vec3_t vec;
float time, dist;
if (!self || !self->enemy || !self->enemy->inuse)
{
return;
}
AngleVectors(self->s.angles, forward, right, NULL);
//1
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_1], forward, right, start);
VectorSubtract(self->enemy->s.origin, start, dir);
dist = VectorLength(dir);
time = dist / BOSS2_ROCKET_SPEED;
VectorMA(self->enemy->s.origin, time-0.3, self->enemy->velocity, vec);
VectorSubtract(vec, start, dir);
VectorNormalize(dir);
monster_fire_rocket(self, start, dir, 50, BOSS2_ROCKET_SPEED, MZ2_BOSS2_ROCKET_1);
//2
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_2], forward, right, start);
VectorSubtract(self->enemy->s.origin, start, dir);
dist = VectorLength(dir);
time = dist / BOSS2_ROCKET_SPEED;
VectorMA(self->enemy->s.origin, time-0.15, self->enemy->velocity, vec);
VectorSubtract(vec, start, dir);
VectorNormalize(dir);
monster_fire_rocket(self, start, dir, 50, BOSS2_ROCKET_SPEED, MZ2_BOSS2_ROCKET_2);
//3
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_3], forward, right, start);
VectorSubtract(self->enemy->s.origin, start, dir);
dist = VectorLength(dir);
time = dist / BOSS2_ROCKET_SPEED;
VectorMA(self->enemy->s.origin, time, self->enemy->velocity, vec);
VectorSubtract(vec, start, dir);
VectorNormalize(dir);
monster_fire_rocket(self, start, dir, 50, BOSS2_ROCKET_SPEED, MZ2_BOSS2_ROCKET_3);
//4
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_4], forward, right, start);
VectorSubtract(self->enemy->s.origin, start, dir);
dist = VectorLength(dir);
time = dist / BOSS2_ROCKET_SPEED;
VectorMA(self->enemy->s.origin, time+0.15, self->enemy->velocity, vec);
VectorSubtract(vec, start, dir);
VectorNormalize(dir);
monster_fire_rocket(self, start, dir, 50, BOSS2_ROCKET_SPEED, MZ2_BOSS2_ROCKET_4);
}
void
Boss2Rocket(edict_t *self)
{
vec3_t forward, right;
vec3_t start;
vec3_t dir;
vec3_t vec;
if (!self || !self->enemy || !self->enemy->inuse)
{
return;
}
if (self->enemy->client && random() < 0.9)
{
Boss2PredictiveRocket(self);
return;
}
AngleVectors(self->s.angles, forward, right, NULL);
//1
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_1], forward, right, start);
VectorCopy(self->enemy->s.origin, vec);
vec[2] -= 15;
VectorSubtract(vec, start, dir);
VectorNormalize(dir);
VectorMA(dir, 0.4, right, dir);
VectorNormalize(dir);
monster_fire_rocket(self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_1);
//2
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_2], forward, right, start);
VectorCopy(self->enemy->s.origin, vec);
VectorSubtract(vec, start, dir);
VectorNormalize(dir);
VectorMA(dir, 0.025, right, dir);
VectorNormalize(dir);
monster_fire_rocket(self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_2);
//3
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_3], forward, right, start);
VectorCopy(self->enemy->s.origin, vec);
VectorSubtract(vec, start, dir);
VectorNormalize(dir);
VectorMA(dir, -0.025, right, dir);
VectorNormalize(dir);
monster_fire_rocket(self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_3);
//4
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_ROCKET_4], forward, right, start);
VectorCopy(self->enemy->s.origin, vec);
vec[2] -= 15;
VectorSubtract(vec, start, dir);
VectorNormalize(dir);
VectorMA(dir, -0.4, right, dir);
VectorNormalize(dir);
monster_fire_rocket(self, start, dir, 50, 500, MZ2_BOSS2_ROCKET_4);
}
void
boss2_firebullet_right(edict_t *self)
{
vec3_t forward, right, target;
vec3_t start;
if (!self)
{
return;
}
AngleVectors(self->s.angles, forward, right, NULL);
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_MACHINEGUN_R1],
forward, right, start);
VectorMA(self->enemy->s.origin, 0.2, self->enemy->velocity, target);
target[2] += self->enemy->viewheight;
VectorSubtract(target, start, forward);
VectorNormalize(forward);
monster_fire_bullet(self, start, forward, 6, 4, DEFAULT_BULLET_HSPREAD*3,
DEFAULT_BULLET_VSPREAD, MZ2_BOSS2_MACHINEGUN_R1);
}
void
boss2_firebullet_left(edict_t *self)
{
vec3_t forward, right, target;
vec3_t start;
if (!self)
{
return;
}
AngleVectors(self->s.angles, forward, right, NULL);
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_BOSS2_MACHINEGUN_L1],
forward, right, start);
VectorMA(self->enemy->s.origin, 0.2, self->enemy->velocity, target);
target[2] += self->enemy->viewheight;
VectorSubtract(target, start, forward);
VectorNormalize(forward);
monster_fire_bullet(self, start, forward, 6, 4, DEFAULT_BULLET_HSPREAD*3,
DEFAULT_BULLET_VSPREAD, MZ2_BOSS2_MACHINEGUN_L1);
}
void
Boss2MachineGun(edict_t *self)
{
if (!self)
{
return;
}
boss2_firebullet_left(self);
boss2_firebullet_right(self);
}
static mframe_t boss2_frames_stand[] = {
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL}
};
mmove_t boss2_move_stand =
{
FRAME_stand30,
FRAME_stand50,
boss2_frames_stand,
NULL
};
static mframe_t boss2_frames_fidget[] = {
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL}
};
mmove_t boss2_move_fidget =
{
FRAME_stand1,
FRAME_stand30,
boss2_frames_fidget,
NULL
};
static mframe_t boss2_frames_walk[] = {
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL},
{ai_walk, 10, NULL}
};
mmove_t boss2_move_walk = {
FRAME_walk1,
FRAME_walk20,
boss2_frames_walk,
NULL
};
static mframe_t boss2_frames_run[] = {
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL}
};
mmove_t boss2_move_run = {
FRAME_walk1,
FRAME_walk20,
boss2_frames_run,
NULL
};
static mframe_t boss2_frames_attack_pre_mg[] = {
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, boss2_attack_mg}
};
mmove_t boss2_move_attack_pre_mg = {
FRAME_attack1,
FRAME_attack9,
boss2_frames_attack_pre_mg,
NULL
};
/* Loop this */
static mframe_t boss2_frames_attack_mg[] = {
{ai_charge, 2, Boss2MachineGun},
{ai_charge, 2, Boss2MachineGun},
{ai_charge, 2, Boss2MachineGun},
{ai_charge, 2, Boss2MachineGun},
{ai_charge, 2, Boss2MachineGun},
{ai_charge, 2, boss2_reattack_mg}
};
mmove_t boss2_move_attack_mg =
{
FRAME_attack10,
FRAME_attack15,
boss2_frames_attack_mg,
NULL
};
static mframe_t boss2_frames_attack_post_mg[] = {
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL}
};
mmove_t boss2_move_attack_post_mg = {
FRAME_attack16,
FRAME_attack19,
boss2_frames_attack_post_mg,
boss2_run
};
static mframe_t boss2_frames_attack_rocket[] = {
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_move, -5, Boss2Rocket},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL},
{ai_charge, 2, NULL}
};
mmove_t boss2_move_attack_rocket = {FRAME_attack20,
FRAME_attack40,
boss2_frames_attack_rocket,
boss2_run
};
static mframe_t boss2_frames_pain_heavy[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t boss2_move_pain_heavy = {
FRAME_pain2,
FRAME_pain19,
boss2_frames_pain_heavy,
boss2_run
};
static mframe_t boss2_frames_pain_light[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t boss2_move_pain_light = {
FRAME_pain20,
FRAME_pain23,
boss2_frames_pain_light,
boss2_run
};
static mframe_t boss2_frames_death[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, BossExplode}
};
mmove_t boss2_move_death = {
FRAME_death2,
FRAME_death50,
boss2_frames_death,
boss2_dead
};
void
boss2_stand(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &boss2_move_stand;
}
void
boss2_run(edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
{
self->monsterinfo.currentmove = &boss2_move_stand;
}
else
{
self->monsterinfo.currentmove = &boss2_move_run;
}
}
void
boss2_walk(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &boss2_move_walk;
}
void
boss2_attack(edict_t *self)
{
vec3_t vec;
float range;
if (!self)
{
return;
}
VectorSubtract(self->enemy->s.origin, self->s.origin, vec);
range = VectorLength(vec);
if (range <= 125)
{
self->monsterinfo.currentmove = &boss2_move_attack_pre_mg;
}
else
{
if (random() <= 0.6)
{
self->monsterinfo.currentmove = &boss2_move_attack_pre_mg;
}
else
{
self->monsterinfo.currentmove = &boss2_move_attack_rocket;
}
}
}
void
boss2_attack_mg(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &boss2_move_attack_mg;
}
void
boss2_reattack_mg(edict_t *self)
{
if (!self)
{
return;
}
if (infront(self, self->enemy))
{
if (random() <= 0.7)
{
self->monsterinfo.currentmove = &boss2_move_attack_mg;
}
else
{
self->monsterinfo.currentmove = &boss2_move_attack_post_mg;
}
}
else
{
self->monsterinfo.currentmove = &boss2_move_attack_post_mg;
}
}
void
boss2_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
{
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
{
self->s.skinnum = 1;
}
if (level.time < self->pain_debounce_time)
{
return;
}
self->pain_debounce_time = level.time + 3;
/* American wanted these at no attenuation */
if (damage < 10)
{
gi.sound(self, CHAN_VOICE, sound_pain3, 1, ATTN_NONE, 0);
self->monsterinfo.currentmove = &boss2_move_pain_light;
}
else if (damage < 30)
{
gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NONE, 0);
self->monsterinfo.currentmove = &boss2_move_pain_light;
}
else
{
gi.sound(self, CHAN_VOICE, sound_pain2, 1, ATTN_NONE, 0);
self->monsterinfo.currentmove = &boss2_move_pain_heavy;
}
}
void
boss2_dead(edict_t *self)
{
if (!self)
{
return;
}
VectorSet(self->mins, -56, -56, 0);
VectorSet(self->maxs, 56, 56, 80);
self->movetype = MOVETYPE_TOSS;
self->svflags |= SVF_DEADMONSTER;
self->nextthink = 0;
gi.linkentity(self);
}
void
boss2_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
int damage /* unused */, vec3_t point /* unused */)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_VOICE, sound_death, 1, ATTN_NONE, 0);
self->deadflag = DEAD_DEAD;
self->takedamage = DAMAGE_NO;
self->count = 0;
self->monsterinfo.currentmove = &boss2_move_death;
}
qboolean
Boss2_CheckAttack(edict_t *self)
{
vec3_t spot1, spot2;
vec3_t temp;
float chance;
trace_t tr;
int enemy_range;
float enemy_yaw;
if (!self)
{
return false;
}
if (self->enemy->health > 0)
{
/* see if any entities are in the way of the shot */
VectorCopy(self->s.origin, spot1);
spot1[2] += self->viewheight;
VectorCopy(self->enemy->s.origin, spot2);
spot2[2] += self->enemy->viewheight;
tr = gi.trace(spot1, NULL, NULL, spot2, self,
CONTENTS_SOLID | CONTENTS_MONSTER | CONTENTS_SLIME |
CONTENTS_LAVA);
/* do we have a clear shot? */
if (tr.ent != self->enemy)
{
/* we want them to go ahead and shoot at info_notnulls if they can */
if (self->enemy->solid != SOLID_NOT || tr.fraction < 1.0)
{
return false;
}
}
}
enemy_range = range(self, self->enemy);
VectorSubtract(self->enemy->s.origin, self->s.origin, temp);
enemy_yaw = vectoyaw(temp);
self->ideal_yaw = enemy_yaw;
/* melee attack */
if (enemy_range == RANGE_MELEE)
{
if (self->monsterinfo.melee)
{
self->monsterinfo.attack_state = AS_MELEE;
}
else
{
self->monsterinfo.attack_state = AS_MISSILE;
}
return true;
}
/* missile attack */
if (!self->monsterinfo.attack)
{
return false;
}
if (level.time < self->monsterinfo.attack_finished)
{
return false;
}
if (enemy_range == RANGE_FAR)
{
return false;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
{
chance = 0.4;
}
else if (enemy_range == RANGE_NEAR)
{
chance = 0.8;
}
else if (enemy_range == RANGE_MID)
{
chance = 0.8;
}
else
{
return false;
}
if ((random() < chance) || (self->enemy->solid == SOLID_NOT))
{
self->monsterinfo.attack_state = AS_MISSILE;
self->monsterinfo.attack_finished = level.time + 2 * random();
return true;
}
if (self->flags & FL_FLY)
{
if (random() < 0.3)
{
self->monsterinfo.attack_state = AS_SLIDING;
}
else
{
self->monsterinfo.attack_state = AS_STRAIGHT;
}
}
return false;
}
/*
* QUAKED monster_boss2 (1 .5 0) (-56 -56 0) (56 56 80) Ambush Trigger_Spawn Sight
*/
void
SP_monster_boss2(edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict(self);
return;
}
sound_pain1 = gi.soundindex("bosshovr/bhvpain1.wav");
sound_pain2 = gi.soundindex("bosshovr/bhvpain2.wav");
sound_pain3 = gi.soundindex("bosshovr/bhvpain3.wav");
sound_death = gi.soundindex("bosshovr/bhvdeth1.wav");
sound_search1 = gi.soundindex("bosshovr/bhvunqv1.wav");
self->s.sound = gi.soundindex("bosshovr/bhvengn1.wav");
self->movetype = MOVETYPE_STEP;
self->solid = SOLID_BBOX;
self->s.modelindex = gi.modelindex("models/monsters/boss2/tris.md2");
VectorSet(self->mins, -56, -56, 0);
VectorSet(self->maxs, 56, 56, 80);
self->health = 2000;
self->gib_health = -200;
self->mass = 1000;
self->flags |= FL_IMMUNE_LASER;
self->pain = boss2_pain;
self->die = boss2_die;
self->monsterinfo.stand = boss2_stand;
self->monsterinfo.walk = boss2_walk;
self->monsterinfo.run = boss2_run;
self->monsterinfo.attack = boss2_attack;
self->monsterinfo.search = boss2_search;
self->monsterinfo.checkattack = Boss2_CheckAttack;
gi.linkentity(self);
self->monsterinfo.currentmove = &boss2_move_stand;
self->monsterinfo.scale = MODEL_SCALE;
flymonster_start(self);
}

View file

@ -1,209 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Animations for boss2.
*
* =======================================================================
*/
#define FRAME_stand30 0
#define FRAME_stand31 1
#define FRAME_stand32 2
#define FRAME_stand33 3
#define FRAME_stand34 4
#define FRAME_stand35 5
#define FRAME_stand36 6
#define FRAME_stand37 7
#define FRAME_stand38 8
#define FRAME_stand39 9
#define FRAME_stand40 10
#define FRAME_stand41 11
#define FRAME_stand42 12
#define FRAME_stand43 13
#define FRAME_stand44 14
#define FRAME_stand45 15
#define FRAME_stand46 16
#define FRAME_stand47 17
#define FRAME_stand48 18
#define FRAME_stand49 19
#define FRAME_stand50 20
#define FRAME_stand1 21
#define FRAME_stand2 22
#define FRAME_stand3 23
#define FRAME_stand4 24
#define FRAME_stand5 25
#define FRAME_stand6 26
#define FRAME_stand7 27
#define FRAME_stand8 28
#define FRAME_stand9 29
#define FRAME_stand10 30
#define FRAME_stand11 31
#define FRAME_stand12 32
#define FRAME_stand13 33
#define FRAME_stand14 34
#define FRAME_stand15 35
#define FRAME_stand16 36
#define FRAME_stand17 37
#define FRAME_stand18 38
#define FRAME_stand19 39
#define FRAME_stand20 40
#define FRAME_stand21 41
#define FRAME_stand22 42
#define FRAME_stand23 43
#define FRAME_stand24 44
#define FRAME_stand25 45
#define FRAME_stand26 46
#define FRAME_stand27 47
#define FRAME_stand28 48
#define FRAME_stand29 49
#define FRAME_walk1 50
#define FRAME_walk2 51
#define FRAME_walk3 52
#define FRAME_walk4 53
#define FRAME_walk5 54
#define FRAME_walk6 55
#define FRAME_walk7 56
#define FRAME_walk8 57
#define FRAME_walk9 58
#define FRAME_walk10 59
#define FRAME_walk11 60
#define FRAME_walk12 61
#define FRAME_walk13 62
#define FRAME_walk14 63
#define FRAME_walk15 64
#define FRAME_walk16 65
#define FRAME_walk17 66
#define FRAME_walk18 67
#define FRAME_walk19 68
#define FRAME_walk20 69
#define FRAME_attack1 70
#define FRAME_attack2 71
#define FRAME_attack3 72
#define FRAME_attack4 73
#define FRAME_attack5 74
#define FRAME_attack6 75
#define FRAME_attack7 76
#define FRAME_attack8 77
#define FRAME_attack9 78
#define FRAME_attack10 79
#define FRAME_attack11 80
#define FRAME_attack12 81
#define FRAME_attack13 82
#define FRAME_attack14 83
#define FRAME_attack15 84
#define FRAME_attack16 85
#define FRAME_attack17 86
#define FRAME_attack18 87
#define FRAME_attack19 88
#define FRAME_attack20 89
#define FRAME_attack21 90
#define FRAME_attack22 91
#define FRAME_attack23 92
#define FRAME_attack24 93
#define FRAME_attack25 94
#define FRAME_attack26 95
#define FRAME_attack27 96
#define FRAME_attack28 97
#define FRAME_attack29 98
#define FRAME_attack30 99
#define FRAME_attack31 100
#define FRAME_attack32 101
#define FRAME_attack33 102
#define FRAME_attack34 103
#define FRAME_attack35 104
#define FRAME_attack36 105
#define FRAME_attack37 106
#define FRAME_attack38 107
#define FRAME_attack39 108
#define FRAME_attack40 109
#define FRAME_pain2 110
#define FRAME_pain3 111
#define FRAME_pain4 112
#define FRAME_pain5 113
#define FRAME_pain6 114
#define FRAME_pain7 115
#define FRAME_pain8 116
#define FRAME_pain9 117
#define FRAME_pain10 118
#define FRAME_pain11 119
#define FRAME_pain12 120
#define FRAME_pain13 121
#define FRAME_pain14 122
#define FRAME_pain15 123
#define FRAME_pain16 124
#define FRAME_pain17 125
#define FRAME_pain18 126
#define FRAME_pain19 127
#define FRAME_pain20 128
#define FRAME_pain21 129
#define FRAME_pain22 130
#define FRAME_pain23 131
#define FRAME_death2 132
#define FRAME_death3 133
#define FRAME_death4 134
#define FRAME_death5 135
#define FRAME_death6 136
#define FRAME_death7 137
#define FRAME_death8 138
#define FRAME_death9 139
#define FRAME_death10 140
#define FRAME_death11 141
#define FRAME_death12 142
#define FRAME_death13 143
#define FRAME_death14 144
#define FRAME_death15 145
#define FRAME_death16 146
#define FRAME_death17 147
#define FRAME_death18 148
#define FRAME_death19 149
#define FRAME_death20 150
#define FRAME_death21 151
#define FRAME_death22 152
#define FRAME_death23 153
#define FRAME_death24 154
#define FRAME_death25 155
#define FRAME_death26 156
#define FRAME_death27 157
#define FRAME_death28 158
#define FRAME_death29 159
#define FRAME_death30 160
#define FRAME_death31 161
#define FRAME_death32 162
#define FRAME_death33 163
#define FRAME_death34 164
#define FRAME_death35 165
#define FRAME_death36 166
#define FRAME_death37 167
#define FRAME_death38 168
#define FRAME_death39 169
#define FRAME_death40 170
#define FRAME_death41 171
#define FRAME_death42 172
#define FRAME_death43 173
#define FRAME_death44 174
#define FRAME_death45 175
#define FRAME_death46 176
#define FRAME_death47 177
#define FRAME_death48 178
#define FRAME_death49 179
#define FRAME_death50 180
#define MODEL_SCALE 1.000000

View file

@ -1,796 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Brain.
*
* =======================================================================
*/
#include "../../header/local.h"
#include "brain.h"
static int sound_chest_open;
static int sound_tentacles_extend;
static int sound_tentacles_retract;
static int sound_death;
static int sound_idle1;
static int sound_idle2;
static int sound_idle3;
static int sound_pain1;
static int sound_pain2;
static int sound_sight;
static int sound_search;
static int sound_melee1;
static int sound_melee2;
static int sound_melee3;
void brain_run(edict_t *self);
void brain_dead(edict_t *self);
void
brain_sight(edict_t *self, edict_t *other /* unused */)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
void
brain_search(edict_t *self)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
}
/* STAND */
static mframe_t brain_frames_stand[] = {
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL}
};
mmove_t brain_move_stand = {
FRAME_stand01,
FRAME_stand30,
brain_frames_stand,
NULL
};
void
brain_stand(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &brain_move_stand;
}
/* IDLE */
static mframe_t brain_frames_idle[] = {
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL}
};
mmove_t brain_move_idle = {
FRAME_stand31,
FRAME_stand60,
brain_frames_idle,
brain_stand
};
void
brain_idle(edict_t *self)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_AUTO, sound_idle3, 1, ATTN_IDLE, 0);
self->monsterinfo.currentmove = &brain_move_idle;
}
/* WALK */
static mframe_t brain_frames_walk1[] = {
{ai_walk, 7, NULL},
{ai_walk, 2, NULL},
{ai_walk, 3, NULL},
{ai_walk, 3, NULL},
{ai_walk, 1, NULL},
{ai_walk, 0, NULL},
{ai_walk, 0, NULL},
{ai_walk, 9, NULL},
{ai_walk, -4, NULL},
{ai_walk, -1, NULL},
{ai_walk, 2, NULL}
};
mmove_t brain_move_walk1 = {
FRAME_walk101,
FRAME_walk111,
brain_frames_walk1,
NULL
};
void
brain_walk(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &brain_move_walk1;
}
static mframe_t brain_frames_defense[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t brain_move_defense = {
FRAME_defens01,
FRAME_defens08,
brain_frames_defense,
NULL
};
static mframe_t brain_frames_pain3[] = {
{ai_move, -2, NULL},
{ai_move, 2, NULL},
{ai_move, 1, NULL},
{ai_move, 3, NULL},
{ai_move, 0, NULL},
{ai_move, -4, NULL}
};
mmove_t brain_move_pain3 = {
FRAME_pain301,
FRAME_pain306,
brain_frames_pain3,
brain_run
};
static mframe_t brain_frames_pain2[] = {
{ai_move, -2, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 3, NULL},
{ai_move, 1, NULL},
{ai_move, -2, NULL}
};
mmove_t brain_move_pain2 = {
FRAME_pain201,
FRAME_pain208,
brain_frames_pain2,
brain_run
};
static mframe_t brain_frames_pain1[] = {
{ai_move, -6, NULL},
{ai_move, -2, NULL},
{ai_move, -6, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 2, NULL},
{ai_move, 0, NULL},
{ai_move, 2, NULL},
{ai_move, 1, NULL},
{ai_move, 7, NULL},
{ai_move, 0, NULL},
{ai_move, 3, NULL},
{ai_move, -1, NULL}
};
mmove_t brain_move_pain1 = {
FRAME_pain101,
FRAME_pain121,
brain_frames_pain1,
brain_run
};
static mframe_t brain_frames_duck[] = {
{ai_move, 0, NULL},
{ai_move, -2, monster_duck_down},
{ai_move, 17, monster_duck_hold},
{ai_move, -3, NULL},
{ai_move, -1, monster_duck_up},
{ai_move, -5, NULL},
{ai_move, -6, NULL},
{ai_move, -6, NULL}
};
mmove_t brain_move_duck = {
FRAME_duck01,
FRAME_duck08,
brain_frames_duck,
brain_run
};
static mframe_t brain_frames_death2[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 9, NULL},
{ai_move, 0, NULL}
};
mmove_t brain_move_death2 = {
FRAME_death201,
FRAME_death205,
brain_frames_death2,
brain_dead
};
static mframe_t brain_frames_death1[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, -2, NULL},
{ai_move, 9, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t brain_move_death1 = {
FRAME_death101,
FRAME_death118,
brain_frames_death1,
brain_dead
};
/* MELEE */
void
brain_swing_right(edict_t *self)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_BODY, sound_melee1, 1, ATTN_NORM, 0);
}
void
brain_hit_right(edict_t *self)
{
vec3_t aim;
if (!self)
{
return;
}
VectorSet(aim, MELEE_DISTANCE, self->maxs[0], 8);
if (fire_hit(self, aim, (15 + (rand() % 5)), 40))
{
gi.sound(self, CHAN_WEAPON, sound_melee3, 1, ATTN_NORM, 0);
}
}
void
brain_swing_left(edict_t *self)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_BODY, sound_melee2, 1, ATTN_NORM, 0);
}
void
brain_hit_left(edict_t *self)
{
if (!self)
{
return;
}
vec3_t aim;
VectorSet(aim, MELEE_DISTANCE, self->mins[0], 8);
if (fire_hit(self, aim, (15 + (rand() % 5)), 40))
{
gi.sound(self, CHAN_WEAPON, sound_melee3, 1, ATTN_NORM, 0);
}
}
static mframe_t brain_frames_attack1[] = {
{ai_charge, 8, NULL},
{ai_charge, 3, NULL},
{ai_charge, 5, NULL},
{ai_charge, 0, NULL},
{ai_charge, -3, brain_swing_right},
{ai_charge, 0, NULL},
{ai_charge, -5, NULL},
{ai_charge, -7, brain_hit_right},
{ai_charge, 0, NULL},
{ai_charge, 6, brain_swing_left},
{ai_charge, 1, NULL},
{ai_charge, 2, brain_hit_left},
{ai_charge, -3, NULL},
{ai_charge, 6, NULL},
{ai_charge, -1, NULL},
{ai_charge, -3, NULL},
{ai_charge, 2, NULL},
{ai_charge, -11, NULL}
};
mmove_t brain_move_attack1 = {
FRAME_attak101,
FRAME_attak118,
brain_frames_attack1,
brain_run
};
void
brain_chest_open(edict_t *self)
{
if (!self)
{
return;
}
self->spawnflags &= ~65536;
self->monsterinfo.power_armor_type = POWER_ARMOR_NONE;
gi.sound(self, CHAN_BODY, sound_chest_open, 1, ATTN_NORM, 0);
}
void
brain_tentacle_attack(edict_t *self)
{
vec3_t aim;
if (!self)
{
return;
}
VectorSet(aim, MELEE_DISTANCE, 0, 8);
if (fire_hit(self, aim, (10 + (rand() % 5)), -600) && (skill->value > 0))
{
self->spawnflags |= 65536;
}
gi.sound(self, CHAN_WEAPON, sound_tentacles_retract, 1, ATTN_NORM, 0);
}
void
brain_chest_closed(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN;
if (self->spawnflags & 65536)
{
self->spawnflags &= ~65536;
self->monsterinfo.currentmove = &brain_move_attack1;
}
}
static mframe_t brain_frames_attack2[] = {
{ai_charge, 5, NULL},
{ai_charge, -4, NULL},
{ai_charge, -4, NULL},
{ai_charge, -3, NULL},
{ai_charge, 0, brain_chest_open},
{ai_charge, 0, NULL},
{ai_charge, 13, brain_tentacle_attack},
{ai_charge, 0, NULL},
{ai_charge, 2, NULL},
{ai_charge, 0, NULL},
{ai_charge, -9, brain_chest_closed},
{ai_charge, 0, NULL},
{ai_charge, 4, NULL},
{ai_charge, 3, NULL},
{ai_charge, 2, NULL},
{ai_charge, -3, NULL},
{ai_charge, -6, NULL}
};
mmove_t brain_move_attack2 = {
FRAME_attak201,
FRAME_attak217,
brain_frames_attack2,
brain_run
};
void
brain_melee(edict_t *self)
{
if (!self)
{
return;
}
if (random() <= 0.5)
{
self->monsterinfo.currentmove = &brain_move_attack1;
}
else
{
self->monsterinfo.currentmove = &brain_move_attack2;
}
}
/* RUN */
static mframe_t brain_frames_run[] = {
{ai_run, 9, NULL},
{ai_run, 2, NULL},
{ai_run, 3, NULL},
{ai_run, 3, NULL},
{ai_run, 1, NULL},
{ai_run, 0, NULL},
{ai_run, 0, NULL},
{ai_run, 10, NULL},
{ai_run, -4, NULL},
{ai_run, -1, NULL},
{ai_run, 2, NULL}
};
mmove_t brain_move_run = {
FRAME_walk101,
FRAME_walk111,
brain_frames_run,
NULL
};
void
brain_run(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN;
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
{
self->monsterinfo.currentmove = &brain_move_stand;
}
else
{
self->monsterinfo.currentmove = &brain_move_run;
}
}
void
brain_pain(edict_t *self, edict_t *other /* unused */, float kick /* unused */,
int damage /* unused */)
{
float r;
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
{
self->s.skinnum = 1;
}
if (level.time < self->pain_debounce_time)
{
return;
}
self->pain_debounce_time = level.time + 3;
if (skill->value == SKILL_HARDPLUS)
{
return; /* no pain anims in nightmare */
}
r = random();
if (r < 0.33)
{
gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &brain_move_pain1;
}
else if (r < 0.66)
{
gi.sound(self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &brain_move_pain2;
}
else
{
gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &brain_move_pain3;
}
/* clear duck flag */
if (self->monsterinfo.aiflags & AI_DUCKED)
{
monster_duck_up(self);
}
}
void
brain_dead(edict_t *self)
{
if (!self)
{
return;
}
VectorSet(self->mins, -16, -16, -24);
VectorSet(self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
self->svflags |= SVF_DEADMONSTER;
self->nextthink = 0;
gi.linkentity(self);
}
void
brain_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
int damage, vec3_t point /* unused */)
{
int n;
if (!self)
{
return;
}
self->s.effects = 0;
self->monsterinfo.power_armor_type = POWER_ARMOR_NONE;
/* check for gib */
if (self->health <= self->gib_health)
{
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
for (n = 0; n < 2; n++)
{
ThrowGib(self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
}
for (n = 0; n < 4; n++)
{
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
}
ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
self->deadflag = DEAD_DEAD;
return;
}
if (self->deadflag == DEAD_DEAD)
{
return;
}
/* regular death */
gi.sound(self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
self->deadflag = DEAD_DEAD;
self->takedamage = DAMAGE_YES;
if (random() <= 0.5)
{
self->monsterinfo.currentmove = &brain_move_death1;
}
else
{
self->monsterinfo.currentmove = &brain_move_death2;
}
}
void
brain_duck(edict_t *self, float eta)
{
if (!self)
{
return;
}
/* has to be done immediately otherwise he can get stuck */
monster_duck_down(self);
if (skill->value == SKILL_EASY)
{
/* PMM - stupid dodge */
self->monsterinfo.duck_wait_time = level.time + eta + 1;
}
else
{
self->monsterinfo.duck_wait_time = level.time + eta + (0.1 * (3 - skill->value));
}
self->monsterinfo.currentmove = &brain_move_duck;
self->monsterinfo.nextframe = FRAME_duck01;
return;
}
/*
* QUAKED monster_brain (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
*/
void
SP_monster_brain(edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict(self);
return;
}
sound_chest_open = gi.soundindex("brain/brnatck1.wav");
sound_tentacles_extend = gi.soundindex("brain/brnatck2.wav");
sound_tentacles_retract = gi.soundindex("brain/brnatck3.wav");
sound_death = gi.soundindex("brain/brndeth1.wav");
sound_idle1 = gi.soundindex("brain/brnidle1.wav");
sound_idle2 = gi.soundindex("brain/brnidle2.wav");
sound_idle3 = gi.soundindex("brain/brnlens1.wav");
sound_pain1 = gi.soundindex("brain/brnpain1.wav");
sound_pain2 = gi.soundindex("brain/brnpain2.wav");
sound_sight = gi.soundindex("brain/brnsght1.wav");
sound_search = gi.soundindex("brain/brnsrch1.wav");
sound_melee1 = gi.soundindex("brain/melee1.wav");
sound_melee2 = gi.soundindex("brain/melee2.wav");
sound_melee3 = gi.soundindex("brain/melee3.wav");
self->movetype = MOVETYPE_STEP;
self->solid = SOLID_BBOX;
self->s.modelindex = gi.modelindex("models/monsters/brain/tris.md2");
VectorSet(self->mins, -16, -16, -24);
VectorSet(self->maxs, 16, 16, 32);
self->health = 300;
self->gib_health = -150;
self->mass = 400;
self->pain = brain_pain;
self->die = brain_die;
self->monsterinfo.stand = brain_stand;
self->monsterinfo.walk = brain_walk;
self->monsterinfo.run = brain_run;
self->monsterinfo.dodge = M_MonsterDodge;
self->monsterinfo.duck = brain_duck;
self->monsterinfo.unduck = monster_duck_up;
self->monsterinfo.melee = brain_melee;
self->monsterinfo.sight = brain_sight;
self->monsterinfo.search = brain_search;
self->monsterinfo.idle = brain_idle;
self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN;
self->monsterinfo.power_armor_power = 100;
gi.linkentity(self);
self->monsterinfo.currentmove = &brain_move_stand;
self->monsterinfo.scale = MODEL_SCALE;
walkmonster_start(self);
}

View file

@ -1,251 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Brain animations.
*
* =======================================================================
*
*/
#define FRAME_walk101 0
#define FRAME_walk102 1
#define FRAME_walk103 2
#define FRAME_walk104 3
#define FRAME_walk105 4
#define FRAME_walk106 5
#define FRAME_walk107 6
#define FRAME_walk108 7
#define FRAME_walk109 8
#define FRAME_walk110 9
#define FRAME_walk111 10
#define FRAME_walk112 11
#define FRAME_walk113 12
#define FRAME_walk201 13
#define FRAME_walk202 14
#define FRAME_walk203 15
#define FRAME_walk204 16
#define FRAME_walk205 17
#define FRAME_walk206 18
#define FRAME_walk207 19
#define FRAME_walk208 20
#define FRAME_walk209 21
#define FRAME_walk210 22
#define FRAME_walk211 23
#define FRAME_walk212 24
#define FRAME_walk213 25
#define FRAME_walk214 26
#define FRAME_walk215 27
#define FRAME_walk216 28
#define FRAME_walk217 29
#define FRAME_walk218 30
#define FRAME_walk219 31
#define FRAME_walk220 32
#define FRAME_walk221 33
#define FRAME_walk222 34
#define FRAME_walk223 35
#define FRAME_walk224 36
#define FRAME_walk225 37
#define FRAME_walk226 38
#define FRAME_walk227 39
#define FRAME_walk228 40
#define FRAME_walk229 41
#define FRAME_walk230 42
#define FRAME_walk231 43
#define FRAME_walk232 44
#define FRAME_walk233 45
#define FRAME_walk234 46
#define FRAME_walk235 47
#define FRAME_walk236 48
#define FRAME_walk237 49
#define FRAME_walk238 50
#define FRAME_walk239 51
#define FRAME_walk240 52
#define FRAME_attak101 53
#define FRAME_attak102 54
#define FRAME_attak103 55
#define FRAME_attak104 56
#define FRAME_attak105 57
#define FRAME_attak106 58
#define FRAME_attak107 59
#define FRAME_attak108 60
#define FRAME_attak109 61
#define FRAME_attak110 62
#define FRAME_attak111 63
#define FRAME_attak112 64
#define FRAME_attak113 65
#define FRAME_attak114 66
#define FRAME_attak115 67
#define FRAME_attak116 68
#define FRAME_attak117 69
#define FRAME_attak118 70
#define FRAME_attak201 71
#define FRAME_attak202 72
#define FRAME_attak203 73
#define FRAME_attak204 74
#define FRAME_attak205 75
#define FRAME_attak206 76
#define FRAME_attak207 77
#define FRAME_attak208 78
#define FRAME_attak209 79
#define FRAME_attak210 80
#define FRAME_attak211 81
#define FRAME_attak212 82
#define FRAME_attak213 83
#define FRAME_attak214 84
#define FRAME_attak215 85
#define FRAME_attak216 86
#define FRAME_attak217 87
#define FRAME_pain101 88
#define FRAME_pain102 89
#define FRAME_pain103 90
#define FRAME_pain104 91
#define FRAME_pain105 92
#define FRAME_pain106 93
#define FRAME_pain107 94
#define FRAME_pain108 95
#define FRAME_pain109 96
#define FRAME_pain110 97
#define FRAME_pain111 98
#define FRAME_pain112 99
#define FRAME_pain113 100
#define FRAME_pain114 101
#define FRAME_pain115 102
#define FRAME_pain116 103
#define FRAME_pain117 104
#define FRAME_pain118 105
#define FRAME_pain119 106
#define FRAME_pain120 107
#define FRAME_pain121 108
#define FRAME_pain201 109
#define FRAME_pain202 110
#define FRAME_pain203 111
#define FRAME_pain204 112
#define FRAME_pain205 113
#define FRAME_pain206 114
#define FRAME_pain207 115
#define FRAME_pain208 116
#define FRAME_pain301 117
#define FRAME_pain302 118
#define FRAME_pain303 119
#define FRAME_pain304 120
#define FRAME_pain305 121
#define FRAME_pain306 122
#define FRAME_death101 123
#define FRAME_death102 124
#define FRAME_death103 125
#define FRAME_death104 126
#define FRAME_death105 127
#define FRAME_death106 128
#define FRAME_death107 129
#define FRAME_death108 130
#define FRAME_death109 131
#define FRAME_death110 132
#define FRAME_death111 133
#define FRAME_death112 134
#define FRAME_death113 135
#define FRAME_death114 136
#define FRAME_death115 137
#define FRAME_death116 138
#define FRAME_death117 139
#define FRAME_death118 140
#define FRAME_death201 141
#define FRAME_death202 142
#define FRAME_death203 143
#define FRAME_death204 144
#define FRAME_death205 145
#define FRAME_duck01 146
#define FRAME_duck02 147
#define FRAME_duck03 148
#define FRAME_duck04 149
#define FRAME_duck05 150
#define FRAME_duck06 151
#define FRAME_duck07 152
#define FRAME_duck08 153
#define FRAME_defens01 154
#define FRAME_defens02 155
#define FRAME_defens03 156
#define FRAME_defens04 157
#define FRAME_defens05 158
#define FRAME_defens06 159
#define FRAME_defens07 160
#define FRAME_defens08 161
#define FRAME_stand01 162
#define FRAME_stand02 163
#define FRAME_stand03 164
#define FRAME_stand04 165
#define FRAME_stand05 166
#define FRAME_stand06 167
#define FRAME_stand07 168
#define FRAME_stand08 169
#define FRAME_stand09 170
#define FRAME_stand10 171
#define FRAME_stand11 172
#define FRAME_stand12 173
#define FRAME_stand13 174
#define FRAME_stand14 175
#define FRAME_stand15 176
#define FRAME_stand16 177
#define FRAME_stand17 178
#define FRAME_stand18 179
#define FRAME_stand19 180
#define FRAME_stand20 181
#define FRAME_stand21 182
#define FRAME_stand22 183
#define FRAME_stand23 184
#define FRAME_stand24 185
#define FRAME_stand25 186
#define FRAME_stand26 187
#define FRAME_stand27 188
#define FRAME_stand28 189
#define FRAME_stand29 190
#define FRAME_stand30 191
#define FRAME_stand31 192
#define FRAME_stand32 193
#define FRAME_stand33 194
#define FRAME_stand34 195
#define FRAME_stand35 196
#define FRAME_stand36 197
#define FRAME_stand37 198
#define FRAME_stand38 199
#define FRAME_stand39 200
#define FRAME_stand40 201
#define FRAME_stand41 202
#define FRAME_stand42 203
#define FRAME_stand43 204
#define FRAME_stand44 205
#define FRAME_stand45 206
#define FRAME_stand46 207
#define FRAME_stand47 208
#define FRAME_stand48 209
#define FRAME_stand49 210
#define FRAME_stand50 211
#define FRAME_stand51 212
#define FRAME_stand52 213
#define FRAME_stand53 214
#define FRAME_stand54 215
#define FRAME_stand55 216
#define FRAME_stand56 217
#define FRAME_stand57 218
#define FRAME_stand58 219
#define FRAME_stand59 220
#define FRAME_stand60 221
#define MODEL_SCALE 1.000000

View file

@ -1,316 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Iron Maiden animations.
*
* =======================================================================
*/
#define FRAME_attak101 0
#define FRAME_attak102 1
#define FRAME_attak103 2
#define FRAME_attak104 3
#define FRAME_attak105 4
#define FRAME_attak106 5
#define FRAME_attak107 6
#define FRAME_attak108 7
#define FRAME_attak109 8
#define FRAME_attak110 9
#define FRAME_attak111 10
#define FRAME_attak112 11
#define FRAME_attak113 12
#define FRAME_attak114 13
#define FRAME_attak115 14
#define FRAME_attak116 15
#define FRAME_attak117 16
#define FRAME_attak118 17
#define FRAME_attak119 18
#define FRAME_attak120 19
#define FRAME_attak121 20
#define FRAME_attak122 21
#define FRAME_attak123 22
#define FRAME_attak124 23
#define FRAME_attak125 24
#define FRAME_attak126 25
#define FRAME_attak127 26
#define FRAME_attak128 27
#define FRAME_attak129 28
#define FRAME_attak130 29
#define FRAME_attak131 30
#define FRAME_attak132 31
#define FRAME_attak201 32
#define FRAME_attak202 33
#define FRAME_attak203 34
#define FRAME_attak204 35
#define FRAME_attak205 36
#define FRAME_attak206 37
#define FRAME_attak207 38
#define FRAME_attak208 39
#define FRAME_attak209 40
#define FRAME_attak210 41
#define FRAME_attak211 42
#define FRAME_attak212 43
#define FRAME_attak213 44
#define FRAME_attak214 45
#define FRAME_attak215 46
#define FRAME_attak216 47
#define FRAME_death101 48
#define FRAME_death102 49
#define FRAME_death103 50
#define FRAME_death104 51
#define FRAME_death105 52
#define FRAME_death106 53
#define FRAME_death107 54
#define FRAME_death108 55
#define FRAME_death109 56
#define FRAME_death110 57
#define FRAME_death111 58
#define FRAME_death112 59
#define FRAME_death201 60
#define FRAME_death202 61
#define FRAME_death203 62
#define FRAME_death204 63
#define FRAME_death205 64
#define FRAME_death206 65
#define FRAME_death207 66
#define FRAME_death208 67
#define FRAME_death209 68
#define FRAME_death210 69
#define FRAME_death211 70
#define FRAME_death212 71
#define FRAME_death213 72
#define FRAME_death214 73
#define FRAME_death215 74
#define FRAME_death216 75
#define FRAME_death217 76
#define FRAME_death218 77
#define FRAME_death219 78
#define FRAME_death220 79
#define FRAME_death221 80
#define FRAME_death222 81
#define FRAME_death223 82
#define FRAME_duck01 83
#define FRAME_duck02 84
#define FRAME_duck03 85
#define FRAME_duck04 86
#define FRAME_duck05 87
#define FRAME_duck06 88
#define FRAME_duck07 89
#define FRAME_pain101 90
#define FRAME_pain102 91
#define FRAME_pain103 92
#define FRAME_pain104 93
#define FRAME_pain105 94
#define FRAME_pain201 95
#define FRAME_pain202 96
#define FRAME_pain203 97
#define FRAME_pain204 98
#define FRAME_pain205 99
#define FRAME_pain301 100
#define FRAME_pain302 101
#define FRAME_pain303 102
#define FRAME_pain304 103
#define FRAME_pain305 104
#define FRAME_pain306 105
#define FRAME_pain307 106
#define FRAME_pain308 107
#define FRAME_pain309 108
#define FRAME_pain310 109
#define FRAME_pain311 110
#define FRAME_pain312 111
#define FRAME_pain313 112
#define FRAME_pain314 113
#define FRAME_pain315 114
#define FRAME_pain316 115
#define FRAME_pain317 116
#define FRAME_pain318 117
#define FRAME_pain319 118
#define FRAME_pain320 119
#define FRAME_pain321 120
#define FRAME_stand101 121
#define FRAME_stand102 122
#define FRAME_stand103 123
#define FRAME_stand104 124
#define FRAME_stand105 125
#define FRAME_stand106 126
#define FRAME_stand107 127
#define FRAME_stand108 128
#define FRAME_stand109 129
#define FRAME_stand110 130
#define FRAME_stand111 131
#define FRAME_stand112 132
#define FRAME_stand113 133
#define FRAME_stand114 134
#define FRAME_stand115 135
#define FRAME_stand116 136
#define FRAME_stand117 137
#define FRAME_stand118 138
#define FRAME_stand119 139
#define FRAME_stand120 140
#define FRAME_stand121 141
#define FRAME_stand122 142
#define FRAME_stand123 143
#define FRAME_stand124 144
#define FRAME_stand125 145
#define FRAME_stand126 146
#define FRAME_stand127 147
#define FRAME_stand128 148
#define FRAME_stand129 149
#define FRAME_stand130 150
#define FRAME_stand201 151
#define FRAME_stand202 152
#define FRAME_stand203 153
#define FRAME_stand204 154
#define FRAME_stand205 155
#define FRAME_stand206 156
#define FRAME_stand207 157
#define FRAME_stand208 158
#define FRAME_stand209 159
#define FRAME_stand210 160
#define FRAME_stand211 161
#define FRAME_stand212 162
#define FRAME_stand213 163
#define FRAME_stand214 164
#define FRAME_stand215 165
#define FRAME_stand216 166
#define FRAME_stand217 167
#define FRAME_stand218 168
#define FRAME_stand219 169
#define FRAME_stand220 170
#define FRAME_stand221 171
#define FRAME_stand222 172
#define FRAME_stand223 173
#define FRAME_stand224 174
#define FRAME_stand225 175
#define FRAME_stand226 176
#define FRAME_stand227 177
#define FRAME_stand228 178
#define FRAME_stand229 179
#define FRAME_stand230 180
#define FRAME_walk01 181
#define FRAME_walk02 182
#define FRAME_walk03 183
#define FRAME_walk04 184
#define FRAME_walk05 185
#define FRAME_walk06 186
#define FRAME_walk07 187
#define FRAME_walk08 188
#define FRAME_walk09 189
#define FRAME_walk10 190
#define FRAME_walk11 191
#define FRAME_walk12 192
#define FRAME_walk13 193
#define FRAME_walk14 194
#define FRAME_walk15 195
#define FRAME_walk16 196
#define FRAME_walk17 197
#define FRAME_walk18 198
#define FRAME_walk19 199
#define FRAME_walk20 200
#define FRAME_walk21 201
#define FRAME_walk22 202
#define FRAME_walk23 203
#define FRAME_walk24 204
#define FRAME_walk25 205
#define FRAME_walk26 206
#define FRAME_walk27 207
#define FRAME_recln201 208
#define FRAME_recln202 209
#define FRAME_recln203 210
#define FRAME_recln204 211
#define FRAME_recln205 212
#define FRAME_recln206 213
#define FRAME_recln207 214
#define FRAME_recln208 215
#define FRAME_recln209 216
#define FRAME_recln210 217
#define FRAME_recln211 218
#define FRAME_recln212 219
#define FRAME_recln213 220
#define FRAME_recln214 221
#define FRAME_recln215 222
#define FRAME_recln216 223
#define FRAME_recln217 224
#define FRAME_recln218 225
#define FRAME_recln219 226
#define FRAME_recln220 227
#define FRAME_recln221 228
#define FRAME_recln222 229
#define FRAME_recln223 230
#define FRAME_recln224 231
#define FRAME_recln225 232
#define FRAME_recln226 233
#define FRAME_recln227 234
#define FRAME_recln228 235
#define FRAME_recln229 236
#define FRAME_recln230 237
#define FRAME_recln231 238
#define FRAME_recln232 239
#define FRAME_recln233 240
#define FRAME_recln234 241
#define FRAME_recln235 242
#define FRAME_recln236 243
#define FRAME_recln237 244
#define FRAME_recln238 245
#define FRAME_recln239 246
#define FRAME_recln240 247
#define FRAME_recln101 248
#define FRAME_recln102 249
#define FRAME_recln103 250
#define FRAME_recln104 251
#define FRAME_recln105 252
#define FRAME_recln106 253
#define FRAME_recln107 254
#define FRAME_recln108 255
#define FRAME_recln109 256
#define FRAME_recln110 257
#define FRAME_recln111 258
#define FRAME_recln112 259
#define FRAME_recln113 260
#define FRAME_recln114 261
#define FRAME_recln115 262
#define FRAME_recln116 263
#define FRAME_recln117 264
#define FRAME_recln118 265
#define FRAME_recln119 266
#define FRAME_recln120 267
#define FRAME_recln121 268
#define FRAME_recln122 269
#define FRAME_recln123 270
#define FRAME_recln124 271
#define FRAME_recln125 272
#define FRAME_recln126 273
#define FRAME_recln127 274
#define FRAME_recln128 275
#define FRAME_recln129 276
#define FRAME_recln130 277
#define FRAME_recln131 278
#define FRAME_recln132 279
#define FRAME_recln133 280
#define FRAME_recln134 281
#define FRAME_recln135 282
#define FRAME_recln136 283
#define FRAME_recln137 284
#define FRAME_recln138 285
#define FRAME_recln139 286
#define FRAME_recln140 287
#define MODEL_SCALE 1.000000

View file

@ -1,552 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Baracuda Shark.
*
* =======================================================================
*/
#include "../../header/local.h"
#include "flipper.h"
#define FLIPPER_RUN_SPEED 24
static int sound_chomp;
static int sound_attack;
static int sound_pain1;
static int sound_pain2;
static int sound_death;
static int sound_idle;
static int sound_search;
static int sound_sight;
void flipper_stand(edict_t *self);
static mframe_t flipper_frames_stand[] = {
{ai_stand, 0, NULL}
};
mmove_t flipper_move_stand = {
FRAME_flphor01,
FRAME_flphor01,
flipper_frames_stand,
NULL
};
void
flipper_stand(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flipper_move_stand;
}
static mframe_t flipper_frames_run[] = {
{ai_run, FLIPPER_RUN_SPEED, NULL}, /* 6 */
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL}, /* 10 */
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL}, /* 20 */
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL},
{ai_run, FLIPPER_RUN_SPEED, NULL} /* 29 */
};
mmove_t flipper_move_run_loop = {
FRAME_flpver06,
FRAME_flpver29,
flipper_frames_run,
NULL
};
void
flipper_run_loop(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flipper_move_run_loop;
}
static mframe_t flipper_frames_run_start[] = {
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL}
};
mmove_t flipper_move_run_start = {
FRAME_flpver01,
FRAME_flpver06,
flipper_frames_run_start,
flipper_run_loop
};
void
flipper_run(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flipper_move_run_start;
}
/* Standard Swimming */
static mframe_t flipper_frames_walk[] = {
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL}
};
mmove_t flipper_move_walk = {
FRAME_flphor01,
FRAME_flphor24,
flipper_frames_walk,
NULL
};
void
flipper_walk(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flipper_move_walk;
}
static mframe_t flipper_frames_start_run[] = {
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, NULL},
{ai_run, 8, flipper_run}
};
mmove_t flipper_move_start_run = {
FRAME_flphor01,
FRAME_flphor05,
flipper_frames_start_run,
NULL
};
void
flipper_start_run(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flipper_move_start_run;
}
static mframe_t flipper_frames_pain2[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t flipper_move_pain2 = {
FRAME_flppn101,
FRAME_flppn105,
flipper_frames_pain2,
flipper_run
};
static mframe_t flipper_frames_pain1[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t flipper_move_pain1 = {
FRAME_flppn201,
FRAME_flppn205,
flipper_frames_pain1,
flipper_run
};
void
flipper_bite(edict_t *self)
{
vec3_t aim;
if (!self)
{
return;
}
VectorSet(aim, MELEE_DISTANCE, 0, 0);
fire_hit(self, aim, 5, 0);
}
void
flipper_preattack(edict_t *self)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_WEAPON, sound_chomp, 1, ATTN_NORM, 0);
}
static mframe_t flipper_frames_attack[] = {
{ai_charge, 0, flipper_preattack},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, flipper_bite},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, flipper_bite},
{ai_charge, 0, NULL}
};
mmove_t flipper_move_attack = {
FRAME_flpbit01,
FRAME_flpbit20,
flipper_frames_attack,
flipper_run
};
void
flipper_melee(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &flipper_move_attack;
}
void
flipper_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
{
int n;
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
{
self->s.skinnum = 1;
}
if (level.time < self->pain_debounce_time)
{
return;
}
self->pain_debounce_time = level.time + 3;
if (skill->value == SKILL_HARDPLUS)
{
return; /* no pain anims in nightmare */
}
n = (rand() + 1) % 2;
if (n == 0)
{
gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &flipper_move_pain1;
}
else
{
gi.sound(self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &flipper_move_pain2;
}
}
void
flipper_dead(edict_t *self)
{
vec3_t p;
trace_t tr;
if (!self)
{
return;
}
/* original dead bbox was wrong - and make sure the bbox adjustment stays in solidity */
p[0] = self->s.origin[0];
p[1] = self->s.origin[1];
p[2] = self->s.origin[2] - 8;
tr = gi.trace(self->s.origin, self->mins, self->maxs, p, self, self->clipmask);
self->mins[2] = tr.endpos[2] - self->s.origin[2];
self->movetype = MOVETYPE_TOSS;
self->svflags |= SVF_DEADMONSTER;
self->nextthink = 0;
gi.linkentity(self);
}
static mframe_t flipper_frames_death[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t flipper_move_death = {
FRAME_flpdth01,
FRAME_flpdth56,
flipper_frames_death,
flipper_dead
};
void
flipper_sight(edict_t *self, edict_t *other /* unused */)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
void
flipper_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
int damage, vec3_t point /* unused */)
{
int n;
if (!self)
{
return;
}
/* check for gib */
if (self->health <= self->gib_health)
{
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
for (n = 0; n < 2; n++)
{
ThrowGib(self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
}
for (n = 0; n < 2; n++)
{
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
}
ThrowHead(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
self->deadflag = DEAD_DEAD;
return;
}
if (self->deadflag == DEAD_DEAD)
{
return;
}
/* regular death */
gi.sound(self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
self->deadflag = DEAD_DEAD;
self->takedamage = DAMAGE_YES;
self->monsterinfo.currentmove = &flipper_move_death;
}
/*
* QUAKED monster_flipper (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
*/
void
SP_monster_flipper(edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict(self);
return;
}
sound_pain1 = gi.soundindex("flipper/flppain1.wav");
sound_pain2 = gi.soundindex("flipper/flppain2.wav");
sound_death = gi.soundindex("flipper/flpdeth1.wav");
sound_chomp = gi.soundindex("flipper/flpatck1.wav");
sound_attack = gi.soundindex("flipper/flpatck2.wav");
sound_idle = gi.soundindex("flipper/flpidle1.wav");
sound_search = gi.soundindex("flipper/flpsrch1.wav");
sound_sight = gi.soundindex("flipper/flpsght1.wav");
self->movetype = MOVETYPE_STEP;
self->solid = SOLID_BBOX;
self->s.modelindex = gi.modelindex("models/monsters/flipper/tris.md2");
VectorSet(self->mins, -16, -16, 0);
VectorSet(self->maxs, 16, 16, 32);
self->health = 50;
self->gib_health = -30;
self->mass = 100;
self->pain = flipper_pain;
self->die = flipper_die;
self->monsterinfo.stand = flipper_stand;
self->monsterinfo.walk = flipper_walk;
self->monsterinfo.run = flipper_start_run;
self->monsterinfo.melee = flipper_melee;
self->monsterinfo.sight = flipper_sight;
gi.linkentity(self);
self->monsterinfo.currentmove = &flipper_move_stand;
self->monsterinfo.scale = MODEL_SCALE;
swimmonster_start(self);
}

View file

@ -1,188 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Baracuda Shark animations.
*
* =======================================================================
*/
#define FRAME_flpbit01 0
#define FRAME_flpbit02 1
#define FRAME_flpbit03 2
#define FRAME_flpbit04 3
#define FRAME_flpbit05 4
#define FRAME_flpbit06 5
#define FRAME_flpbit07 6
#define FRAME_flpbit08 7
#define FRAME_flpbit09 8
#define FRAME_flpbit10 9
#define FRAME_flpbit11 10
#define FRAME_flpbit12 11
#define FRAME_flpbit13 12
#define FRAME_flpbit14 13
#define FRAME_flpbit15 14
#define FRAME_flpbit16 15
#define FRAME_flpbit17 16
#define FRAME_flpbit18 17
#define FRAME_flpbit19 18
#define FRAME_flpbit20 19
#define FRAME_flptal01 20
#define FRAME_flptal02 21
#define FRAME_flptal03 22
#define FRAME_flptal04 23
#define FRAME_flptal05 24
#define FRAME_flptal06 25
#define FRAME_flptal07 26
#define FRAME_flptal08 27
#define FRAME_flptal09 28
#define FRAME_flptal10 29
#define FRAME_flptal11 30
#define FRAME_flptal12 31
#define FRAME_flptal13 32
#define FRAME_flptal14 33
#define FRAME_flptal15 34
#define FRAME_flptal16 35
#define FRAME_flptal17 36
#define FRAME_flptal18 37
#define FRAME_flptal19 38
#define FRAME_flptal20 39
#define FRAME_flptal21 40
#define FRAME_flphor01 41
#define FRAME_flphor02 42
#define FRAME_flphor03 43
#define FRAME_flphor04 44
#define FRAME_flphor05 45
#define FRAME_flphor06 46
#define FRAME_flphor07 47
#define FRAME_flphor08 48
#define FRAME_flphor09 49
#define FRAME_flphor10 50
#define FRAME_flphor11 51
#define FRAME_flphor12 52
#define FRAME_flphor13 53
#define FRAME_flphor14 54
#define FRAME_flphor15 55
#define FRAME_flphor16 56
#define FRAME_flphor17 57
#define FRAME_flphor18 58
#define FRAME_flphor19 59
#define FRAME_flphor20 60
#define FRAME_flphor21 61
#define FRAME_flphor22 62
#define FRAME_flphor23 63
#define FRAME_flphor24 64
#define FRAME_flpver01 65
#define FRAME_flpver02 66
#define FRAME_flpver03 67
#define FRAME_flpver04 68
#define FRAME_flpver05 69
#define FRAME_flpver06 70
#define FRAME_flpver07 71
#define FRAME_flpver08 72
#define FRAME_flpver09 73
#define FRAME_flpver10 74
#define FRAME_flpver11 75
#define FRAME_flpver12 76
#define FRAME_flpver13 77
#define FRAME_flpver14 78
#define FRAME_flpver15 79
#define FRAME_flpver16 80
#define FRAME_flpver17 81
#define FRAME_flpver18 82
#define FRAME_flpver19 83
#define FRAME_flpver20 84
#define FRAME_flpver21 85
#define FRAME_flpver22 86
#define FRAME_flpver23 87
#define FRAME_flpver24 88
#define FRAME_flpver25 89
#define FRAME_flpver26 90
#define FRAME_flpver27 91
#define FRAME_flpver28 92
#define FRAME_flpver29 93
#define FRAME_flppn101 94
#define FRAME_flppn102 95
#define FRAME_flppn103 96
#define FRAME_flppn104 97
#define FRAME_flppn105 98
#define FRAME_flppn201 99
#define FRAME_flppn202 100
#define FRAME_flppn203 101
#define FRAME_flppn204 102
#define FRAME_flppn205 103
#define FRAME_flpdth01 104
#define FRAME_flpdth02 105
#define FRAME_flpdth03 106
#define FRAME_flpdth04 107
#define FRAME_flpdth05 108
#define FRAME_flpdth06 109
#define FRAME_flpdth07 110
#define FRAME_flpdth08 111
#define FRAME_flpdth09 112
#define FRAME_flpdth10 113
#define FRAME_flpdth11 114
#define FRAME_flpdth12 115
#define FRAME_flpdth13 116
#define FRAME_flpdth14 117
#define FRAME_flpdth15 118
#define FRAME_flpdth16 119
#define FRAME_flpdth17 120
#define FRAME_flpdth18 121
#define FRAME_flpdth19 122
#define FRAME_flpdth20 123
#define FRAME_flpdth21 124
#define FRAME_flpdth22 125
#define FRAME_flpdth23 126
#define FRAME_flpdth24 127
#define FRAME_flpdth25 128
#define FRAME_flpdth26 129
#define FRAME_flpdth27 130
#define FRAME_flpdth28 131
#define FRAME_flpdth29 132
#define FRAME_flpdth30 133
#define FRAME_flpdth31 134
#define FRAME_flpdth32 135
#define FRAME_flpdth33 136
#define FRAME_flpdth34 137
#define FRAME_flpdth35 138
#define FRAME_flpdth36 139
#define FRAME_flpdth37 140
#define FRAME_flpdth38 141
#define FRAME_flpdth39 142
#define FRAME_flpdth40 143
#define FRAME_flpdth41 144
#define FRAME_flpdth42 145
#define FRAME_flpdth43 146
#define FRAME_flpdth44 147
#define FRAME_flpdth45 148
#define FRAME_flpdth46 149
#define FRAME_flpdth47 150
#define FRAME_flpdth48 151
#define FRAME_flpdth49 152
#define FRAME_flpdth50 153
#define FRAME_flpdth51 154
#define FRAME_flpdth52 155
#define FRAME_flpdth53 156
#define FRAME_flpdth54 157
#define FRAME_flpdth55 158
#define FRAME_flpdth56 159
#define MODEL_SCALE 1.000000

View file

@ -1,895 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Mechanic.
*
* =======================================================================
*/
#include "../../header/local.h"
#include "float.h"
static int sound_attack2;
static int sound_attack3;
static int sound_death1;
static int sound_idle;
static int sound_pain1;
static int sound_pain2;
static int sound_sight;
void floater_dead(edict_t *self);
void floater_die(edict_t *self, edict_t *inflictor, edict_t *attacker,
int damage, vec3_t point);
void floater_run(edict_t *self);
void floater_wham(edict_t *self);
void floater_zap(edict_t *self);
void
floater_sight(edict_t *self, edict_t *other /* unused */)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
void
floater_idle(edict_t *self)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
}
void
floater_fire_blaster(edict_t *self)
{
vec3_t start;
vec3_t forward, right;
vec3_t end;
vec3_t dir;
int effect;
if (!self || !self->enemy || !self->enemy->inuse)
{
return;
}
if ((self->s.frame == FRAME_attak104) || (self->s.frame == FRAME_attak107))
{
effect = EF_HYPERBLASTER;
}
else
{
effect = 0;
}
AngleVectors(self->s.angles, forward, right, NULL);
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_FLOAT_BLASTER_1], forward,
right, start);
VectorCopy(self->enemy->s.origin, end);
end[2] += self->enemy->viewheight;
VectorSubtract(end, start, dir);
monster_fire_blaster(self, start, dir, 1, 1000, MZ2_FLOAT_BLASTER_1, effect);
}
static mframe_t floater_frames_stand1[] = {
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL}
};
mmove_t floater_move_stand1 = {
FRAME_stand101,
FRAME_stand152,
floater_frames_stand1,
NULL
};
static mframe_t floater_frames_stand2[] = {
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL}
};
mmove_t floater_move_stand2 = {
FRAME_stand201,
FRAME_stand252,
floater_frames_stand2,
NULL
};
void
floater_stand(edict_t *self)
{
if (!self)
{
return;
}
if (random() <= 0.5)
{
self->monsterinfo.currentmove = &floater_move_stand1;
}
else
{
self->monsterinfo.currentmove = &floater_move_stand2;
}
}
static mframe_t floater_frames_activate[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t floater_move_activate = {
FRAME_actvat01,
FRAME_actvat31,
floater_frames_activate,
NULL
};
static mframe_t floater_frames_attack1[] = {
{ai_charge, 0, NULL}, /* Blaster attack */
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, floater_fire_blaster}, /* BOOM (0, -25.8, 32.5) -- LOOP Starts */
{ai_charge, 0, floater_fire_blaster},
{ai_charge, 0, floater_fire_blaster},
{ai_charge, 0, floater_fire_blaster},
{ai_charge, 0, floater_fire_blaster},
{ai_charge, 0, floater_fire_blaster},
{ai_charge, 0, floater_fire_blaster},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL} /* -- LOOP Ends */
};
mmove_t floater_move_attack1 = {
FRAME_attak101,
FRAME_attak114,
floater_frames_attack1,
floater_run
};
/* circle strafe frames */
static mframe_t floater_frames_attack1a[] = {
{ai_charge, 10, NULL}, // Blaster attack
{ai_charge, 10, NULL},
{ai_charge, 10, NULL},
{ai_charge, 10, floater_fire_blaster}, // BOOM (0, -25.8, 32.5) -- LOOP Starts
{ai_charge, 10, floater_fire_blaster},
{ai_charge, 10, floater_fire_blaster},
{ai_charge, 10, floater_fire_blaster},
{ai_charge, 10, floater_fire_blaster},
{ai_charge, 10, floater_fire_blaster},
{ai_charge, 10, floater_fire_blaster},
{ai_charge, 10, NULL},
{ai_charge, 10, NULL},
{ai_charge, 10, NULL},
{ai_charge, 10, NULL} // -- LOOP Ends
};
mmove_t floater_move_attack1a = {
FRAME_attak101,
FRAME_attak114,
floater_frames_attack1a,
floater_run
};
static mframe_t floater_frames_attack2[] = {
{ai_charge, 0, NULL}, /* Claws */
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, floater_wham}, /* WHAM (0, -45, 29}.6) -- LOOP Starts */
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL}, /* -- LOOP Ends */
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL}
};
mmove_t floater_move_attack2 = {
FRAME_attak201,
FRAME_attak225,
floater_frames_attack2,
floater_run
};
static mframe_t floater_frames_attack3[] = {
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, floater_zap}, /* -- LOOP Starts */
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL}, /* -- LOOP Ends */
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL}
};
mmove_t floater_move_attack3 = {
FRAME_attak301,
FRAME_attak334,
floater_frames_attack3,
floater_run
};
static mframe_t floater_frames_death[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t floater_move_death = {
FRAME_death01,
FRAME_death13,
floater_frames_death,
floater_dead
};
static mframe_t floater_frames_pain1[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t floater_move_pain1 = {
FRAME_pain101,
FRAME_pain107,
floater_frames_pain1,
floater_run
};
static mframe_t floater_frames_pain2[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t floater_move_pain2 = {
FRAME_pain201,
FRAME_pain208,
floater_frames_pain2,
floater_run
};
static mframe_t floater_frames_pain3[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t floater_move_pain3 = {
FRAME_pain301,
FRAME_pain312,
floater_frames_pain3,
floater_run
};
static mframe_t floater_frames_walk[] = {
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL}
};
mmove_t floater_move_walk = {
FRAME_stand101,
FRAME_stand152,
floater_frames_walk,
NULL
};
static mframe_t floater_frames_run[] = {
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL},
{ai_run, 13, NULL}
};
mmove_t floater_move_run = {
FRAME_stand101,
FRAME_stand152,
floater_frames_run,
NULL
};
void
floater_run(edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
{
self->monsterinfo.currentmove = &floater_move_stand1;
}
else
{
self->monsterinfo.currentmove = &floater_move_run;
}
}
void
floater_walk(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &floater_move_walk;
}
void
floater_wham(edict_t *self)
{
static vec3_t aim = {MELEE_DISTANCE, 0, 0};
if (!self)
{
return;
}
gi.sound(self, CHAN_WEAPON, sound_attack3, 1, ATTN_NORM, 0);
fire_hit(self, aim, 5 + rand() % 6, -50);
}
void
floater_zap(edict_t *self)
{
vec3_t forward, right;
vec3_t origin;
vec3_t dir;
vec3_t offset;
if (!self)
{
return;
}
VectorSubtract(self->enemy->s.origin, self->s.origin, dir);
AngleVectors(self->s.angles, forward, right, NULL);
VectorSet(offset, 18.5, -0.9, 10);
G_ProjectSource(self->s.origin, offset, forward, right, origin);
gi.sound(self, CHAN_WEAPON, sound_attack2, 1, ATTN_NORM, 0);
gi.WriteByte(svc_temp_entity);
gi.WriteByte(TE_SPLASH);
gi.WriteByte(32);
gi.WritePosition(origin);
gi.WriteDir(dir);
gi.WriteByte(1); /* sparks */
gi.multicast(origin, MULTICAST_PVS);
if (range(self, self->enemy) == RANGE_MELEE && infront(self, self->enemy) &&
visible(self, self->enemy))
{
T_Damage(self->enemy, self, self, dir, self->enemy->s.origin,
vec3_origin, 5 + rand() % 6, -10, DAMAGE_ENERGY, MOD_UNKNOWN);
}
}
void
floater_attack(edict_t *self)
{
float chance;
if (!self)
{
return;
}
// 0% chance of circle in easy
// 50% chance in normal
// 75% chance in hard
// 86.67% chance in nightmare
if (skill->value == SKILL_EASY)
{
chance = 0;
}
else
{
chance = 1.0 - (0.5/(float)(skill->value));
}
if (random() > chance)
{
self->monsterinfo.attack_state = AS_STRAIGHT;
self->monsterinfo.currentmove = &floater_move_attack1;
}
else // circle strafe
{
if (random () <= 0.5) // switch directions
{
self->monsterinfo.lefty = 1 - self->monsterinfo.lefty;
}
self->monsterinfo.attack_state = AS_SLIDING;
self->monsterinfo.currentmove = &floater_move_attack1a;
}
}
void
floater_melee(edict_t *self)
{
if (!self)
{
return;
}
if (random() < 0.5)
{
self->monsterinfo.currentmove = &floater_move_attack3;
}
else
{
self->monsterinfo.currentmove = &floater_move_attack2;
}
}
void
floater_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
{
int n;
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
{
self->s.skinnum = 1;
}
if (level.time < self->pain_debounce_time)
{
return;
}
self->pain_debounce_time = level.time + 3;
if (skill->value == SKILL_HARDPLUS)
{
return; /* no pain anims in nightmare */
}
n = (rand() + 1) % 3;
if (n == 0)
{
gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &floater_move_pain1;
}
else
{
gi.sound(self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &floater_move_pain2;
}
}
void
floater_dead(edict_t *self)
{
if (!self)
{
return;
}
VectorSet(self->mins, -16, -16, -24);
VectorSet(self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
self->svflags |= SVF_DEADMONSTER;
self->nextthink = 0;
gi.linkentity(self);
}
void
floater_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
int damage /* unused */, vec3_t point /* unused */)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_VOICE, sound_death1, 1, ATTN_NORM, 0);
BecomeExplosion1(self);
}
qboolean
floater_blocked(edict_t *self, float dist)
{
return false;
}
/*
* QUAKED monster_floater (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
*/
void
SP_monster_floater(edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict(self);
return;
}
sound_attack2 = gi.soundindex("floater/fltatck2.wav");
sound_attack3 = gi.soundindex("floater/fltatck3.wav");
sound_death1 = gi.soundindex("floater/fltdeth1.wav");
sound_idle = gi.soundindex("floater/fltidle1.wav");
sound_pain1 = gi.soundindex("floater/fltpain1.wav");
sound_pain2 = gi.soundindex("floater/fltpain2.wav");
sound_sight = gi.soundindex("floater/fltsght1.wav");
gi.soundindex("floater/fltatck1.wav");
self->s.sound = gi.soundindex("floater/fltsrch1.wav");
self->movetype = MOVETYPE_STEP;
self->solid = SOLID_BBOX;
self->s.modelindex = gi.modelindex("models/monsters/float/tris.md2");
VectorSet(self->mins, -24, -24, -24);
VectorSet(self->maxs, 24, 24, 32);
self->health = 200;
self->gib_health = -80;
self->mass = 300;
self->pain = floater_pain;
self->die = floater_die;
self->monsterinfo.stand = floater_stand;
self->monsterinfo.walk = floater_walk;
self->monsterinfo.run = floater_run;
self->monsterinfo.attack = floater_attack;
self->monsterinfo.melee = floater_melee;
self->monsterinfo.sight = floater_sight;
self->monsterinfo.idle = floater_idle;
self->monsterinfo.blocked = floater_blocked;
gi.linkentity(self);
if (random() <= 0.5)
{
self->monsterinfo.currentmove = &floater_move_stand1;
}
else
{
self->monsterinfo.currentmove = &floater_move_stand2;
}
self->monsterinfo.scale = MODEL_SCALE;
flymonster_start(self);
}

View file

@ -1,276 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Mechanic animations.
*
* =======================================================================
*/
#define FRAME_actvat01 0
#define FRAME_actvat02 1
#define FRAME_actvat03 2
#define FRAME_actvat04 3
#define FRAME_actvat05 4
#define FRAME_actvat06 5
#define FRAME_actvat07 6
#define FRAME_actvat08 7
#define FRAME_actvat09 8
#define FRAME_actvat10 9
#define FRAME_actvat11 10
#define FRAME_actvat12 11
#define FRAME_actvat13 12
#define FRAME_actvat14 13
#define FRAME_actvat15 14
#define FRAME_actvat16 15
#define FRAME_actvat17 16
#define FRAME_actvat18 17
#define FRAME_actvat19 18
#define FRAME_actvat20 19
#define FRAME_actvat21 20
#define FRAME_actvat22 21
#define FRAME_actvat23 22
#define FRAME_actvat24 23
#define FRAME_actvat25 24
#define FRAME_actvat26 25
#define FRAME_actvat27 26
#define FRAME_actvat28 27
#define FRAME_actvat29 28
#define FRAME_actvat30 29
#define FRAME_actvat31 30
#define FRAME_attak101 31
#define FRAME_attak102 32
#define FRAME_attak103 33
#define FRAME_attak104 34
#define FRAME_attak105 35
#define FRAME_attak106 36
#define FRAME_attak107 37
#define FRAME_attak108 38
#define FRAME_attak109 39
#define FRAME_attak110 40
#define FRAME_attak111 41
#define FRAME_attak112 42
#define FRAME_attak113 43
#define FRAME_attak114 44
#define FRAME_attak201 45
#define FRAME_attak202 46
#define FRAME_attak203 47
#define FRAME_attak204 48
#define FRAME_attak205 49
#define FRAME_attak206 50
#define FRAME_attak207 51
#define FRAME_attak208 52
#define FRAME_attak209 53
#define FRAME_attak210 54
#define FRAME_attak211 55
#define FRAME_attak212 56
#define FRAME_attak213 57
#define FRAME_attak214 58
#define FRAME_attak215 59
#define FRAME_attak216 60
#define FRAME_attak217 61
#define FRAME_attak218 62
#define FRAME_attak219 63
#define FRAME_attak220 64
#define FRAME_attak221 65
#define FRAME_attak222 66
#define FRAME_attak223 67
#define FRAME_attak224 68
#define FRAME_attak225 69
#define FRAME_attak301 70
#define FRAME_attak302 71
#define FRAME_attak303 72
#define FRAME_attak304 73
#define FRAME_attak305 74
#define FRAME_attak306 75
#define FRAME_attak307 76
#define FRAME_attak308 77
#define FRAME_attak309 78
#define FRAME_attak310 79
#define FRAME_attak311 80
#define FRAME_attak312 81
#define FRAME_attak313 82
#define FRAME_attak314 83
#define FRAME_attak315 84
#define FRAME_attak316 85
#define FRAME_attak317 86
#define FRAME_attak318 87
#define FRAME_attak319 88
#define FRAME_attak320 89
#define FRAME_attak321 90
#define FRAME_attak322 91
#define FRAME_attak323 92
#define FRAME_attak324 93
#define FRAME_attak325 94
#define FRAME_attak326 95
#define FRAME_attak327 96
#define FRAME_attak328 97
#define FRAME_attak329 98
#define FRAME_attak330 99
#define FRAME_attak331 100
#define FRAME_attak332 101
#define FRAME_attak333 102
#define FRAME_attak334 103
#define FRAME_death01 104
#define FRAME_death02 105
#define FRAME_death03 106
#define FRAME_death04 107
#define FRAME_death05 108
#define FRAME_death06 109
#define FRAME_death07 110
#define FRAME_death08 111
#define FRAME_death09 112
#define FRAME_death10 113
#define FRAME_death11 114
#define FRAME_death12 115
#define FRAME_death13 116
#define FRAME_pain101 117
#define FRAME_pain102 118
#define FRAME_pain103 119
#define FRAME_pain104 120
#define FRAME_pain105 121
#define FRAME_pain106 122
#define FRAME_pain107 123
#define FRAME_pain201 124
#define FRAME_pain202 125
#define FRAME_pain203 126
#define FRAME_pain204 127
#define FRAME_pain205 128
#define FRAME_pain206 129
#define FRAME_pain207 130
#define FRAME_pain208 131
#define FRAME_pain301 132
#define FRAME_pain302 133
#define FRAME_pain303 134
#define FRAME_pain304 135
#define FRAME_pain305 136
#define FRAME_pain306 137
#define FRAME_pain307 138
#define FRAME_pain308 139
#define FRAME_pain309 140
#define FRAME_pain310 141
#define FRAME_pain311 142
#define FRAME_pain312 143
#define FRAME_stand101 144
#define FRAME_stand102 145
#define FRAME_stand103 146
#define FRAME_stand104 147
#define FRAME_stand105 148
#define FRAME_stand106 149
#define FRAME_stand107 150
#define FRAME_stand108 151
#define FRAME_stand109 152
#define FRAME_stand110 153
#define FRAME_stand111 154
#define FRAME_stand112 155
#define FRAME_stand113 156
#define FRAME_stand114 157
#define FRAME_stand115 158
#define FRAME_stand116 159
#define FRAME_stand117 160
#define FRAME_stand118 161
#define FRAME_stand119 162
#define FRAME_stand120 163
#define FRAME_stand121 164
#define FRAME_stand122 165
#define FRAME_stand123 166
#define FRAME_stand124 167
#define FRAME_stand125 168
#define FRAME_stand126 169
#define FRAME_stand127 170
#define FRAME_stand128 171
#define FRAME_stand129 172
#define FRAME_stand130 173
#define FRAME_stand131 174
#define FRAME_stand132 175
#define FRAME_stand133 176
#define FRAME_stand134 177
#define FRAME_stand135 178
#define FRAME_stand136 179
#define FRAME_stand137 180
#define FRAME_stand138 181
#define FRAME_stand139 182
#define FRAME_stand140 183
#define FRAME_stand141 184
#define FRAME_stand142 185
#define FRAME_stand143 186
#define FRAME_stand144 187
#define FRAME_stand145 188
#define FRAME_stand146 189
#define FRAME_stand147 190
#define FRAME_stand148 191
#define FRAME_stand149 192
#define FRAME_stand150 193
#define FRAME_stand151 194
#define FRAME_stand152 195
#define FRAME_stand201 196
#define FRAME_stand202 197
#define FRAME_stand203 198
#define FRAME_stand204 199
#define FRAME_stand205 200
#define FRAME_stand206 201
#define FRAME_stand207 202
#define FRAME_stand208 203
#define FRAME_stand209 204
#define FRAME_stand210 205
#define FRAME_stand211 206
#define FRAME_stand212 207
#define FRAME_stand213 208
#define FRAME_stand214 209
#define FRAME_stand215 210
#define FRAME_stand216 211
#define FRAME_stand217 212
#define FRAME_stand218 213
#define FRAME_stand219 214
#define FRAME_stand220 215
#define FRAME_stand221 216
#define FRAME_stand222 217
#define FRAME_stand223 218
#define FRAME_stand224 219
#define FRAME_stand225 220
#define FRAME_stand226 221
#define FRAME_stand227 222
#define FRAME_stand228 223
#define FRAME_stand229 224
#define FRAME_stand230 225
#define FRAME_stand231 226
#define FRAME_stand232 227
#define FRAME_stand233 228
#define FRAME_stand234 229
#define FRAME_stand235 230
#define FRAME_stand236 231
#define FRAME_stand237 232
#define FRAME_stand238 233
#define FRAME_stand239 234
#define FRAME_stand240 235
#define FRAME_stand241 236
#define FRAME_stand242 237
#define FRAME_stand243 238
#define FRAME_stand244 239
#define FRAME_stand245 240
#define FRAME_stand246 241
#define FRAME_stand247 242
#define FRAME_stand248 243
#define FRAME_stand249 244
#define FRAME_stand250 245
#define FRAME_stand251 246
#define FRAME_stand252 247
#define MODEL_SCALE 1.000000

View file

@ -1,568 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Gladiator.
*
* =======================================================================
*/
#include "../../header/local.h"
#include "gladiator.h"
static int sound_pain1;
static int sound_pain2;
static int sound_die;
static int sound_gun;
static int sound_cleaver_swing;
static int sound_cleaver_hit;
static int sound_cleaver_miss;
static int sound_idle;
static int sound_search;
static int sound_sight;
void
gladiator_idle(edict_t *self)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
}
void
gladiator_sight(edict_t *self, edict_t *other /* unused */)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
void
gladiator_search(edict_t *self)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
}
void
gladiator_cleaver_swing(edict_t *self)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_WEAPON, sound_cleaver_swing, 1, ATTN_NORM, 0);
}
static mframe_t gladiator_frames_stand[] = {
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL}
};
mmove_t gladiator_move_stand = {
FRAME_stand1,
FRAME_stand7,
gladiator_frames_stand,
NULL
};
void
gladiator_stand(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &gladiator_move_stand;
}
static mframe_t gladiator_frames_walk[] = {
{ai_walk, 15, NULL},
{ai_walk, 7, NULL},
{ai_walk, 6, NULL},
{ai_walk, 5, NULL},
{ai_walk, 2, NULL},
{ai_walk, 0, NULL},
{ai_walk, 2, NULL},
{ai_walk, 8, NULL},
{ai_walk, 12, NULL},
{ai_walk, 8, NULL},
{ai_walk, 5, NULL},
{ai_walk, 5, NULL},
{ai_walk, 2, NULL},
{ai_walk, 2, NULL},
{ai_walk, 1, NULL},
{ai_walk, 8, NULL}
};
mmove_t gladiator_move_walk = {
FRAME_walk1,
FRAME_walk16,
gladiator_frames_walk,
NULL
};
void
gladiator_walk(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &gladiator_move_walk;
}
static mframe_t gladiator_frames_run[] = {
{ai_run, 23, NULL},
{ai_run, 14, NULL},
{ai_run, 14, NULL},
{ai_run, 21, NULL},
{ai_run, 12, NULL},
{ai_run, 13, NULL}
};
mmove_t gladiator_move_run = {
FRAME_run1,
FRAME_run6,
gladiator_frames_run,
NULL
};
void
gladiator_run(edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
{
self->monsterinfo.currentmove = &gladiator_move_stand;
}
else
{
self->monsterinfo.currentmove = &gladiator_move_run;
}
}
void
GaldiatorMelee(edict_t *self)
{
vec3_t aim;
if (!self)
{
return;
}
VectorSet(aim, MELEE_DISTANCE, self->mins[0], -4);
if (fire_hit(self, aim, (20 + (rand() % 5)), 300))
{
gi.sound(self, CHAN_AUTO, sound_cleaver_hit, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_AUTO, sound_cleaver_miss, 1, ATTN_NORM, 0);
}
}
static mframe_t gladiator_frames_attack_melee[] = {
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, gladiator_cleaver_swing},
{ai_charge, 0, NULL},
{ai_charge, 0, GaldiatorMelee},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, gladiator_cleaver_swing},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, GaldiatorMelee},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL}
};
mmove_t gladiator_move_attack_melee = {
FRAME_melee1,
FRAME_melee17,
gladiator_frames_attack_melee,
gladiator_run
};
void
gladiator_melee(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &gladiator_move_attack_melee;
}
void
GladiatorGun(edict_t *self)
{
vec3_t start;
vec3_t dir;
vec3_t forward, right;
if (!self)
{
return;
}
AngleVectors(self->s.angles, forward, right, NULL);
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_GLADIATOR_RAILGUN_1],
forward, right, start);
/* calc direction to where we targted */
VectorSubtract(self->pos1, start, dir);
VectorNormalize(dir);
monster_fire_railgun(self, start, dir, 50, 100, MZ2_GLADIATOR_RAILGUN_1);
}
static mframe_t gladiator_frames_attack_gun[] = {
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, GladiatorGun},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL}
};
mmove_t gladiator_move_attack_gun = {
FRAME_attack1,
FRAME_attack9,
gladiator_frames_attack_gun,
gladiator_run
};
void
gladiator_attack(edict_t *self)
{
float range;
vec3_t v;
if (!self)
{
return;
}
/* a small safe zone
but not for stand-ground ones since players can
abuse it by standing still inside this range
*/
if (!(self->monsterinfo.aiflags & AI_STAND_GROUND))
{
VectorSubtract(self->s.origin, self->enemy->s.origin, v);
range = VectorLength(v);
if (range <= (MELEE_DISTANCE + 32))
{
return;
}
}
/* charge up the railgun */
gi.sound(self, CHAN_WEAPON, sound_gun, 1, ATTN_NORM, 0);
VectorCopy(self->enemy->s.origin, self->pos1); /* save for aiming the shot */
self->pos1[2] += self->enemy->viewheight;
self->monsterinfo.currentmove = &gladiator_move_attack_gun;
}
static mframe_t gladiator_frames_pain[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t gladiator_move_pain = {
FRAME_pain1,
FRAME_pain6,
gladiator_frames_pain,
gladiator_run
};
static mframe_t gladiator_frames_pain_air[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t gladiator_move_pain_air = {
FRAME_painup1,
FRAME_painup7,
gladiator_frames_pain_air,
gladiator_run
};
void
gladiator_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
{
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
{
self->s.skinnum = 1;
}
if (level.time < self->pain_debounce_time)
{
if ((self->velocity[2] > 100) &&
(self->monsterinfo.currentmove == &gladiator_move_pain))
{
self->monsterinfo.currentmove = &gladiator_move_pain_air;
}
return;
}
self->pain_debounce_time = level.time + 3;
if (random() < 0.5)
{
gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
}
if (skill->value == SKILL_HARDPLUS)
{
return; /* no pain anims in nightmare */
}
if (self->velocity[2] > 100)
{
self->monsterinfo.currentmove = &gladiator_move_pain_air;
}
else
{
self->monsterinfo.currentmove = &gladiator_move_pain;
}
}
void
gladiator_dead(edict_t *self)
{
if (!self)
{
return;
}
VectorSet(self->mins, -16, -16, -24);
VectorSet(self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
self->svflags |= SVF_DEADMONSTER;
self->nextthink = 0;
gi.linkentity(self);
}
static mframe_t gladiator_frames_death[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t gladiator_move_death = {
FRAME_death1,
FRAME_death22,
gladiator_frames_death,
gladiator_dead
};
void
gladiator_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
int damage, vec3_t point /* unused */)
{
int n;
if (!self)
{
return;
}
/* check for gib */
if (self->health <= self->gib_health)
{
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
for (n = 0; n < 2; n++)
{
ThrowGib(self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
}
for (n = 0; n < 4; n++)
{
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
}
ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
self->deadflag = DEAD_DEAD;
return;
}
if (self->deadflag == DEAD_DEAD)
{
return;
}
/* regular death */
gi.sound(self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0);
self->deadflag = DEAD_DEAD;
self->takedamage = DAMAGE_YES;
self->monsterinfo.currentmove = &gladiator_move_death;
}
qboolean
gladiator_blocked(edict_t *self, float dist)
{
if (!self)
{
return false;
}
if (blocked_checkplat(self, dist))
{
return true;
}
return false;
}
/*
* QUAKED monster_gladiator (1 .5 0) (-32 -32 -24) (32 32 64) Ambush Trigger_Spawn Sight
*/
void
SP_monster_gladiator(edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict(self);
return;
}
sound_pain1 = gi.soundindex("gladiator/pain.wav");
sound_pain2 = gi.soundindex("gladiator/gldpain2.wav");
sound_die = gi.soundindex("gladiator/glddeth2.wav");
sound_gun = gi.soundindex("gladiator/railgun.wav");
sound_cleaver_swing = gi.soundindex("gladiator/melee1.wav");
sound_cleaver_hit = gi.soundindex("gladiator/melee2.wav");
sound_cleaver_miss = gi.soundindex("gladiator/melee3.wav");
sound_idle = gi.soundindex("gladiator/gldidle1.wav");
sound_search = gi.soundindex("gladiator/gldsrch1.wav");
sound_sight = gi.soundindex("gladiator/sight.wav");
self->movetype = MOVETYPE_STEP;
self->solid = SOLID_BBOX;
self->s.modelindex = gi.modelindex("models/monsters/gladiatr/tris.md2");
VectorSet(self->mins, -32, -32, -24);
VectorSet(self->maxs, 32, 32, 64);
self->health = 400;
self->gib_health = -175;
self->mass = 400;
self->pain = gladiator_pain;
self->die = gladiator_die;
self->monsterinfo.stand = gladiator_stand;
self->monsterinfo.walk = gladiator_walk;
self->monsterinfo.run = gladiator_run;
self->monsterinfo.dodge = NULL;
self->monsterinfo.attack = gladiator_attack;
self->monsterinfo.melee = gladiator_melee;
self->monsterinfo.sight = gladiator_sight;
self->monsterinfo.idle = gladiator_idle;
self->monsterinfo.search = gladiator_search;
self->monsterinfo.blocked = gladiator_blocked;
gi.linkentity(self);
self->monsterinfo.currentmove = &gladiator_move_stand;
self->monsterinfo.scale = MODEL_SCALE;
walkmonster_start(self);
}

View file

@ -1,118 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Gladiator animations.
*
* =======================================================================
*/
#define FRAME_stand1 0
#define FRAME_stand2 1
#define FRAME_stand3 2
#define FRAME_stand4 3
#define FRAME_stand5 4
#define FRAME_stand6 5
#define FRAME_stand7 6
#define FRAME_walk1 7
#define FRAME_walk2 8
#define FRAME_walk3 9
#define FRAME_walk4 10
#define FRAME_walk5 11
#define FRAME_walk6 12
#define FRAME_walk7 13
#define FRAME_walk8 14
#define FRAME_walk9 15
#define FRAME_walk10 16
#define FRAME_walk11 17
#define FRAME_walk12 18
#define FRAME_walk13 19
#define FRAME_walk14 20
#define FRAME_walk15 21
#define FRAME_walk16 22
#define FRAME_run1 23
#define FRAME_run2 24
#define FRAME_run3 25
#define FRAME_run4 26
#define FRAME_run5 27
#define FRAME_run6 28
#define FRAME_melee1 29
#define FRAME_melee2 30
#define FRAME_melee3 31
#define FRAME_melee4 32
#define FRAME_melee5 33
#define FRAME_melee6 34
#define FRAME_melee7 35
#define FRAME_melee8 36
#define FRAME_melee9 37
#define FRAME_melee10 38
#define FRAME_melee11 39
#define FRAME_melee12 40
#define FRAME_melee13 41
#define FRAME_melee14 42
#define FRAME_melee15 43
#define FRAME_melee16 44
#define FRAME_melee17 45
#define FRAME_attack1 46
#define FRAME_attack2 47
#define FRAME_attack3 48
#define FRAME_attack4 49
#define FRAME_attack5 50
#define FRAME_attack6 51
#define FRAME_attack7 52
#define FRAME_attack8 53
#define FRAME_attack9 54
#define FRAME_pain1 55
#define FRAME_pain2 56
#define FRAME_pain3 57
#define FRAME_pain4 58
#define FRAME_pain5 59
#define FRAME_pain6 60
#define FRAME_death1 61
#define FRAME_death2 62
#define FRAME_death3 63
#define FRAME_death4 64
#define FRAME_death5 65
#define FRAME_death6 66
#define FRAME_death7 67
#define FRAME_death8 68
#define FRAME_death9 69
#define FRAME_death10 70
#define FRAME_death11 71
#define FRAME_death12 72
#define FRAME_death13 73
#define FRAME_death14 74
#define FRAME_death15 75
#define FRAME_death16 76
#define FRAME_death17 77
#define FRAME_death18 78
#define FRAME_death19 79
#define FRAME_death20 80
#define FRAME_death21 81
#define FRAME_death22 82
#define FRAME_painup1 83
#define FRAME_painup2 84
#define FRAME_painup3 85
#define FRAME_painup4 86
#define FRAME_painup5 87
#define FRAME_painup6 88
#define FRAME_painup7 89
#define MODEL_SCALE 1.000000

File diff suppressed because it is too large Load diff

View file

@ -1,247 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Gunner animations.
*
* =======================================================================
*/
#define FRAME_stand01 0
#define FRAME_stand02 1
#define FRAME_stand03 2
#define FRAME_stand04 3
#define FRAME_stand05 4
#define FRAME_stand06 5
#define FRAME_stand07 6
#define FRAME_stand08 7
#define FRAME_stand09 8
#define FRAME_stand10 9
#define FRAME_stand11 10
#define FRAME_stand12 11
#define FRAME_stand13 12
#define FRAME_stand14 13
#define FRAME_stand15 14
#define FRAME_stand16 15
#define FRAME_stand17 16
#define FRAME_stand18 17
#define FRAME_stand19 18
#define FRAME_stand20 19
#define FRAME_stand21 20
#define FRAME_stand22 21
#define FRAME_stand23 22
#define FRAME_stand24 23
#define FRAME_stand25 24
#define FRAME_stand26 25
#define FRAME_stand27 26
#define FRAME_stand28 27
#define FRAME_stand29 28
#define FRAME_stand30 29
#define FRAME_stand31 30
#define FRAME_stand32 31
#define FRAME_stand33 32
#define FRAME_stand34 33
#define FRAME_stand35 34
#define FRAME_stand36 35
#define FRAME_stand37 36
#define FRAME_stand38 37
#define FRAME_stand39 38
#define FRAME_stand40 39
#define FRAME_stand41 40
#define FRAME_stand42 41
#define FRAME_stand43 42
#define FRAME_stand44 43
#define FRAME_stand45 44
#define FRAME_stand46 45
#define FRAME_stand47 46
#define FRAME_stand48 47
#define FRAME_stand49 48
#define FRAME_stand50 49
#define FRAME_stand51 50
#define FRAME_stand52 51
#define FRAME_stand53 52
#define FRAME_stand54 53
#define FRAME_stand55 54
#define FRAME_stand56 55
#define FRAME_stand57 56
#define FRAME_stand58 57
#define FRAME_stand59 58
#define FRAME_stand60 59
#define FRAME_stand61 60
#define FRAME_stand62 61
#define FRAME_stand63 62
#define FRAME_stand64 63
#define FRAME_stand65 64
#define FRAME_stand66 65
#define FRAME_stand67 66
#define FRAME_stand68 67
#define FRAME_stand69 68
#define FRAME_stand70 69
#define FRAME_walk01 70
#define FRAME_walk02 71
#define FRAME_walk03 72
#define FRAME_walk04 73
#define FRAME_walk05 74
#define FRAME_walk06 75
#define FRAME_walk07 76
#define FRAME_walk08 77
#define FRAME_walk09 78
#define FRAME_walk10 79
#define FRAME_walk11 80
#define FRAME_walk12 81
#define FRAME_walk13 82
#define FRAME_walk14 83
#define FRAME_walk15 84
#define FRAME_walk16 85
#define FRAME_walk17 86
#define FRAME_walk18 87
#define FRAME_walk19 88
#define FRAME_walk20 89
#define FRAME_walk21 90
#define FRAME_walk22 91
#define FRAME_walk23 92
#define FRAME_walk24 93
#define FRAME_run01 94
#define FRAME_run02 95
#define FRAME_run03 96
#define FRAME_run04 97
#define FRAME_run05 98
#define FRAME_run06 99
#define FRAME_run07 100
#define FRAME_run08 101
#define FRAME_runs01 102
#define FRAME_runs02 103
#define FRAME_runs03 104
#define FRAME_runs04 105
#define FRAME_runs05 106
#define FRAME_runs06 107
#define FRAME_attak101 108
#define FRAME_attak102 109
#define FRAME_attak103 110
#define FRAME_attak104 111
#define FRAME_attak105 112
#define FRAME_attak106 113
#define FRAME_attak107 114
#define FRAME_attak108 115
#define FRAME_attak109 116
#define FRAME_attak110 117
#define FRAME_attak111 118
#define FRAME_attak112 119
#define FRAME_attak113 120
#define FRAME_attak114 121
#define FRAME_attak115 122
#define FRAME_attak116 123
#define FRAME_attak117 124
#define FRAME_attak118 125
#define FRAME_attak119 126
#define FRAME_attak120 127
#define FRAME_attak121 128
#define FRAME_attak201 129
#define FRAME_attak202 130
#define FRAME_attak203 131
#define FRAME_attak204 132
#define FRAME_attak205 133
#define FRAME_attak206 134
#define FRAME_attak207 135
#define FRAME_attak208 136
#define FRAME_attak209 137
#define FRAME_attak210 138
#define FRAME_attak211 139
#define FRAME_attak212 140
#define FRAME_attak213 141
#define FRAME_attak214 142
#define FRAME_attak215 143
#define FRAME_attak216 144
#define FRAME_attak217 145
#define FRAME_attak218 146
#define FRAME_attak219 147
#define FRAME_attak220 148
#define FRAME_attak221 149
#define FRAME_attak222 150
#define FRAME_attak223 151
#define FRAME_attak224 152
#define FRAME_attak225 153
#define FRAME_attak226 154
#define FRAME_attak227 155
#define FRAME_attak228 156
#define FRAME_attak229 157
#define FRAME_attak230 158
#define FRAME_pain101 159
#define FRAME_pain102 160
#define FRAME_pain103 161
#define FRAME_pain104 162
#define FRAME_pain105 163
#define FRAME_pain106 164
#define FRAME_pain107 165
#define FRAME_pain108 166
#define FRAME_pain109 167
#define FRAME_pain110 168
#define FRAME_pain111 169
#define FRAME_pain112 170
#define FRAME_pain113 171
#define FRAME_pain114 172
#define FRAME_pain115 173
#define FRAME_pain116 174
#define FRAME_pain117 175
#define FRAME_pain118 176
#define FRAME_pain201 177
#define FRAME_pain202 178
#define FRAME_pain203 179
#define FRAME_pain204 180
#define FRAME_pain205 181
#define FRAME_pain206 182
#define FRAME_pain207 183
#define FRAME_pain208 184
#define FRAME_pain301 185
#define FRAME_pain302 186
#define FRAME_pain303 187
#define FRAME_pain304 188
#define FRAME_pain305 189
#define FRAME_death01 190
#define FRAME_death02 191
#define FRAME_death03 192
#define FRAME_death04 193
#define FRAME_death05 194
#define FRAME_death06 195
#define FRAME_death07 196
#define FRAME_death08 197
#define FRAME_death09 198
#define FRAME_death10 199
#define FRAME_death11 200
#define FRAME_duck01 201
#define FRAME_duck02 202
#define FRAME_duck03 203
#define FRAME_duck04 204
#define FRAME_duck05 205
#define FRAME_duck06 206
#define FRAME_duck07 207
#define FRAME_duck08 208
#define FRAME_jump01 209
#define FRAME_jump02 210
#define FRAME_jump03 211
#define FRAME_jump04 212
#define FRAME_jump05 213
#define FRAME_jump06 214
#define FRAME_jump07 215
#define FRAME_jump08 216
#define FRAME_jump09 217
#define FRAME_jump10 218
#define MODEL_SCALE 1.150000

View file

@ -1,870 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Icarus and Daedalus.
*
* =======================================================================
*/
#include "../../header/local.h"
#include "hover.h"
qboolean visible(edict_t *self, edict_t *other);
void hover_run(edict_t *self);
void hover_stand(edict_t *self);
void hover_dead(edict_t *self);
void hover_attack(edict_t *self);
void hover_reattack(edict_t *self);
void hover_fire_blaster(edict_t *self);
void hover_die(edict_t *self, edict_t *inflictor, edict_t *attacker,
int damage, vec3_t point);
static int sound_pain1;
static int sound_pain2;
static int sound_death1;
static int sound_death2;
static int sound_sight;
static int sound_search1;
static int sound_search2;
/* daedalus sounds */
static int daed_sound_pain1;
static int daed_sound_pain2;
static int daed_sound_death1;
static int daed_sound_death2;
static int daed_sound_sight;
static int daed_sound_search1;
static int daed_sound_search2;
void
hover_sight(edict_t *self, edict_t *other /* unused */)
{
if (!self)
{
return;
}
if (self->mass < 225)
{
gi.sound(self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, daed_sound_sight, 1, ATTN_NORM, 0);
}
}
void
hover_search(edict_t *self)
{
if (!self)
{
return;
}
if (self->mass < 225)
{
if (random() < 0.5)
{
gi.sound(self, CHAN_VOICE, sound_search1, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, sound_search2, 1, ATTN_NORM, 0);
}
}
else
{
if (random() < 0.5)
{
gi.sound(self, CHAN_VOICE, daed_sound_search1, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, daed_sound_search2, 1, ATTN_NORM, 0);
}
}
}
static mframe_t hover_frames_stand[] = {
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL}
};
mmove_t hover_move_stand = {
FRAME_stand01,
FRAME_stand30,
hover_frames_stand,
NULL
};
static mframe_t hover_frames_pain3[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t hover_move_pain3 = {
FRAME_pain301,
FRAME_pain309,
hover_frames_pain3,
hover_run
};
static mframe_t hover_frames_pain2[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t hover_move_pain2 = {
FRAME_pain201,
FRAME_pain212,
hover_frames_pain2,
hover_run
};
static mframe_t hover_frames_pain1[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 2, NULL},
{ai_move, -8, NULL},
{ai_move, -4, NULL},
{ai_move, -6, NULL},
{ai_move, -4, NULL},
{ai_move, -3, NULL},
{ai_move, 1, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 3, NULL},
{ai_move, 1, NULL},
{ai_move, 0, NULL},
{ai_move, 2, NULL},
{ai_move, 3, NULL},
{ai_move, 2, NULL},
{ai_move, 7, NULL},
{ai_move, 1, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 2, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 5, NULL},
{ai_move, 3, NULL},
{ai_move, 4, NULL}
};
mmove_t hover_move_pain1 = {
FRAME_pain101,
FRAME_pain128,
hover_frames_pain1,
hover_run
};
static mframe_t hover_frames_walk[] = {
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL}
};
mmove_t hover_move_walk = {
FRAME_forwrd01,
FRAME_forwrd35,
hover_frames_walk,
NULL
};
static mframe_t hover_frames_run[] = {
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL},
{ai_run, 10, NULL}
};
mmove_t hover_move_run = {
FRAME_forwrd01,
FRAME_forwrd35,
hover_frames_run,
NULL
};
static mframe_t hover_frames_death1[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, -10, NULL},
{ai_move, 3, NULL},
{ai_move, 5, NULL},
{ai_move, 4, NULL},
{ai_move, 7, NULL}
};
mmove_t hover_move_death1 = {
FRAME_death101,
FRAME_death111,
hover_frames_death1,
hover_dead
};
static mframe_t hover_frames_start_attack[] = {
{ai_charge, 1, NULL},
{ai_charge, 1, NULL},
{ai_charge, 1, NULL}
};
mmove_t hover_move_start_attack = {
FRAME_attak101,
FRAME_attak103,
hover_frames_start_attack,
hover_attack
};
static mframe_t hover_frames_attack1[] = {
{ai_charge, -10, hover_fire_blaster},
{ai_charge, -10, hover_fire_blaster},
{ai_charge, 0, hover_reattack},
};
mmove_t hover_move_attack1 = {
FRAME_attak104,
FRAME_attak106,
hover_frames_attack1,
NULL
};
static mframe_t hover_frames_end_attack[] = {
{ai_charge, 1, NULL},
{ai_charge, 1, NULL}
};
mmove_t hover_move_end_attack = {
FRAME_attak107,
FRAME_attak108,
hover_frames_end_attack,
hover_run
};
static mframe_t hover_frames_start_attack2[] = {
{ai_charge, 15, NULL},
{ai_charge, 15, NULL},
{ai_charge, 15, NULL}
};
mmove_t hover_move_start_attack2 = {
FRAME_attak101,
FRAME_attak103,
hover_frames_start_attack2,
hover_attack
};
static mframe_t hover_frames_attack2[] = {
{ai_charge, 10, hover_fire_blaster},
{ai_charge, 10, hover_fire_blaster},
{ai_charge, 10, hover_reattack},
};
mmove_t hover_move_attack2 = {
FRAME_attak104,
FRAME_attak106,
hover_frames_attack2,
NULL
};
static mframe_t hover_frames_end_attack2[] = {
{ai_charge, 15, NULL},
{ai_charge, 15, NULL}
};
mmove_t hover_move_end_attack2 = {
FRAME_attak107,
FRAME_attak108,
hover_frames_end_attack2,
hover_run
};
void
hover_reattack(edict_t *self)
{
if (!self)
{
return;
}
if (self->enemy->health > 0)
{
if (visible(self, self->enemy))
{
if (random() <= 0.6)
{
if (self->monsterinfo.attack_state == AS_STRAIGHT)
{
self->monsterinfo.currentmove = &hover_move_attack1;
return;
}
else if (self->monsterinfo.attack_state == AS_SLIDING)
{
self->monsterinfo.currentmove = &hover_move_attack2;
return;
}
else
{
gi.dprintf("hover_reattack: unexpected state %d\n", self->monsterinfo.attack_state);
}
}
}
}
self->monsterinfo.currentmove = &hover_move_end_attack;
}
void
hover_fire_blaster(edict_t *self)
{
vec3_t start;
vec3_t forward, right;
vec3_t end;
vec3_t dir;
int effect;
if (!self)
{
return;
}
if (!self->enemy || !self->enemy->inuse)
{
return;
}
if (self->s.frame == FRAME_attak104)
{
effect = EF_HYPERBLASTER;
}
else
{
effect = 0;
}
AngleVectors(self->s.angles, forward, right, NULL);
G_ProjectSource(self->s.origin, monster_flash_offset[MZ2_HOVER_BLASTER_1],
forward, right, start);
VectorCopy(self->enemy->s.origin, end);
end[2] += self->enemy->viewheight;
VectorSubtract(end, start, dir);
if (self->mass < 200)
{
monster_fire_blaster(self, start, dir, 1,
1000, MZ2_HOVER_BLASTER_1, effect);
}
else
{
monster_fire_blaster2(self, start, dir, 1, 1000,
MZ2_DAEDALUS_BLASTER, EF_BLASTER);
}
}
void
hover_stand(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &hover_move_stand;
}
void
hover_run(edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
{
self->monsterinfo.currentmove = &hover_move_stand;
}
else
{
self->monsterinfo.currentmove = &hover_move_run;
}
}
void
hover_walk(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &hover_move_walk;
}
void
hover_start_attack(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &hover_move_start_attack;
}
void
hover_attack(edict_t *self)
{
float chance;
if (!self)
{
return;
}
if (skill->value == SKILL_EASY)
{
chance = 0;
}
else
{
chance = 1.0 - (0.5 / (float)(skill->value));
}
if (self->mass > 150) /* the daedalus strafes more */
{
chance += 0.1;
}
if (random() > chance)
{
self->monsterinfo.currentmove = &hover_move_attack1;
self->monsterinfo.attack_state = AS_STRAIGHT;
}
else /* circle strafe */
{
if (random() <= 0.5) /* switch directions */
{
self->monsterinfo.lefty = 1 - self->monsterinfo.lefty;
}
self->monsterinfo.currentmove = &hover_move_attack2;
self->monsterinfo.attack_state = AS_SLIDING;
}
}
void
hover_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
{
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
{
self->s.skinnum |= 1; /* support for skins 2 & 3. */
}
if (level.time < self->pain_debounce_time)
{
return;
}
self->pain_debounce_time = level.time + 3;
if (skill->value == SKILL_HARDPLUS)
{
return; /* no pain anims in nightmare */
}
if (damage <= 25)
{
if (random() < 0.5)
{
/* daedalus sounds */
if (self->mass < 225)
{
gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, daed_sound_pain1, 1, ATTN_NORM, 0);
}
self->monsterinfo.currentmove = &hover_move_pain3;
}
else
{
/* daedalus sounds */
if (self->mass < 225)
{
gi.sound(self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, daed_sound_pain2, 1, ATTN_NORM, 0);
}
self->monsterinfo.currentmove = &hover_move_pain2;
}
}
else
{
if (random() < (0.45 - (0.1 * skill->value)))
{
/* daedalus sounds */
if (self->mass < 225)
{
gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, daed_sound_pain1, 1, ATTN_NORM, 0);
}
self->monsterinfo.currentmove = &hover_move_pain1;
}
else
{
/* daedalus sounds */
if (self->mass < 225)
{
gi.sound(self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, daed_sound_pain2, 1, ATTN_NORM, 0);
}
self->monsterinfo.currentmove = &hover_move_pain2;
}
}
}
void
hover_deadthink(edict_t *self)
{
if (!self)
{
return;
}
if (!self->groundentity && (level.time < self->timestamp))
{
self->nextthink = level.time + FRAMETIME;
return;
}
BecomeExplosion1(self);
}
void
hover_dead(edict_t *self)
{
if (!self)
{
return;
}
VectorSet(self->mins, -16, -16, -24);
VectorSet(self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
self->think = hover_deadthink;
self->nextthink = level.time + FRAMETIME;
self->timestamp = level.time + 15;
gi.linkentity(self);
}
void
hover_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
int damage, vec3_t point /* unused */)
{
int n;
if (!self)
{
return;
}
self->s.effects = 0;
self->monsterinfo.power_armor_type = POWER_ARMOR_NONE;
/* check for gib */
if (self->health <= self->gib_health)
{
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
for (n = 0; n < 2; n++)
{
ThrowGib(self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
}
for (n = 0; n < 2; n++)
{
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
}
ThrowHead(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
self->deadflag = DEAD_DEAD;
return;
}
if (self->deadflag == DEAD_DEAD)
{
return;
}
/* regular death */
if (self->mass < 225)
{
if (random() < 0.5)
{
gi.sound(self, CHAN_VOICE, sound_death1, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, sound_death2, 1, ATTN_NORM, 0);
}
}
else
{
if (random() < 0.5)
{
gi.sound(self, CHAN_VOICE, daed_sound_death1, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, daed_sound_death2, 1, ATTN_NORM, 0);
}
}
self->deadflag = DEAD_DEAD;
self->takedamage = DAMAGE_YES;
self->monsterinfo.currentmove = &hover_move_death1;
}
qboolean
hover_blocked(edict_t *self, float dist)
{
return false;
}
/*
* QUAKED monster_hover (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
*
* QUAKED monster_daedalus (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
* This is the improved icarus monster.
*/
void
SP_monster_hover(edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict(self);
return;
}
self->movetype = MOVETYPE_STEP;
self->solid = SOLID_BBOX;
self->s.modelindex = gi.modelindex("models/monsters/hover/tris.md2");
VectorSet(self->mins, -24, -24, -24);
VectorSet(self->maxs, 24, 24, 32);
self->health = 240;
self->gib_health = -100;
self->mass = 150;
self->pain = hover_pain;
self->die = hover_die;
self->monsterinfo.stand = hover_stand;
self->monsterinfo.walk = hover_walk;
self->monsterinfo.run = hover_run;
self->monsterinfo.attack = hover_start_attack;
self->monsterinfo.sight = hover_sight;
self->monsterinfo.search = hover_search;
self->monsterinfo.blocked = hover_blocked;
if (strcmp(self->classname, "monster_daedalus") == 0)
{
self->health = 450;
self->mass = 225;
self->yaw_speed = 25;
self->monsterinfo.power_armor_type = POWER_ARMOR_SCREEN;
self->monsterinfo.power_armor_power = 100;
self->s.sound = gi.soundindex("daedalus/daedidle1.wav");
daed_sound_pain1 = gi.soundindex("daedalus/daedpain1.wav");
daed_sound_pain2 = gi.soundindex("daedalus/daedpain2.wav");
daed_sound_death1 = gi.soundindex("daedalus/daeddeth1.wav");
daed_sound_death2 = gi.soundindex("daedalus/daeddeth2.wav");
daed_sound_sight = gi.soundindex("daedalus/daedsght1.wav");
daed_sound_search1 = gi.soundindex("daedalus/daedsrch1.wav");
daed_sound_search2 = gi.soundindex("daedalus/daedsrch2.wav");
gi.soundindex("tank/tnkatck3.wav");
}
else
{
sound_pain1 = gi.soundindex("hover/hovpain1.wav");
sound_pain2 = gi.soundindex("hover/hovpain2.wav");
sound_death1 = gi.soundindex("hover/hovdeth1.wav");
sound_death2 = gi.soundindex("hover/hovdeth2.wav");
sound_sight = gi.soundindex("hover/hovsght1.wav");
sound_search1 = gi.soundindex("hover/hovsrch1.wav");
sound_search2 = gi.soundindex("hover/hovsrch2.wav");
gi.soundindex("hover/hovatck1.wav");
self->s.sound = gi.soundindex("hover/hovidle1.wav");
}
gi.linkentity(self);
self->monsterinfo.currentmove = &hover_move_stand;
self->monsterinfo.scale = MODEL_SCALE;
flymonster_start(self);
if (strcmp(self->classname, "monster_daedalus") == 0)
{
self->s.skinnum = 2;
}
}

View file

@ -1,233 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Icarus and Daedalus animations.
*
* =======================================================================
*/
#define FRAME_stand01 0
#define FRAME_stand02 1
#define FRAME_stand03 2
#define FRAME_stand04 3
#define FRAME_stand05 4
#define FRAME_stand06 5
#define FRAME_stand07 6
#define FRAME_stand08 7
#define FRAME_stand09 8
#define FRAME_stand10 9
#define FRAME_stand11 10
#define FRAME_stand12 11
#define FRAME_stand13 12
#define FRAME_stand14 13
#define FRAME_stand15 14
#define FRAME_stand16 15
#define FRAME_stand17 16
#define FRAME_stand18 17
#define FRAME_stand19 18
#define FRAME_stand20 19
#define FRAME_stand21 20
#define FRAME_stand22 21
#define FRAME_stand23 22
#define FRAME_stand24 23
#define FRAME_stand25 24
#define FRAME_stand26 25
#define FRAME_stand27 26
#define FRAME_stand28 27
#define FRAME_stand29 28
#define FRAME_stand30 29
#define FRAME_forwrd01 30
#define FRAME_forwrd02 31
#define FRAME_forwrd03 32
#define FRAME_forwrd04 33
#define FRAME_forwrd05 34
#define FRAME_forwrd06 35
#define FRAME_forwrd07 36
#define FRAME_forwrd08 37
#define FRAME_forwrd09 38
#define FRAME_forwrd10 39
#define FRAME_forwrd11 40
#define FRAME_forwrd12 41
#define FRAME_forwrd13 42
#define FRAME_forwrd14 43
#define FRAME_forwrd15 44
#define FRAME_forwrd16 45
#define FRAME_forwrd17 46
#define FRAME_forwrd18 47
#define FRAME_forwrd19 48
#define FRAME_forwrd20 49
#define FRAME_forwrd21 50
#define FRAME_forwrd22 51
#define FRAME_forwrd23 52
#define FRAME_forwrd24 53
#define FRAME_forwrd25 54
#define FRAME_forwrd26 55
#define FRAME_forwrd27 56
#define FRAME_forwrd28 57
#define FRAME_forwrd29 58
#define FRAME_forwrd30 59
#define FRAME_forwrd31 60
#define FRAME_forwrd32 61
#define FRAME_forwrd33 62
#define FRAME_forwrd34 63
#define FRAME_forwrd35 64
#define FRAME_stop101 65
#define FRAME_stop102 66
#define FRAME_stop103 67
#define FRAME_stop104 68
#define FRAME_stop105 69
#define FRAME_stop106 70
#define FRAME_stop107 71
#define FRAME_stop108 72
#define FRAME_stop109 73
#define FRAME_stop201 74
#define FRAME_stop202 75
#define FRAME_stop203 76
#define FRAME_stop204 77
#define FRAME_stop205 78
#define FRAME_stop206 79
#define FRAME_stop207 80
#define FRAME_stop208 81
#define FRAME_takeof01 82
#define FRAME_takeof02 83
#define FRAME_takeof03 84
#define FRAME_takeof04 85
#define FRAME_takeof05 86
#define FRAME_takeof06 87
#define FRAME_takeof07 88
#define FRAME_takeof08 89
#define FRAME_takeof09 90
#define FRAME_takeof10 91
#define FRAME_takeof11 92
#define FRAME_takeof12 93
#define FRAME_takeof13 94
#define FRAME_takeof14 95
#define FRAME_takeof15 96
#define FRAME_takeof16 97
#define FRAME_takeof17 98
#define FRAME_takeof18 99
#define FRAME_takeof19 100
#define FRAME_takeof20 101
#define FRAME_takeof21 102
#define FRAME_takeof22 103
#define FRAME_takeof23 104
#define FRAME_takeof24 105
#define FRAME_takeof25 106
#define FRAME_takeof26 107
#define FRAME_takeof27 108
#define FRAME_takeof28 109
#define FRAME_takeof29 110
#define FRAME_takeof30 111
#define FRAME_land01 112
#define FRAME_pain101 113
#define FRAME_pain102 114
#define FRAME_pain103 115
#define FRAME_pain104 116
#define FRAME_pain105 117
#define FRAME_pain106 118
#define FRAME_pain107 119
#define FRAME_pain108 120
#define FRAME_pain109 121
#define FRAME_pain110 122
#define FRAME_pain111 123
#define FRAME_pain112 124
#define FRAME_pain113 125
#define FRAME_pain114 126
#define FRAME_pain115 127
#define FRAME_pain116 128
#define FRAME_pain117 129
#define FRAME_pain118 130
#define FRAME_pain119 131
#define FRAME_pain120 132
#define FRAME_pain121 133
#define FRAME_pain122 134
#define FRAME_pain123 135
#define FRAME_pain124 136
#define FRAME_pain125 137
#define FRAME_pain126 138
#define FRAME_pain127 139
#define FRAME_pain128 140
#define FRAME_pain201 141
#define FRAME_pain202 142
#define FRAME_pain203 143
#define FRAME_pain204 144
#define FRAME_pain205 145
#define FRAME_pain206 146
#define FRAME_pain207 147
#define FRAME_pain208 148
#define FRAME_pain209 149
#define FRAME_pain210 150
#define FRAME_pain211 151
#define FRAME_pain212 152
#define FRAME_pain301 153
#define FRAME_pain302 154
#define FRAME_pain303 155
#define FRAME_pain304 156
#define FRAME_pain305 157
#define FRAME_pain306 158
#define FRAME_pain307 159
#define FRAME_pain308 160
#define FRAME_pain309 161
#define FRAME_death101 162
#define FRAME_death102 163
#define FRAME_death103 164
#define FRAME_death104 165
#define FRAME_death105 166
#define FRAME_death106 167
#define FRAME_death107 168
#define FRAME_death108 169
#define FRAME_death109 170
#define FRAME_death110 171
#define FRAME_death111 172
#define FRAME_backwd01 173
#define FRAME_backwd02 174
#define FRAME_backwd03 175
#define FRAME_backwd04 176
#define FRAME_backwd05 177
#define FRAME_backwd06 178
#define FRAME_backwd07 179
#define FRAME_backwd08 180
#define FRAME_backwd09 181
#define FRAME_backwd10 182
#define FRAME_backwd11 183
#define FRAME_backwd12 184
#define FRAME_backwd13 185
#define FRAME_backwd14 186
#define FRAME_backwd15 187
#define FRAME_backwd16 188
#define FRAME_backwd17 189
#define FRAME_backwd18 190
#define FRAME_backwd19 191
#define FRAME_backwd20 192
#define FRAME_backwd21 193
#define FRAME_backwd22 194
#define FRAME_backwd23 195
#define FRAME_backwd24 196
#define FRAME_attak101 197
#define FRAME_attak102 198
#define FRAME_attak103 199
#define FRAME_attak104 200
#define FRAME_attak105 201
#define FRAME_attak106 202
#define FRAME_attak107 203
#define FRAME_attak108 204
#define MODEL_SCALE 1.000000

View file

@ -1,954 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* The insane earth soldiers.
*
* =======================================================================
*/
#include "../../header/local.h"
#include "insane.h"
#define SPAWNFLAG_CRUSIFIED 8
static int sound_fist;
static int sound_shake;
static int sound_moan;
static int sound_scream[8];
void insane_stand(edict_t *self);
void insane_dead(edict_t *self);
void insane_cross(edict_t *self);
void insane_walk(edict_t *self);
void insane_run(edict_t *self);
void insane_checkdown(edict_t *self);
void insane_checkup(edict_t *self);
void insane_onground(edict_t *self);
void
insane_fist(edict_t *self)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_VOICE, sound_fist, 1, ATTN_IDLE, 0);
}
void
insane_shake(edict_t *self)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_VOICE, sound_shake, 1, ATTN_IDLE, 0);
}
void
insane_moan(edict_t *self)
{
if (!self)
{
return;
}
/* suppress screaming so pain sounds can play */
if (self->fly_sound_debounce_time > level.time)
{
return;
}
gi.sound(self, CHAN_VOICE, sound_moan, 1, ATTN_IDLE, 0);
}
void
insane_scream(edict_t *self)
{
if (!self)
{
return;
}
/* suppress screaming so pain sounds can play */
if (self->fly_sound_debounce_time > level.time)
{
return;
}
gi.sound(self, CHAN_VOICE, sound_scream[rand() % 8], 1, ATTN_IDLE, 0);
}
static mframe_t insane_frames_stand_normal[] = {
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, insane_checkdown}
};
mmove_t insane_move_stand_normal = {
FRAME_stand60,
FRAME_stand65,
insane_frames_stand_normal,
insane_stand
};
static mframe_t insane_frames_stand_insane[] = {
{ai_stand, 0, insane_shake},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, insane_checkdown}
};
mmove_t insane_move_stand_insane = {
FRAME_stand65,
FRAME_stand94,
insane_frames_stand_insane,
insane_stand
};
static mframe_t insane_frames_uptodown[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, insane_moan},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 2.7, NULL},
{ai_move, 4.1, NULL},
{ai_move, 6, NULL},
{ai_move, 7.6, NULL},
{ai_move, 3.6, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, insane_fist},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, insane_fist},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t insane_move_uptodown = {
FRAME_stand1,
FRAME_stand40,
insane_frames_uptodown,
insane_onground
};
static mframe_t insane_frames_downtoup[] = {
{ai_move, -0.7, NULL}, /* 41 */
{ai_move, -1.2, NULL}, /* 42 */
{ai_move, -1.5, NULL}, /* 43 */
{ai_move, -4.5, NULL}, /* 44 */
{ai_move, -3.5, NULL}, /* 45 */
{ai_move, -0.2, NULL}, /* 46 */
{ai_move, 0, NULL}, /* 47 */
{ai_move, -1.3, NULL}, /* 48 */
{ai_move, -3, NULL}, /* 49 */
{ai_move, -2, NULL}, /* 50 */
{ai_move, 0, NULL}, /* 51 */
{ai_move, 0, NULL}, /* 52 */
{ai_move, 0, NULL}, /* 53 */
{ai_move, -3.3, NULL}, /* 54 */
{ai_move, -1.6, NULL}, /* 55 */
{ai_move, -0.3, NULL}, /* 56 */
{ai_move, 0, NULL}, /* 57 */
{ai_move, 0, NULL}, /* 58 */
{ai_move, 0, NULL} /* 59 */
};
mmove_t insane_move_downtoup = {
FRAME_stand41,
FRAME_stand59,
insane_frames_downtoup,
insane_stand
};
static mframe_t insane_frames_jumpdown[] = {
{ai_move, 0.2, NULL},
{ai_move, 11.5, NULL},
{ai_move, 5.1, NULL},
{ai_move, 7.1, NULL},
{ai_move, 0, NULL}
};
mmove_t insane_move_jumpdown = {
FRAME_stand96,
FRAME_stand100,
insane_frames_jumpdown,
insane_onground
};
static mframe_t insane_frames_down[] = {
{ai_move, 0, NULL}, /* 100 */
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}, /* 110 */
{ai_move, -1.7, NULL},
{ai_move, -1.6, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, insane_fist},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}, /* 120 */
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}, /* 130 */
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, insane_moan},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}, /* 140 */
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}, /* 150 */
{ai_move, 0.5, NULL},
{ai_move, 0, NULL},
{ai_move, -0.2, insane_scream},
{ai_move, 0, NULL},
{ai_move, 0.2, NULL},
{ai_move, 0.4, NULL},
{ai_move, 0.6, NULL},
{ai_move, 0.8, NULL},
{ai_move, 0.7, NULL},
{ai_move, 0, insane_checkup} /* 160 */
};
mmove_t insane_move_down = {
FRAME_stand100,
FRAME_stand160,
insane_frames_down,
insane_onground
};
static mframe_t insane_frames_walk_normal[] = {
{ai_walk, 0, insane_scream},
{ai_walk, 2.5, NULL},
{ai_walk, 3.5, NULL},
{ai_walk, 1.7, NULL},
{ai_walk, 2.3, NULL},
{ai_walk, 2.4, NULL},
{ai_walk, 2.2, NULL},
{ai_walk, 4.2, NULL},
{ai_walk, 5.6, NULL},
{ai_walk, 3.3, NULL},
{ai_walk, 2.4, NULL},
{ai_walk, 0.9, NULL},
{ai_walk, 0, NULL}
};
mmove_t insane_move_walk_normal = {
FRAME_walk27,
FRAME_walk39,
insane_frames_walk_normal,
insane_walk
};
mmove_t insane_move_run_normal = {
FRAME_walk27,
FRAME_walk39,
insane_frames_walk_normal,
insane_run
};
static mframe_t insane_frames_walk_insane[] = {
{ai_walk, 0, insane_scream}, /* walk 1 */
{ai_walk, 3.4, NULL}, /* walk 2 */
{ai_walk, 3.6, NULL}, /* 3 */
{ai_walk, 2.9, NULL}, /* 4 */
{ai_walk, 2.2, NULL}, /* 5 */
{ai_walk, 2.6, NULL}, /* 6 */
{ai_walk, 0, NULL}, /* 7 */
{ai_walk, 0.7, NULL}, /* 8 */
{ai_walk, 4.8, NULL}, /* 9 */
{ai_walk, 5.3, NULL}, /* 10 */
{ai_walk, 1.1, NULL}, /* 11 */
{ai_walk, 2, NULL}, /* 12 */
{ai_walk, 0.5, NULL}, /* 13 */
{ai_walk, 0, NULL}, /* 14 */
{ai_walk, 0, NULL}, /* 15 */
{ai_walk, 4.9, NULL}, /* 16 */
{ai_walk, 6.7, NULL}, /* 17 */
{ai_walk, 3.8, NULL}, /* 18 */
{ai_walk, 2, NULL}, /* 19 */
{ai_walk, 0.2, NULL}, /* 20 */
{ai_walk, 0, NULL}, /* 21 */
{ai_walk, 3.4, NULL}, /* 22 */
{ai_walk, 6.4, NULL}, /* 23 */
{ai_walk, 5, NULL}, /* 24 */
{ai_walk, 1.8, NULL}, /* 25 */
{ai_walk, 0, NULL} /* 26 */
};
mmove_t insane_move_walk_insane = {
FRAME_walk1,
FRAME_walk26,
insane_frames_walk_insane,
insane_walk
};
mmove_t insane_move_run_insane = {
FRAME_walk1,
FRAME_walk26,
insane_frames_walk_insane,
insane_run
};
static mframe_t insane_frames_stand_pain[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t insane_move_stand_pain = {
FRAME_st_pain2,
FRAME_st_pain12,
insane_frames_stand_pain,
insane_run
};
static mframe_t insane_frames_stand_death[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t insane_move_stand_death = {
FRAME_st_death2,
FRAME_st_death18,
insane_frames_stand_death,
insane_dead
};
static mframe_t insane_frames_crawl[] = {
{ai_walk, 0, insane_scream},
{ai_walk, 1.5, NULL},
{ai_walk, 2.1, NULL},
{ai_walk, 3.6, NULL},
{ai_walk, 2, NULL},
{ai_walk, 0.9, NULL},
{ai_walk, 3, NULL},
{ai_walk, 3.4, NULL},
{ai_walk, 2.4, NULL}
};
mmove_t insane_move_crawl = {
FRAME_crawl1,
FRAME_crawl9,
insane_frames_crawl,
NULL
};
mmove_t insane_move_runcrawl = {
FRAME_crawl1,
FRAME_crawl9,
insane_frames_crawl,
NULL
};
static mframe_t insane_frames_crawl_pain[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t insane_move_crawl_pain = {
FRAME_cr_pain2,
FRAME_cr_pain10,
insane_frames_crawl_pain,
insane_run
};
static mframe_t insane_frames_crawl_death[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t insane_move_crawl_death = {
FRAME_cr_death10,
FRAME_cr_death16,
insane_frames_crawl_death,
insane_dead
};
static mframe_t insane_frames_cross[] = {
{ai_move, 0, insane_moan},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t insane_move_cross = {
FRAME_cross1,
FRAME_cross15,
insane_frames_cross,
insane_cross
};
static mframe_t insane_frames_struggle_cross[] = {
{ai_move, 0, insane_scream},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t insane_move_struggle_cross = {
FRAME_cross16,
FRAME_cross30,
insane_frames_struggle_cross,
insane_cross
};
void
insane_cross(edict_t *self)
{
if (!self)
{
return;
}
if (random() < 0.8)
{
self->monsterinfo.currentmove = &insane_move_cross;
}
else
{
self->monsterinfo.currentmove = &insane_move_struggle_cross;
}
}
void
insane_walk(edict_t *self)
{
if (!self)
{
return;
}
if (self->spawnflags & 16) /* Hold Ground? */
{
if (self->s.frame == FRAME_cr_pain10)
{
self->monsterinfo.currentmove = &insane_move_down;
return;
}
}
if (self->spawnflags & 4)
{
self->monsterinfo.currentmove = &insane_move_crawl;
}
else
if (random() <= 0.5)
{
self->monsterinfo.currentmove = &insane_move_walk_normal;
}
else
{
self->monsterinfo.currentmove = &insane_move_walk_insane;
}
}
void
insane_run(edict_t *self)
{
if (!self)
{
return;
}
if (self->spawnflags & 16) /* Hold Ground? */
{
if (self->s.frame == FRAME_cr_pain10)
{
self->monsterinfo.currentmove = &insane_move_down;
return;
}
}
if (self->spawnflags & 4) /* Crawling? */
{
self->monsterinfo.currentmove = &insane_move_runcrawl;
}
else
if (random() <= 0.5) /* Else, mix it up */
{
self->monsterinfo.currentmove = &insane_move_run_normal;
}
else
{
self->monsterinfo.currentmove = &insane_move_run_insane;
}
}
void
insane_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
{
int l, r;
if (!self)
{
return;
}
if (level.time < self->pain_debounce_time)
{
return;
}
self->pain_debounce_time = level.time + 3;
r = 1 + (rand() & 1);
if (self->health < 25)
{
l = 25;
}
else if (self->health < 50)
{
l = 50;
}
else if (self->health < 75)
{
l = 75;
}
else
{
l = 100;
}
gi.sound(self, CHAN_VOICE, gi.soundindex(va("player/male/pain%i_%i.wav", l, r)), 1, ATTN_IDLE, 0);
/* suppress screaming and moaning for 1 second so pain sound plays */
self->fly_sound_debounce_time = level.time + 1;
if (skill->value == SKILL_HARDPLUS)
{
return; /* no pain anims in nightmare */
}
/* Don't go into pain frames if crucified. */
if (self->spawnflags & 8)
{
self->monsterinfo.currentmove = &insane_move_struggle_cross;
return;
}
if (((self->s.frame >= FRAME_crawl1) &&
(self->s.frame <= FRAME_crawl9)) ||
((self->s.frame >= FRAME_stand99) &&
(self->s.frame <= FRAME_stand160)))
{
self->monsterinfo.currentmove = &insane_move_crawl_pain;
}
else
{
self->monsterinfo.currentmove = &insane_move_stand_pain;
}
}
void
insane_onground(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &insane_move_down;
}
void
insane_checkdown(edict_t *self)
{
if (!self)
{
return;
}
if (self->spawnflags & 32) /* Always stand */
{
return;
}
if (random() < 0.3)
{
if (random() < 0.5)
{
self->monsterinfo.currentmove = &insane_move_uptodown;
}
else
{
self->monsterinfo.currentmove = &insane_move_jumpdown;
}
}
}
void
insane_checkup(edict_t *self)
{
if (!self)
{
return;
}
/* If Hold_Ground and Crawl are set */
if ((self->spawnflags & 4) && (self->spawnflags & 16))
{
return;
}
if (random() < 0.5)
{
self->monsterinfo.currentmove = &insane_move_downtoup;
}
}
void
insane_stand(edict_t *self)
{
if (!self)
{
return;
}
if (self->spawnflags & SPAWNFLAG_CRUSIFIED) /* If crucified */
{
self->monsterinfo.currentmove = &insane_move_cross;
self->monsterinfo.aiflags |= AI_STAND_GROUND;
}
/* If Hold_Ground and Crawl are set */
else if ((self->spawnflags & 4) && (self->spawnflags & 16))
{
self->monsterinfo.currentmove = &insane_move_down;
}
else
if (random() < 0.5)
{
self->monsterinfo.currentmove = &insane_move_stand_normal;
}
else
{
self->monsterinfo.currentmove = &insane_move_stand_insane;
}
}
void
insane_dead(edict_t *self)
{
if (!self)
{
return;
}
if (self->spawnflags & SPAWNFLAG_CRUSIFIED)
{
self->flags |= FL_FLY;
}
else
{
VectorSet(self->mins, -16, -16, -24);
VectorSet(self->maxs, 16, 16, -8);
self->movetype = MOVETYPE_TOSS;
}
self->svflags |= SVF_DEADMONSTER;
self->nextthink = 0;
gi.linkentity(self);
}
void
insane_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
int damage, vec3_t point /* unused */)
{
int n;
if (!self)
{
return;
}
if (self->health <= self->gib_health)
{
gi.sound(self, CHAN_VOICE, gi.soundindex(
"misc/udeath.wav"), 1, ATTN_IDLE, 0);
for (n = 0; n < 2; n++)
{
ThrowGib(self, "models/objects/gibs/bone/tris.md2", damage, GIB_ORGANIC);
}
for (n = 0; n < 4; n++)
{
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
}
ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC);
self->deadflag = DEAD_DEAD;
return;
}
if (self->deadflag == DEAD_DEAD)
{
return;
}
gi.sound(self, CHAN_VOICE, gi.soundindex(va("player/male/death%i.wav", (rand() % 4) + 1)), 1, ATTN_IDLE, 0);
self->deadflag = DEAD_DEAD;
self->takedamage = DAMAGE_YES;
if (self->spawnflags & SPAWNFLAG_CRUSIFIED)
{
insane_dead(self);
}
else
{
if (((self->s.frame >= FRAME_crawl1) &&
(self->s.frame <= FRAME_crawl9)) ||
((self->s.frame >= FRAME_stand99) &&
(self->s.frame <= FRAME_stand160)))
{
self->monsterinfo.currentmove = &insane_move_crawl_death;
}
else
{
self->monsterinfo.currentmove = &insane_move_stand_death;
}
}
}
/*
* QUAKED misc_insane (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn CRAWL CRUCIFIED STAND_GROUND ALWAYS_STAND
*/
void
SP_misc_insane(edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict(self);
return;
}
sound_fist = gi.soundindex("insane/insane11.wav");
sound_shake = gi.soundindex("insane/insane5.wav");
sound_moan = gi.soundindex("insane/insane7.wav");
sound_scream[0] = gi.soundindex("insane/insane1.wav");
sound_scream[1] = gi.soundindex("insane/insane2.wav");
sound_scream[2] = gi.soundindex("insane/insane3.wav");
sound_scream[3] = gi.soundindex("insane/insane4.wav");
sound_scream[4] = gi.soundindex("insane/insane6.wav");
sound_scream[5] = gi.soundindex("insane/insane8.wav");
sound_scream[6] = gi.soundindex("insane/insane9.wav");
sound_scream[7] = gi.soundindex("insane/insane10.wav");
self->movetype = MOVETYPE_STEP;
self->solid = SOLID_BBOX;
self->s.modelindex = gi.modelindex("models/monsters/insane/tris.md2");
VectorSet(self->mins, -16, -16, -24);
VectorSet(self->maxs, 16, 16, 32);
self->health = 100;
self->gib_health = -50;
self->mass = 300;
self->pain = insane_pain;
self->die = insane_die;
self->monsterinfo.stand = insane_stand;
self->monsterinfo.walk = insane_walk;
self->monsterinfo.run = insane_run;
self->monsterinfo.dodge = NULL;
self->monsterinfo.attack = NULL;
self->monsterinfo.melee = NULL;
self->monsterinfo.sight = NULL;
self->monsterinfo.aiflags |= AI_GOOD_GUY;
gi.linkentity(self);
if (self->spawnflags & 16) /* Stand Ground */
{
self->monsterinfo.aiflags |= AI_STAND_GROUND;
}
self->monsterinfo.currentmove = &insane_move_stand_normal;
self->monsterinfo.scale = MODEL_SCALE;
if (self->spawnflags & SPAWNFLAG_CRUSIFIED) /* Crucified ? */
{
VectorSet(self->mins, -16, 0, 0);
VectorSet(self->maxs, 16, 8, 32);
self->flags |= FL_NO_KNOCKBACK;
flymonster_start(self);
}
else
{
walkmonster_start(self);
self->s.skinnum = rand() % 3;
}
}

View file

@ -1,310 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Insane animations
*
* =======================================================================
*/
#define FRAME_stand1 0
#define FRAME_stand2 1
#define FRAME_stand3 2
#define FRAME_stand4 3
#define FRAME_stand5 4
#define FRAME_stand6 5
#define FRAME_stand7 6
#define FRAME_stand8 7
#define FRAME_stand9 8
#define FRAME_stand10 9
#define FRAME_stand11 10
#define FRAME_stand12 11
#define FRAME_stand13 12
#define FRAME_stand14 13
#define FRAME_stand15 14
#define FRAME_stand16 15
#define FRAME_stand17 16
#define FRAME_stand18 17
#define FRAME_stand19 18
#define FRAME_stand20 19
#define FRAME_stand21 20
#define FRAME_stand22 21
#define FRAME_stand23 22
#define FRAME_stand24 23
#define FRAME_stand25 24
#define FRAME_stand26 25
#define FRAME_stand27 26
#define FRAME_stand28 27
#define FRAME_stand29 28
#define FRAME_stand30 29
#define FRAME_stand31 30
#define FRAME_stand32 31
#define FRAME_stand33 32
#define FRAME_stand34 33
#define FRAME_stand35 34
#define FRAME_stand36 35
#define FRAME_stand37 36
#define FRAME_stand38 37
#define FRAME_stand39 38
#define FRAME_stand40 39
#define FRAME_stand41 40
#define FRAME_stand42 41
#define FRAME_stand43 42
#define FRAME_stand44 43
#define FRAME_stand45 44
#define FRAME_stand46 45
#define FRAME_stand47 46
#define FRAME_stand48 47
#define FRAME_stand49 48
#define FRAME_stand50 49
#define FRAME_stand51 50
#define FRAME_stand52 51
#define FRAME_stand53 52
#define FRAME_stand54 53
#define FRAME_stand55 54
#define FRAME_stand56 55
#define FRAME_stand57 56
#define FRAME_stand58 57
#define FRAME_stand59 58
#define FRAME_stand60 59
#define FRAME_stand61 60
#define FRAME_stand62 61
#define FRAME_stand63 62
#define FRAME_stand64 63
#define FRAME_stand65 64
#define FRAME_stand66 65
#define FRAME_stand67 66
#define FRAME_stand68 67
#define FRAME_stand69 68
#define FRAME_stand70 69
#define FRAME_stand71 70
#define FRAME_stand72 71
#define FRAME_stand73 72
#define FRAME_stand74 73
#define FRAME_stand75 74
#define FRAME_stand76 75
#define FRAME_stand77 76
#define FRAME_stand78 77
#define FRAME_stand79 78
#define FRAME_stand80 79
#define FRAME_stand81 80
#define FRAME_stand82 81
#define FRAME_stand83 82
#define FRAME_stand84 83
#define FRAME_stand85 84
#define FRAME_stand86 85
#define FRAME_stand87 86
#define FRAME_stand88 87
#define FRAME_stand89 88
#define FRAME_stand90 89
#define FRAME_stand91 90
#define FRAME_stand92 91
#define FRAME_stand93 92
#define FRAME_stand94 93
#define FRAME_stand95 94
#define FRAME_stand96 95
#define FRAME_stand97 96
#define FRAME_stand98 97
#define FRAME_stand99 98
#define FRAME_stand100 99
#define FRAME_stand101 100
#define FRAME_stand102 101
#define FRAME_stand103 102
#define FRAME_stand104 103
#define FRAME_stand105 104
#define FRAME_stand106 105
#define FRAME_stand107 106
#define FRAME_stand108 107
#define FRAME_stand109 108
#define FRAME_stand110 109
#define FRAME_stand111 110
#define FRAME_stand112 111
#define FRAME_stand113 112
#define FRAME_stand114 113
#define FRAME_stand115 114
#define FRAME_stand116 115
#define FRAME_stand117 116
#define FRAME_stand118 117
#define FRAME_stand119 118
#define FRAME_stand120 119
#define FRAME_stand121 120
#define FRAME_stand122 121
#define FRAME_stand123 122
#define FRAME_stand124 123
#define FRAME_stand125 124
#define FRAME_stand126 125
#define FRAME_stand127 126
#define FRAME_stand128 127
#define FRAME_stand129 128
#define FRAME_stand130 129
#define FRAME_stand131 130
#define FRAME_stand132 131
#define FRAME_stand133 132
#define FRAME_stand134 133
#define FRAME_stand135 134
#define FRAME_stand136 135
#define FRAME_stand137 136
#define FRAME_stand138 137
#define FRAME_stand139 138
#define FRAME_stand140 139
#define FRAME_stand141 140
#define FRAME_stand142 141
#define FRAME_stand143 142
#define FRAME_stand144 143
#define FRAME_stand145 144
#define FRAME_stand146 145
#define FRAME_stand147 146
#define FRAME_stand148 147
#define FRAME_stand149 148
#define FRAME_stand150 149
#define FRAME_stand151 150
#define FRAME_stand152 151
#define FRAME_stand153 152
#define FRAME_stand154 153
#define FRAME_stand155 154
#define FRAME_stand156 155
#define FRAME_stand157 156
#define FRAME_stand158 157
#define FRAME_stand159 158
#define FRAME_stand160 159
#define FRAME_walk27 160
#define FRAME_walk28 161
#define FRAME_walk29 162
#define FRAME_walk30 163
#define FRAME_walk31 164
#define FRAME_walk32 165
#define FRAME_walk33 166
#define FRAME_walk34 167
#define FRAME_walk35 168
#define FRAME_walk36 169
#define FRAME_walk37 170
#define FRAME_walk38 171
#define FRAME_walk39 172
#define FRAME_walk1 173
#define FRAME_walk2 174
#define FRAME_walk3 175
#define FRAME_walk4 176
#define FRAME_walk5 177
#define FRAME_walk6 178
#define FRAME_walk7 179
#define FRAME_walk8 180
#define FRAME_walk9 181
#define FRAME_walk10 182
#define FRAME_walk11 183
#define FRAME_walk12 184
#define FRAME_walk13 185
#define FRAME_walk14 186
#define FRAME_walk15 187
#define FRAME_walk16 188
#define FRAME_walk17 189
#define FRAME_walk18 190
#define FRAME_walk19 191
#define FRAME_walk20 192
#define FRAME_walk21 193
#define FRAME_walk22 194
#define FRAME_walk23 195
#define FRAME_walk24 196
#define FRAME_walk25 197
#define FRAME_walk26 198
#define FRAME_st_pain2 199
#define FRAME_st_pain3 200
#define FRAME_st_pain4 201
#define FRAME_st_pain5 202
#define FRAME_st_pain6 203
#define FRAME_st_pain7 204
#define FRAME_st_pain8 205
#define FRAME_st_pain9 206
#define FRAME_st_pain10 207
#define FRAME_st_pain11 208
#define FRAME_st_pain12 209
#define FRAME_st_death2 210
#define FRAME_st_death3 211
#define FRAME_st_death4 212
#define FRAME_st_death5 213
#define FRAME_st_death6 214
#define FRAME_st_death7 215
#define FRAME_st_death8 216
#define FRAME_st_death9 217
#define FRAME_st_death10 218
#define FRAME_st_death11 219
#define FRAME_st_death12 220
#define FRAME_st_death13 221
#define FRAME_st_death14 222
#define FRAME_st_death15 223
#define FRAME_st_death16 224
#define FRAME_st_death17 225
#define FRAME_st_death18 226
#define FRAME_crawl1 227
#define FRAME_crawl2 228
#define FRAME_crawl3 229
#define FRAME_crawl4 230
#define FRAME_crawl5 231
#define FRAME_crawl6 232
#define FRAME_crawl7 233
#define FRAME_crawl8 234
#define FRAME_crawl9 235
#define FRAME_cr_pain2 236
#define FRAME_cr_pain3 237
#define FRAME_cr_pain4 238
#define FRAME_cr_pain5 239
#define FRAME_cr_pain6 240
#define FRAME_cr_pain7 241
#define FRAME_cr_pain8 242
#define FRAME_cr_pain9 243
#define FRAME_cr_pain10 244
#define FRAME_cr_death10 245
#define FRAME_cr_death11 246
#define FRAME_cr_death12 247
#define FRAME_cr_death13 248
#define FRAME_cr_death14 249
#define FRAME_cr_death15 250
#define FRAME_cr_death16 251
#define FRAME_cross1 252
#define FRAME_cross2 253
#define FRAME_cross3 254
#define FRAME_cross4 255
#define FRAME_cross5 256
#define FRAME_cross6 257
#define FRAME_cross7 258
#define FRAME_cross8 259
#define FRAME_cross9 260
#define FRAME_cross10 261
#define FRAME_cross11 262
#define FRAME_cross12 263
#define FRAME_cross13 264
#define FRAME_cross14 265
#define FRAME_cross15 266
#define FRAME_cross16 267
#define FRAME_cross17 268
#define FRAME_cross18 269
#define FRAME_cross19 270
#define FRAME_cross20 271
#define FRAME_cross21 272
#define FRAME_cross22 273
#define FRAME_cross23 274
#define FRAME_cross24 275
#define FRAME_cross25 276
#define FRAME_cross26 277
#define FRAME_cross27 278
#define FRAME_cross28 279
#define FRAME_cross29 280
#define FRAME_cross30 281
#define MODEL_SCALE 1.000000

File diff suppressed because it is too large Load diff

View file

@ -1,265 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Medic and Medic Commander animations.
*
* =======================================================================
*/
#define FRAME_walk1 0
#define FRAME_walk2 1
#define FRAME_walk3 2
#define FRAME_walk4 3
#define FRAME_walk5 4
#define FRAME_walk6 5
#define FRAME_walk7 6
#define FRAME_walk8 7
#define FRAME_walk9 8
#define FRAME_walk10 9
#define FRAME_walk11 10
#define FRAME_walk12 11
#define FRAME_wait1 12
#define FRAME_wait2 13
#define FRAME_wait3 14
#define FRAME_wait4 15
#define FRAME_wait5 16
#define FRAME_wait6 17
#define FRAME_wait7 18
#define FRAME_wait8 19
#define FRAME_wait9 20
#define FRAME_wait10 21
#define FRAME_wait11 22
#define FRAME_wait12 23
#define FRAME_wait13 24
#define FRAME_wait14 25
#define FRAME_wait15 26
#define FRAME_wait16 27
#define FRAME_wait17 28
#define FRAME_wait18 29
#define FRAME_wait19 30
#define FRAME_wait20 31
#define FRAME_wait21 32
#define FRAME_wait22 33
#define FRAME_wait23 34
#define FRAME_wait24 35
#define FRAME_wait25 36
#define FRAME_wait26 37
#define FRAME_wait27 38
#define FRAME_wait28 39
#define FRAME_wait29 40
#define FRAME_wait30 41
#define FRAME_wait31 42
#define FRAME_wait32 43
#define FRAME_wait33 44
#define FRAME_wait34 45
#define FRAME_wait35 46
#define FRAME_wait36 47
#define FRAME_wait37 48
#define FRAME_wait38 49
#define FRAME_wait39 50
#define FRAME_wait40 51
#define FRAME_wait41 52
#define FRAME_wait42 53
#define FRAME_wait43 54
#define FRAME_wait44 55
#define FRAME_wait45 56
#define FRAME_wait46 57
#define FRAME_wait47 58
#define FRAME_wait48 59
#define FRAME_wait49 60
#define FRAME_wait50 61
#define FRAME_wait51 62
#define FRAME_wait52 63
#define FRAME_wait53 64
#define FRAME_wait54 65
#define FRAME_wait55 66
#define FRAME_wait56 67
#define FRAME_wait57 68
#define FRAME_wait58 69
#define FRAME_wait59 70
#define FRAME_wait60 71
#define FRAME_wait61 72
#define FRAME_wait62 73
#define FRAME_wait63 74
#define FRAME_wait64 75
#define FRAME_wait65 76
#define FRAME_wait66 77
#define FRAME_wait67 78
#define FRAME_wait68 79
#define FRAME_wait69 80
#define FRAME_wait70 81
#define FRAME_wait71 82
#define FRAME_wait72 83
#define FRAME_wait73 84
#define FRAME_wait74 85
#define FRAME_wait75 86
#define FRAME_wait76 87
#define FRAME_wait77 88
#define FRAME_wait78 89
#define FRAME_wait79 90
#define FRAME_wait80 91
#define FRAME_wait81 92
#define FRAME_wait82 93
#define FRAME_wait83 94
#define FRAME_wait84 95
#define FRAME_wait85 96
#define FRAME_wait86 97
#define FRAME_wait87 98
#define FRAME_wait88 99
#define FRAME_wait89 100
#define FRAME_wait90 101
#define FRAME_run1 102
#define FRAME_run2 103
#define FRAME_run3 104
#define FRAME_run4 105
#define FRAME_run5 106
#define FRAME_run6 107
#define FRAME_paina1 108
#define FRAME_paina2 109
#define FRAME_paina3 110
#define FRAME_paina4 111
#define FRAME_paina5 112
#define FRAME_paina6 113
#define FRAME_paina7 114
#define FRAME_paina8 115
#define FRAME_painb1 116
#define FRAME_painb2 117
#define FRAME_painb3 118
#define FRAME_painb4 119
#define FRAME_painb5 120
#define FRAME_painb6 121
#define FRAME_painb7 122
#define FRAME_painb8 123
#define FRAME_painb9 124
#define FRAME_painb10 125
#define FRAME_painb11 126
#define FRAME_painb12 127
#define FRAME_painb13 128
#define FRAME_painb14 129
#define FRAME_painb15 130
#define FRAME_duck1 131
#define FRAME_duck2 132
#define FRAME_duck3 133
#define FRAME_duck4 134
#define FRAME_duck5 135
#define FRAME_duck6 136
#define FRAME_duck7 137
#define FRAME_duck8 138
#define FRAME_duck9 139
#define FRAME_duck10 140
#define FRAME_duck11 141
#define FRAME_duck12 142
#define FRAME_duck13 143
#define FRAME_duck14 144
#define FRAME_duck15 145
#define FRAME_duck16 146
#define FRAME_death1 147
#define FRAME_death2 148
#define FRAME_death3 149
#define FRAME_death4 150
#define FRAME_death5 151
#define FRAME_death6 152
#define FRAME_death7 153
#define FRAME_death8 154
#define FRAME_death9 155
#define FRAME_death10 156
#define FRAME_death11 157
#define FRAME_death12 158
#define FRAME_death13 159
#define FRAME_death14 160
#define FRAME_death15 161
#define FRAME_death16 162
#define FRAME_death17 163
#define FRAME_death18 164
#define FRAME_death19 165
#define FRAME_death20 166
#define FRAME_death21 167
#define FRAME_death22 168
#define FRAME_death23 169
#define FRAME_death24 170
#define FRAME_death25 171
#define FRAME_death26 172
#define FRAME_death27 173
#define FRAME_death28 174
#define FRAME_death29 175
#define FRAME_death30 176
#define FRAME_attack1 177
#define FRAME_attack2 178
#define FRAME_attack3 179
#define FRAME_attack4 180
#define FRAME_attack5 181
#define FRAME_attack6 182
#define FRAME_attack7 183
#define FRAME_attack8 184
#define FRAME_attack9 185
#define FRAME_attack10 186
#define FRAME_attack11 187
#define FRAME_attack12 188
#define FRAME_attack13 189
#define FRAME_attack14 190
#define FRAME_attack15 191
#define FRAME_attack16 192
#define FRAME_attack17 193
#define FRAME_attack18 194
#define FRAME_attack19 195
#define FRAME_attack20 196
#define FRAME_attack21 197
#define FRAME_attack22 198
#define FRAME_attack23 199
#define FRAME_attack24 200
#define FRAME_attack25 201
#define FRAME_attack26 202
#define FRAME_attack27 203
#define FRAME_attack28 204
#define FRAME_attack29 205
#define FRAME_attack30 206
#define FRAME_attack31 207
#define FRAME_attack32 208
#define FRAME_attack33 209
#define FRAME_attack34 210
#define FRAME_attack35 211
#define FRAME_attack36 212
#define FRAME_attack37 213
#define FRAME_attack38 214
#define FRAME_attack39 215
#define FRAME_attack40 216
#define FRAME_attack41 217
#define FRAME_attack42 218
#define FRAME_attack43 219
#define FRAME_attack44 220
#define FRAME_attack45 221
#define FRAME_attack46 222
#define FRAME_attack47 223
#define FRAME_attack48 224
#define FRAME_attack49 225
#define FRAME_attack50 226
#define FRAME_attack51 227
#define FRAME_attack52 228
#define FRAME_attack53 229
#define FRAME_attack54 230
#define FRAME_attack55 231
#define FRAME_attack56 232
#define FRAME_attack57 233
#define FRAME_attack58 234
#define FRAME_attack59 235
#define FRAME_attack60 236
#define MODEL_SCALE 1.000000

View file

@ -1,875 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Monster movement support functions.
*
* =======================================================================
*/
#include "../../header/local.h"
#define DI_NODIR -1
#define STEPSIZE 18
/* this is used for communications out of
* sv_movestep to say what entity is blocking us */
edict_t *new_bad;
/*
* Returns false if any part of the bottom of the
* entity is off an edge that is not a staircase.
*/
qboolean
M_CheckBottom(edict_t *ent)
{
vec3_t mins, maxs, start, stop;
trace_t trace;
int x, y;
float mid, bottom;
if (!ent)
{
return false;
}
VectorAdd(ent->s.origin, ent->mins, mins);
VectorAdd(ent->s.origin, ent->maxs, maxs);
/* if all of the points under the corners are solid world, don't bother
with the tougher checksthe corners must be within 16 of the midpoint */
start[2] = mins[2] - 1;
if (ent->gravityVector[2] > 0)
{
start[2] = maxs[2] + 1;
}
for (x = 0; x <= 1; x++)
{
for (y = 0; y <= 1; y++)
{
start[0] = x ? maxs[0] : mins[0];
start[1] = y ? maxs[1] : mins[1];
if (gi.pointcontents(start) != CONTENTS_SOLID)
{
goto realcheck;
}
}
}
return true; /* we got out easy */
realcheck:
start[2] = mins[2];
/* the midpoint must be within 16 of the bottom */
start[0] = stop[0] = (mins[0] + maxs[0]) * 0.5;
start[1] = stop[1] = (mins[1] + maxs[1]) * 0.5;
if (ent->gravityVector[2] < 0)
{
start[2] = mins[2];
stop[2] = start[2] - STEPSIZE - STEPSIZE;
}
else
{
start[2] = maxs[2];
stop[2] = start[2] + STEPSIZE + STEPSIZE;
}
trace = gi.trace(start, vec3_origin, vec3_origin,
stop, ent, MASK_MONSTERSOLID);
if (trace.fraction == 1.0)
{
return false;
}
mid = bottom = trace.endpos[2];
/* the corners must be within 16 of the midpoint */
for (x = 0; x <= 1; x++)
{
for (y = 0; y <= 1; y++)
{
start[0] = stop[0] = x ? maxs[0] : mins[0];
start[1] = stop[1] = y ? maxs[1] : mins[1];
trace = gi.trace(start, vec3_origin, vec3_origin,
stop, ent, MASK_MONSTERSOLID);
if (ent->gravityVector[2] > 0)
{
if ((trace.fraction != 1.0) && (trace.endpos[2] < bottom))
{
bottom = trace.endpos[2];
}
if ((trace.fraction == 1.0) ||
(trace.endpos[2] - mid > STEPSIZE))
{
return false;
}
}
else
{
if ((trace.fraction != 1.0) && (trace.endpos[2] > bottom))
{
bottom = trace.endpos[2];
}
if ((trace.fraction == 1.0) ||
(mid - trace.endpos[2] > STEPSIZE))
{
return false;
}
}
}
}
return true;
}
qboolean
IsBadAhead(edict_t *self, edict_t *bad, vec3_t move)
{
vec3_t dir;
vec3_t forward;
float dp_bad, dp_move;
vec3_t move_copy;
if (!self || !bad)
{
return false;
}
VectorCopy(move, move_copy);
VectorSubtract(bad->s.origin, self->s.origin, dir);
VectorNormalize(dir);
AngleVectors(self->s.angles, forward, NULL, NULL);
dp_bad = DotProduct(forward, dir);
VectorNormalize(move_copy);
AngleVectors(self->s.angles, forward, NULL, NULL);
dp_move = DotProduct(forward, move_copy);
if ((dp_bad < 0) && (dp_move < 0))
{
return true;
}
if ((dp_bad > 0) && (dp_move > 0))
{
return true;
}
return false;
}
/*
* The move will be adjusted for slopes and stairs, but if the move isn't
* possible, no move is done, false is returned, and
* pr_global_struct->trace_normal is set to the normal of the blocking wall
*/
qboolean
SV_movestep(edict_t *ent, vec3_t move, qboolean relink)
{
float dz;
vec3_t oldorg, neworg, end;
trace_t trace;
int i;
float stepsize;
vec3_t test;
int contents;
edict_t *current_bad = NULL;
float minheight;
if (!ent)
{
return false;
}
if (ent->health > 0)
{
current_bad = CheckForBadArea(ent);
if (current_bad)
{
ent->bad_area = current_bad;
if (ent->enemy && !strcmp(ent->enemy->classname, "tesla"))
{
/* if the tesla is in front of us, back up... */
if (IsBadAhead(ent, current_bad, move))
{
VectorScale(move, -1, move);
}
}
}
else if (ent->bad_area)
{
/* if we're no longer in a bad area, get back to business. */
ent->bad_area = NULL;
if (ent->oldenemy)
{
ent->enemy = ent->oldenemy;
ent->goalentity = ent->oldenemy;
FoundTarget(ent);
return true;
}
}
}
/* try the move */
VectorCopy(ent->s.origin, oldorg);
VectorAdd(ent->s.origin, move, neworg);
/* flying monsters don't step up */
if (ent->flags & (FL_SWIM | FL_FLY))
{
/* try one move with vertical motion, then one without */
for (i = 0; i < 2; i++)
{
VectorAdd(ent->s.origin, move, neworg);
if ((i == 0) && ent->enemy)
{
if (!ent->goalentity)
{
ent->goalentity = ent->enemy;
}
dz = ent->s.origin[2] - ent->goalentity->s.origin[2];
if (ent->goalentity->client)
{
/* we want the carrier to stay a certain distance off the ground,
to help prevent him from shooting his fliers, who spawn in below him */
if (!strcmp(ent->classname, "monster_carrier"))
{
minheight = 104;
}
else
{
minheight = 40;
}
if (dz > minheight)
{
neworg[2] -= 8;
}
if (!((ent->flags & FL_SWIM) && (ent->waterlevel < 2)))
{
if (dz < (minheight - 10))
{
neworg[2] += 8;
}
}
}
else
{
if (dz > 8)
{
neworg[2] -= 8;
}
else if (dz > 0)
{
neworg[2] -= dz;
}
else if (dz < -8)
{
neworg[2] += 8;
}
else
{
neworg[2] += dz;
}
}
}
trace = gi.trace(ent->s.origin, ent->mins, ent->maxs, neworg,
ent, MASK_MONSTERSOLID);
/* fly monsters don't enter water voluntarily */
if (ent->flags & FL_FLY)
{
if (!ent->waterlevel)
{
test[0] = trace.endpos[0];
test[1] = trace.endpos[1];
test[2] = trace.endpos[2] + ent->mins[2] + 1;
contents = gi.pointcontents(test);
if (contents & MASK_WATER)
{
return false;
}
}
}
/* swim monsters don't exit water voluntarily */
if (ent->flags & FL_SWIM)
{
if (ent->waterlevel < 2)
{
test[0] = trace.endpos[0];
test[1] = trace.endpos[1];
test[2] = trace.endpos[2] + ent->mins[2] + 1;
contents = gi.pointcontents(test);
if (!(contents & MASK_WATER))
{
return false;
}
}
}
if ((trace.fraction == 1) && (!trace.allsolid) && (!trace.startsolid))
{
VectorCopy(trace.endpos, ent->s.origin);
if (!current_bad && CheckForBadArea(ent))
{
VectorCopy(oldorg, ent->s.origin);
}
else
{
if (relink)
{
gi.linkentity(ent);
G_TouchTriggers(ent);
}
return true;
}
}
if (!ent->enemy)
{
break;
}
}
return false;
}
/* push down from a step height above the wished position */
if (!(ent->monsterinfo.aiflags & AI_NOSTEP))
{
stepsize = STEPSIZE;
}
else
{
stepsize = 1;
}
/* trace from 1 stepsize gravityUp to 2 stepsize gravityDown. */
VectorMA(neworg, -1 * stepsize, ent->gravityVector, neworg);
VectorMA(neworg, 2 * stepsize, ent->gravityVector, end);
trace = gi.trace(neworg, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID);
if (trace.allsolid)
{
return false;
}
if (trace.startsolid)
{
neworg[2] -= stepsize;
trace = gi.trace(neworg, ent->mins, ent->maxs, end,
ent, MASK_MONSTERSOLID);
if (trace.allsolid || trace.startsolid)
{
return false;
}
}
/* don't go in to water */
if (ent->waterlevel == 0)
{
test[0] = trace.endpos[0];
test[1] = trace.endpos[1];
if (ent->gravityVector[2] > 0)
{
test[2] = trace.endpos[2] + ent->maxs[2] - 1;
}
else
{
test[2] = trace.endpos[2] + ent->mins[2] + 1;
}
contents = gi.pointcontents(test);
if (contents & MASK_WATER)
{
return false;
}
}
if (trace.fraction == 1)
{
/* if monster had the ground pulled out, go ahead and fall */
if (ent->flags & FL_PARTIALGROUND)
{
VectorAdd(ent->s.origin, move, ent->s.origin);
if (relink)
{
gi.linkentity(ent);
G_TouchTriggers(ent);
}
ent->groundentity = NULL;
return true;
}
return false;/* walked off an edge */
}
/* check point traces down for dangling corners */
VectorCopy(trace.endpos, ent->s.origin);
if (ent->health > 0)
{
/* use AI_BLOCKED to tell the calling layer that we're now mad at a tesla */
new_bad = CheckForBadArea(ent);
if (!current_bad && new_bad)
{
if (new_bad->owner && !strcmp(new_bad->owner->classname, "tesla"))
{
if (!ent->enemy || !ent->enemy->inuse ||
!ent->enemy->client || !visible(ent, ent->enemy))
{
TargetTesla(ent, new_bad->owner);
ent->monsterinfo.aiflags |= AI_BLOCKED;
}
}
VectorCopy(oldorg, ent->s.origin);
return false;
}
}
if (!M_CheckBottom(ent))
{
if (ent->flags & FL_PARTIALGROUND)
{
/* entity had floor mostly pulled out from
nderneath it and is trying to correct */
if (relink)
{
gi.linkentity(ent);
G_TouchTriggers(ent);
}
return true;
}
VectorCopy(oldorg, ent->s.origin);
return false;
}
if (ent->flags & FL_PARTIALGROUND)
{
ent->flags &= ~FL_PARTIALGROUND;
}
ent->groundentity = trace.ent;
ent->groundentity_linkcount = trace.ent->linkcount;
if (relink)
{
gi.linkentity(ent);
G_TouchTriggers(ent);
}
return true;
}
/* ============================================================================ */
void
M_ChangeYaw(edict_t *ent)
{
float ideal;
float current;
float move;
float speed;
if (!ent)
{
return;
}
current = anglemod(ent->s.angles[YAW]);
ideal = ent->ideal_yaw;
if (current == ideal)
{
return;
}
move = ideal - current;
speed = ent->yaw_speed;
if (ideal > current)
{
if (move >= 180)
{
move = move - 360;
}
}
else
{
if (move <= -180)
{
move = move + 360;
}
}
if (move > 0)
{
if (move > speed)
{
move = speed;
}
}
else
{
if (move < -speed)
{
move = -speed;
}
}
ent->s.angles[YAW] = anglemod(current + move);
}
/*
* Turns to the movement direction, and
* walks the current distance if facing it.
*/
qboolean
SV_StepDirection(edict_t *ent, float yaw, float dist)
{
vec3_t move, oldorigin;
float delta;
if (!ent)
{
return false;
}
if (!ent->inuse)
{
return true;
}
ent->ideal_yaw = yaw;
M_ChangeYaw(ent);
yaw = yaw * M_PI * 2 / 360;
move[0] = cos(yaw) * dist;
move[1] = sin(yaw) * dist;
move[2] = 0;
VectorCopy(ent->s.origin, oldorigin);
if (SV_movestep(ent, move, false))
{
ent->monsterinfo.aiflags &= ~AI_BLOCKED;
if (!ent->inuse)
{
return true;
}
delta = ent->s.angles[YAW] - ent->ideal_yaw;
if (strncmp(ent->classname, "monster_widow", 13))
{
if ((delta > 45) && (delta < 315))
{
/* not turned far enough, so don't take the step */
VectorCopy(oldorigin, ent->s.origin);
}
}
gi.linkentity(ent);
G_TouchTriggers(ent);
return true;
}
gi.linkentity(ent);
G_TouchTriggers(ent);
return false;
}
void
SV_FixCheckBottom(edict_t *ent)
{
if (!ent)
{
return;
}
ent->flags |= FL_PARTIALGROUND;
}
void
SV_NewChaseDir(edict_t *actor, edict_t *enemy, float dist)
{
float deltax, deltay;
float d[3];
float tdir, olddir, turnaround;
if (!actor || !enemy)
{
return;
}
olddir = anglemod((int)(actor->ideal_yaw / 45) * 45);
turnaround = anglemod(olddir - 180);
deltax = enemy->s.origin[0] - actor->s.origin[0];
deltay = enemy->s.origin[1] - actor->s.origin[1];
if (deltax > 10)
{
d[1] = 0;
}
else if (deltax < -10)
{
d[1] = 180;
}
else
{
d[1] = DI_NODIR;
}
if (deltay < -10)
{
d[2] = 270;
}
else if (deltay > 10)
{
d[2] = 90;
}
else
{
d[2] = DI_NODIR;
}
/* try direct route */
if ((d[1] != DI_NODIR) && (d[2] != DI_NODIR))
{
if (d[1] == 0)
{
tdir = d[2] == 90 ? 45 : 315;
}
else
{
tdir = d[2] == 90 ? 135 : 215;
}
if ((tdir != turnaround) && SV_StepDirection(actor, tdir, dist))
{
return;
}
}
/* try other directions */
if (((rand() & 3) & 1) || (fabsf(deltay) > fabsf(deltax)))
{
tdir = d[1];
d[1] = d[2];
d[2] = tdir;
}
if ((d[1] != DI_NODIR) && (d[1] != turnaround) &&
SV_StepDirection(actor, d[1], dist))
{
return;
}
if ((d[2] != DI_NODIR) && (d[2] != turnaround) &&
SV_StepDirection(actor, d[2], dist))
{
return;
}
if (actor->monsterinfo.blocked)
{
if ((actor->inuse) && (actor->health > 0))
{
if ((actor->monsterinfo.blocked)(actor, dist))
{
return;
}
}
}
if ((olddir != DI_NODIR) && SV_StepDirection(actor, olddir, dist))
{
return;
}
if (rand() & 1) /*randomly determine direction of search*/
{
for (tdir = 0; tdir <= 315; tdir += 45)
{
if ((tdir != turnaround) && SV_StepDirection(actor, tdir, dist))
{
return;
}
}
}
else
{
for (tdir = 315; tdir >= 0; tdir -= 45)
{
if ((tdir != turnaround) && SV_StepDirection(actor, tdir, dist))
{
return;
}
}
}
if ((turnaround != DI_NODIR) && SV_StepDirection(actor, turnaround, dist))
{
return;
}
actor->ideal_yaw = olddir; /* can't move */
/* if a bridge was pulled out from underneath a monster,
it may not have a valid standing position at all */
if (!M_CheckBottom(actor))
{
SV_FixCheckBottom(actor);
}
}
qboolean
SV_CloseEnough(edict_t *ent, edict_t *goal, float dist)
{
int i;
if (!ent || !goal)
{
return false;
}
for (i = 0; i < 3; i++)
{
if (goal->absmin[i] > ent->absmax[i] + dist)
{
return false;
}
if (goal->absmax[i] < ent->absmin[i] - dist)
{
return false;
}
}
return true;
}
void
M_MoveToGoal(edict_t *ent, float dist)
{
edict_t *goal;
if (!ent)
{
return;
}
goal = ent->goalentity;
if (!ent->groundentity && !(ent->flags & (FL_FLY | FL_SWIM)))
{
return;
}
/* if the next step hits the enemy, return immediately */
if (ent->enemy && SV_CloseEnough(ent, ent->enemy, dist))
{
return;
}
if ((((rand() & 3) == 1) &&
!(ent->monsterinfo.aiflags & AI_CHARGING)) ||
!SV_StepDirection(ent, ent->ideal_yaw, dist))
{
if (ent->monsterinfo.aiflags & AI_BLOCKED)
{
ent->monsterinfo.aiflags &= ~AI_BLOCKED;
return;
}
if (ent->inuse)
{
SV_NewChaseDir(ent, goal, dist);
}
}
}
qboolean
M_walkmove(edict_t *ent, float yaw, float dist)
{
vec3_t move;
qboolean retval;
if (!ent)
{
return false;
}
if (!ent->groundentity && !(ent->flags & (FL_FLY | FL_SWIM)))
{
return false;
}
yaw = yaw * M_PI * 2 / 360;
move[0] = cos(yaw) * dist;
move[1] = sin(yaw) * dist;
move[2] = 0;
retval = SV_movestep(ent, move, true);
ent->monsterinfo.aiflags &= ~AI_BLOCKED;
return retval;
}

View file

@ -1,226 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Player (the arm and the weapons) animation.
*
* =======================================================================
*/
#define FRAME_stand01 0
#define FRAME_stand02 1
#define FRAME_stand03 2
#define FRAME_stand04 3
#define FRAME_stand05 4
#define FRAME_stand06 5
#define FRAME_stand07 6
#define FRAME_stand08 7
#define FRAME_stand09 8
#define FRAME_stand10 9
#define FRAME_stand11 10
#define FRAME_stand12 11
#define FRAME_stand13 12
#define FRAME_stand14 13
#define FRAME_stand15 14
#define FRAME_stand16 15
#define FRAME_stand17 16
#define FRAME_stand18 17
#define FRAME_stand19 18
#define FRAME_stand20 19
#define FRAME_stand21 20
#define FRAME_stand22 21
#define FRAME_stand23 22
#define FRAME_stand24 23
#define FRAME_stand25 24
#define FRAME_stand26 25
#define FRAME_stand27 26
#define FRAME_stand28 27
#define FRAME_stand29 28
#define FRAME_stand30 29
#define FRAME_stand31 30
#define FRAME_stand32 31
#define FRAME_stand33 32
#define FRAME_stand34 33
#define FRAME_stand35 34
#define FRAME_stand36 35
#define FRAME_stand37 36
#define FRAME_stand38 37
#define FRAME_stand39 38
#define FRAME_stand40 39
#define FRAME_run1 40
#define FRAME_run2 41
#define FRAME_run3 42
#define FRAME_run4 43
#define FRAME_run5 44
#define FRAME_run6 45
#define FRAME_attack1 46
#define FRAME_attack2 47
#define FRAME_attack3 48
#define FRAME_attack4 49
#define FRAME_attack5 50
#define FRAME_attack6 51
#define FRAME_attack7 52
#define FRAME_attack8 53
#define FRAME_pain101 54
#define FRAME_pain102 55
#define FRAME_pain103 56
#define FRAME_pain104 57
#define FRAME_pain201 58
#define FRAME_pain202 59
#define FRAME_pain203 60
#define FRAME_pain204 61
#define FRAME_pain301 62
#define FRAME_pain302 63
#define FRAME_pain303 64
#define FRAME_pain304 65
#define FRAME_jump1 66
#define FRAME_jump2 67
#define FRAME_jump3 68
#define FRAME_jump4 69
#define FRAME_jump5 70
#define FRAME_jump6 71
#define FRAME_flip01 72
#define FRAME_flip02 73
#define FRAME_flip03 74
#define FRAME_flip04 75
#define FRAME_flip05 76
#define FRAME_flip06 77
#define FRAME_flip07 78
#define FRAME_flip08 79
#define FRAME_flip09 80
#define FRAME_flip10 81
#define FRAME_flip11 82
#define FRAME_flip12 83
#define FRAME_salute01 84
#define FRAME_salute02 85
#define FRAME_salute03 86
#define FRAME_salute04 87
#define FRAME_salute05 88
#define FRAME_salute06 89
#define FRAME_salute07 90
#define FRAME_salute08 91
#define FRAME_salute09 92
#define FRAME_salute10 93
#define FRAME_salute11 94
#define FRAME_taunt01 95
#define FRAME_taunt02 96
#define FRAME_taunt03 97
#define FRAME_taunt04 98
#define FRAME_taunt05 99
#define FRAME_taunt06 100
#define FRAME_taunt07 101
#define FRAME_taunt08 102
#define FRAME_taunt09 103
#define FRAME_taunt10 104
#define FRAME_taunt11 105
#define FRAME_taunt12 106
#define FRAME_taunt13 107
#define FRAME_taunt14 108
#define FRAME_taunt15 109
#define FRAME_taunt16 110
#define FRAME_taunt17 111
#define FRAME_wave01 112
#define FRAME_wave02 113
#define FRAME_wave03 114
#define FRAME_wave04 115
#define FRAME_wave05 116
#define FRAME_wave06 117
#define FRAME_wave07 118
#define FRAME_wave08 119
#define FRAME_wave09 120
#define FRAME_wave10 121
#define FRAME_wave11 122
#define FRAME_point01 123
#define FRAME_point02 124
#define FRAME_point03 125
#define FRAME_point04 126
#define FRAME_point05 127
#define FRAME_point06 128
#define FRAME_point07 129
#define FRAME_point08 130
#define FRAME_point09 131
#define FRAME_point10 132
#define FRAME_point11 133
#define FRAME_point12 134
#define FRAME_crstnd01 135
#define FRAME_crstnd02 136
#define FRAME_crstnd03 137
#define FRAME_crstnd04 138
#define FRAME_crstnd05 139
#define FRAME_crstnd06 140
#define FRAME_crstnd07 141
#define FRAME_crstnd08 142
#define FRAME_crstnd09 143
#define FRAME_crstnd10 144
#define FRAME_crstnd11 145
#define FRAME_crstnd12 146
#define FRAME_crstnd13 147
#define FRAME_crstnd14 148
#define FRAME_crstnd15 149
#define FRAME_crstnd16 150
#define FRAME_crstnd17 151
#define FRAME_crstnd18 152
#define FRAME_crstnd19 153
#define FRAME_crwalk1 154
#define FRAME_crwalk2 155
#define FRAME_crwalk3 156
#define FRAME_crwalk4 157
#define FRAME_crwalk5 158
#define FRAME_crwalk6 159
#define FRAME_crattak1 160
#define FRAME_crattak2 161
#define FRAME_crattak3 162
#define FRAME_crattak4 163
#define FRAME_crattak5 164
#define FRAME_crattak6 165
#define FRAME_crattak7 166
#define FRAME_crattak8 167
#define FRAME_crattak9 168
#define FRAME_crpain1 169
#define FRAME_crpain2 170
#define FRAME_crpain3 171
#define FRAME_crpain4 172
#define FRAME_crdeath1 173
#define FRAME_crdeath2 174
#define FRAME_crdeath3 175
#define FRAME_crdeath4 176
#define FRAME_crdeath5 177
#define FRAME_death101 178
#define FRAME_death102 179
#define FRAME_death103 180
#define FRAME_death104 181
#define FRAME_death105 182
#define FRAME_death106 183
#define FRAME_death201 184
#define FRAME_death202 185
#define FRAME_death203 186
#define FRAME_death204 187
#define FRAME_death205 188
#define FRAME_death206 189
#define FRAME_death301 190
#define FRAME_death302 191
#define FRAME_death303 192
#define FRAME_death304 193
#define FRAME_death305 194
#define FRAME_death306 195
#define FRAME_death307 196
#define FRAME_death308 197
#define MODEL_SCALE 1.000000

File diff suppressed because it is too large Load diff

View file

@ -1,182 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Mutant animations.
*
* =======================================================================
*/
#define FRAME_attack01 0
#define FRAME_attack02 1
#define FRAME_attack03 2
#define FRAME_attack04 3
#define FRAME_attack05 4
#define FRAME_attack06 5
#define FRAME_attack07 6
#define FRAME_attack08 7
#define FRAME_attack09 8
#define FRAME_attack10 9
#define FRAME_attack11 10
#define FRAME_attack12 11
#define FRAME_attack13 12
#define FRAME_attack14 13
#define FRAME_attack15 14
#define FRAME_death101 15
#define FRAME_death102 16
#define FRAME_death103 17
#define FRAME_death104 18
#define FRAME_death105 19
#define FRAME_death106 20
#define FRAME_death107 21
#define FRAME_death108 22
#define FRAME_death109 23
#define FRAME_death201 24
#define FRAME_death202 25
#define FRAME_death203 26
#define FRAME_death204 27
#define FRAME_death205 28
#define FRAME_death206 29
#define FRAME_death207 30
#define FRAME_death208 31
#define FRAME_death209 32
#define FRAME_death210 33
#define FRAME_pain101 34
#define FRAME_pain102 35
#define FRAME_pain103 36
#define FRAME_pain104 37
#define FRAME_pain105 38
#define FRAME_pain201 39
#define FRAME_pain202 40
#define FRAME_pain203 41
#define FRAME_pain204 42
#define FRAME_pain205 43
#define FRAME_pain206 44
#define FRAME_pain301 45
#define FRAME_pain302 46
#define FRAME_pain303 47
#define FRAME_pain304 48
#define FRAME_pain305 49
#define FRAME_pain306 50
#define FRAME_pain307 51
#define FRAME_pain308 52
#define FRAME_pain309 53
#define FRAME_pain310 54
#define FRAME_pain311 55
#define FRAME_run03 56
#define FRAME_run04 57
#define FRAME_run05 58
#define FRAME_run06 59
#define FRAME_run07 60
#define FRAME_run08 61
#define FRAME_stand101 62
#define FRAME_stand102 63
#define FRAME_stand103 64
#define FRAME_stand104 65
#define FRAME_stand105 66
#define FRAME_stand106 67
#define FRAME_stand107 68
#define FRAME_stand108 69
#define FRAME_stand109 70
#define FRAME_stand110 71
#define FRAME_stand111 72
#define FRAME_stand112 73
#define FRAME_stand113 74
#define FRAME_stand114 75
#define FRAME_stand115 76
#define FRAME_stand116 77
#define FRAME_stand117 78
#define FRAME_stand118 79
#define FRAME_stand119 80
#define FRAME_stand120 81
#define FRAME_stand121 82
#define FRAME_stand122 83
#define FRAME_stand123 84
#define FRAME_stand124 85
#define FRAME_stand125 86
#define FRAME_stand126 87
#define FRAME_stand127 88
#define FRAME_stand128 89
#define FRAME_stand129 90
#define FRAME_stand130 91
#define FRAME_stand131 92
#define FRAME_stand132 93
#define FRAME_stand133 94
#define FRAME_stand134 95
#define FRAME_stand135 96
#define FRAME_stand136 97
#define FRAME_stand137 98
#define FRAME_stand138 99
#define FRAME_stand139 100
#define FRAME_stand140 101
#define FRAME_stand141 102
#define FRAME_stand142 103
#define FRAME_stand143 104
#define FRAME_stand144 105
#define FRAME_stand145 106
#define FRAME_stand146 107
#define FRAME_stand147 108
#define FRAME_stand148 109
#define FRAME_stand149 110
#define FRAME_stand150 111
#define FRAME_stand151 112
#define FRAME_stand152 113
#define FRAME_stand153 114
#define FRAME_stand154 115
#define FRAME_stand155 116
#define FRAME_stand156 117
#define FRAME_stand157 118
#define FRAME_stand158 119
#define FRAME_stand159 120
#define FRAME_stand160 121
#define FRAME_stand161 122
#define FRAME_stand162 123
#define FRAME_stand163 124
#define FRAME_stand164 125
#define FRAME_walk01 126
#define FRAME_walk02 127
#define FRAME_walk03 128
#define FRAME_walk04 129
#define FRAME_walk05 130
#define FRAME_walk06 131
#define FRAME_walk07 132
#define FRAME_walk08 133
#define FRAME_walk09 134
#define FRAME_walk10 135
#define FRAME_walk11 136
#define FRAME_walk12 137
#define FRAME_walk13 138
#define FRAME_walk14 139
#define FRAME_walk15 140
#define FRAME_walk16 141
#define FRAME_walk17 142
#define FRAME_walk18 143
#define FRAME_walk19 144
#define FRAME_walk20 145
#define FRAME_walk21 146
#define FRAME_walk22 147
#define FRAME_walk23 148
#define FRAME_jump01 149
#define FRAME_jump02 150
#define FRAME_jump03 151
#define FRAME_jump04 152
#define FRAME_jump05 153
#define MODEL_SCALE 1.000000

File diff suppressed because it is too large Load diff

View file

@ -1,154 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Parasite animations.
*
* =======================================================================
*/
#define FRAME_break01 0
#define FRAME_break02 1
#define FRAME_break03 2
#define FRAME_break04 3
#define FRAME_break05 4
#define FRAME_break06 5
#define FRAME_break07 6
#define FRAME_break08 7
#define FRAME_break09 8
#define FRAME_break10 9
#define FRAME_break11 10
#define FRAME_break12 11
#define FRAME_break13 12
#define FRAME_break14 13
#define FRAME_break15 14
#define FRAME_break16 15
#define FRAME_break17 16
#define FRAME_break18 17
#define FRAME_break19 18
#define FRAME_break20 19
#define FRAME_break21 20
#define FRAME_break22 21
#define FRAME_break23 22
#define FRAME_break24 23
#define FRAME_break25 24
#define FRAME_break26 25
#define FRAME_break27 26
#define FRAME_break28 27
#define FRAME_break29 28
#define FRAME_break30 29
#define FRAME_break31 30
#define FRAME_break32 31
#define FRAME_death101 32
#define FRAME_death102 33
#define FRAME_death103 34
#define FRAME_death104 35
#define FRAME_death105 36
#define FRAME_death106 37
#define FRAME_death107 38
#define FRAME_drain01 39
#define FRAME_drain02 40
#define FRAME_drain03 41
#define FRAME_drain04 42
#define FRAME_drain05 43
#define FRAME_drain06 44
#define FRAME_drain07 45
#define FRAME_drain08 46
#define FRAME_drain09 47
#define FRAME_drain10 48
#define FRAME_drain11 49
#define FRAME_drain12 50
#define FRAME_drain13 51
#define FRAME_drain14 52
#define FRAME_drain15 53
#define FRAME_drain16 54
#define FRAME_drain17 55
#define FRAME_drain18 56
#define FRAME_pain101 57
#define FRAME_pain102 58
#define FRAME_pain103 59
#define FRAME_pain104 60
#define FRAME_pain105 61
#define FRAME_pain106 62
#define FRAME_pain107 63
#define FRAME_pain108 64
#define FRAME_pain109 65
#define FRAME_pain110 66
#define FRAME_pain111 67
#define FRAME_run01 68
#define FRAME_run02 69
#define FRAME_run03 70
#define FRAME_run04 71
#define FRAME_run05 72
#define FRAME_run06 73
#define FRAME_run07 74
#define FRAME_run08 75
#define FRAME_run09 76
#define FRAME_run10 77
#define FRAME_run11 78
#define FRAME_run12 79
#define FRAME_run13 80
#define FRAME_run14 81
#define FRAME_run15 82
#define FRAME_stand01 83
#define FRAME_stand02 84
#define FRAME_stand03 85
#define FRAME_stand04 86
#define FRAME_stand05 87
#define FRAME_stand06 88
#define FRAME_stand07 89
#define FRAME_stand08 90
#define FRAME_stand09 91
#define FRAME_stand10 92
#define FRAME_stand11 93
#define FRAME_stand12 94
#define FRAME_stand13 95
#define FRAME_stand14 96
#define FRAME_stand15 97
#define FRAME_stand16 98
#define FRAME_stand17 99
#define FRAME_stand18 100
#define FRAME_stand19 101
#define FRAME_stand20 102
#define FRAME_stand21 103
#define FRAME_stand22 104
#define FRAME_stand23 105
#define FRAME_stand24 106
#define FRAME_stand25 107
#define FRAME_stand26 108
#define FRAME_stand27 109
#define FRAME_stand28 110
#define FRAME_stand29 111
#define FRAME_stand30 112
#define FRAME_stand31 113
#define FRAME_stand32 114
#define FRAME_stand33 115
#define FRAME_stand34 116
#define FRAME_stand35 117
#define FRAME_jump01 118
#define FRAME_jump02 119
#define FRAME_jump03 120
#define FRAME_jump04 121
#define FRAME_jump05 122
#define FRAME_jump06 123
#define FRAME_jump07 124
#define FRAME_jump08 125
#define MODEL_SCALE 1.000000

View file

@ -1,921 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Supertank aka "Boss1".
*
* =======================================================================
*/
#include "../../header/local.h"
#include "supertank.h"
qboolean visible(edict_t *self, edict_t *other);
static int sound_pain1;
static int sound_pain2;
static int sound_pain3;
static int sound_death;
static int sound_search1;
static int sound_search2;
static int tread_sound;
void BossExplode(edict_t *self);
void supertank_dead(edict_t *self);
void supertankRocket(edict_t *self);
void supertankMachineGun(edict_t *self);
void supertank_reattack1(edict_t *self);
void
TreadSound(edict_t *self)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_VOICE, tread_sound, 1, ATTN_NORM, 0);
}
void
supertank_search(edict_t *self)
{
if (!self)
{
return;
}
if (random() < 0.5)
{
gi.sound(self, CHAN_VOICE, sound_search1, 1, ATTN_NORM, 0);
}
else
{
gi.sound(self, CHAN_VOICE, sound_search2, 1, ATTN_NORM, 0);
}
}
static mframe_t supertank_frames_stand[] = {
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL},
{ai_stand, 0, NULL}
};
mmove_t supertank_move_stand = {
FRAME_stand_1,
FRAME_stand_60,
supertank_frames_stand,
NULL
};
void
supertank_stand(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &supertank_move_stand;
}
static mframe_t supertank_frames_run[] = {
{ai_run, 12, TreadSound},
{ai_run, 12, NULL},
{ai_run, 12, NULL},
{ai_run, 12, NULL},
{ai_run, 12, NULL},
{ai_run, 12, NULL},
{ai_run, 12, NULL},
{ai_run, 12, NULL},
{ai_run, 12, NULL},
{ai_run, 12, NULL},
{ai_run, 12, NULL},
{ai_run, 12, NULL},
{ai_run, 12, NULL},
{ai_run, 12, NULL},
{ai_run, 12, NULL},
{ai_run, 12, NULL},
{ai_run, 12, NULL},
{ai_run, 12, NULL}
};
mmove_t supertank_move_run = {
FRAME_forwrd_1,
FRAME_forwrd_18,
supertank_frames_run,
NULL
};
static mframe_t supertank_frames_forward[] = {
{ai_walk, 4, TreadSound},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL},
{ai_walk, 4, NULL}
};
mmove_t supertank_move_forward = {
FRAME_forwrd_1,
FRAME_forwrd_18,
supertank_frames_forward,
NULL
};
void
supertank_forward(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &supertank_move_forward;
}
void
supertank_walk(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &supertank_move_forward;
}
void
supertank_run(edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
{
self->monsterinfo.currentmove = &supertank_move_stand;
}
else
{
self->monsterinfo.currentmove = &supertank_move_run;
}
}
static mframe_t supertank_frames_turn_right[] = {
{ai_move, 0, TreadSound},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t supertank_move_turn_right = {
FRAME_right_1,
FRAME_right_18,
supertank_frames_turn_right,
supertank_run
};
static mframe_t supertank_frames_turn_left[] = {
{ai_move, 0, TreadSound},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t supertank_move_turn_left = {
FRAME_left_1,
FRAME_left_18,
supertank_frames_turn_left,
supertank_run
};
static mframe_t supertank_frames_pain3[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t supertank_move_pain3 = {
FRAME_pain3_9,
FRAME_pain3_12,
supertank_frames_pain3,
supertank_run
};
static mframe_t supertank_frames_pain2[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t supertank_move_pain2 = {
FRAME_pain2_5,
FRAME_pain2_8,
supertank_frames_pain2,
supertank_run
};
static mframe_t supertank_frames_pain1[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t supertank_move_pain1 = {
FRAME_pain1_1,
FRAME_pain1_4,
supertank_frames_pain1,
supertank_run
};
static mframe_t supertank_frames_death1[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, BossExplode}
};
mmove_t supertank_move_death = {
FRAME_death_1,
FRAME_death_24,
supertank_frames_death1,
supertank_dead
};
static mframe_t supertank_frames_backward[] = {
{ai_walk, 0, TreadSound},
{ai_walk, 0, NULL},
{ai_walk, 0, NULL},
{ai_walk, 0, NULL},
{ai_walk, 0, NULL},
{ai_walk, 0, NULL},
{ai_walk, 0, NULL},
{ai_walk, 0, NULL},
{ai_walk, 0, NULL},
{ai_walk, 0, NULL},
{ai_walk, 0, NULL},
{ai_walk, 0, NULL},
{ai_walk, 0, NULL},
{ai_walk, 0, NULL},
{ai_walk, 0, NULL},
{ai_walk, 0, NULL},
{ai_walk, 0, NULL},
{ai_walk, 0, NULL}
};
mmove_t supertank_move_backward = {
FRAME_backwd_1,
FRAME_backwd_18,
supertank_frames_backward,
NULL
};
static mframe_t supertank_frames_attack4[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t supertank_move_attack4 = {
FRAME_attak4_1,
FRAME_attak4_6,
supertank_frames_attack4,
supertank_run
};
static mframe_t supertank_frames_attack3[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t supertank_move_attack3 = {
FRAME_attak3_1,
FRAME_attak3_27,
supertank_frames_attack3,
supertank_run
};
static mframe_t supertank_frames_attack2[] = {
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, supertankRocket},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, supertankRocket},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, supertankRocket},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t supertank_move_attack2 = {
FRAME_attak2_1,
FRAME_attak2_27,
supertank_frames_attack2,
supertank_run
};
static mframe_t supertank_frames_attack1[] = {
{ai_charge, 0, supertankMachineGun},
{ai_charge, 0, supertankMachineGun},
{ai_charge, 0, supertankMachineGun},
{ai_charge, 0, supertankMachineGun},
{ai_charge, 0, supertankMachineGun},
{ai_charge, 0, supertankMachineGun},
};
mmove_t supertank_move_attack1 = {
FRAME_attak1_1,
FRAME_attak1_6,
supertank_frames_attack1,
supertank_reattack1
};
static mframe_t supertank_frames_end_attack1[] = {
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL}
};
mmove_t supertank_move_end_attack1 = {
FRAME_attak1_7,
FRAME_attak1_20,
supertank_frames_end_attack1,
supertank_run
};
void
supertank_reattack1(edict_t *self)
{
if (!self)
{
return;
}
if (visible(self, self->enemy))
{
if (random() < 0.9)
{
self->monsterinfo.currentmove = &supertank_move_attack1;
}
else
{
self->monsterinfo.currentmove = &supertank_move_end_attack1;
}
}
else
{
self->monsterinfo.currentmove = &supertank_move_end_attack1;
}
}
void
supertank_pain(edict_t *self, edict_t *other /* unused */, float kick, int damage)
{
if (!self)
{
return;
}
if (self->health < (self->max_health / 2))
{
self->s.skinnum = 1;
}
if (level.time < self->pain_debounce_time)
{
return;
}
/* Lessen the chance of him going into his pain frames */
if (damage <= 25)
{
if (random() < 0.2)
{
return;
}
}
/* Don't go into pain if he's firing his rockets */
if (skill->value >= SKILL_HARD)
{
if ((self->s.frame >= FRAME_attak2_1) &&
(self->s.frame <= FRAME_attak2_14))
{
return;
}
}
self->pain_debounce_time = level.time + 3;
if (skill->value == SKILL_HARDPLUS)
{
return; /* no pain anims in nightmare */
}
if (damage <= 10)
{
gi.sound(self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &supertank_move_pain1;
}
else if (damage <= 25)
{
gi.sound(self, CHAN_VOICE, sound_pain3, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &supertank_move_pain2;
}
else
{
gi.sound(self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
self->monsterinfo.currentmove = &supertank_move_pain3;
}
}
void
supertankRocket(edict_t *self)
{
vec3_t forward, right;
vec3_t start;
vec3_t dir;
vec3_t vec;
int flash_number;
if (!self->enemy || !self->enemy->inuse)
{
return;
}
if (self->s.frame == FRAME_attak2_8)
{
flash_number = MZ2_SUPERTANK_ROCKET_1;
}
else if (self->s.frame == FRAME_attak2_11)
{
flash_number = MZ2_SUPERTANK_ROCKET_2;
}
else
{
flash_number = MZ2_SUPERTANK_ROCKET_3;
}
AngleVectors(self->s.angles, forward, right, NULL);
G_ProjectSource(self->s.origin, monster_flash_offset[flash_number],
forward, right, start);
VectorCopy(self->enemy->s.origin, vec);
vec[2] += self->enemy->viewheight;
VectorSubtract(vec, start, dir);
VectorNormalize(dir);
monster_fire_rocket(self, start, dir, 50, 500, flash_number);
}
void
supertankMachineGun(edict_t *self)
{
vec3_t dir;
vec3_t vec;
vec3_t start;
vec3_t forward, right;
int flash_number;
if (!self)
{
return;
}
if (!self->enemy || !self->enemy->inuse)
{
return;
}
flash_number = MZ2_SUPERTANK_MACHINEGUN_1 +
(self->s.frame - FRAME_attak1_1);
dir[0] = 0;
dir[1] = self->s.angles[1];
dir[2] = 0;
AngleVectors(dir, forward, right, NULL);
G_ProjectSource(self->s.origin, monster_flash_offset[flash_number],
forward, right, start);
VectorCopy(self->enemy->s.origin, vec);
VectorMA(vec, 0, self->enemy->velocity, vec);
vec[2] += self->enemy->viewheight;
VectorSubtract(vec, start, forward);
VectorNormalize(forward);
monster_fire_bullet(self, start, forward, 6, 4, DEFAULT_BULLET_HSPREAD,
DEFAULT_BULLET_VSPREAD, flash_number);
}
void
supertank_attack(edict_t *self)
{
vec3_t vec;
float range;
if (!self)
{
return;
}
VectorSubtract(self->enemy->s.origin, self->s.origin, vec);
range = VectorLength(vec);
if (range <= 160)
{
self->monsterinfo.currentmove = &supertank_move_attack1;
}
else
{
/* fire rockets more often at distance */
if (random() < 0.3)
{
self->monsterinfo.currentmove = &supertank_move_attack1;
}
else
{
self->monsterinfo.currentmove = &supertank_move_attack2;
}
}
}
void
supertank_dead(edict_t *self)
{
if (!self)
{
return;
}
VectorSet(self->mins, -60, -60, 0);
VectorSet(self->maxs, 60, 60, 72);
self->movetype = MOVETYPE_TOSS;
self->svflags |= SVF_DEADMONSTER;
self->nextthink = 0;
gi.linkentity(self);
}
void
BossExplode(edict_t *self)
{
vec3_t org;
int n;
if (!self)
{
return;
}
self->think = BossExplode;
VectorCopy(self->s.origin, org);
org[2] += 24 + (rand() & 15);
switch (self->count++)
{
case 0:
org[0] -= 24;
org[1] -= 24;
break;
case 1:
org[0] += 24;
org[1] += 24;
break;
case 2:
org[0] += 24;
org[1] -= 24;
break;
case 3:
org[0] -= 24;
org[1] += 24;
break;
case 4:
org[0] -= 48;
org[1] -= 48;
break;
case 5:
org[0] += 48;
org[1] += 48;
break;
case 6:
org[0] -= 48;
org[1] += 48;
break;
case 7:
org[0] += 48;
org[1] -= 48;
break;
case 8:
self->s.sound = 0;
for (n = 0; n < 4; n++)
{
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", 500, GIB_ORGANIC);
}
for (n = 0; n < 8; n++)
{
ThrowGib(self, "models/objects/gibs/sm_metal/tris.md2", 500, GIB_METALLIC);
}
ThrowGib(self, "models/objects/gibs/chest/tris.md2", 500, GIB_ORGANIC);
ThrowHead(self, "models/objects/gibs/gear/tris.md2", 500, GIB_METALLIC);
self->deadflag = DEAD_DEAD;
return;
}
gi.WriteByte(svc_temp_entity);
gi.WriteByte(TE_EXPLOSION1);
gi.WritePosition(org);
gi.multicast(self->s.origin, MULTICAST_PVS);
self->nextthink = level.time + 0.1;
}
void
supertank_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
int damage /* unused */, vec3_t point /* unused */)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
self->deadflag = DEAD_DEAD;
self->takedamage = DAMAGE_NO;
self->count = 0;
self->monsterinfo.currentmove = &supertank_move_death;
}
qboolean
supertank_blocked(edict_t *self, float dist)
{
if (!self)
{
return false;
}
if (blocked_checkplat(self, dist))
{
return true;
}
return false;
}
/*
* QUAKED monster_supertank (1 .5 0) (-64 -64 0) (64 64 72) Ambush Trigger_Spawn Sight
*/
void
SP_monster_supertank(edict_t *self)
{
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict(self);
return;
}
sound_pain1 = gi.soundindex("bosstank/btkpain1.wav");
sound_pain2 = gi.soundindex("bosstank/btkpain2.wav");
sound_pain3 = gi.soundindex("bosstank/btkpain3.wav");
sound_death = gi.soundindex("bosstank/btkdeth1.wav");
sound_search1 = gi.soundindex("bosstank/btkunqv1.wav");
sound_search2 = gi.soundindex("bosstank/btkunqv2.wav");
tread_sound = gi.soundindex("bosstank/btkengn1.wav");
self->movetype = MOVETYPE_STEP;
self->solid = SOLID_BBOX;
self->s.modelindex = gi.modelindex("models/monsters/boss1/tris.md2");
VectorSet(self->mins, -64, -64, 0);
VectorSet(self->maxs, 64, 64, 112);
self->health = 1500;
self->gib_health = -500;
self->mass = 800;
self->pain = supertank_pain;
self->die = supertank_die;
self->monsterinfo.stand = supertank_stand;
self->monsterinfo.walk = supertank_walk;
self->monsterinfo.run = supertank_run;
self->monsterinfo.dodge = NULL;
self->monsterinfo.attack = supertank_attack;
self->monsterinfo.search = supertank_search;
self->monsterinfo.melee = NULL;
self->monsterinfo.sight = NULL;
self->monsterinfo.blocked = supertank_blocked;
gi.linkentity(self);
self->monsterinfo.currentmove = &supertank_move_stand;
self->monsterinfo.scale = MODEL_SCALE;
walkmonster_start(self);
self->monsterinfo.aiflags |= AI_IGNORE_SHOTS;
}

View file

@ -1,282 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Supertank aka "Boss1" animations.
*
* =======================================================================
*/
#define FRAME_attak1_1 0
#define FRAME_attak1_2 1
#define FRAME_attak1_3 2
#define FRAME_attak1_4 3
#define FRAME_attak1_5 4
#define FRAME_attak1_6 5
#define FRAME_attak1_7 6
#define FRAME_attak1_8 7
#define FRAME_attak1_9 8
#define FRAME_attak1_10 9
#define FRAME_attak1_11 10
#define FRAME_attak1_12 11
#define FRAME_attak1_13 12
#define FRAME_attak1_14 13
#define FRAME_attak1_15 14
#define FRAME_attak1_16 15
#define FRAME_attak1_17 16
#define FRAME_attak1_18 17
#define FRAME_attak1_19 18
#define FRAME_attak1_20 19
#define FRAME_attak2_1 20
#define FRAME_attak2_2 21
#define FRAME_attak2_3 22
#define FRAME_attak2_4 23
#define FRAME_attak2_5 24
#define FRAME_attak2_6 25
#define FRAME_attak2_7 26
#define FRAME_attak2_8 27
#define FRAME_attak2_9 28
#define FRAME_attak2_10 29
#define FRAME_attak2_11 30
#define FRAME_attak2_12 31
#define FRAME_attak2_13 32
#define FRAME_attak2_14 33
#define FRAME_attak2_15 34
#define FRAME_attak2_16 35
#define FRAME_attak2_17 36
#define FRAME_attak2_18 37
#define FRAME_attak2_19 38
#define FRAME_attak2_20 39
#define FRAME_attak2_21 40
#define FRAME_attak2_22 41
#define FRAME_attak2_23 42
#define FRAME_attak2_24 43
#define FRAME_attak2_25 44
#define FRAME_attak2_26 45
#define FRAME_attak2_27 46
#define FRAME_attak3_1 47
#define FRAME_attak3_2 48
#define FRAME_attak3_3 49
#define FRAME_attak3_4 50
#define FRAME_attak3_5 51
#define FRAME_attak3_6 52
#define FRAME_attak3_7 53
#define FRAME_attak3_8 54
#define FRAME_attak3_9 55
#define FRAME_attak3_10 56
#define FRAME_attak3_11 57
#define FRAME_attak3_12 58
#define FRAME_attak3_13 59
#define FRAME_attak3_14 60
#define FRAME_attak3_15 61
#define FRAME_attak3_16 62
#define FRAME_attak3_17 63
#define FRAME_attak3_18 64
#define FRAME_attak3_19 65
#define FRAME_attak3_20 66
#define FRAME_attak3_21 67
#define FRAME_attak3_22 68
#define FRAME_attak3_23 69
#define FRAME_attak3_24 70
#define FRAME_attak3_25 71
#define FRAME_attak3_26 72
#define FRAME_attak3_27 73
#define FRAME_attak4_1 74
#define FRAME_attak4_2 75
#define FRAME_attak4_3 76
#define FRAME_attak4_4 77
#define FRAME_attak4_5 78
#define FRAME_attak4_6 79
#define FRAME_backwd_1 80
#define FRAME_backwd_2 81
#define FRAME_backwd_3 82
#define FRAME_backwd_4 83
#define FRAME_backwd_5 84
#define FRAME_backwd_6 85
#define FRAME_backwd_7 86
#define FRAME_backwd_8 87
#define FRAME_backwd_9 88
#define FRAME_backwd_10 89
#define FRAME_backwd_11 90
#define FRAME_backwd_12 91
#define FRAME_backwd_13 92
#define FRAME_backwd_14 93
#define FRAME_backwd_15 94
#define FRAME_backwd_16 95
#define FRAME_backwd_17 96
#define FRAME_backwd_18 97
#define FRAME_death_1 98
#define FRAME_death_2 99
#define FRAME_death_3 100
#define FRAME_death_4 101
#define FRAME_death_5 102
#define FRAME_death_6 103
#define FRAME_death_7 104
#define FRAME_death_8 105
#define FRAME_death_9 106
#define FRAME_death_10 107
#define FRAME_death_11 108
#define FRAME_death_12 109
#define FRAME_death_13 110
#define FRAME_death_14 111
#define FRAME_death_15 112
#define FRAME_death_16 113
#define FRAME_death_17 114
#define FRAME_death_18 115
#define FRAME_death_19 116
#define FRAME_death_20 117
#define FRAME_death_21 118
#define FRAME_death_22 119
#define FRAME_death_23 120
#define FRAME_death_24 121
#define FRAME_death_31 122
#define FRAME_death_32 123
#define FRAME_death_33 124
#define FRAME_death_45 125
#define FRAME_death_46 126
#define FRAME_death_47 127
#define FRAME_forwrd_1 128
#define FRAME_forwrd_2 129
#define FRAME_forwrd_3 130
#define FRAME_forwrd_4 131
#define FRAME_forwrd_5 132
#define FRAME_forwrd_6 133
#define FRAME_forwrd_7 134
#define FRAME_forwrd_8 135
#define FRAME_forwrd_9 136
#define FRAME_forwrd_10 137
#define FRAME_forwrd_11 138
#define FRAME_forwrd_12 139
#define FRAME_forwrd_13 140
#define FRAME_forwrd_14 141
#define FRAME_forwrd_15 142
#define FRAME_forwrd_16 143
#define FRAME_forwrd_17 144
#define FRAME_forwrd_18 145
#define FRAME_left_1 146
#define FRAME_left_2 147
#define FRAME_left_3 148
#define FRAME_left_4 149
#define FRAME_left_5 150
#define FRAME_left_6 151
#define FRAME_left_7 152
#define FRAME_left_8 153
#define FRAME_left_9 154
#define FRAME_left_10 155
#define FRAME_left_11 156
#define FRAME_left_12 157
#define FRAME_left_13 158
#define FRAME_left_14 159
#define FRAME_left_15 160
#define FRAME_left_16 161
#define FRAME_left_17 162
#define FRAME_left_18 163
#define FRAME_pain1_1 164
#define FRAME_pain1_2 165
#define FRAME_pain1_3 166
#define FRAME_pain1_4 167
#define FRAME_pain2_5 168
#define FRAME_pain2_6 169
#define FRAME_pain2_7 170
#define FRAME_pain2_8 171
#define FRAME_pain3_9 172
#define FRAME_pain3_10 173
#define FRAME_pain3_11 174
#define FRAME_pain3_12 175
#define FRAME_right_1 176
#define FRAME_right_2 177
#define FRAME_right_3 178
#define FRAME_right_4 179
#define FRAME_right_5 180
#define FRAME_right_6 181
#define FRAME_right_7 182
#define FRAME_right_8 183
#define FRAME_right_9 184
#define FRAME_right_10 185
#define FRAME_right_11 186
#define FRAME_right_12 187
#define FRAME_right_13 188
#define FRAME_right_14 189
#define FRAME_right_15 190
#define FRAME_right_16 191
#define FRAME_right_17 192
#define FRAME_right_18 193
#define FRAME_stand_1 194
#define FRAME_stand_2 195
#define FRAME_stand_3 196
#define FRAME_stand_4 197
#define FRAME_stand_5 198
#define FRAME_stand_6 199
#define FRAME_stand_7 200
#define FRAME_stand_8 201
#define FRAME_stand_9 202
#define FRAME_stand_10 203
#define FRAME_stand_11 204
#define FRAME_stand_12 205
#define FRAME_stand_13 206
#define FRAME_stand_14 207
#define FRAME_stand_15 208
#define FRAME_stand_16 209
#define FRAME_stand_17 210
#define FRAME_stand_18 211
#define FRAME_stand_19 212
#define FRAME_stand_20 213
#define FRAME_stand_21 214
#define FRAME_stand_22 215
#define FRAME_stand_23 216
#define FRAME_stand_24 217
#define FRAME_stand_25 218
#define FRAME_stand_26 219
#define FRAME_stand_27 220
#define FRAME_stand_28 221
#define FRAME_stand_29 222
#define FRAME_stand_30 223
#define FRAME_stand_31 224
#define FRAME_stand_32 225
#define FRAME_stand_33 226
#define FRAME_stand_34 227
#define FRAME_stand_35 228
#define FRAME_stand_36 229
#define FRAME_stand_37 230
#define FRAME_stand_38 231
#define FRAME_stand_39 232
#define FRAME_stand_40 233
#define FRAME_stand_41 234
#define FRAME_stand_42 235
#define FRAME_stand_43 236
#define FRAME_stand_44 237
#define FRAME_stand_45 238
#define FRAME_stand_46 239
#define FRAME_stand_47 240
#define FRAME_stand_48 241
#define FRAME_stand_49 242
#define FRAME_stand_50 243
#define FRAME_stand_51 244
#define FRAME_stand_52 245
#define FRAME_stand_53 246
#define FRAME_stand_54 247
#define FRAME_stand_55 248
#define FRAME_stand_56 249
#define FRAME_stand_57 250
#define FRAME_stand_58 251
#define FRAME_stand_59 252
#define FRAME_stand_60 253
#define MODEL_SCALE 1.000000

File diff suppressed because it is too large Load diff

View file

@ -1,322 +0,0 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) ZeniMax Media Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* Tank and Tank Commander animations.
*
* =======================================================================
*/
#define FRAME_stand01 0
#define FRAME_stand02 1
#define FRAME_stand03 2
#define FRAME_stand04 3
#define FRAME_stand05 4
#define FRAME_stand06 5
#define FRAME_stand07 6
#define FRAME_stand08 7
#define FRAME_stand09 8
#define FRAME_stand10 9
#define FRAME_stand11 10
#define FRAME_stand12 11
#define FRAME_stand13 12
#define FRAME_stand14 13
#define FRAME_stand15 14
#define FRAME_stand16 15
#define FRAME_stand17 16
#define FRAME_stand18 17
#define FRAME_stand19 18
#define FRAME_stand20 19
#define FRAME_stand21 20
#define FRAME_stand22 21
#define FRAME_stand23 22
#define FRAME_stand24 23
#define FRAME_stand25 24
#define FRAME_stand26 25
#define FRAME_stand27 26
#define FRAME_stand28 27
#define FRAME_stand29 28
#define FRAME_stand30 29
#define FRAME_walk01 30
#define FRAME_walk02 31
#define FRAME_walk03 32
#define FRAME_walk04 33
#define FRAME_walk05 34
#define FRAME_walk06 35
#define FRAME_walk07 36
#define FRAME_walk08 37
#define FRAME_walk09 38
#define FRAME_walk10 39
#define FRAME_walk11 40
#define FRAME_walk12 41
#define FRAME_walk13 42
#define FRAME_walk14 43
#define FRAME_walk15 44
#define FRAME_walk16 45
#define FRAME_walk17 46
#define FRAME_walk18 47
#define FRAME_walk19 48
#define FRAME_walk20 49
#define FRAME_walk21 50
#define FRAME_walk22 51
#define FRAME_walk23 52
#define FRAME_walk24 53
#define FRAME_walk25 54
#define FRAME_attak101 55
#define FRAME_attak102 56
#define FRAME_attak103 57
#define FRAME_attak104 58
#define FRAME_attak105 59
#define FRAME_attak106 60
#define FRAME_attak107 61
#define FRAME_attak108 62
#define FRAME_attak109 63
#define FRAME_attak110 64
#define FRAME_attak111 65
#define FRAME_attak112 66
#define FRAME_attak113 67
#define FRAME_attak114 68
#define FRAME_attak115 69
#define FRAME_attak116 70
#define FRAME_attak117 71
#define FRAME_attak118 72
#define FRAME_attak119 73
#define FRAME_attak120 74
#define FRAME_attak121 75
#define FRAME_attak122 76
#define FRAME_attak201 77
#define FRAME_attak202 78
#define FRAME_attak203 79
#define FRAME_attak204 80
#define FRAME_attak205 81
#define FRAME_attak206 82
#define FRAME_attak207 83
#define FRAME_attak208 84
#define FRAME_attak209 85
#define FRAME_attak210 86
#define FRAME_attak211 87
#define FRAME_attak212 88
#define FRAME_attak213 89
#define FRAME_attak214 90
#define FRAME_attak215 91
#define FRAME_attak216 92
#define FRAME_attak217 93
#define FRAME_attak218 94
#define FRAME_attak219 95
#define FRAME_attak220 96
#define FRAME_attak221 97
#define FRAME_attak222 98
#define FRAME_attak223 99
#define FRAME_attak224 100
#define FRAME_attak225 101
#define FRAME_attak226 102
#define FRAME_attak227 103
#define FRAME_attak228 104
#define FRAME_attak229 105
#define FRAME_attak230 106
#define FRAME_attak231 107
#define FRAME_attak232 108
#define FRAME_attak233 109
#define FRAME_attak234 110
#define FRAME_attak235 111
#define FRAME_attak236 112
#define FRAME_attak237 113
#define FRAME_attak238 114
#define FRAME_attak301 115
#define FRAME_attak302 116
#define FRAME_attak303 117
#define FRAME_attak304 118
#define FRAME_attak305 119
#define FRAME_attak306 120
#define FRAME_attak307 121
#define FRAME_attak308 122
#define FRAME_attak309 123
#define FRAME_attak310 124
#define FRAME_attak311 125
#define FRAME_attak312 126
#define FRAME_attak313 127
#define FRAME_attak314 128
#define FRAME_attak315 129
#define FRAME_attak316 130
#define FRAME_attak317 131
#define FRAME_attak318 132
#define FRAME_attak319 133
#define FRAME_attak320 134
#define FRAME_attak321 135
#define FRAME_attak322 136
#define FRAME_attak323 137
#define FRAME_attak324 138
#define FRAME_attak325 139
#define FRAME_attak326 140
#define FRAME_attak327 141
#define FRAME_attak328 142
#define FRAME_attak329 143
#define FRAME_attak330 144
#define FRAME_attak331 145
#define FRAME_attak332 146
#define FRAME_attak333 147
#define FRAME_attak334 148
#define FRAME_attak335 149
#define FRAME_attak336 150
#define FRAME_attak337 151
#define FRAME_attak338 152
#define FRAME_attak339 153
#define FRAME_attak340 154
#define FRAME_attak341 155
#define FRAME_attak342 156
#define FRAME_attak343 157
#define FRAME_attak344 158
#define FRAME_attak345 159
#define FRAME_attak346 160
#define FRAME_attak347 161
#define FRAME_attak348 162
#define FRAME_attak349 163
#define FRAME_attak350 164
#define FRAME_attak351 165
#define FRAME_attak352 166
#define FRAME_attak353 167
#define FRAME_attak401 168
#define FRAME_attak402 169
#define FRAME_attak403 170
#define FRAME_attak404 171
#define FRAME_attak405 172
#define FRAME_attak406 173
#define FRAME_attak407 174
#define FRAME_attak408 175
#define FRAME_attak409 176
#define FRAME_attak410 177
#define FRAME_attak411 178
#define FRAME_attak412 179
#define FRAME_attak413 180
#define FRAME_attak414 181
#define FRAME_attak415 182
#define FRAME_attak416 183
#define FRAME_attak417 184
#define FRAME_attak418 185
#define FRAME_attak419 186
#define FRAME_attak420 187
#define FRAME_attak421 188
#define FRAME_attak422 189
#define FRAME_attak423 190
#define FRAME_attak424 191
#define FRAME_attak425 192
#define FRAME_attak426 193
#define FRAME_attak427 194
#define FRAME_attak428 195
#define FRAME_attak429 196
#define FRAME_pain101 197
#define FRAME_pain102 198
#define FRAME_pain103 199
#define FRAME_pain104 200
#define FRAME_pain201 201
#define FRAME_pain202 202
#define FRAME_pain203 203
#define FRAME_pain204 204
#define FRAME_pain205 205
#define FRAME_pain301 206
#define FRAME_pain302 207
#define FRAME_pain303 208
#define FRAME_pain304 209
#define FRAME_pain305 210
#define FRAME_pain306 211
#define FRAME_pain307 212
#define FRAME_pain308 213
#define FRAME_pain309 214
#define FRAME_pain310 215
#define FRAME_pain311 216
#define FRAME_pain312 217
#define FRAME_pain313 218
#define FRAME_pain314 219
#define FRAME_pain315 220
#define FRAME_pain316 221
#define FRAME_death101 222
#define FRAME_death102 223
#define FRAME_death103 224
#define FRAME_death104 225
#define FRAME_death105 226
#define FRAME_death106 227
#define FRAME_death107 228
#define FRAME_death108 229
#define FRAME_death109 230
#define FRAME_death110 231
#define FRAME_death111 232
#define FRAME_death112 233
#define FRAME_death113 234
#define FRAME_death114 235
#define FRAME_death115 236
#define FRAME_death116 237
#define FRAME_death117 238
#define FRAME_death118 239
#define FRAME_death119 240
#define FRAME_death120 241
#define FRAME_death121 242
#define FRAME_death122 243
#define FRAME_death123 244
#define FRAME_death124 245
#define FRAME_death125 246
#define FRAME_death126 247
#define FRAME_death127 248
#define FRAME_death128 249
#define FRAME_death129 250
#define FRAME_death130 251
#define FRAME_death131 252
#define FRAME_death132 253
#define FRAME_recln101 254
#define FRAME_recln102 255
#define FRAME_recln103 256
#define FRAME_recln104 257
#define FRAME_recln105 258
#define FRAME_recln106 259
#define FRAME_recln107 260
#define FRAME_recln108 261
#define FRAME_recln109 262
#define FRAME_recln110 263
#define FRAME_recln111 264
#define FRAME_recln112 265
#define FRAME_recln113 266
#define FRAME_recln114 267
#define FRAME_recln115 268
#define FRAME_recln116 269
#define FRAME_recln117 270
#define FRAME_recln118 271
#define FRAME_recln119 272
#define FRAME_recln120 273
#define FRAME_recln121 274
#define FRAME_recln122 275
#define FRAME_recln123 276
#define FRAME_recln124 277
#define FRAME_recln125 278
#define FRAME_recln126 279
#define FRAME_recln127 280
#define FRAME_recln128 281
#define FRAME_recln129 282
#define FRAME_recln130 283
#define FRAME_recln131 284
#define FRAME_recln132 285
#define FRAME_recln133 286
#define FRAME_recln134 287
#define FRAME_recln135 288
#define FRAME_recln136 289
#define FRAME_recln137 290
#define FRAME_recln138 291
#define FRAME_recln139 292
#define FRAME_recln140 293
#define MODEL_SCALE 1.000000