game: Add ReRelease Guardian Monster

This commit is contained in:
Denis Pauk 2023-11-12 23:51:58 +02:00
parent 145027c240
commit 1151c91069
10 changed files with 1043 additions and 17 deletions

View file

@ -909,6 +909,7 @@ GAME_OBJS_ = \
src/game/monster/gekk/gekk.o \ src/game/monster/gekk/gekk.o \
src/game/monster/gladiator/gladb.o \ src/game/monster/gladiator/gladb.o \
src/game/monster/gladiator/gladiator.o \ src/game/monster/gladiator/gladiator.o \
src/game/monster/guardian/guardian.o \
src/game/monster/gunner/gunner.o \ src/game/monster/gunner/gunner.o \
src/game/monster/hover/hover.o \ src/game/monster/hover/hover.o \
src/game/monster/infantry/infantry.o \ src/game/monster/infantry/infantry.o \

View file

@ -50,18 +50,19 @@ SZ_GetSpace(sizebuf_t *buf, int length)
{ {
if (!buf->allowoverflow) if (!buf->allowoverflow)
{ {
Com_Error(ERR_FATAL, "SZ_GetSpace: overflow without allowoverflow set"); Com_Error(ERR_FATAL, "%s: overflow without allowoverflow set",
__func__);
} }
if (length > buf->maxsize) if (length > buf->maxsize)
{ {
Com_Error(ERR_FATAL, "SZ_GetSpace: %i is > full buffer size", Com_Error(ERR_FATAL, "%s: %i is > full buffer size",
length); __func__, length);
} }
SZ_Clear(buf); SZ_Clear(buf);
buf->overflowed = true; buf->overflowed = true;
Com_Printf("SZ_GetSpace: overflow\n"); Com_Printf("%s: overflow\n", __func__);
} }
data = buf->data + buf->cursize; data = buf->data + buf->cursize;

View file

