mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-26 06:20:48 +00:00
game: sync all rogue monsters to game
This commit is contained in:
parent
5c87db6e88
commit
a46d6a2d83
50 changed files with 2844 additions and 17743 deletions
28
Makefile
28
Makefile
|
@ -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 \
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
* Brain animations.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#define FRAME_walk101 0
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Icarus animations.
|
||||
* Icarus and Daedalus animations.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
|
|
@ -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
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Medic animations.
|
||||
* Medic and Medic Commander animations.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = ¶site_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 = ¶site_move_jump_up;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->monsterinfo.currentmove = ¶site_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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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
|
Loading…
Reference in a new issue