@ -193,7 +193,7 @@ gib_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unu
} }
void void
ThrowGib(edict_t *self, char *gibname, int damage, int type) ThrowGib(edict_t *self, const char *gibname, int damage, int type)
{ {
edict_t *gib; edict_t *gib;
vec3_t vd; vec3_t vd;
@ -262,7 +262,7 @@ ThrowGib(edict_t *self, char *gibname, int damage, int type)
} }
void void
ThrowHead(edict_t *self, char *gibname, int damage, int type) ThrowHead(edict_t *self, const char *gibname, int damage, int type)
{ {
vec3_t vd; vec3_t vd;
float vscale; float vscale;
@ -319,7 +319,7 @@ ThrowHead(edict_t *self, char *gibname, int damage, int type)
} }
void void
ThrowGibACID(edict_t *self, char *gibname, int damage, int type) ThrowGibACID(edict_t *self, const char *gibname, int damage, int type)
{ {
edict_t *gib; edict_t *gib;
vec3_t vd; vec3_t vd;
@ -387,7 +387,7 @@ ThrowGibACID(edict_t *self, char *gibname, int damage, int type)
} }
void void
ThrowHeadACID(edict_t *self, char *gibname, int damage, int type) ThrowHeadACID(edict_t *self, const char *gibname, int damage, int type)
{ {
vec3_t vd; vec3_t vd;
float vscale; float vscale;

View file

@ -135,6 +135,7 @@ void SP_monster_berserk(edict_t *self);
void SP_monster_gladiator(edict_t *self); void SP_monster_gladiator(edict_t *self);
void SP_monster_gunner(edict_t *self); void SP_monster_gunner(edict_t *self);
void SP_monster_guncmdr(edict_t *self); void SP_monster_guncmdr(edict_t *self);
void SP_monster_guardian(edict_t *self);
void SP_monster_infantry(edict_t *self); void SP_monster_infantry(edict_t *self);
void SP_monster_soldier_light(edict_t *self); void SP_monster_soldier_light(edict_t *self);
void SP_monster_soldier(edict_t *self); void SP_monster_soldier(edict_t *self);
@ -328,6 +329,7 @@ static spawn_t spawns[] = {
{"monster_gladiator", SP_monster_gladiator}, {"monster_gladiator", SP_monster_gladiator},
{"monster_gunner", SP_monster_gunner}, {"monster_gunner", SP_monster_gunner},
{"monster_guncmdr", SP_monster_guncmdr}, {"monster_guncmdr", SP_monster_guncmdr},
{"monster_guardian", SP_monster_guardian},
{"monster_infantry", SP_monster_infantry}, {"monster_infantry", SP_monster_infantry},
{"monster_soldier_light", SP_monster_soldier_light}, {"monster_soldier_light", SP_monster_soldier_light},
{"monster_soldier", SP_monster_soldier}, {"monster_soldier", SP_monster_soldier},

View file

@ -878,12 +878,12 @@ void stationarymonster_start(edict_t *self);
void monster_done_dodge(edict_t *self); void monster_done_dodge(edict_t *self);
/* g_misc.c */ /* g_misc.c */
void ThrowHead(edict_t *self, char *gibname, int damage, int type); void ThrowHead(edict_t *self, const char *gibname, int damage, int type);
void ThrowClientHead(edict_t *self, int damage); void ThrowClientHead(edict_t *self, int damage);
void ThrowGib(edict_t *self, char *gibname, int damage, int type); void ThrowGib(edict_t *self, const char *gibname, int damage, int type);
void BecomeExplosion1(edict_t *self); void BecomeExplosion1(edict_t *self);
void ThrowHeadACID(edict_t *self, char *gibname, int damage, int type); void ThrowHeadACID(edict_t *self, const char *gibname, int damage, int type);
void ThrowGibACID(edict_t *self, char *gibname, int damage, int type); void ThrowGibACID(edict_t *self, const char *gibname, int damage, int type);
/* g_ai.c */ /* g_ai.c */
void AI_SetSightClient(void); void AI_SetSightClient(void);

View file

@ -0,0 +1,776 @@
/*
* 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 Guardian.
*
* =======================================================================
*/
#include "../../header/local.h"
#include "guardian.h"
void BossExplode(edict_t *self);
static int sound_charge;
static int sound_spin_loop;
//
// stand
//
static mframe_t guardian_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}
};
mmove_t guardian_move_stand =
{
FRAME_idle1,
FRAME_idle52,
guardian_frames_stand,
NULL
};
void
guardian_stand(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &guardian_move_stand;
}
//
// walk
//
static int sound_step;
void guardian_footstep(edict_t *self)
{
gi.sound(self, CHAN_BODY, sound_step, 1.f, ATTN_NORM, 0.0f);
}
static mframe_t guardian_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, guardian_footstep},
{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, guardian_footstep},
{ai_walk, 8, NULL}
};
mmove_t guardian_move_walk =
{
FRAME_walk1,
FRAME_walk19,
guardian_frames_walk,
NULL
};
void
guardian_walk(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &guardian_move_walk;
}
//
// run
//
static mframe_t guardian_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, guardian_footstep},
{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, guardian_footstep},
{ai_run, 8, NULL}
};
mmove_t guardian_move_run =
{
FRAME_walk1,
FRAME_walk19,
guardian_frames_run,
NULL
};
void
guardian_run(edict_t *self)
{
if (!self)
{
return;
}
if (self->monsterinfo.aiflags & AI_STAND_GROUND)
{
self->monsterinfo.currentmove = &guardian_move_stand;
return;
}
self->monsterinfo.currentmove = &guardian_move_run;
}
//
// pain
//
static mframe_t guardian_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},
{ai_move, 0, NULL}
};
mmove_t guardian_move_pain1 =
{
FRAME_pain1_1,
FRAME_pain1_8,
guardian_frames_pain1,
guardian_run
};
void
guardian_pain(edict_t *self, edict_t *other /* other */,
float kick /* other */, int damage)
{
if (!self)
{
return;
}
if (damage <= 10)
{
return;
}
if (level.time < self->pain_debounce_time)
{
return;
}
if (damage <= 75)
{
if (random() > 0.2)
{
return;
}
}
/* don't go into pain while attacking */
if ((self->s.frame >= FRAME_atk1_spin1) && (self->s.frame <= FRAME_atk1_spin15))
{
return;
}
if ((self->s.frame >= FRAME_atk2_fire1) && (self->s.frame <= FRAME_atk2_fire4))
{
return;
}
if ((self->s.frame >= FRAME_kick_in1) && (self->s.frame <= FRAME_kick_in13))
{
return;
}
self->pain_debounce_time = level.time + 3;
if (skill->value == SKILL_HARDPLUS)
{
return; /* no pain anims in nightmare */
}
self->monsterinfo.currentmove = &guardian_move_pain1;
}
static mframe_t guardian_frames_atk1_out[] = {
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL}
};
mmove_t guardian_atk1_out =
{
FRAME_atk1_out1,
FRAME_atk1_out3,
guardian_frames_atk1_out,
guardian_run
};
void guardian_atk1_finish(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &guardian_atk1_out;
}
void guardian_atk1_charge(edict_t *self)
{
gi.sound(self, CHAN_WEAPON, sound_charge, 1.f, ATTN_NORM, 0.f);
}
void guardian_fire_blaster(edict_t *self)
{
vec3_t forward, right, target;
vec3_t start;
int id = MZ2_TANK_BLASTER_1;
AngleVectors(self->s.angles, forward, right, NULL);
G_ProjectSource(self->s.origin, monster_flash_offset[id], forward, right, start);
VectorCopy(self->enemy->s.origin, target);
target[2] += self->enemy->viewheight;
for (int i = 0; i < 3; i++)
{
target[i] += (randk() % 10) - 5.f;
}
/* calc direction to where we targeted */
VectorSubtract(target, start, forward);
VectorNormalize(forward);
monster_fire_blaster(self, start, forward, 2, 1000, id, (self->s.frame % 4) ? 0 : EF_HYPERBLASTER);
if (self->enemy && self->enemy->health > 0 &&
self->s.frame == FRAME_atk1_spin12 && self->timestamp > level.time && visible(self, self->enemy))
self->monsterinfo.nextframe = FRAME_atk1_spin5;
}
void
guardian_hyper_sound(edict_t *self)
{
if (!self)
{
return;
}
gi.sound(self, CHAN_WEAPON, sound_spin_loop, 1.f, ATTN_NORM, 0.f);
}
static mframe_t guardian_frames_atk1_spin[] = {
{ai_charge, 0, guardian_atk1_charge},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, guardian_hyper_sound},
{ai_charge, 0, guardian_fire_blaster},
{ai_charge, 0, guardian_fire_blaster},
{ai_charge, 0, guardian_fire_blaster},
{ai_charge, 0, guardian_fire_blaster},
{ai_charge, 0, guardian_fire_blaster},
{ai_charge, 0, guardian_fire_blaster},
{ai_charge, 0, guardian_fire_blaster},
{ai_charge, 0, guardian_fire_blaster},
{ai_charge, 0},
{ai_charge, 0},
{ai_charge, 0}
};
mmove_t guardian_move_atk1_spin =
{
FRAME_atk1_spin1,
FRAME_atk1_spin15,
guardian_frames_atk1_spin,
guardian_atk1_finish
};
void guardian_atk1(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &guardian_move_atk1_spin;
self->timestamp = level.time + 0.650f + (randk() % 10 ) / 10.f * 1.5f;
}
static mframe_t guardian_frames_atk1_in[] = {
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL}
};
mmove_t guardian_move_atk1_in =
{
FRAME_atk1_in1,
FRAME_atk1_in3,
guardian_frames_atk1_in,
guardian_atk1
};
static mframe_t guardian_frames_atk2_out[] = {
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, guardian_footstep},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL}
};
mmove_t guardian_move_atk2_out =
{
FRAME_atk2_out1,
FRAME_atk2_out7,
guardian_frames_atk2_out,
guardian_run
};
void guardian_atk2_out(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &guardian_move_atk2_out;
}
static int sound_laser;
static vec3_t laser_positions[] = {
{ 125.0f, -70.f, 60.f},
{ 112.0f, -62.f, 60.f }
};
void guardian_laser_fire(edict_t *self)
{
vec3_t forward, right, up;
vec3_t tempang, start;
vec3_t dir, angles, end;
vec3_t tempvec;
edict_t *ent;
if (!self)
{
return;
}
gi.sound(self, CHAN_WEAPON, sound_laser, 1.f, ATTN_NORM, 0.f);
if (random() > 0.8)
{
gi.sound(self, CHAN_AUTO, gi.soundindex("misc/lasfly.wav"), 1, ATTN_STATIC, 0);
}
VectorCopy(self->s.origin, start);
VectorCopy(self->enemy->s.origin, end);
VectorSubtract(end, start, dir);
vectoangles(dir, angles);
VectorCopy(laser_positions[1 - (self->s.frame & 1)], tempvec);
ent = G_Spawn();
VectorCopy(self->s.origin, ent->s.origin);
VectorCopy(angles, tempang);
AngleVectors(tempang, forward, right, up);
VectorCopy(tempang, ent->s.angles);
VectorCopy(ent->s.origin, start);
VectorMA(start, tempvec[0] + 2, right, start);
VectorMA(start, tempvec[2] + 8, up, start);
VectorMA(start, tempvec[1], forward, start);
VectorCopy(start, ent->s.origin);
ent->enemy = self->enemy;
ent->owner = self;
ent->dmg = 25;
monster_dabeam(ent);
}
static mframe_t guardian_frames_atk2_fire[] = {
{ai_charge, 0, guardian_laser_fire},
{ai_charge, 0, guardian_laser_fire},
{ai_charge, 0, guardian_laser_fire},
{ai_charge, 0, guardian_laser_fire }
};
mmove_t guardian_move_atk2_fire =
{
FRAME_atk2_fire1,
FRAME_atk2_fire4,
guardian_frames_atk2_fire,
guardian_atk2_out
};
void guardian_atk2(edict_t *self)
{
if (!self)
{
return;
}
self->monsterinfo.currentmove = &guardian_move_atk2_fire;
}
static mframe_t guardian_frames_atk2_in[] = {
{ai_charge, 0, guardian_footstep},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, guardian_footstep},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, guardian_footstep},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL}
};
mmove_t guardian_move_atk2_in =
{
FRAME_atk2_in1,
FRAME_atk2_in12,
guardian_frames_atk2_in,
guardian_atk2
};
void
guardian_kick(edict_t *self)
{
vec3_t aim = {MELEE_DISTANCE, 0, -80};
fire_hit(self, aim, 85, 700);
}
static mframe_t guardian_frames_kick[] =
{
{ai_charge, 0, NULL},
{ai_charge, 0, guardian_footstep},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, guardian_kick},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL},
{ai_charge, 0, guardian_footstep},
{ai_charge, 0, NULL},
{ai_charge, 0, NULL}
};
mmove_t guardian_move_kick =
{
FRAME_kick_in1,
FRAME_kick_in13,
guardian_frames_kick,
guardian_run
};
void
guardian_attack(edict_t *self)
{
float r;
if (!self->enemy || !self->enemy->inuse)
{
return;
}
r = realrange(self, self->enemy);
if (r > RANGE_NEAR)
{
self->monsterinfo.currentmove = &guardian_move_atk2_in;
}
else if (r < 120.f)
{
self->monsterinfo.currentmove = &guardian_move_kick;
}
else
{
self->monsterinfo.currentmove = &guardian_move_atk1_in;
}
}
//
// death
//
void guardian_explode(edict_t *self)
{
vec3_t start, pos;
int i;
VectorAdd(self->s.origin, self->mins, start);
VectorCopy(self->size, pos);
for (i = 0; i < 3; i++)
{
pos[i] *= random();
}
VectorAdd(start, pos, pos);
gi.WriteByte(svc_temp_entity);
gi.WriteByte(TE_EXPLOSION1_BIG);
gi.WritePosition(pos);
gi.multicast(self->s.origin, MULTICAST_ALL);
}
static const char *gibs[] = {
"models/monsters/guardian/gib1.md2",
"models/monsters/guardian/gib2.md2",
"models/monsters/guardian/gib3.md2",
"models/monsters/guardian/gib4.md2",
"models/monsters/guardian/gib5.md2",
"models/monsters/guardian/gib6.md2",
"models/monsters/guardian/gib7.md2"
};
void guardian_dead(edict_t *self)
{
int i, n;
for (i = 0; i < 3; i++)
{
guardian_explode(self);
}
for (n = 0; n < 2; n++)
{
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2",
125, GIB_ORGANIC);
}
for (n = 0; n < 4; n++)
{
ThrowGib(self, "models/objects/gibs/sm_metal/tris.md2",
125, GIB_METALLIC);
}
for (n = 0; n < 6; n++)
{
for (i = 0; i < 2; i++)
{
ThrowGib(self, gibs[n], 125, GIB_METALLIC);
}
}
ThrowHead(self, gibs[6], 125, GIB_METALLIC);
}
static mframe_t guardian_frames_death1[FRAME_death26 - FRAME_death1 + 1] = {
{ai_move, 0, BossExplode},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{ai_move, 0, NULL},
{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 guardian_move_death =
{
FRAME_death1,
FRAME_death26,
guardian_frames_death1,
guardian_dead
};
void
guardian_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* unused */,
int damage, vec3_t point /* unused */)
{
if (!self)
{
return;
}
/* regular death */
self->deadflag = true;
self->takedamage = true;
self->monsterinfo.currentmove = &guardian_move_death;
}
//
// monster_tank
//
/*
* QUAKED monster_guardian (1 .5 0) (-96 -96 -66) (96 96 62) Ambush Trigger_Spawn Sight
*/
void
SP_monster_guardian(edict_t *self)
{
int i;
if (!self)
{
return;
}
if (deathmatch->value)
{
G_FreeEdict(self);
return;
}
sound_step = gi.soundindex("zortemp/step.wav");
sound_charge = gi.soundindex("weapons/hyprbu1a.wav");
sound_spin_loop = gi.soundindex("weapons/hyprbl1a.wav");
sound_laser = gi.soundindex("weapons/laser2.wav");
for(i = 0; i < sizeof(gibs) / sizeof(*gibs); i++)
{
gi.modelindex(gibs[i]);
}
self->s.modelindex = gi.modelindex("models/monsters/guardian/tris.md2");
VectorSet(self->mins, -96, -96, -66);
VectorSet(self->maxs, 96, 96, 62);
self->movetype = MOVETYPE_STEP;
self->solid = SOLID_BBOX;
self->health = 2500;
self->gib_health = -200;
self->monsterinfo.scale = MODEL_SCALE;
self->mass = 850;
self->pain = guardian_pain;
self->die = guardian_die;
self->monsterinfo.stand = guardian_stand;
self->monsterinfo.walk = guardian_walk;
self->monsterinfo.run = guardian_run;
self->monsterinfo.attack = guardian_attack;
gi.linkentity(self);
self->monsterinfo.currentmove = &guardian_move_stand;
walkmonster_start(self);
}

View file

@ -0,0 +1,244 @@
/*
* 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.
*
* =======================================================================
*
* Guardian animations.
*
* =======================================================================
*/
#define FRAME_sleep1 0
#define FRAME_sleep2 1
#define FRAME_sleep3 2
#define FRAME_sleep4 3
#define FRAME_sleep5 4
#define FRAME_sleep6 5
#define FRAME_sleep7 6
#define FRAME_sleep8 7
#define FRAME_sleep9 8
#define FRAME_sleep10 9
#define FRAME_sleep11 10
#define FRAME_sleep12 11
#define FRAME_sleep13 12
#define FRAME_sleep14 13
#define FRAME_death1 14
#define FRAME_death2 15
#define FRAME_death3 16
#define FRAME_death4 17
#define FRAME_death5 18
#define FRAME_death6 19
#define FRAME_death7 20
#define FRAME_death8 21
#define FRAME_death9 22
#define FRAME_death10 23
#define FRAME_death11 24
#define FRAME_death12 25
#define FRAME_death13 26
#define FRAME_death14 27
#define FRAME_death15 28
#define FRAME_death16 29
#define FRAME_death17 30
#define FRAME_death18 31
#define FRAME_death19 32
#define FRAME_death20 33
#define FRAME_death21 34
#define FRAME_death22 35
#define FRAME_death23 36
#define FRAME_death24 37
#define FRAME_death25 38
#define FRAME_death26 39
#define FRAME_atk1_out1 40
#define FRAME_atk1_out2 41
#define FRAME_atk1_out3 42
#define FRAME_atk2_out1 43
#define FRAME_atk2_out2 44
#define FRAME_atk2_out3 45
#define FRAME_atk2_out4 46
#define FRAME_atk2_out5 47
#define FRAME_atk2_out6 48
#define FRAME_atk2_out7 49
#define FRAME_kick_out1 50
#define FRAME_kick_out2 51
#define FRAME_kick_out3 52
#define FRAME_kick_out4 53
#define FRAME_kick_out5 54
#define FRAME_kick_out6 55
#define FRAME_kick_out7 56
#define FRAME_kick_out8 57
#define FRAME_kick_out9 58
#define FRAME_kick_out10 59
#define FRAME_kick_out11 60
#define FRAME_kick_out12 61
#define FRAME_pain1_1 62
#define FRAME_pain1_2 63
#define FRAME_pain1_3 64
#define FRAME_pain1_4 65
#define FRAME_pain1_5 66
#define FRAME_pain1_6 67
#define FRAME_pain1_7 68
#define FRAME_pain1_8 69
#define FRAME_idle1 70
#define FRAME_idle2 71
#define FRAME_idle3 72
#define FRAME_idle4 73
#define FRAME_idle5 74
#define FRAME_idle6 75
#define FRAME_idle7 76
#define FRAME_idle8 77
#define FRAME_idle9 78
#define FRAME_idle10 79
#define FRAME_idle11 80
#define FRAME_idle12 81
#define FRAME_idle13 82
#define FRAME_idle14 83
#define FRAME_idle15 84
#define FRAME_idle16 85
#define FRAME_idle17 86
#define FRAME_idle18 87
#define FRAME_idle19 88
#define FRAME_idle20 89
#define FRAME_idle21 90
#define FRAME_idle22 91
#define FRAME_idle23 92
#define FRAME_idle24 93
#define FRAME_idle25 94
#define FRAME_idle26 95
#define FRAME_idle27 96
#define FRAME_idle28 97
#define FRAME_idle29 98
#define FRAME_idle30 99
#define FRAME_idle31 100
#define FRAME_idle32 101
#define FRAME_idle33 102
#define FRAME_idle34 103
#define FRAME_idle35 104
#define FRAME_idle36 105
#define FRAME_idle37 106
#define FRAME_idle38 107
#define FRAME_idle39 108
#define FRAME_idle40 109
#define FRAME_idle41 110
#define FRAME_idle42 111
#define FRAME_idle43 112
#define FRAME_idle44 113
#define FRAME_idle45 114
#define FRAME_idle46 115
#define FRAME_idle47 116
#define FRAME_idle48 117
#define FRAME_idle49 118
#define FRAME_idle50 119
#define FRAME_idle51 120
#define FRAME_idle52 121
#define FRAME_atk1_in1 122
#define FRAME_atk1_in2 123
#define FRAME_atk1_in3 124
#define FRAME_kick_in1 125
#define FRAME_kick_in2 126
#define FRAME_kick_in3 127
#define FRAME_kick_in4 128
#define FRAME_kick_in5 129
#define FRAME_kick_in6 130
#define FRAME_kick_in7 131
#define FRAME_kick_in8 132
#define FRAME_kick_in9 133
#define FRAME_kick_in10 134
#define FRAME_kick_in11 135
#define FRAME_kick_in12 136
#define FRAME_kick_in13 137
#define FRAME_walk1 138
#define FRAME_walk2 139
#define FRAME_walk3 140
#define FRAME_walk4 141
#define FRAME_walk5 142
#define FRAME_walk6 143
#define FRAME_walk7 144
#define FRAME_walk8 145
#define FRAME_walk9 146
#define FRAME_walk10 147
#define FRAME_walk11 148
#define FRAME_walk12 149
#define FRAME_walk13 150
#define FRAME_walk14 151
#define FRAME_walk15 152
#define FRAME_walk16 153
#define FRAME_walk17 154
#define FRAME_walk18 155
#define FRAME_walk19 156
#define FRAME_wake1 157
#define FRAME_wake2 158
#define FRAME_wake3 159
#define FRAME_wake4 160
#define FRAME_wake5 161
#define FRAME_atk1_spin1 162
#define FRAME_atk1_spin2 163
#define FRAME_atk1_spin3 164
#define FRAME_atk1_spin4 165
#define FRAME_atk1_spin5 166
#define FRAME_atk1_spin6 167
#define FRAME_atk1_spin7 168
#define FRAME_atk1_spin8 169
#define FRAME_atk1_spin9 170
#define FRAME_atk1_spin10 171
#define FRAME_atk1_spin11 172
#define FRAME_atk1_spin12 173
#define FRAME_atk1_spin13 174
#define FRAME_atk1_spin14 175
#define FRAME_atk1_spin15 176
#define FRAME_atk2_fire1 177
#define FRAME_atk2_fire2 178
#define FRAME_atk2_fire3 179
#define FRAME_atk2_fire4 180
#define FRAME_turnl_1 181
#define FRAME_turnl_2 182
#define FRAME_turnl_3 183
#define FRAME_turnl_4 184
#define FRAME_turnl_5 185
#define FRAME_turnl_6 186
#define FRAME_turnl_7 187
#define FRAME_turnl_8 188
#define FRAME_turnl_9 189
#define FRAME_turnl_10 190
#define FRAME_turnl_11 191
#define FRAME_turnr_1 192
#define FRAME_turnr_2 193
#define FRAME_turnr_3 194
#define FRAME_turnr_4 195
#define FRAME_turnr_5 196
#define FRAME_turnr_6 197
#define FRAME_turnr_7 198
#define FRAME_turnr_8 199
#define FRAME_turnr_9 200
#define FRAME_turnr_10 201
#define FRAME_turnr_11 202
#define FRAME_atk2_in1 203
#define FRAME_atk2_in2 204
#define FRAME_atk2_in3 205
#define FRAME_atk2_in4 206
#define FRAME_atk2_in5 207
#define FRAME_atk2_in6 208
#define FRAME_atk2_in7 209
#define FRAME_atk2_in8 210
#define FRAME_atk2_in9 211
#define FRAME_atk2_in10 212
#define FRAME_atk2_in11 213
#define FRAME_atk2_in12 214
#define MODEL_SCALE 1.000000

View file

@ -2630,7 +2630,7 @@ soldierh_laserbeam(edict_t *self, int flash_index)
VectorCopy(tempang, ent->s.angles); VectorCopy(tempang, ent->s.angles);
VectorCopy(ent->s.origin, start); VectorCopy(ent->s.origin, start);
if (flash_index == 85) if (flash_index == MZ2_SOLDIER_MACHINEGUN_3)
{ {
VectorMA(start, tempvec[0] - 14, right, start); VectorMA(start, tempvec[0] - 14, right, start);
VectorMA(start, tempvec[2] + 8, up, start); VectorMA(start, tempvec[2] + 8, up, start);

View file

@ -235,6 +235,7 @@ extern void ThrowWidowGibLoc ( edict_t * self , char * gibname , int damage , in
extern void ThrowWidowGib ( edict_t * self , char * gibname , int damage , int type ) ; extern void ThrowWidowGib ( edict_t * self , char * gibname , int damage , int type ) ;
extern void widow_gib_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ; extern void widow_gib_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ;
extern void WidowVelocityForDamage ( int damage , vec3_t v ) ; extern void WidowVelocityForDamage ( int damage , vec3_t v ) ;
extern void SP_monster_guardian(edict_t *self);
extern void SP_monster_widow2 ( edict_t * self ) ; extern void SP_monster_widow2 ( edict_t * self ) ;
extern void Widow2Precache ( void ) ; extern void Widow2Precache ( void ) ;
extern qboolean Widow2_CheckAttack ( edict_t * self ) ; extern qboolean Widow2_CheckAttack ( edict_t * self ) ;
@ -1499,10 +1500,10 @@ extern void BecomeExplosion1 ( edict_t * self ) ;
extern void ThrowDebris ( edict_t * self , char * modelname , float speed , vec3_t origin ) ; extern void ThrowDebris ( edict_t * self , char * modelname , float speed , vec3_t origin ) ;
extern void debris_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; extern void debris_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ;
extern void ThrowClientHead ( edict_t * self , int damage ) ; extern void ThrowClientHead ( edict_t * self , int damage ) ;
extern void ThrowHeadACID ( edict_t * self , char * gibname , int damage , int type ) ; extern void ThrowHeadACID ( edict_t * self , const char * gibname , int damage , int type ) ;
extern void ThrowGibACID ( edict_t * self , char * gibname , int damage , int type ) ; extern void ThrowGibACID ( edict_t * self , const char * gibname , int damage , int type ) ;
extern void ThrowHead ( edict_t * self , char * gibname , int damage , int type ) ; extern void ThrowHead ( edict_t * self , const char * gibname , int damage , int type ) ;
extern void ThrowGib ( edict_t * self , char * gibname , int damage , int type ) ; extern void ThrowGib ( edict_t * self , const char * gibname , int damage , int type ) ;
extern void gib_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; extern void gib_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ;
extern void gib_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ; extern void gib_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ;
extern void gib_think ( edict_t * self ) ; extern void gib_think ( edict_t * self ) ;

View file

@ -237,6 +237,7 @@
{"ThrowWidowGib", (byte *)ThrowWidowGib}, {"ThrowWidowGib", (byte *)ThrowWidowGib},
{"widow_gib_touch", (byte *)widow_gib_touch}, {"widow_gib_touch", (byte *)widow_gib_touch},
{"WidowVelocityForDamage", (byte *)WidowVelocityForDamage}, {"WidowVelocityForDamage", (byte *)WidowVelocityForDamage},
{"SP_monster_guardian", (byte *)SP_monster_guardian},
{"SP_monster_widow2", (byte *)SP_monster_widow2}, {"SP_monster_widow2", (byte *)SP_monster_widow2},
{"Widow2Precache", (byte *)Widow2Precache}, {"Widow2Precache", (byte *)Widow2Precache},
{"Widow2_CheckAttack", (byte *)Widow2_CheckAttack}, {"Widow2_CheckAttack", (byte *)Widow2_CheckAttack},