mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-01-31 21:30:36 +00:00
game: Sync game/header/game.h, game/header/local.h
This commit is contained in:
parent
748cc322b3
commit
7b50b2d89f
42 changed files with 3164 additions and 698 deletions
|
@ -458,11 +458,6 @@ extern spawn_temp_t st;
|
|||
extern int sm_meat_index;
|
||||
extern int snd_fry;
|
||||
|
||||
extern int jacket_armor_index;
|
||||
extern int combat_armor_index;
|
||||
extern int body_armor_index;
|
||||
|
||||
|
||||
// means of death
|
||||
#define MOD_UNKNOWN 0
|
||||
#define MOD_BLASTER 1
|
||||
|
|
|
@ -1632,7 +1632,7 @@ CTFResetGrapple(edict_t *self)
|
|||
}
|
||||
|
||||
gi.sound(self->owner, CHAN_RELIABLE + CHAN_WEAPON,
|
||||
gi.soundindex( "weapons/grapple/grreset.wav"), volume, ATTN_NORM, 0);
|
||||
gi.soundindex("weapons/grapple/grreset.wav"), volume, ATTN_NORM, 0);
|
||||
cl = self->owner->client;
|
||||
cl->ctf_grapple = NULL;
|
||||
cl->ctf_grapplereleasetime = level.time;
|
||||
|
|
|
@ -984,7 +984,7 @@ body_die(edict_t *self, edict_t *inflictor, edict_t *attacker,
|
|||
|
||||
if (self->health < -40)
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_BODY, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
|
|
|
@ -801,7 +801,7 @@ T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir,
|
|||
{
|
||||
if (targ->pain_debounce_time < level.time)
|
||||
{
|
||||
gi.sound(targ, CHAN_ITEM, gi.soundindex( "items/protect4.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(targ, CHAN_ITEM, gi.soundindex("items/protect4.wav"), 1, ATTN_NORM, 0);
|
||||
targ->pain_debounce_time = level.time + 2;
|
||||
}
|
||||
|
||||
|
@ -816,7 +816,7 @@ T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir,
|
|||
{
|
||||
if (targ->pain_debounce_time < level.time)
|
||||
{
|
||||
gi.sound(targ, CHAN_ITEM, gi.soundindex( "items/protect4.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(targ, CHAN_ITEM, gi.soundindex("items/protect4.wav"), 1, ATTN_NORM, 0);
|
||||
targ->pain_debounce_time = level.time + 2;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
qboolean Pickup_Weapon(edict_t *ent, edict_t *other);
|
||||
void Use_Weapon(edict_t *ent, gitem_t *inv);
|
||||
void Use_Weapon2(edict_t *ent, gitem_t *inv);
|
||||
void Drop_Weapon(edict_t *ent, gitem_t *inv);
|
||||
|
||||
void Weapon_Blaster(edict_t *ent);
|
||||
|
@ -1426,7 +1427,7 @@ Use_PowerArmor(edict_t *ent, gitem_t *item)
|
|||
if (ent->flags & FL_POWER_ARMOR)
|
||||
{
|
||||
ent->flags &= ~FL_POWER_ARMOR;
|
||||
gi.sound(ent, CHAN_AUTO, gi.soundindex( "misc/power2.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(ent, CHAN_AUTO, gi.soundindex("misc/power2.wav"), 1, ATTN_NORM, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3589,6 +3590,28 @@ SP_item_health_mega(edict_t *self)
|
|||
self->style = HEALTH_IGNORE_MAX | HEALTH_TIMED;
|
||||
}
|
||||
|
||||
void
|
||||
SP_item_foodcube(edict_t *self)
|
||||
{
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH))
|
||||
{
|
||||
G_FreeEdict(self);
|
||||
return;
|
||||
}
|
||||
|
||||
self->model = "models/objects/trapfx/tris.md2";
|
||||
SpawnItem(self, FindItem("Health"));
|
||||
self->spawnflags |= DROPPED_ITEM;
|
||||
self->style = HEALTH_IGNORE_MAX;
|
||||
gi.soundindex("items/s_health.wav");
|
||||
self->classname = "foodcube";
|
||||
}
|
||||
|
||||
void
|
||||
InitItems(void)
|
||||
{
|
||||
|
|
|
@ -1,8 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
* Copyright (c) ZeniMax Media Inc.
|
||||
* Licensed under the GNU General Public License 2.0.
|
||||
*/
|
||||
/* =======================================================================
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Misc. utility functions for the game logic.
|
||||
*
|
||||
|
@ -13,10 +29,10 @@
|
|||
|
||||
#define MAXCHOICES 8
|
||||
|
||||
vec3_t VEC_UP = {0, -1, 0};
|
||||
vec3_t MOVEDIR_UP = {0, 0, 1};
|
||||
vec3_t VEC_DOWN = {0, -2, 0};
|
||||
vec3_t MOVEDIR_DOWN = {0, 0, -1};
|
||||
static vec3_t VEC_UP = {0, -1, 0};
|
||||
static vec3_t MOVEDIR_UP = {0, 0, 1};
|
||||
static vec3_t VEC_DOWN = {0, -2, 0};
|
||||
static vec3_t MOVEDIR_DOWN = {0, 0, -1};
|
||||
|
||||
void
|
||||
G_ProjectSource(vec3_t point, vec3_t distance, vec3_t forward,
|
||||
|
@ -24,7 +40,8 @@ G_ProjectSource(vec3_t point, vec3_t distance, vec3_t forward,
|
|||
{
|
||||
result[0] = point[0] + forward[0] * distance[0] + right[0] * distance[1];
|
||||
result[1] = point[1] + forward[1] * distance[0] + right[1] * distance[1];
|
||||
result[2] = point[2] + forward[2] * distance[0] + right[2] * distance[1] + distance[2];
|
||||
result[2] = point[2] + forward[2] * distance[0] + right[2] * distance[1] +
|
||||
distance[2];
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -40,14 +57,13 @@ G_ProjectSource2(vec3_t point, vec3_t distance, vec3_t forward,
|
|||
}
|
||||
|
||||
/*
|
||||
* Searches all active entities for the next one that holds
|
||||
* the matching string at fieldofs (use the FOFS() macro) in
|
||||
* the structure.
|
||||
* Searches all active entities for the next
|
||||
* one that holds the matching string at fieldofs
|
||||
* (use the FOFS() macro) in the structure.
|
||||
*
|
||||
* Searches beginning at the edict after from, or the beginning
|
||||
* if NULL.
|
||||
*
|
||||
* NULL will be returned if the end of the list is reached.
|
||||
* Searches beginning at the edict after from, or
|
||||
* the beginning. If NULL, NULL will be returned
|
||||
* if the end of the list is reached.
|
||||
*/
|
||||
edict_t *
|
||||
G_Find(edict_t *from, int fieldofs, char *match)
|
||||
|
@ -92,7 +108,8 @@ G_Find(edict_t *from, int fieldofs, char *match)
|
|||
}
|
||||
|
||||
/*
|
||||
* Returns entities that have origins within a spherical area
|
||||
* Returns entities that have origins
|
||||
* within a spherical area
|
||||
*/
|
||||
edict_t *
|
||||
findradius(edict_t *from, vec3_t org, float rad)
|
||||
|
@ -123,7 +140,8 @@ findradius(edict_t *from, vec3_t org, float rad)
|
|||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
eorg[j] = org[j] - (from->s.origin[j] + (from->mins[j] + from->maxs[j]) * 0.5);
|
||||
eorg[j] = org[j] - (from->s.origin[j] +
|
||||
(from->mins[j] + from->maxs[j]) * 0.5);
|
||||
}
|
||||
|
||||
if (VectorLength(eorg) > rad)
|
||||
|
@ -195,14 +213,14 @@ findradius2(edict_t *from, vec3_t org, float rad)
|
|||
}
|
||||
|
||||
/*
|
||||
* Searches all active entities for the next one that holds
|
||||
* the matching string at fieldofs (use the FOFS() macro) in
|
||||
* the structure.
|
||||
* Searches all active entities for
|
||||
* the next one that holds the matching
|
||||
* string at fieldofs (use the FOFS() macro)
|
||||
* in the structure.
|
||||
*
|
||||
* Searches beginning at the edict after from, or the beginning
|
||||
* if NULL.
|
||||
*
|
||||
* NULL will be returned if the end of the list is reached.
|
||||
* Searches beginning at the edict after from,
|
||||
* or the beginning. If NULL, NULL will be
|
||||
* returned if the end of the list is reached.
|
||||
*/
|
||||
edict_t *
|
||||
G_PickTarget(char *targetname)
|
||||
|
@ -240,7 +258,7 @@ G_PickTarget(char *targetname)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return choice[rand() % num_choices];
|
||||
return choice[randk() % num_choices];
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -256,17 +274,17 @@ Think_Delay(edict_t *ent)
|
|||
}
|
||||
|
||||
/*
|
||||
* the global "activator" should be set to the entity that initiated the firing.
|
||||
* The global "activator" should be set to
|
||||
* the entity that initiated the firing.
|
||||
*
|
||||
* If self.delay is set, a DelayedUse entity will be created that will actually
|
||||
* do the SUB_UseTargets after that many seconds have passed.
|
||||
* If self.delay is set, a DelayedUse entity
|
||||
* will be created that will actually do the
|
||||
* SUB_UseTargets after that many seconds have passed.
|
||||
*
|
||||
* Centerprints any self.message to the activator.
|
||||
*
|
||||
* Search for (string)targetname in all entities that
|
||||
* match (string)self.target and call their .use function
|
||||
*
|
||||
* ==============================
|
||||
*/
|
||||
void
|
||||
G_UseTargets(edict_t *ent, edict_t *activator)
|
||||
|
@ -289,6 +307,11 @@ G_UseTargets(edict_t *ent, edict_t *activator)
|
|||
t->think = Think_Delay;
|
||||
t->activator = activator;
|
||||
|
||||
if (!activator)
|
||||
{
|
||||
gi.dprintf("Think_Delay with no activator\n");
|
||||
}
|
||||
|
||||
t->message = ent->message;
|
||||
t->target = ent->target;
|
||||
t->killtarget = ent->killtarget;
|
||||
|
@ -306,7 +329,8 @@ G_UseTargets(edict_t *ent, edict_t *activator)
|
|||
}
|
||||
else
|
||||
{
|
||||
gi.sound(activator, CHAN_AUTO, gi.soundindex("misc/talk1.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(activator, CHAN_AUTO, gi.soundindex(
|
||||
"misc/talk1.wav"), 1, ATTN_NORM, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -398,8 +422,9 @@ tv(float x, float y, float z)
|
|||
static vec3_t vecs[8];
|
||||
float *v;
|
||||
|
||||
/* use an array so that multiple tempvectors
|
||||
won't collide for a while */
|
||||
/* use an array so that multiple
|
||||
tempvectors won't collide
|
||||
for a while */
|
||||
v = vecs[index];
|
||||
index = (index + 1) & 7;
|
||||
|
||||
|
@ -468,18 +493,16 @@ vectoyaw(vec3_t vec)
|
|||
float yaw;
|
||||
|
||||
if (vec[PITCH] == 0)
|
||||
{
|
||||
if (vec[YAW] == 0)
|
||||
{
|
||||
yaw = 0;
|
||||
}
|
||||
else if (vec[YAW] > 0)
|
||||
|
||||
if (vec[YAW] > 0)
|
||||
{
|
||||
yaw = 90;
|
||||
}
|
||||
else
|
||||
else if (vec[YAW] < 0)
|
||||
{
|
||||
yaw = 270;
|
||||
yaw = -90;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -559,7 +582,7 @@ vectoangles(vec3_t value1, vec3_t angles)
|
|||
}
|
||||
else
|
||||
{
|
||||
yaw = 270;
|
||||
yaw = -90;
|
||||
}
|
||||
|
||||
if (yaw < 0)
|
||||
|
@ -749,10 +772,20 @@ G_FreeEdict(edict_t *ed)
|
|||
|
||||
gi.unlinkentity(ed); /* unlink from world */
|
||||
|
||||
if (deathmatch->value || coop->value)
|
||||
{
|
||||
if ((ed - g_edicts) <= (maxclients->value + BODY_QUEUE_SIZE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ed - g_edicts) <= maxclients->value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
memset(ed, 0, sizeof(*ed));
|
||||
ed->classname = "freed";
|
||||
|
@ -801,8 +834,10 @@ G_TouchTriggers(edict_t *ent)
|
|||
}
|
||||
|
||||
/*
|
||||
* Call after linking a new trigger in during gameplay
|
||||
* to force all entities it covers to immediately touch it
|
||||
* Call after linking a new trigger
|
||||
* in during gameplay to force all
|
||||
* entities it covers to immediately
|
||||
* touch it
|
||||
*/
|
||||
void
|
||||
G_TouchSolids(edict_t *ent)
|
||||
|
@ -815,7 +850,8 @@ G_TouchSolids(edict_t *ent)
|
|||
return;
|
||||
}
|
||||
|
||||
num = gi.BoxEdicts(ent->absmin, ent->absmax, touch, MAX_EDICTS, AREA_SOLID);
|
||||
num = gi.BoxEdicts(ent->absmin, ent->absmax, touch,
|
||||
MAX_EDICTS, AREA_SOLID);
|
||||
|
||||
/* be careful, it is possible to have an entity in this
|
||||
list removed before we get to it (killtriggered) */
|
||||
|
@ -841,8 +877,9 @@ G_TouchSolids(edict_t *ent)
|
|||
}
|
||||
|
||||
/*
|
||||
* Kills all entities that would touch the proposed new positioning
|
||||
* of ent. Ent should be unlinked before calling this!
|
||||
* Kills all entities that would touch the
|
||||
* proposed new positioning of ent. Ent s
|
||||
* hould be unlinked before calling this!
|
||||
*/
|
||||
qboolean
|
||||
KillBox(edict_t *ent)
|
||||
|
@ -856,8 +893,8 @@ KillBox(edict_t *ent)
|
|||
|
||||
while (1)
|
||||
{
|
||||
tr = gi.trace(ent->s.origin, ent->mins, ent->maxs,
|
||||
ent->s.origin, NULL, MASK_PLAYERSOLID);
|
||||
tr = gi.trace(ent->s.origin, ent->mins, ent->maxs, ent->s.origin,
|
||||
NULL, MASK_PLAYERSOLID);
|
||||
|
||||
if (!tr.ent)
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,8 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
* Copyright (c) ZeniMax Media Inc.
|
||||
* Licensed under the GNU General Public License 2.0.
|
||||
*/
|
||||
/* =======================================================================
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Here are the client, server and game are tied together.
|
||||
*
|
||||
|
@ -29,6 +45,8 @@
|
|||
#define SVF_MONSTER 0x00000004 /* treat as CONTENTS_MONSTER for collision */
|
||||
#define SVF_DAMAGEABLE 0x00000008
|
||||
|
||||
#define MAX_ENT_CLUSTERS 16
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SOLID_NOT, /* no interaction with other objects */
|
||||
|
@ -45,7 +63,6 @@ typedef struct link_s
|
|||
struct link_s *prev, *next;
|
||||
} link_t;
|
||||
|
||||
#define MAX_ENT_CLUSTERS 16
|
||||
|
||||
typedef struct edict_s edict_t;
|
||||
typedef struct gclient_s gclient_t;
|
||||
|
@ -95,29 +112,34 @@ struct edict_s
|
|||
typedef struct
|
||||
{
|
||||
/* special messages */
|
||||
void (*bprintf)(int printlevel, char *fmt, ...);
|
||||
void (*dprintf)(char *fmt, ...);
|
||||
void (*cprintf)(edict_t *ent, int printlevel, char *fmt, ...);
|
||||
void (*centerprintf)(edict_t *ent, char *fmt, ...);
|
||||
void (*sound)(edict_t *ent, int channel, int soundindex, float volume, float attenuation, float timeofs);
|
||||
void (*positioned_sound)(vec3_t origin, edict_t *ent, int channel, int soundinedex, float volume, float attenuation, float timeofs);
|
||||
void (*bprintf)(int printlevel, const char *fmt, ...);
|
||||
void (*dprintf)(const char *fmt, ...);
|
||||
void (*cprintf)(edict_t *ent, int printlevel, const char *fmt, ...);
|
||||
void (*centerprintf)(edict_t *ent, const char *fmt, ...);
|
||||
void (*sound)(edict_t *ent, int channel, int soundindex, float volume,
|
||||
float attenuation, float timeofs);
|
||||
void (*positioned_sound)(vec3_t origin, edict_t *ent, int channel,
|
||||
int soundinedex, float volume, float attenuation, float timeofs);
|
||||
|
||||
/* config strings hold all the index strings, the lightstyles,
|
||||
and misc data like the sky definition and cdtrack.
|
||||
All of the current configstrings are sent to clients when
|
||||
they connect, and changes are sent to all connected clients. */
|
||||
void (*configstring)(int num, char *string);
|
||||
void (*error)(char *fmt, ...);
|
||||
void (*configstring)(int num, const char *string);
|
||||
|
||||
/* the *index functions create configstrings and some internal server state */
|
||||
int (*modelindex)(char *name);
|
||||
int (*soundindex)(char *name);
|
||||
int (*imageindex)(char *name);
|
||||
YQ2_ATTR_NORETURN_FUNCPTR void (*error)(const char *fmt, ...);
|
||||
|
||||
void (*setmodel)(edict_t *ent, char *name);
|
||||
/* the *index functions create configstrings
|
||||
and some internal server state */
|
||||
int (*modelindex)(const char *name);
|
||||
int (*soundindex)(const char *name);
|
||||
int (*imageindex)(const char *name);
|
||||
|
||||
void (*setmodel)(edict_t *ent, const char *name);
|
||||
|
||||
/* collision detection */
|
||||
trace_t (*trace)(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passent, int contentmask);
|
||||
trace_t (*trace)(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
|
||||
edict_t *passent, int contentmask);
|
||||
int (*pointcontents)(vec3_t point);
|
||||
qboolean (*inPVS)(vec3_t p1, vec3_t p2);
|
||||
qboolean (*inPHS)(vec3_t p1, vec3_t p2);
|
||||
|
@ -129,7 +151,8 @@ typedef struct
|
|||
solidity changes, it must be relinked. */
|
||||
void (*linkentity)(edict_t *ent);
|
||||
void (*unlinkentity)(edict_t *ent); /* call before removing an interactive edict */
|
||||
int (*BoxEdicts)(vec3_t mins, vec3_t maxs, edict_t **list, int maxcount, int areatype);
|
||||
int (*BoxEdicts)(vec3_t mins, vec3_t maxs, edict_t **list, int maxcount,
|
||||
int areatype);
|
||||
void (*Pmove)(pmove_t *pmove); /* player movement code common with client prediction */
|
||||
|
||||
/* network messaging */
|
||||
|
@ -140,7 +163,7 @@ typedef struct
|
|||
void (*WriteShort)(int c);
|
||||
void (*WriteLong)(int c);
|
||||
void (*WriteFloat)(float f);
|
||||
void (*WriteString)(char *s);
|
||||
void (*WriteString)(const char *s);
|
||||
void (*WritePosition)(vec3_t pos); /* some fractional bits */
|
||||
void (*WriteDir)(vec3_t pos); /* single byte encoded, very coarse */
|
||||
void (*WriteAngle)(float f);
|
||||
|
@ -151,17 +174,18 @@ typedef struct
|
|||
void (*FreeTags)(int tag);
|
||||
|
||||
/* console variable interaction */
|
||||
cvar_t *(*cvar)(char *var_name, char *value, int flags);
|
||||
cvar_t *(*cvar_set)(char *var_name, char *value);
|
||||
cvar_t *(*cvar_forceset)(char *var_name, char *value);
|
||||
cvar_t *(*cvar)(const char *var_name, const char *value, int flags);
|
||||
cvar_t *(*cvar_set)(const char *var_name, const char *value);
|
||||
cvar_t *(*cvar_forceset)(const char *var_name, const char *value);
|
||||
|
||||
/* ClientCommand and ServerCommand parameter access */
|
||||
int (*argc)(void);
|
||||
char *(*argv)(int n);
|
||||
char *(*args)(void); /* concatenation of all argv >= 1 */
|
||||
|
||||
/* add commands to the server console as if they were typed in for map changing, etc */
|
||||
void (*AddCommandString)(char *text);
|
||||
/* add commands to the server console as if
|
||||
they were typed in for map changing, etc */
|
||||
void (*AddCommandString)(const char *text);
|
||||
|
||||
void (*DebugGraph)(float value, int color);
|
||||
} game_import_t;
|
||||
|
@ -178,18 +202,20 @@ typedef struct
|
|||
void (*Shutdown)(void);
|
||||
|
||||
/* each new level entered will cause a call to SpawnEntities */
|
||||
void (*SpawnEntities)(char *mapname, char *entstring, char *spawnpoint);
|
||||
void (*SpawnEntities)(const char *mapname, char *entstring, const char *spawnpoint);
|
||||
|
||||
/* Read/Write Game is for storing persistant cross level information
|
||||
about the world state and the clients. WriteGame is called every time
|
||||
a level is exited. ReadGame is called on a loadgame. */
|
||||
void (*WriteGame)(char *filename, qboolean autosave);
|
||||
void (*ReadGame)(char *filename);
|
||||
about the world state and the clients.
|
||||
WriteGame is called every time a level is exited.
|
||||
ReadGame is called on a loadgame. */
|
||||
void (*WriteGame)(const char *filename, qboolean autosave);
|
||||
void (*ReadGame)(const char *filename);
|
||||
|
||||
/* ReadLevel is called after the default map
|
||||
information has been loaded with SpawnEntities */
|
||||
void (*WriteLevel)(char *filename);
|
||||
void (*ReadLevel)(char *filename);
|
||||
/* ReadLevel is called after the default
|
||||
map information has been loaded with
|
||||
SpawnEntities */
|
||||
void (*WriteLevel)(const char *filename);
|
||||
void (*ReadLevel)(const char *filename);
|
||||
|
||||
qboolean (*ClientConnect)(edict_t *ent, char *userinfo);
|
||||
void (*ClientBegin)(edict_t *ent);
|
||||
|
@ -200,16 +226,17 @@ typedef struct
|
|||
|
||||
void (*RunFrame)(void);
|
||||
|
||||
/* ServerCommand will be called when an "sv <command>" command
|
||||
is issued on the server console. The game can issue gi.argc()
|
||||
gi.argv() commands to get the rest of the parameters */
|
||||
/* ServerCommand will be called when an "sv <command>"
|
||||
command is issued on the server console. The game can
|
||||
issue gi.argc() / gi.argv() commands to get the rest
|
||||
of the parameters */
|
||||
void (*ServerCommand)(void);
|
||||
|
||||
/* global variables shared between game and server */
|
||||
|
||||
/* The edict array is allocated in the game dll so it can vary in
|
||||
size from one game to another. The size will be fixed when
|
||||
ge->Init() is called */
|
||||
/* The edict array is allocated in the game dll so it
|
||||
can vary in size from one game to another.
|
||||
The size will be fixed when ge->Init() is called */
|
||||
struct edict_s *edicts;
|
||||
int edict_size;
|
||||
int num_edicts; /* current number, <= max_edicts */
|
||||
|
|
|
@ -1,8 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
* Copyright (c) ZeniMax Media Inc.
|
||||
* Licensed under the GNU General Public License 2.0.
|
||||
*/
|
||||
/* =======================================================================
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Main header file for the game module.
|
||||
*
|
||||
|
@ -147,6 +163,7 @@ typedef enum
|
|||
#define AI_COMBAT_POINT 0x00001000
|
||||
#define AI_MEDIC 0x00002000
|
||||
#define AI_RESURRECTING 0x00004000
|
||||
#define AI_IGNORE_PAIN 0x00008000
|
||||
|
||||
/* ROGUE */
|
||||
#define AI_WALK_WALLS 0x00008000
|
||||
|
@ -216,7 +233,8 @@ typedef enum
|
|||
MOVETYPE_FLY,
|
||||
MOVETYPE_TOSS, /* gravity */
|
||||
MOVETYPE_FLYMISSILE, /* extra size to monsters */
|
||||
MOVETYPE_BOUNCE,
|
||||
MOVETYPE_BOUNCE, /* added this (the comma at the end of line) */
|
||||
MOVETYPE_WALLBOUNCE,
|
||||
MOVETYPE_NEWTOSS /* for deathball */
|
||||
} movetype_t;
|
||||
|
||||
|
@ -229,6 +247,7 @@ typedef struct
|
|||
int armor;
|
||||
} gitem_armor_t;
|
||||
|
||||
/* gitem_t->flags */
|
||||
#define IT_WEAPON 0x00000001 /* use makes active weapon */
|
||||
#define IT_AMMO 0x00000002
|
||||
#define IT_ARMOR 0x00000004
|
||||
|
@ -251,12 +270,13 @@ typedef struct
|
|||
#define WEAP_HYPERBLASTER 9
|
||||
#define WEAP_RAILGUN 10
|
||||
#define WEAP_BFG 11
|
||||
|
||||
#define WEAP_DISRUPTOR 12
|
||||
#define WEAP_ETFRIFLE 13
|
||||
#define WEAP_PLASMA 14
|
||||
#define WEAP_PROXLAUNCH 15
|
||||
#define WEAP_CHAINFIST 16
|
||||
#define WEAP_PHALANX 12
|
||||
#define WEAP_BOOMER 13
|
||||
#define WEAP_DISRUPTOR 14
|
||||
#define WEAP_ETFRIFLE 15
|
||||
#define WEAP_PLASMA 16
|
||||
#define WEAP_PROXLAUNCH 17
|
||||
#define WEAP_CHAINFIST 18
|
||||
|
||||
typedef struct gitem_s
|
||||
{
|
||||
|
@ -299,8 +319,9 @@ typedef struct
|
|||
|
||||
gclient_t *clients; /* [maxclients] */
|
||||
|
||||
/* can't store spawnpoint in level, because it
|
||||
would get overwritten by the savegame restore */
|
||||
/* can't store spawnpoint in level, because
|
||||
it would get overwritten by the savegame
|
||||
restore */
|
||||
char spawnpoint[512]; /* needed for coop respawns */
|
||||
|
||||
/* store latched cvars here that we want to get at often */
|
||||
|
@ -371,6 +392,7 @@ typedef struct
|
|||
/* world vars */
|
||||
char *sky;
|
||||
float skyrotate;
|
||||
int skyautorotate;
|
||||
vec3_t skyaxis;
|
||||
char *nextmap;
|
||||
|
||||
|
@ -445,7 +467,7 @@ typedef struct
|
|||
void (*search)(edict_t *self);
|
||||
void (*walk)(edict_t *self);
|
||||
void (*run)(edict_t *self);
|
||||
void (*dodge)(edict_t *self, edict_t *other, float eta, trace_t *tr);
|
||||
void (*dodge)(edict_t *self, edict_t *other, float eta);
|
||||
void (*attack)(edict_t *self);
|
||||
void (*melee)(edict_t *self);
|
||||
void (*sight)(edict_t *self, edict_t *other);
|
||||
|
@ -508,10 +530,6 @@ extern spawn_temp_t st;
|
|||
extern int sm_meat_index;
|
||||
extern int snd_fry;
|
||||
|
||||
extern int jacket_armor_index;
|
||||
extern int combat_armor_index;
|
||||
extern int body_armor_index;
|
||||
|
||||
extern int debristhisframe;
|
||||
extern int gibsthisframe;
|
||||
|
||||
|
@ -550,6 +568,12 @@ extern int gibsthisframe;
|
|||
#define MOD_TRIGGER_HURT 31
|
||||
#define MOD_HIT 32
|
||||
#define MOD_TARGET_BLASTER 33
|
||||
#define MOD_RIPPER 34
|
||||
#define MOD_PHALANX 35
|
||||
#define MOD_BRAINTENTACLE 36
|
||||
#define MOD_BLASTOFF 37
|
||||
#define MOD_GEKK 38
|
||||
#define MOD_TRAP 39
|
||||
#define MOD_FRIENDLY_FIRE 0x8000000
|
||||
#define MOD_CHAINFIST 40
|
||||
#define MOD_DISINTEGRATOR 41
|
||||
|
@ -589,6 +613,7 @@ extern cvar_t *maxentities;
|
|||
extern cvar_t *deathmatch;
|
||||
extern cvar_t *coop;
|
||||
extern cvar_t *coop_baseq2; /* treat spawnflags according to baseq2 rules */
|
||||
extern cvar_t *coop_pickup_weapons;
|
||||
extern cvar_t *coop_elevator_delay;
|
||||
extern cvar_t *coop_pickup_weapons;
|
||||
extern cvar_t *dmflags;
|
||||
|
@ -597,10 +622,13 @@ extern cvar_t *fraglimit;
|
|||
extern cvar_t *timelimit;
|
||||
extern cvar_t *password;
|
||||
extern cvar_t *spectator_password;
|
||||
extern cvar_t *needpass;
|
||||
extern cvar_t *g_select_empty;
|
||||
extern cvar_t *dedicated;
|
||||
extern cvar_t *g_footsteps;
|
||||
extern cvar_t *g_monsterfootsteps;
|
||||
extern cvar_t *g_fix_triggered;
|
||||
extern cvar_t *g_commanderbody_nogod;
|
||||
|
||||
extern cvar_t *filterban;
|
||||
|
||||
|
@ -639,6 +667,7 @@ extern cvar_t *g_disruptor;
|
|||
|
||||
extern cvar_t *aimfix;
|
||||
extern cvar_t *g_machinegun_norecoil;
|
||||
extern cvar_t *g_swap_speed;
|
||||
|
||||
/* this is for the count of monsters */
|
||||
#define ENT_SLOTS_LEFT \
|
||||
|
@ -659,8 +688,8 @@ extern cvar_t *g_machinegun_norecoil;
|
|||
#define DROPPED_PLAYER_ITEM 0x00020000
|
||||
#define ITEM_TARGETS_USED 0x00040000
|
||||
|
||||
/* fields are needed for spawning from the entity string
|
||||
and saving / loading games */
|
||||
/* fields are needed for spawning from the entity
|
||||
string and saving / loading games */
|
||||
#define FFL_SPAWNTEMP 1
|
||||
#define FFL_NOSPAWN 2
|
||||
|
||||
|
@ -692,8 +721,16 @@ typedef struct
|
|||
extern field_t fields[];
|
||||
extern gitem_t itemlist[];
|
||||
|
||||
/* player/client.c */
|
||||
void ClientBegin(edict_t *ent);
|
||||
void ClientDisconnect(edict_t *ent);
|
||||
void ClientUserinfoChanged(edict_t *ent, char *userinfo);
|
||||
qboolean ClientConnect(edict_t *ent, char *userinfo);
|
||||
void ClientThink(edict_t *ent, usercmd_t *cmd);
|
||||
|
||||
/* g_cmds.c */
|
||||
void Cmd_Help_f(edict_t *ent);
|
||||
void ClientCommand(edict_t *ent);
|
||||
|
||||
/* g_items.c */
|
||||
void PrecacheItem(gitem_t *it);
|
||||
|
@ -703,6 +740,7 @@ gitem_t *FindItem(char *pickup_name);
|
|||
gitem_t *FindItemByClassname(char *classname);
|
||||
|
||||
#define ITEM_INDEX(x) ((x) - itemlist)
|
||||
|
||||
edict_t *Drop_Item(edict_t *ent, gitem_t *item);
|
||||
void SetRespawn(edict_t *ent, float delay);
|
||||
void ChangeWeapon(edict_t *ent);
|
||||
|
@ -748,14 +786,18 @@ float vectoyaw2(vec3_t vec);
|
|||
void vectoangles2(vec3_t vec, vec3_t angles);
|
||||
edict_t *findradius2(edict_t *from, vec3_t org, float rad);
|
||||
|
||||
/* g_spawn.c */
|
||||
void ED_CallSpawn(edict_t *ent);
|
||||
|
||||
/* g_combat.c */
|
||||
qboolean OnSameTeam(edict_t *ent1, edict_t *ent2);
|
||||
qboolean CanDamage(edict_t *targ, edict_t *inflictor);
|
||||
void T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir,
|
||||
vec3_t point, vec3_t normal, int damage, int knockback, int dflags, int mod);
|
||||
void T_RadiusDamage(edict_t *inflictor, edict_t *attacker, float damage, edict_t *ignore,
|
||||
float radius, int mod);
|
||||
|
||||
void T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker,
|
||||
vec3_t dir, vec3_t point, vec3_t normal, int damage,
|
||||
int knockback, int dflags, int mod);
|
||||
void T_RadiusDamage(edict_t *inflictor, edict_t *attacker,
|
||||
float damage, edict_t *ignore, float radius,
|
||||
int mod);
|
||||
void T_RadiusNukeDamage(edict_t *inflictor, edict_t *attacker, float damage,
|
||||
edict_t *ignore, float radius, int mod);
|
||||
void T_RadiusClassDamage(edict_t *inflictor, edict_t *attacker, float damage,
|
||||
|
@ -777,24 +819,33 @@ void cleanupHealTarget(edict_t *ent);
|
|||
#define DEFAULT_BULLET_VSPREAD 500
|
||||
#define DEFAULT_SHOTGUN_HSPREAD 1000
|
||||
#define DEFAULT_SHOTGUN_VSPREAD 500
|
||||
#define DEFAULT_DEATHMATCH_SHOTGUN_COUNT 12
|
||||
#define DEFAULT_SHOTGUN_COUNT 12
|
||||
#define DEFAULT_SSHOTGUN_COUNT 20
|
||||
|
||||
/* g_monster.c */
|
||||
void monster_fire_bullet(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int kick, int hspread, int vspread, int flashtype);
|
||||
void monster_fire_shotgun(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int kick, int hspread, int vspread, int count, int flashtype);
|
||||
void monster_fire_blaster(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
void monster_fire_shotgun(edict_t *self, vec3_t start, vec3_t aimdir,
|
||||
int damage, int kick, int hspread, int vspread, int count,
|
||||
int flashtype);
|
||||
void monster_fire_blaster(edict_t *self, vec3_t start, vec3_t dir,
|
||||
int damage, int speed, int flashtype, int effect);
|
||||
void monster_fire_grenade(edict_t *self, vec3_t start, vec3_t aimdir,
|
||||
int damage, int speed, int flashtype);
|
||||
void monster_fire_rocket(edict_t *self, vec3_t start, vec3_t dir,
|
||||
int damage, int speed, int flashtype);
|
||||
void monster_fire_railgun(edict_t *self, vec3_t start, vec3_t aimdir,
|
||||
int damage, int kick, int flashtype);
|
||||
void monster_fire_bfg(edict_t *self, vec3_t start, vec3_t aimdir,
|
||||
int damage, int speed, int kick, float damage_radius,
|
||||
int flashtype);
|
||||
void monster_fire_ionripper(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int flashtype, int effect);
|
||||
void monster_fire_grenade(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, int flashtype);
|
||||
void monster_fire_rocket(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int flashtype);
|
||||
void monster_fire_railgun(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int kick, int flashtype);
|
||||
void monster_fire_bfg(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, int kick, float damage_radius, int flashtype);
|
||||
void monster_dabeam(edict_t *self);
|
||||
void monster_fire_blueblaster(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int flashtype, int effect);
|
||||
|
||||
void M_droptofloor(edict_t *ent);
|
||||
void monster_think(edict_t *self);
|
||||
void walkmonster_start(edict_t *self);
|
||||
|
@ -811,8 +862,6 @@ void monster_fire_blaster2(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
|||
int speed, int flashtype, int effect);
|
||||
void monster_fire_tracker(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, edict_t *enemy, int flashtype);
|
||||
void monster_fire_heat(edict_t *self, vec3_t start, vec3_t dir, vec3_t offset,
|
||||
int damage, int kick, int flashtype);
|
||||
void stationarymonster_start(edict_t *self);
|
||||
void monster_done_dodge(edict_t *self);
|
||||
|
||||
|
@ -821,6 +870,8 @@ void ThrowHead(edict_t *self, char *gibname, int damage, int type);
|
|||
void ThrowClientHead(edict_t *self, int damage);
|
||||
void ThrowGib(edict_t *self, char *gibname, int damage, int type);
|
||||
void BecomeExplosion1(edict_t *self);
|
||||
void ThrowHeadACID(edict_t *self, char *gibname, int damage, int type);
|
||||
void ThrowGibACID(edict_t *self, char *gibname, int damage, int type);
|
||||
|
||||
/* g_ai.c */
|
||||
void AI_SetSightClient(void);
|
||||
|
@ -852,10 +903,19 @@ void fire_grenade(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
|||
void fire_grenade2(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, float timer, float damage_radius, qboolean held);
|
||||
void fire_rocket(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, float damage_radius, int radius_damage);
|
||||
int speed, float damage_radius,
|
||||
int radius_damage);
|
||||
void fire_rail(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick);
|
||||
void fire_bfg(edict_t *self, vec3_t start, vec3_t dir,
|
||||
int damage, int speed, float damage_radius);
|
||||
void fire_bfg(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, float damage_radius);
|
||||
void fire_ionripper(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, int effect);
|
||||
void fire_blueblaster(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, int effect);
|
||||
void fire_plasma(edict_t *self, vec3_t start, vec3_t dir, int damage, int speed,
|
||||
float damage_radius, int radius_damage);
|
||||
void fire_trap(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, float timer, float damage_radius, qboolean held);
|
||||
|
||||
/* g_ptrail.c */
|
||||
void PlayerTrail_Init(void);
|
||||
|
@ -918,6 +978,14 @@ void ChaseNext(edict_t *ent);
|
|||
void ChasePrev(edict_t *ent);
|
||||
void GetChaseTarget(edict_t *ent);
|
||||
|
||||
/* savegame */
|
||||
void InitGame(void);
|
||||
void ReadLevel(const char *filename);
|
||||
void WriteLevel(const char *filename);
|
||||
void ReadGame(const char *filename);
|
||||
void WriteGame(const char *filename, qboolean autosave);
|
||||
void SpawnEntities(const char *mapname, char *entities, const char *spawnpoint);
|
||||
|
||||
void fire_flechette(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int kick);
|
||||
void fire_prox(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
|
@ -937,9 +1005,6 @@ void fire_tesla(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
|||
int speed);
|
||||
void fire_blaster2(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, int effect, qboolean hyper);
|
||||
void fire_heat(edict_t *self, vec3_t start, vec3_t aimdir, vec3_t offset,
|
||||
int damage, int kick,
|
||||
qboolean monster);
|
||||
void fire_tracker(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, edict_t *enemy);
|
||||
|
||||
|
@ -1023,7 +1088,8 @@ typedef struct
|
|||
qboolean connected; /* a loadgame will leave valid entities that
|
||||
just don't have a connection yet */
|
||||
|
||||
/* values saved and restored from edicts when changing levels */
|
||||
/* values saved and restored from
|
||||
edicts when changing levels */
|
||||
int health;
|
||||
int max_health;
|
||||
int savedFlags;
|
||||
|
@ -1038,6 +1104,8 @@ typedef struct
|
|||
int max_grenades;
|
||||
int max_cells;
|
||||
int max_slugs;
|
||||
int max_magslug;
|
||||
int max_trap;
|
||||
|
||||
gitem_t *weapon;
|
||||
gitem_t *lastweapon;
|
||||
|
@ -1139,6 +1207,10 @@ struct gclient_s
|
|||
|
||||
qboolean grenade_blew_up;
|
||||
float grenade_time;
|
||||
float quadfire_framenum;
|
||||
qboolean trap_blew_up;
|
||||
float trap_time;
|
||||
|
||||
int silencer_shots;
|
||||
int weapon_sound;
|
||||
|
||||
|
@ -1232,7 +1304,7 @@ struct edict_s
|
|||
float ideal_yaw;
|
||||
|
||||
float nextthink;
|
||||
void (*prethink) (edict_t *ent);
|
||||
void (*prethink)(edict_t *ent);
|
||||
void (*think)(edict_t *self);
|
||||
void (*blocked)(edict_t *self, edict_t *other); /* move to moveinfo? */
|
||||
void (*touch)(edict_t *self, edict_t *other, cplane_t *plane,
|
||||
|
@ -1242,10 +1314,11 @@ struct edict_s
|
|||
void (*die)(edict_t *self, edict_t *inflictor, edict_t *attacker,
|
||||
int damage, vec3_t point);
|
||||
|
||||
float touch_debounce_time;
|
||||
float touch_debounce_time; /* now also used by fixbots for timeouts when getting stuck */
|
||||
float pain_debounce_time;
|
||||
float damage_debounce_time;
|
||||
float fly_sound_debounce_time; /* now also used by insane marines to store pain sound timeout */
|
||||
/* and by fixbots for storing object_repair timeout when getting stuck */
|
||||
float last_move_time;
|
||||
|
||||
int health;
|
||||
|
@ -1296,6 +1369,7 @@ struct edict_s
|
|||
vec3_t move_origin;
|
||||
vec3_t move_angles;
|
||||
|
||||
/* move this to clientinfo? */
|
||||
int light_level;
|
||||
int style; /* also used as areaportal number */
|
||||
|
||||
|
@ -1305,6 +1379,8 @@ struct edict_s
|
|||
moveinfo_t moveinfo;
|
||||
monsterinfo_t monsterinfo;
|
||||
|
||||
int orders;
|
||||
|
||||
int plat2flags;
|
||||
vec3_t offset;
|
||||
vec3_t gravityVector;
|
||||
|
|
|
@ -710,7 +710,7 @@ hover_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* u
|
|||
/* check for gib */
|
||||
if (self->health <= self->gib_health)
|
||||
{
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
|
|
|
@ -735,7 +735,7 @@ player_die(edict_t *self, edict_t *inflictor, edict_t *attacker,
|
|||
if (!(self->flags & FL_NOGIB))
|
||||
{
|
||||
/* gib (play sound at end of server frame) */
|
||||
self->sounds = gi.soundindex( "misc/udeath.wav");
|
||||
self->sounds = gi.soundindex("misc/udeath.wav");
|
||||
|
||||
/* more meaty gibs for your dollar! */
|
||||
if ((deathmatch->value) && (self->health < -80))
|
||||
|
@ -1366,7 +1366,7 @@ body_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* un
|
|||
|
||||
if (self->health < -40)
|
||||
{
|
||||
gi.sound(self, CHAN_BODY, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_BODY, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
|
|
|
@ -427,7 +427,7 @@ G_SetStats(edict_t *ent)
|
|||
{
|
||||
/* ran out of cells for power armor */
|
||||
ent->flags &= ~FL_POWER_ARMOR;
|
||||
gi.sound(ent, CHAN_ITEM, gi.soundindex( "misc/power2.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/power2.wav"), 1, ATTN_NORM, 0);
|
||||
power_armor_type = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,9 +40,9 @@ gitem_armor_t jacketarmor_info = {25, 50, .30, .00, ARMOR_JACKET};
|
|||
gitem_armor_t combatarmor_info = {50, 100, .60, .30, ARMOR_COMBAT};
|
||||
gitem_armor_t bodyarmor_info = {100, 200, .80, .60, ARMOR_BODY};
|
||||
|
||||
int jacket_armor_index;
|
||||
int combat_armor_index;
|
||||
int body_armor_index;
|
||||
static int jacket_armor_index;
|
||||
static int combat_armor_index;
|
||||
static int body_armor_index;
|
||||
static int power_screen_index;
|
||||
static int power_shield_index;
|
||||
|
||||
|
@ -2927,7 +2927,7 @@ SP_item_health(edict_t *self)
|
|||
}
|
||||
|
||||
/*
|
||||
* QUAKED item_health_small (.3 .3 1) (-16 -16 -16) (16 16 16)
|
||||
* QUAKED item_health_small (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
|
||||
*/
|
||||
void
|
||||
SP_item_health_small(edict_t *self)
|
||||
|
@ -2951,7 +2951,7 @@ SP_item_health_small(edict_t *self)
|
|||
}
|
||||
|
||||
/*
|
||||
* QUAKED item_health_large (.3 .3 1) (-16 -16 -16) (16 16 16)
|
||||
* QUAKED item_health_large (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
|
||||
*/
|
||||
void
|
||||
SP_item_health_large(edict_t *self)
|
||||
|
@ -2974,7 +2974,7 @@ SP_item_health_large(edict_t *self)
|
|||
}
|
||||
|
||||
/*
|
||||
* QUAKED item_health_mega (.3 .3 1) (-16 -16 -16) (16 16 16)
|
||||
* QUAKED item_health_mega (.3 .3 1) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN
|
||||
*/
|
||||
void
|
||||
SP_item_health_mega(edict_t *self)
|
||||
|
|
|
@ -543,7 +543,7 @@ M_WorldEffects(edict_t *ent)
|
|||
{
|
||||
if (ent->flags & FL_INWATER)
|
||||
{
|
||||
gi.sound(ent, CHAN_BODY, gi.soundindex( "player/watr_out.wav"),
|
||||
gi.sound(ent, CHAN_BODY, gi.soundindex("player/watr_out.wav"),
|
||||
1, ATTN_NORM, 0);
|
||||
ent->flags &= ~FL_INWATER;
|
||||
}
|
||||
|
@ -579,7 +579,7 @@ M_WorldEffects(edict_t *ent)
|
|||
{
|
||||
if (random() <= 0.5)
|
||||
{
|
||||
gi.sound(ent, CHAN_BODY, gi.soundindex( "player/lava1.wav"),
|
||||
gi.sound(ent, CHAN_BODY, gi.soundindex("player/lava1.wav"),
|
||||
1, ATTN_NORM, 0);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,8 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
* Copyright (c) ZeniMax Media Inc.
|
||||
* Licensed under the GNU General Public License 2.0.
|
||||
*/
|
||||
/* =======================================================================
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Misc. utility functions for the game logic.
|
||||
*
|
||||
|
@ -13,13 +29,19 @@
|
|||
|
||||
#define MAXCHOICES 8
|
||||
|
||||
static vec3_t VEC_UP = {0, -1, 0};
|
||||
static vec3_t MOVEDIR_UP = {0, 0, 1};
|
||||
static vec3_t VEC_DOWN = {0, -2, 0};
|
||||
static vec3_t MOVEDIR_DOWN = {0, 0, -1};
|
||||
|
||||
void
|
||||
G_ProjectSource(vec3_t point, vec3_t distance, vec3_t forward,
|
||||
vec3_t right, vec3_t result)
|
||||
{
|
||||
result[0] = point[0] + forward[0] * distance[0] + right[0] * distance[1];
|
||||
result[1] = point[1] + forward[1] * distance[0] + right[1] * distance[1];
|
||||
result[2] = point[2] + forward[2] * distance[0] + right[2] * distance[1] + distance[2];
|
||||
result[2] = point[2] + forward[2] * distance[0] + right[2] * distance[1] +
|
||||
distance[2];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -34,6 +56,11 @@ G_Find(edict_t *from, int fieldofs, char *match)
|
|||
{
|
||||
char *s;
|
||||
|
||||
if (!match)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!from)
|
||||
{
|
||||
from = g_edicts;
|
||||
|
@ -67,7 +94,8 @@ G_Find(edict_t *from, int fieldofs, char *match)
|
|||
}
|
||||
|
||||
/*
|
||||
* Returns entities that have origins within a spherical area
|
||||
* Returns entities that have origins
|
||||
* within a spherical area
|
||||
*/
|
||||
edict_t *
|
||||
findradius(edict_t *from, vec3_t org, float rad)
|
||||
|
@ -338,11 +366,6 @@ get_normal_vector(const cplane_t *p, vec3_t normal)
|
|||
}
|
||||
}
|
||||
|
||||
vec3_t VEC_UP = {0, -1, 0};
|
||||
vec3_t MOVEDIR_UP = {0, 0, 1};
|
||||
vec3_t VEC_DOWN = {0, -2, 0};
|
||||
vec3_t MOVEDIR_DOWN = {0, 0, -1};
|
||||
|
||||
void
|
||||
G_SetMovedir(vec3_t angles, vec3_t movedir)
|
||||
{
|
||||
|
|
|
@ -1,8 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
* Copyright (c) ZeniMax Media Inc.
|
||||
* Licensed under the GNU General Public License 2.0.
|
||||
*/
|
||||
/* =======================================================================
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Weapon support functions.
|
||||
*
|
||||
|
@ -48,7 +64,7 @@ check_dodge(edict_t *self, vec3_t start, vec3_t dir, int speed)
|
|||
{
|
||||
VectorSubtract(tr.endpos, start, v);
|
||||
eta = (VectorLength(v) - tr.ent->maxs[0]) / speed;
|
||||
tr.ent->monsterinfo.dodge(tr.ent, self, eta);
|
||||
tr.ent->monsterinfo.dodge(tr.ent, self, eta, &tr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,6 +86,7 @@ fire_hit(edict_t *self, vec3_t aim, int damage, int kick)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Lazarus: Paranoia check */
|
||||
if (!self->enemy)
|
||||
{
|
||||
return false;
|
||||
|
@ -86,12 +103,14 @@ fire_hit(edict_t *self, vec3_t aim, int damage, int kick)
|
|||
|
||||
if ((aim[1] > self->mins[0]) && (aim[1] < self->maxs[0]))
|
||||
{
|
||||
/* the hit is straight on so back the range up to the edge of their bbox */
|
||||
/* the hit is straight on so back the
|
||||
range up to the edge of their bbox */
|
||||
range -= self->enemy->maxs[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this is a side hit so adjust the "right" value out to the edge of their bbox */
|
||||
/* this is a side hit so adjust the "right"
|
||||
value out to the edge of their bbox */
|
||||
if (aim[1] < 0)
|
||||
{
|
||||
aim[1] = self->enemy->mins[0];
|
||||
|
@ -113,7 +132,8 @@ fire_hit(edict_t *self, vec3_t aim, int damage, int kick)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* if it will hit any client/monster then hit the one we wanted to hit */
|
||||
/* if it will hit any client/monster
|
||||
then hit the one we wanted to hit */
|
||||
if ((tr.ent->svflags & SVF_MONSTER) || (tr.ent->client))
|
||||
{
|
||||
tr.ent = self->enemy;
|
||||
|
@ -127,8 +147,8 @@ fire_hit(edict_t *self, vec3_t aim, int damage, int kick)
|
|||
VectorSubtract(point, self->enemy->s.origin, dir);
|
||||
|
||||
/* do the damage */
|
||||
T_Damage(tr.ent, self, self, dir, point, vec3_origin,
|
||||
damage, kick / 2, DAMAGE_NO_KNOCKBACK, MOD_HIT);
|
||||
T_Damage(tr.ent, self, self, dir, point, vec3_origin, damage,
|
||||
kick / 2, DAMAGE_NO_KNOCKBACK, MOD_HIT);
|
||||
|
||||
if (!(tr.ent->svflags & SVF_MONSTER) && (!tr.ent->client))
|
||||
{
|
||||
|
@ -150,7 +170,8 @@ fire_hit(edict_t *self, vec3_t aim, int damage, int kick)
|
|||
}
|
||||
|
||||
/*
|
||||
* This is an internal support routine used for bullet/pellet based weapons.
|
||||
* This is an internal support routine
|
||||
* used for bullet/pellet based weapons.
|
||||
*/
|
||||
void
|
||||
fire_lead(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick,
|
||||
|
@ -283,7 +304,8 @@ fire_lead(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick,
|
|||
}
|
||||
}
|
||||
|
||||
/* if went through water, determine where the end and make a bubble trail */
|
||||
/* if went through water, determine
|
||||
where the end and make a bubble trail */
|
||||
if (water)
|
||||
{
|
||||
vec3_t pos;
|
||||
|
@ -313,8 +335,8 @@ fire_lead(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick,
|
|||
}
|
||||
|
||||
/*
|
||||
* Fires a single round. Used for machinegun and chaingun.
|
||||
* Would be fine for pistols, rifles, etc....
|
||||
* Fires a single round. Used for machinegun and
|
||||
* chaingun. Would be fine for pistols, rifles, etc....
|
||||
*/
|
||||
void
|
||||
fire_bullet(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
|
@ -325,12 +347,13 @@ fire_bullet(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
|||
return;
|
||||
}
|
||||
|
||||
fire_lead(self, start, aimdir, damage, kick, TE_GUNSHOT,
|
||||
hspread, vspread, mod);
|
||||
fire_lead(self, start, aimdir, damage, kick, TE_GUNSHOT, hspread,
|
||||
vspread, mod);
|
||||
}
|
||||
|
||||
/*
|
||||
* Shoots shotgun pellets. Used by shotgun and super shotgun.
|
||||
* Shoots shotgun pellets. Used
|
||||
* by shotgun and super shotgun.
|
||||
*/
|
||||
void
|
||||
fire_shotgun(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
|
@ -345,13 +368,14 @@ fire_shotgun(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
|||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
fire_lead(self, start, aimdir, damage, kick,
|
||||
TE_SHOTGUN, hspread, vspread, mod);
|
||||
fire_lead(self, start, aimdir, damage, kick, TE_SHOTGUN,
|
||||
hspread, vspread, mod);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fires a single blaster bolt. Used by the blaster and hyper blaster.
|
||||
* Fires a single blaster bolt.
|
||||
* Used by the blaster and hyper blaster.
|
||||
*/
|
||||
void
|
||||
blaster_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
|
@ -359,7 +383,7 @@ blaster_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
int mod;
|
||||
vec3_t normal;
|
||||
|
||||
if (!self || !other)
|
||||
if (!self || !other) /* plane and surf can be NULL */
|
||||
{
|
||||
G_FreeEdict(self);
|
||||
return;
|
||||
|
@ -376,7 +400,7 @@ blaster_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
return;
|
||||
}
|
||||
|
||||
if (self->owner->client)
|
||||
if (self->owner && self->owner->client)
|
||||
{
|
||||
PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT);
|
||||
}
|
||||
|
@ -439,6 +463,7 @@ fire_blaster(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
|||
bolt->clipmask = MASK_SHOT;
|
||||
bolt->solid = SOLID_BBOX;
|
||||
bolt->s.effects |= effect;
|
||||
bolt->s.renderfx |= RF_NOSHADOW;
|
||||
VectorClear(bolt->mins);
|
||||
VectorClear(bolt->maxs);
|
||||
bolt->s.modelindex = gi.modelindex("models/objects/laser/tris.md2");
|
||||
|
@ -532,7 +557,7 @@ Grenade_Explode(edict_t *ent)
|
|||
return;
|
||||
}
|
||||
|
||||
if (ent->owner->client)
|
||||
if (ent->owner && ent->owner->client)
|
||||
{
|
||||
PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT);
|
||||
}
|
||||
|
@ -610,9 +635,9 @@ Grenade_Explode(edict_t *ent)
|
|||
}
|
||||
|
||||
void
|
||||
Grenade_Touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
Grenade_Touch(edict_t *ent, edict_t *other, cplane_t *plane /* unused */, csurface_t *surf)
|
||||
{
|
||||
if (!ent || !other)
|
||||
if (!ent || !other) /* plane is unused, surf can be NULL */
|
||||
{
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
|
@ -635,19 +660,19 @@ Grenade_Touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
{
|
||||
if (random() > 0.5)
|
||||
{
|
||||
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/hgrenb1a.wav"),
|
||||
1, ATTN_NORM, 0);
|
||||
gi.sound(ent, CHAN_VOICE, gi.soundindex(
|
||||
"weapons/hgrenb1a.wav"), 1, ATTN_NORM, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/hgrenb2a.wav"),
|
||||
1, ATTN_NORM, 0);
|
||||
gi.sound(ent, CHAN_VOICE, gi.soundindex(
|
||||
"weapons/hgrenb2a.wav"), 1, ATTN_NORM, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/grenlb1b.wav"),
|
||||
1, ATTN_NORM, 0);
|
||||
gi.sound(ent, CHAN_VOICE, gi.soundindex(
|
||||
"weapons/grenlb1b.wav"), 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -658,8 +683,8 @@ Grenade_Touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
}
|
||||
|
||||
void
|
||||
fire_grenade(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, float timer, float damage_radius)
|
||||
fire_grenade(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed,
|
||||
float timer, float damage_radius)
|
||||
{
|
||||
edict_t *grenade;
|
||||
vec3_t dir;
|
||||
|
@ -751,8 +776,8 @@ fire_grenade2(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
|||
}
|
||||
else
|
||||
{
|
||||
gi.sound(self, CHAN_WEAPON, gi.soundindex("weapons/hgrent1a.wav"),
|
||||
1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_WEAPON, gi.soundindex(
|
||||
"weapons/hgrent1a.wav"), 1, ATTN_NORM, 0);
|
||||
gi.linkentity(grenade);
|
||||
}
|
||||
}
|
||||
|
@ -764,7 +789,7 @@ rocket_touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
vec3_t normal;
|
||||
int n;
|
||||
|
||||
if (!ent || !other)
|
||||
if (!ent || !other) /* plane and surf can be NULL */
|
||||
{
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
|
@ -781,7 +806,7 @@ rocket_touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
return;
|
||||
}
|
||||
|
||||
if (ent->owner->client)
|
||||
if (ent->owner && ent->owner->client)
|
||||
{
|
||||
PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT);
|
||||
}
|
||||
|
@ -804,7 +829,7 @@ rocket_touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
if ((surf) && !(surf->flags &
|
||||
(SURF_WARP | SURF_TRANS33 | SURF_TRANS66 | SURF_FLOWING)))
|
||||
{
|
||||
n = rand() % 5;
|
||||
n = randk() % 5;
|
||||
|
||||
while (n--)
|
||||
{
|
||||
|
@ -815,8 +840,8 @@ rocket_touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
}
|
||||
}
|
||||
|
||||
T_RadiusDamage(ent, ent->owner, ent->radius_dmg, other,
|
||||
ent->dmg_radius, MOD_R_SPLASH);
|
||||
T_RadiusDamage(ent, ent->owner, ent->radius_dmg, other, ent->dmg_radius,
|
||||
MOD_R_SPLASH);
|
||||
|
||||
gi.WriteByte(svc_temp_entity);
|
||||
|
||||
|
@ -910,6 +935,7 @@ fire_rail(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick)
|
|||
{
|
||||
/* -added so rail goes through SOLID_BBOX entities (gibs, etc) */
|
||||
if ((tr.ent->svflags & SVF_MONSTER) || (tr.ent->client) ||
|
||||
(tr.ent->svflags & SVF_DAMAGEABLE) ||
|
||||
(tr.ent->solid == SOLID_BBOX))
|
||||
{
|
||||
ignore = tr.ent;
|
||||
|
@ -1029,7 +1055,7 @@ bfg_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
{
|
||||
vec3_t normal;
|
||||
|
||||
if (!self || !other)
|
||||
if (!self || !other) /* plane and surf can be NULL */
|
||||
{
|
||||
G_FreeEdict(self);
|
||||
return;
|
||||
|
@ -1046,7 +1072,7 @@ bfg_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
return;
|
||||
}
|
||||
|
||||
if (self->owner->client)
|
||||
if (self->owner && self->owner->client)
|
||||
{
|
||||
PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT);
|
||||
}
|
||||
|
@ -1062,11 +1088,21 @@ bfg_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
|
||||
T_RadiusDamage(self, self->owner, 200, other, 100, MOD_BFG_BLAST);
|
||||
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("weapons/bfg__x1b.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex(
|
||||
"weapons/bfg__x1b.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
self->solid = SOLID_NOT;
|
||||
self->touch = NULL;
|
||||
VectorMA(self->s.origin, -1 * FRAMETIME, self->velocity, self->s.origin);
|
||||
|
||||
/* move it back a bit from walls so the effects aren't cut off */
|
||||
if (!other->takedamage)
|
||||
{
|
||||
VectorNormalize(self->velocity);
|
||||
VectorMA(self->s.origin, -40.0f, self->velocity, self->s.origin);
|
||||
}
|
||||
|
||||
VectorClear(self->velocity);
|
||||
|
||||
self->s.modelindex = gi.modelindex("sprites/s_bfg3.sp2");
|
||||
self->s.frame = 0;
|
||||
self->s.sound = 0;
|
||||
|
@ -1075,6 +1111,8 @@ bfg_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
self->nextthink = level.time + FRAMETIME;
|
||||
self->enemy = other;
|
||||
|
||||
gi.linkentity(self);
|
||||
|
||||
gi.WriteByte(svc_temp_entity);
|
||||
gi.WriteByte(TE_BFG_BIGEXPLOSION);
|
||||
gi.WritePosition(self->s.origin);
|
||||
|
@ -1126,8 +1164,8 @@ bfg_think(edict_t *self)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!(ent->svflags & SVF_MONSTER) && (!ent->client) &&
|
||||
(strcmp(ent->classname, "misc_explobox") != 0))
|
||||
if (!(ent->svflags & SVF_MONSTER) && !(ent->svflags & SVF_DAMAGEABLE) &&
|
||||
(!ent->client) && (strcmp(ent->classname, "misc_explobox") != 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -1155,12 +1193,13 @@ bfg_think(edict_t *self)
|
|||
if ((tr.ent->takedamage) && !(tr.ent->flags & FL_IMMUNE_LASER) &&
|
||||
(tr.ent != self->owner))
|
||||
{
|
||||
T_Damage(tr.ent, self, self->owner, dir, tr.endpos,
|
||||
vec3_origin, dmg, 1, DAMAGE_ENERGY, MOD_BFG_LASER);
|
||||
T_Damage(tr.ent, self, self->owner, dir, tr.endpos, vec3_origin,
|
||||
dmg, 1, DAMAGE_ENERGY, MOD_BFG_LASER);
|
||||
}
|
||||
|
||||
/* if we hit something that's not a monster or player we're done */
|
||||
if (!(tr.ent->svflags & SVF_MONSTER) && (!tr.ent->client))
|
||||
if (!(tr.ent->svflags & SVF_MONSTER) &&
|
||||
!(tr.ent->svflags & SVF_DAMAGEABLE) && (!tr.ent->client))
|
||||
{
|
||||
gi.WriteByte(svc_temp_entity);
|
||||
gi.WriteByte(TE_LASER_SPARKS);
|
||||
|
|
|
@ -1,8 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
* Copyright (c) ZeniMax Media Inc.
|
||||
* Licensed under the GNU General Public License 2.0.
|
||||
*/
|
||||
/* =======================================================================
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Here are the client, server and game are tied together.
|
||||
*
|
||||
|
@ -27,6 +43,7 @@
|
|||
#define SVF_NOCLIENT 0x00000001 /* don't send entity to clients, even if it has effects */
|
||||
#define SVF_DEADMONSTER 0x00000002 /* treat as CONTENTS_DEADMONSTER for collision */
|
||||
#define SVF_MONSTER 0x00000004 /* treat as CONTENTS_MONSTER for collision */
|
||||
#define SVF_DAMAGEABLE 0x00000008
|
||||
|
||||
#define MAX_ENT_CLUSTERS 16
|
||||
|
||||
|
@ -74,6 +91,8 @@ struct edict_s
|
|||
int headnode; /* unused if num_clusters != -1 */
|
||||
int areanum, areanum2;
|
||||
|
||||
/* ================================ */
|
||||
|
||||
int svflags; /* SVF_NOCLIENT, SVF_DEADMONSTER, SVF_MONSTER, etc */
|
||||
vec3_t mins, maxs;
|
||||
vec3_t absmin, absmax, size;
|
||||
|
@ -93,10 +112,10 @@ struct edict_s
|
|||
typedef struct
|
||||
{
|
||||
/* special messages */
|
||||
void (*bprintf)(int printlevel, char *fmt, ...);
|
||||
void (*dprintf)(char *fmt, ...);
|
||||
void (*cprintf)(edict_t *ent, int printlevel, char *fmt, ...);
|
||||
void (*centerprintf)(edict_t *ent, char *fmt, ...);
|
||||
void (*bprintf)(int printlevel, const char *fmt, ...);
|
||||
void (*dprintf)(const char *fmt, ...);
|
||||
void (*cprintf)(edict_t *ent, int printlevel, const char *fmt, ...);
|
||||
void (*centerprintf)(edict_t *ent, const char *fmt, ...);
|
||||
void (*sound)(edict_t *ent, int channel, int soundindex, float volume,
|
||||
float attenuation, float timeofs);
|
||||
void (*positioned_sound)(vec3_t origin, edict_t *ent, int channel,
|
||||
|
@ -106,17 +125,17 @@ typedef struct
|
|||
and misc data like the sky definition and cdtrack.
|
||||
All of the current configstrings are sent to clients when
|
||||
they connect, and changes are sent to all connected clients. */
|
||||
void (*configstring)(int num, char *string);
|
||||
void (*configstring)(int num, const char *string);
|
||||
|
||||
void (*error)(char *fmt, ...);
|
||||
YQ2_ATTR_NORETURN_FUNCPTR void (*error)(const char *fmt, ...);
|
||||
|
||||
/* the *index functions create configstrings
|
||||
and some internal server state */
|
||||
int (*modelindex)(char *name);
|
||||
int (*soundindex)(char *name);
|
||||
int (*imageindex)(char *name);
|
||||
int (*modelindex)(const char *name);
|
||||
int (*soundindex)(const char *name);
|
||||
int (*imageindex)(const char *name);
|
||||
|
||||
void (*setmodel)(edict_t *ent, char *name);
|
||||
void (*setmodel)(edict_t *ent, const char *name);
|
||||
|
||||
/* collision detection */
|
||||
trace_t (*trace)(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
|
||||
|
@ -144,7 +163,7 @@ typedef struct
|
|||
void (*WriteShort)(int c);
|
||||
void (*WriteLong)(int c);
|
||||
void (*WriteFloat)(float f);
|
||||
void (*WriteString)(char *s);
|
||||
void (*WriteString)(const char *s);
|
||||
void (*WritePosition)(vec3_t pos); /* some fractional bits */
|
||||
void (*WriteDir)(vec3_t pos); /* single byte encoded, very coarse */
|
||||
void (*WriteAngle)(float f);
|
||||
|
@ -155,9 +174,9 @@ typedef struct
|
|||
void (*FreeTags)(int tag);
|
||||
|
||||
/* console variable interaction */
|
||||
cvar_t *(*cvar)(char *var_name, char *value, int flags);
|
||||
cvar_t *(*cvar_set)(char *var_name, char *value);
|
||||
cvar_t *(*cvar_forceset)(char *var_name, char *value);
|
||||
cvar_t *(*cvar)(const char *var_name, const char *value, int flags);
|
||||
cvar_t *(*cvar_set)(const char *var_name, const char *value);
|
||||
cvar_t *(*cvar_forceset)(const char *var_name, const char *value);
|
||||
|
||||
/* ClientCommand and ServerCommand parameter access */
|
||||
int (*argc)(void);
|
||||
|
@ -166,7 +185,7 @@ typedef struct
|
|||
|
||||
/* add commands to the server console as if
|
||||
they were typed in for map changing, etc */
|
||||
void (*AddCommandString)(char *text);
|
||||
void (*AddCommandString)(const char *text);
|
||||
|
||||
void (*DebugGraph)(float value, int color);
|
||||
} game_import_t;
|
||||
|
@ -183,20 +202,20 @@ typedef struct
|
|||
void (*Shutdown)(void);
|
||||
|
||||
/* each new level entered will cause a call to SpawnEntities */
|
||||
void (*SpawnEntities)(char *mapname, char *entstring, char *spawnpoint);
|
||||
void (*SpawnEntities)(const char *mapname, char *entstring, const char *spawnpoint);
|
||||
|
||||
/* Read/Write Game is for storing persistant cross level information
|
||||
about the world state and the clients.
|
||||
WriteGame is called every time a level is exited.
|
||||
ReadGame is called on a loadgame. */
|
||||
void (*WriteGame)(char *filename, qboolean autosave);
|
||||
void (*ReadGame)(char *filename);
|
||||
void (*WriteGame)(const char *filename, qboolean autosave);
|
||||
void (*ReadGame)(const char *filename);
|
||||
|
||||
/* ReadLevel is called after the default
|
||||
map information has been loaded with
|
||||
SpawnEntities */
|
||||
void (*WriteLevel)(char *filename);
|
||||
void (*ReadLevel)(char *filename);
|
||||
void (*WriteLevel)(const char *filename);
|
||||
void (*ReadLevel)(const char *filename);
|
||||
|
||||
qboolean (*ClientConnect)(edict_t *ent, char *userinfo);
|
||||
void (*ClientBegin)(edict_t *ent);
|
||||
|
|
|
@ -1,8 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
* Copyright (c) ZeniMax Media Inc.
|
||||
* Licensed under the GNU General Public License 2.0.
|
||||
*/
|
||||
/* =======================================================================
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Main header file for the game module.
|
||||
*
|
||||
|
@ -14,16 +30,16 @@
|
|||
|
||||
#include "shared.h"
|
||||
|
||||
/* define GAME_INCLUDE so that game.h does not define the
|
||||
/* define GAME_INCLUDE so that game.h does not define the
|
||||
short, server-visible gclient_t and edict_t structures,
|
||||
because we define the full size ones in this file */
|
||||
#define GAME_INCLUDE
|
||||
#include "game.h"
|
||||
|
||||
/* the "gameversion" client command will print this plus compile date */
|
||||
/* the "gameversion" client command will print this plus compile date */
|
||||
#define GAMEVERSION "xatrix"
|
||||
|
||||
/* protocol bytes that can be directly added to messages */
|
||||
/* protocol bytes that can be directly added to messages */
|
||||
#define svc_muzzleflash 1
|
||||
#define svc_muzzleflash2 2
|
||||
#define svc_temp_entity 3
|
||||
|
@ -31,19 +47,20 @@
|
|||
#define svc_inventory 5
|
||||
#define svc_stufftext 11
|
||||
|
||||
/* ================================================================== */
|
||||
/* ================================================================== */
|
||||
|
||||
/* view pitching times */
|
||||
/* view pitching times */
|
||||
#define DAMAGE_TIME 0.5
|
||||
#define FALL_TIME 0.3
|
||||
|
||||
/* these are set with checkboxes on each entity in the map editor */
|
||||
/* these are set with checkboxes on each entity in the map editor */
|
||||
#define SPAWNFLAG_NOT_EASY 0x00000100
|
||||
#define SPAWNFLAG_NOT_MEDIUM 0x00000200
|
||||
#define SPAWNFLAG_NOT_HARD 0x00000400
|
||||
#define SPAWNFLAG_NOT_DEATHMATCH 0x00000800
|
||||
#define SPAWNFLAG_NOT_COOP 0x00001000
|
||||
|
||||
/* edict->flags */
|
||||
#define FL_FLY 0x00000001
|
||||
#define FL_SWIM 0x00000002 /* implied immunity to drowining */
|
||||
#define FL_IMMUNE_LASER 0x00000004
|
||||
|
@ -60,14 +77,18 @@
|
|||
#define FL_COOP_TAKEN 0x00002000 /* Another client has already taken it */
|
||||
#define FL_RESPAWN 0x80000000 /* used for item respawning */
|
||||
|
||||
#define FL_MECHANICAL 0x00002000 /* entity is mechanical, use sparks not blood */
|
||||
#define FL_SAM_RAIMI 0x00004000 /* entity is in sam raimi cam mode */
|
||||
#define FL_DISGUISED 0x00008000 /* entity is in disguise, monsters will not recognize. */
|
||||
#define FL_NOGIB 0x00010000 /* player has been vaporized by a nuke, drop no gibs */
|
||||
|
||||
#define FRAMETIME 0.1
|
||||
|
||||
/* memory tags to allow dynamic memory to be cleaned up */
|
||||
/* memory tags to allow dynamic memory to be cleaned up */
|
||||
#define TAG_GAME 765 /* clear when unloading the dll */
|
||||
#define TAG_LEVEL 766 /* clear when loading a new level */
|
||||
|
||||
#define MELEE_DISTANCE 80
|
||||
|
||||
#define BODY_QUEUE_SIZE 8
|
||||
|
||||
typedef enum
|
||||
|
@ -93,8 +114,11 @@ typedef enum
|
|||
AMMO_GRENADES,
|
||||
AMMO_CELLS,
|
||||
AMMO_SLUGS,
|
||||
AMMO_MAGSLUG,
|
||||
AMMO_TRAP
|
||||
|
||||
AMMO_FLECHETTES,
|
||||
AMMO_TESLA,
|
||||
AMMO_PROX,
|
||||
AMMO_DISRUPTOR
|
||||
} ammo_t;
|
||||
|
||||
/* Maximum debris / gibs per frame */
|
||||
|
@ -135,11 +159,27 @@ typedef enum
|
|||
#define AI_RESURRECTING 0x00004000
|
||||
#define AI_IGNORE_PAIN 0x00008000
|
||||
|
||||
/* ROGUE */
|
||||
#define AI_WALK_WALLS 0x00008000
|
||||
#define AI_MANUAL_STEERING 0x00010000
|
||||
#define AI_TARGET_ANGER 0x00020000
|
||||
#define AI_DODGING 0x00040000
|
||||
#define AI_CHARGING 0x00080000
|
||||
#define AI_HINT_PATH 0x00100000
|
||||
#define AI_IGNORE_SHOTS 0x00200000
|
||||
#define AI_DO_NOT_COUNT 0x00400000 /* set for healed monsters */
|
||||
#define AI_SPAWNED_CARRIER 0x00800000 /* both do_not_count and spawned are set for spawned monsters */
|
||||
#define AI_SPAWNED_MEDIC_C 0x01000000 /* both do_not_count and spawned are set for spawned monsters */
|
||||
#define AI_SPAWNED_WIDOW 0x02000000 /* both do_not_count and spawned are set for spawned monsters */
|
||||
#define AI_SPAWNED_MASK 0x03800000 /* mask to catch all three flavors of spawned */
|
||||
#define AI_BLOCKED 0x04000000 /* used by blocked_checkattack: set to say I'm attacking while blocked */
|
||||
/* (prevents run-attacks) */
|
||||
/* monster attack state */
|
||||
#define AS_STRAIGHT 1
|
||||
#define AS_SLIDING 2
|
||||
#define AS_MELEE 3
|
||||
#define AS_MISSILE 4
|
||||
#define AS_BLIND 5
|
||||
|
||||
/* armor types */
|
||||
#define ARMOR_NONE 0
|
||||
|
@ -188,7 +228,8 @@ typedef enum
|
|||
MOVETYPE_TOSS, /* gravity */
|
||||
MOVETYPE_FLYMISSILE, /* extra size to monsters */
|
||||
MOVETYPE_BOUNCE, /* added this (the comma at the end of line) */
|
||||
MOVETYPE_WALLBOUNCE
|
||||
MOVETYPE_WALLBOUNCE,
|
||||
MOVETYPE_NEWTOSS /* for deathball */
|
||||
} movetype_t;
|
||||
|
||||
typedef struct
|
||||
|
@ -201,13 +242,15 @@ typedef struct
|
|||
} gitem_armor_t;
|
||||
|
||||
/* gitem_t->flags */
|
||||
#define IT_WEAPON 1 /* use makes active weapon */
|
||||
#define IT_AMMO 2
|
||||
#define IT_ARMOR 4
|
||||
#define IT_STAY_COOP 8
|
||||
#define IT_KEY 16
|
||||
#define IT_POWERUP 32
|
||||
#define IT_INSTANT_USE 64 /* item is insta-used on pickup if dmflag is set */
|
||||
#define IT_WEAPON 0x00000001 /* use makes active weapon */
|
||||
#define IT_AMMO 0x00000002
|
||||
#define IT_ARMOR 0x00000004
|
||||
#define IT_STAY_COOP 0x00000008
|
||||
#define IT_KEY 0x00000010
|
||||
#define IT_POWERUP 0x00000020
|
||||
#define IT_MELEE 0x00000040
|
||||
#define IT_NOT_GIVEABLE 0x00000080 /* item can not be given */
|
||||
#define IT_INSTANT_USE 0x000000100 /* item is insta-used on pickup if dmflag is set */
|
||||
|
||||
/* gitem_t->weapmodel for weapons indicates model index */
|
||||
#define WEAP_BLASTER 1
|
||||
|
@ -223,6 +266,11 @@ typedef struct
|
|||
#define WEAP_BFG 11
|
||||
#define WEAP_PHALANX 12
|
||||
#define WEAP_BOOMER 13
|
||||
#define WEAP_DISRUPTOR 14
|
||||
#define WEAP_ETFRIFLE 15
|
||||
#define WEAP_PLASMA 16
|
||||
#define WEAP_PROXLAUNCH 17
|
||||
#define WEAP_CHAINFIST 18
|
||||
|
||||
typedef struct gitem_s
|
||||
{
|
||||
|
@ -260,13 +308,14 @@ typedef struct
|
|||
{
|
||||
char helpmessage1[512];
|
||||
char helpmessage2[512];
|
||||
int helpchanged; /* flash F1 icon if non 0, play sound
|
||||
and increment only if 1, 2, or 3 */
|
||||
int helpchanged; /* flash F1 icon if non 0, play sound */
|
||||
/* and increment only if 1, 2, or 3 */
|
||||
|
||||
gclient_t *clients; /* [maxclients] */
|
||||
|
||||
/* can't store spawnpoint in level, because
|
||||
it would get overwritten by the savegame restore */
|
||||
it would get overwritten by the savegame
|
||||
restore */
|
||||
char spawnpoint[512]; /* needed for coop respawns */
|
||||
|
||||
/* store latched cvars here that we want to get at often */
|
||||
|
@ -324,16 +373,20 @@ typedef struct
|
|||
int body_que; /* dead bodies */
|
||||
|
||||
int power_cubes; /* ugly necessity for coop */
|
||||
|
||||
edict_t *disguise_violator;
|
||||
int disguise_violation_framenum;
|
||||
} level_locals_t;
|
||||
|
||||
/* spawn_temp_t is only used to hold entity field values that
|
||||
can be set from the editor, but aren't actualy present
|
||||
can be set from the editor, but aren't actualy present/
|
||||
in edict_t during gameplay */
|
||||
typedef struct
|
||||
{
|
||||
/* world vars */
|
||||
char *sky;
|
||||
float skyrotate;
|
||||
int skyautorotate;
|
||||
vec3_t skyaxis;
|
||||
char *nextmap;
|
||||
|
||||
|
@ -399,7 +452,7 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
mmove_t *currentmove;
|
||||
int aiflags;
|
||||
unsigned int aiflags; /* unsigned, since we're close to the max */
|
||||
int nextframe;
|
||||
float scale;
|
||||
|
||||
|
@ -428,8 +481,40 @@ typedef struct
|
|||
|
||||
int power_armor_type;
|
||||
int power_armor_power;
|
||||
|
||||
qboolean (*blocked)(edict_t *self, float dist);
|
||||
float last_hint_time; /* last time the monster checked for hintpaths. */
|
||||
edict_t *goal_hint; /* which hint_path we're trying to get to */
|
||||
int medicTries;
|
||||
edict_t *badMedic1, *badMedic2; /* these medics have declared this monster "unhealable" */
|
||||
edict_t *healer; /* this is who is healing this monster */
|
||||
void (*duck)(edict_t *self, float eta);
|
||||
void (*unduck)(edict_t *self);
|
||||
void (*sidestep)(edict_t *self);
|
||||
float base_height;
|
||||
float next_duck_time;
|
||||
float duck_wait_time;
|
||||
edict_t *last_player_enemy;
|
||||
qboolean blindfire; /* will the monster blindfire? */
|
||||
float blind_fire_delay;
|
||||
vec3_t blind_fire_target;
|
||||
|
||||
/* used by the spawners to not spawn too much and keep track of #s of monsters spawned */
|
||||
int monster_slots;
|
||||
int monster_used;
|
||||
edict_t *commander;
|
||||
|
||||
/* powerup timers, used by widow, our friend */
|
||||
float quad_framenum;
|
||||
float invincible_framenum;
|
||||
float double_framenum;
|
||||
} monsterinfo_t;
|
||||
|
||||
/* this determines how long to wait after a duck to duck again.
|
||||
this needs to be longer than the time after the monster_duck_up
|
||||
in all of the animation sequences */
|
||||
#define DUCK_INTERVAL 0.5
|
||||
|
||||
extern game_locals_t game;
|
||||
extern level_locals_t level;
|
||||
extern game_import_t gi;
|
||||
|
@ -484,6 +569,22 @@ extern int gibsthisframe;
|
|||
#define MOD_GEKK 38
|
||||
#define MOD_TRAP 39
|
||||
#define MOD_FRIENDLY_FIRE 0x8000000
|
||||
#define MOD_CHAINFIST 40
|
||||
#define MOD_DISINTEGRATOR 41
|
||||
#define MOD_ETF_RIFLE 42
|
||||
#define MOD_BLASTER2 43
|
||||
#define MOD_HEATBEAM 44
|
||||
#define MOD_TESLA 45
|
||||
#define MOD_PROX 46
|
||||
#define MOD_NUKE 47
|
||||
#define MOD_VENGEANCE_SPHERE 48
|
||||
#define MOD_HUNTER_SPHERE 49
|
||||
#define MOD_DEFENDER_SPHERE 50
|
||||
#define MOD_TRACKER 51
|
||||
#define MOD_DBALL_CRUSH 52
|
||||
#define MOD_DOPPLE_EXPLODE 53
|
||||
#define MOD_DOPPLE_VENGEANCE 54
|
||||
#define MOD_DOPPLE_HUNTER 55
|
||||
|
||||
/* Easier handling of AI skill levels */
|
||||
#define SKILL_EASY 0
|
||||
|
@ -505,6 +606,8 @@ extern edict_t *g_edicts;
|
|||
extern cvar_t *maxentities;
|
||||
extern cvar_t *deathmatch;
|
||||
extern cvar_t *coop;
|
||||
extern cvar_t *coop_baseq2; /* treat spawnflags according to baseq2 rules */
|
||||
extern cvar_t *coop_pickup_weapons;
|
||||
extern cvar_t *coop_elevator_delay;
|
||||
extern cvar_t *coop_pickup_weapons;
|
||||
extern cvar_t *dmflags;
|
||||
|
@ -517,7 +620,9 @@ extern cvar_t *needpass;
|
|||
extern cvar_t *g_select_empty;
|
||||
extern cvar_t *dedicated;
|
||||
extern cvar_t *g_footsteps;
|
||||
extern cvar_t *g_monsterfootsteps;
|
||||
extern cvar_t *g_fix_triggered;
|
||||
extern cvar_t *g_commanderbody_nogod;
|
||||
|
||||
extern cvar_t *filterban;
|
||||
|
||||
|
@ -544,23 +649,41 @@ extern cvar_t *flood_waitdelay;
|
|||
|
||||
extern cvar_t *sv_maplist;
|
||||
|
||||
extern cvar_t *sv_stopspeed;
|
||||
|
||||
extern cvar_t *g_showlogic;
|
||||
extern cvar_t *gamerules;
|
||||
extern cvar_t *huntercam;
|
||||
extern cvar_t *strong_mines;
|
||||
extern cvar_t *randomrespawn;
|
||||
|
||||
extern cvar_t *g_disruptor;
|
||||
|
||||
extern cvar_t *aimfix;
|
||||
extern cvar_t *g_machinegun_norecoil;
|
||||
extern cvar_t *g_swap_speed;
|
||||
|
||||
/* this is for the count of monsters */
|
||||
#define ENT_SLOTS_LEFT \
|
||||
(ent->monsterinfo.monster_slots - \
|
||||
ent->monsterinfo.monster_used)
|
||||
#define SELF_SLOTS_LEFT \
|
||||
(self->monsterinfo.monster_slots - \
|
||||
self->monsterinfo.monster_used)
|
||||
|
||||
#define world (&g_edicts[0])
|
||||
|
||||
/* item spawnflags */
|
||||
/* item spawnflags */
|
||||
#define ITEM_TRIGGER_SPAWN 0x00000001
|
||||
#define ITEM_NO_TOUCH 0x00000002
|
||||
/* 6 bits reserved for editor flags
|
||||
8 bits used as power cube id bits
|
||||
for coop games */
|
||||
/* 6 bits reserved for editor flags */
|
||||
/* 8 bits used as power cube id bits for coop games */
|
||||
#define DROPPED_ITEM 0x00010000
|
||||
#define DROPPED_PLAYER_ITEM 0x00020000
|
||||
#define ITEM_TARGETS_USED 0x00040000
|
||||
|
||||
/* fields are needed for spawning from the
|
||||
entity string and saving / loading games */
|
||||
/* fields are needed for spawning from the entity
|
||||
string and saving / loading games */
|
||||
#define FFL_SPAWNTEMP 1
|
||||
#define FFL_NOSPAWN 2
|
||||
|
||||
|
@ -592,8 +715,16 @@ typedef struct
|
|||
extern field_t fields[];
|
||||
extern gitem_t itemlist[];
|
||||
|
||||
/* player/client.c */
|
||||
void ClientBegin(edict_t *ent);
|
||||
void ClientDisconnect(edict_t *ent);
|
||||
void ClientUserinfoChanged(edict_t *ent, char *userinfo);
|
||||
qboolean ClientConnect(edict_t *ent, char *userinfo);
|
||||
void ClientThink(edict_t *ent, usercmd_t *cmd);
|
||||
|
||||
/* g_cmds.c */
|
||||
void Cmd_Help_f(edict_t *ent);
|
||||
void ClientCommand(edict_t *ent);
|
||||
|
||||
/* g_items.c */
|
||||
void PrecacheItem(gitem_t *it);
|
||||
|
@ -603,6 +734,7 @@ gitem_t *FindItem(char *pickup_name);
|
|||
gitem_t *FindItemByClassname(char *classname);
|
||||
|
||||
#define ITEM_INDEX(x) ((x) - itemlist)
|
||||
|
||||
edict_t *Drop_Item(edict_t *ent, gitem_t *item);
|
||||
void SetRespawn(edict_t *ent, float delay);
|
||||
void ChangeWeapon(edict_t *ent);
|
||||
|
@ -612,7 +744,8 @@ int ArmorIndex(edict_t *ent);
|
|||
int PowerArmorType(edict_t *ent);
|
||||
gitem_t *GetItemByIndex(int index);
|
||||
qboolean Add_Ammo(edict_t *ent, gitem_t *item, int count);
|
||||
void Touch_Item(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf);
|
||||
void Touch_Item(edict_t *ent, edict_t *other, cplane_t *plane,
|
||||
csurface_t *surf);
|
||||
|
||||
/* g_utils.c */
|
||||
qboolean KillBox(edict_t *ent);
|
||||
|
@ -641,14 +774,29 @@ void get_normal_vector(const cplane_t *p, vec3_t normal);
|
|||
float vectoyaw(vec3_t vec);
|
||||
void vectoangles(vec3_t vec, vec3_t angles);
|
||||
|
||||
void G_ProjectSource2(vec3_t point, vec3_t distance, vec3_t forward, vec3_t right,
|
||||
vec3_t up, vec3_t result);
|
||||
float vectoyaw2(vec3_t vec);
|
||||
void vectoangles2(vec3_t vec, vec3_t angles);
|
||||
edict_t *findradius2(edict_t *from, vec3_t org, float rad);
|
||||
|
||||
/* g_spawn.c */
|
||||
void ED_CallSpawn(edict_t *ent);
|
||||
|
||||
/* g_combat.c */
|
||||
qboolean OnSameTeam(edict_t *ent1, edict_t *ent2);
|
||||
qboolean CanDamage(edict_t *targ, edict_t *inflictor);
|
||||
void T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker,
|
||||
vec3_t dir, vec3_t point, vec3_t normal, int damage,
|
||||
int knockback, int dflags, int mod);
|
||||
void T_RadiusDamage(edict_t *inflictor, edict_t *attacker, float damage,
|
||||
void T_RadiusDamage(edict_t *inflictor, edict_t *attacker,
|
||||
float damage, edict_t *ignore, float radius,
|
||||
int mod);
|
||||
void T_RadiusNukeDamage(edict_t *inflictor, edict_t *attacker, float damage,
|
||||
edict_t *ignore, float radius, int mod);
|
||||
void T_RadiusClassDamage(edict_t *inflictor, edict_t *attacker, float damage,
|
||||
char *ignoreClass, float radius, int mod);
|
||||
void cleanupHealTarget(edict_t *ent);
|
||||
|
||||
/* damage flags */
|
||||
#define DAMAGE_RADIUS 0x00000001 /* damage was indirect */
|
||||
|
@ -657,33 +805,37 @@ void T_RadiusDamage(edict_t *inflictor, edict_t *attacker, float damage,
|
|||
#define DAMAGE_NO_KNOCKBACK 0x00000008 /* do not affect velocity, just view angles */
|
||||
#define DAMAGE_BULLET 0x00000010 /* damage is from a bullet (used for ricochets) */
|
||||
#define DAMAGE_NO_PROTECTION 0x00000020 /* armor, shields, invulnerability, and godmode have no effect */
|
||||
#define DAMAGE_DESTROY_ARMOR 0x00000040 /* damage is done to armor and health. */
|
||||
#define DAMAGE_NO_REG_ARMOR 0x00000080 /* damage skips regular armor */
|
||||
#define DAMAGE_NO_POWER_ARMOR 0x00000100 /* damage skips power armor */
|
||||
|
||||
#define DEFAULT_BULLET_HSPREAD 300
|
||||
#define DEFAULT_BULLET_VSPREAD 500
|
||||
#define DEFAULT_SHOTGUN_HSPREAD 1000
|
||||
#define DEFAULT_SHOTGUN_VSPREAD 500
|
||||
#define DEFAULT_DEATHMATCH_SHOTGUN_COUNT 12
|
||||
#define DEFAULT_SHOTGUN_COUNT 12
|
||||
#define DEFAULT_SSHOTGUN_COUNT 20
|
||||
|
||||
/* g_monster.c */
|
||||
void monster_fire_bullet(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int kick, int hspread, int vspread, int flashtype);
|
||||
void monster_fire_shotgun(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int kick, int hspread, int vspread, int count, int flashtype);
|
||||
void monster_fire_blaster(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int flashtype, int effect);
|
||||
void monster_fire_grenade(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, int flashtype);
|
||||
void monster_fire_rocket(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int flashtype);
|
||||
void monster_fire_railgun(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int kick, int flashtype);
|
||||
void monster_fire_bfg(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, int kick, float damage_radius, int flashtype);
|
||||
void monster_fire_shotgun(edict_t *self, vec3_t start, vec3_t aimdir,
|
||||
int damage, int kick, int hspread, int vspread, int count,
|
||||
int flashtype);
|
||||
void monster_fire_blaster(edict_t *self, vec3_t start, vec3_t dir,
|
||||
int damage, int speed, int flashtype, int effect);
|
||||
void monster_fire_grenade(edict_t *self, vec3_t start, vec3_t aimdir,
|
||||
int damage, int speed, int flashtype);
|
||||
void monster_fire_rocket(edict_t *self, vec3_t start, vec3_t dir,
|
||||
int damage, int speed, int flashtype);
|
||||
void monster_fire_railgun(edict_t *self, vec3_t start, vec3_t aimdir,
|
||||
int damage, int kick, int flashtype);
|
||||
void monster_fire_bfg(edict_t *self, vec3_t start, vec3_t aimdir,
|
||||
int damage, int speed, int kick, float damage_radius,
|
||||
int flashtype);
|
||||
void monster_fire_ionripper(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int flashtype, int effect);
|
||||
void monster_fire_heat(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int flashtype);
|
||||
void monster_dabeam(edict_t *self);
|
||||
void monster_fire_blueblaster(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int flashtype, int effect);
|
||||
|
@ -700,6 +852,13 @@ qboolean M_CheckAttack(edict_t *self);
|
|||
void M_FlyCheck(edict_t *self);
|
||||
void M_CheckGround(edict_t *ent);
|
||||
|
||||
void monster_fire_blaster2(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int flashtype, int effect);
|
||||
void monster_fire_tracker(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, edict_t *enemy, int flashtype);
|
||||
void stationarymonster_start(edict_t *self);
|
||||
void monster_done_dodge(edict_t *self);
|
||||
|
||||
/* g_misc.c */
|
||||
void ThrowHead(edict_t *self, char *gibname, int damage, int type);
|
||||
void ThrowClientHead(edict_t *self, int damage);
|
||||
|
@ -710,6 +869,7 @@ void ThrowGibACID(edict_t *self, char *gibname, int damage, int type);
|
|||
|
||||
/* g_ai.c */
|
||||
void AI_SetSightClient(void);
|
||||
|
||||
void ai_stand(edict_t *self, float dist);
|
||||
void ai_move(edict_t *self, float dist);
|
||||
void ai_walk(edict_t *self, float dist);
|
||||
|
@ -744,8 +904,6 @@ void fire_bfg(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
|||
int speed, float damage_radius);
|
||||
void fire_ionripper(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, int effect);
|
||||
void fire_heat(edict_t *self, vec3_t start, vec3_t dir, int damage, int speed,
|
||||
float damage_radius, int radius_damage);
|
||||
void fire_blueblaster(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, int effect);
|
||||
void fire_plasma(edict_t *self, vec3_t start, vec3_t dir, int damage, int speed,
|
||||
|
@ -770,7 +928,7 @@ void InitClientResp(gclient_t *client);
|
|||
void InitBodyQue(void);
|
||||
void ClientBeginServerFrame(edict_t *ent);
|
||||
|
||||
/* g_player.c */
|
||||
/* g_player.c */
|
||||
void player_pain(edict_t *self, edict_t *other, float kick, int damage);
|
||||
void player_die(edict_t *self, edict_t *inflictor, edict_t *attacker,
|
||||
int damage, vec3_t point);
|
||||
|
@ -814,7 +972,96 @@ void ChaseNext(edict_t *ent);
|
|||
void ChasePrev(edict_t *ent);
|
||||
void GetChaseTarget(edict_t *ent);
|
||||
|
||||
/* ============================================================================ */
|
||||
/* savegame */
|
||||
void InitGame(void);
|
||||
void ReadLevel(const char *filename);
|
||||
void WriteLevel(const char *filename);
|
||||
void ReadGame(const char *filename);
|
||||
void WriteGame(const char *filename, qboolean autosave);
|
||||
void SpawnEntities(const char *mapname, char *entities, const char *spawnpoint);
|
||||
|
||||
void fire_flechette(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int kick);
|
||||
void fire_prox(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed);
|
||||
void fire_nuke(edict_t *self, vec3_t start, vec3_t aimdir, int speed);
|
||||
void fire_flame(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed);
|
||||
void fire_burst(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed);
|
||||
void fire_maintain(edict_t *, edict_t *, vec3_t start, vec3_t aimdir,
|
||||
int damage, int speed);
|
||||
void fire_incendiary_grenade(edict_t *self, vec3_t start, vec3_t aimdir,
|
||||
int damage, int speed, float timer, float damage_radius);
|
||||
void fire_player_melee(edict_t *self, vec3_t start, vec3_t aim, int reach,
|
||||
int damage, int kick, int quiet, int mod);
|
||||
void fire_tesla(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed);
|
||||
void fire_blaster2(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, int effect, qboolean hyper);
|
||||
void fire_tracker(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, edict_t *enemy);
|
||||
|
||||
/* g_newai.c */
|
||||
qboolean blocked_checkplat(edict_t *self, float dist);
|
||||
qboolean blocked_checkjump(edict_t *self, float dist, float maxDown, float maxUp);
|
||||
qboolean blocked_checknewenemy(edict_t *self);
|
||||
qboolean monsterlost_checkhint(edict_t *self);
|
||||
qboolean inback(edict_t *self, edict_t *other);
|
||||
float realrange(edict_t *self, edict_t *other);
|
||||
edict_t *SpawnBadArea(vec3_t mins, vec3_t maxs, float lifespan, edict_t *owner);
|
||||
edict_t *CheckForBadArea(edict_t *ent);
|
||||
qboolean MarkTeslaArea(edict_t *self, edict_t *tesla);
|
||||
void InitHintPaths(void);
|
||||
void PredictAim(edict_t *target, vec3_t start, float bolt_speed, qboolean eye_height,
|
||||
float offset, vec3_t aimdir, vec3_t aimpoint);
|
||||
qboolean below(edict_t *self, edict_t *other);
|
||||
void drawbbox(edict_t *self);
|
||||
void M_MonsterDodge(edict_t *self, edict_t *attacker, float eta, trace_t *tr);
|
||||
void monster_duck_down(edict_t *self);
|
||||
void monster_duck_hold(edict_t *self);
|
||||
void monster_duck_up(edict_t *self);
|
||||
qboolean has_valid_enemy(edict_t *self);
|
||||
void TargetTesla(edict_t *self, edict_t *tesla);
|
||||
void hintpath_stop(edict_t *self);
|
||||
edict_t *PickCoopTarget(edict_t *self);
|
||||
int CountPlayers(void);
|
||||
void monster_jump_start(edict_t *self);
|
||||
qboolean monster_jump_finished(edict_t *self);
|
||||
|
||||
/* g_sphere.c */
|
||||
void Defender_Launch(edict_t *self);
|
||||
void Vengeance_Launch(edict_t *self);
|
||||
void Hunter_Launch(edict_t *self);
|
||||
|
||||
/* g_newdm.c */
|
||||
void InitGameRules(void);
|
||||
edict_t *DoRandomRespawn(edict_t *ent);
|
||||
void PrecacheForRandomRespawn(void);
|
||||
qboolean Tag_PickupToken(edict_t *ent, edict_t *other);
|
||||
void Tag_DropToken(edict_t *ent, gitem_t *item);
|
||||
void Tag_PlayerDeath(edict_t *targ, edict_t *inflictor, edict_t *attacker);
|
||||
void fire_doppleganger(edict_t *ent, vec3_t start, vec3_t aimdir);
|
||||
|
||||
/* g_spawn.c */
|
||||
edict_t *CreateMonster(vec3_t origin, vec3_t angles, char *classname);
|
||||
edict_t *CreateFlyMonster(vec3_t origin, vec3_t angles, vec3_t mins,
|
||||
vec3_t maxs, char *classname);
|
||||
edict_t *CreateGroundMonster(vec3_t origin, vec3_t angles, vec3_t mins,
|
||||
vec3_t maxs, char *classname, int height);
|
||||
qboolean FindSpawnPoint(vec3_t startpoint, vec3_t mins, vec3_t maxs,
|
||||
vec3_t spawnpoint, float maxMoveUp);
|
||||
qboolean CheckSpawnPoint(vec3_t origin, vec3_t mins, vec3_t maxs);
|
||||
qboolean CheckGroundSpawnPoint(vec3_t origin, vec3_t entMins, vec3_t entMaxs,
|
||||
float height, float gravity);
|
||||
void DetermineBBox(char *classname, vec3_t mins, vec3_t maxs);
|
||||
void SpawnGrow_Spawn(vec3_t startpos, int size);
|
||||
void Widowlegs_Spawn(vec3_t startpos, vec3_t angles);
|
||||
|
||||
/* p_client.c */
|
||||
void RemoveAttackingPainDaemons(edict_t *self);
|
||||
|
||||
/* ============================================================================ */
|
||||
|
||||
/* client_t->anim_priority */
|
||||
#define ANIM_BASIC 0 /* stand / run */
|
||||
|
@ -864,6 +1111,12 @@ typedef struct
|
|||
int helpchanged;
|
||||
|
||||
qboolean spectator; /* client is a spectator */
|
||||
|
||||
int max_tesla;
|
||||
int max_prox;
|
||||
int max_mines;
|
||||
int max_flechettes;
|
||||
int max_rounds;
|
||||
} client_persistant_t;
|
||||
|
||||
/* client data that stays across deathmatch respawns */
|
||||
|
@ -878,8 +1131,7 @@ typedef struct
|
|||
} client_respawn_t;
|
||||
|
||||
/* this structure is cleared on each
|
||||
PutClientInServer(), except for
|
||||
'client->pers' */
|
||||
PutClientInServer(), except for 'client->pers' */
|
||||
struct gclient_s
|
||||
{
|
||||
/* known to server */
|
||||
|
@ -966,16 +1218,21 @@ struct gclient_s
|
|||
|
||||
edict_t *chase_target; /* player we are chasing */
|
||||
qboolean update_chase; /* need to update chase info? */
|
||||
|
||||
float double_framenum;
|
||||
float ir_framenum;
|
||||
float nuke_framenum;
|
||||
float tracker_pain_framenum;
|
||||
|
||||
edict_t *owned_sphere; /* this points to the player's sphere */
|
||||
};
|
||||
|
||||
struct edict_s
|
||||
{
|
||||
entity_state_t s;
|
||||
struct gclient_s *client; /* NULL if not a player */
|
||||
|
||||
/* the server expects the first part
|
||||
of gclient_s to be a player_state_t
|
||||
but the rest of it is opaque */
|
||||
struct gclient_s *client; /* NULL if not a player the server expects the first part
|
||||
of gclient_s to be a player_state_t but the rest of it is
|
||||
opaque */
|
||||
|
||||
qboolean inuse;
|
||||
int linkcount;
|
||||
|
@ -996,8 +1253,8 @@ struct edict_s
|
|||
int clipmask;
|
||||
edict_t *owner;
|
||||
|
||||
/* DO NOT MODIFY ANYTHING ABOVE THIS, THE
|
||||
SERVER EXPECTS THE FIELDS IN THAT ORDER! */
|
||||
/* DO NOT MODIFY ANYTHING ABOVE THIS, THE SERVER */
|
||||
/* EXPECTS THE FIELDS IN THAT ORDER! */
|
||||
|
||||
/* ================================ */
|
||||
|
||||
|
@ -1032,8 +1289,8 @@ struct edict_s
|
|||
vec3_t avelocity;
|
||||
int mass;
|
||||
float air_finished;
|
||||
float gravity; /* per entity gravity multiplier (1.0 is
|
||||
normal) use for lowgrav artifact, flares */
|
||||
float gravity; /* per entity gravity multiplier (1.0 is normal) */
|
||||
/* use for lowgrav artifact, flares */
|
||||
|
||||
edict_t *goalentity;
|
||||
edict_t *movetarget;
|
||||
|
@ -1108,7 +1365,6 @@ struct edict_s
|
|||
|
||||
/* move this to clientinfo? */
|
||||
int light_level;
|
||||
|
||||
int style; /* also used as areaportal number */
|
||||
|
||||
gitem_t *item; /* for bonus items */
|
||||
|
@ -1118,6 +1374,63 @@ struct edict_s
|
|||
monsterinfo_t monsterinfo;
|
||||
|
||||
int orders;
|
||||
|
||||
int plat2flags;
|
||||
vec3_t offset;
|
||||
vec3_t gravityVector;
|
||||
edict_t *bad_area;
|
||||
edict_t *hint_chain;
|
||||
edict_t *monster_hint_chain;
|
||||
edict_t *target_hint_chain;
|
||||
int hint_chain_id;
|
||||
float lastMoveTime;
|
||||
};
|
||||
|
||||
#define SPHERE_DEFENDER 0x0001
|
||||
#define SPHERE_HUNTER 0x0002
|
||||
#define SPHERE_VENGEANCE 0x0004
|
||||
#define SPHERE_DOPPLEGANGER 0x0100
|
||||
|
||||
#define SPHERE_TYPE 0x00FF
|
||||
#define SPHERE_FLAGS 0xFF00
|
||||
|
||||
/* deathmatch games */
|
||||
#define RDM_TAG 2
|
||||
#define RDM_DEATHBALL 3
|
||||
|
||||
typedef struct dm_game_rs
|
||||
{
|
||||
void (*GameInit)(void);
|
||||
void (*PostInitSetup)(void);
|
||||
void (*ClientBegin)(edict_t *ent);
|
||||
void (*SelectSpawnPoint)(edict_t *ent, vec3_t origin, vec3_t angles);
|
||||
void (*PlayerDeath)(edict_t *targ, edict_t *inflictor, edict_t *attacker);
|
||||
void (*Score)(edict_t *attacker, edict_t *victim, int scoreChange);
|
||||
void (*PlayerEffects)(edict_t *ent);
|
||||
void (*DogTag)(edict_t *ent, edict_t *killer, char **pic);
|
||||
void (*PlayerDisconnect)(edict_t *ent);
|
||||
int (*ChangeDamage)(edict_t *targ, edict_t *attacker, int damage, int mod);
|
||||
int (*ChangeKnockback)(edict_t *targ, edict_t *attacker, int knockback, int mod);
|
||||
int (*CheckDMRules)(void);
|
||||
} dm_game_rt;
|
||||
|
||||
extern dm_game_rt DMGame;
|
||||
|
||||
void Tag_GameInit(void);
|
||||
void Tag_PostInitSetup(void);
|
||||
void Tag_PlayerDeath(edict_t *targ, edict_t *inflictor, edict_t *attacker);
|
||||
void Tag_Score(edict_t *attacker, edict_t *victim, int scoreChange);
|
||||
void Tag_PlayerEffects(edict_t *ent);
|
||||
void Tag_DogTag(edict_t *ent, edict_t *killer, char **pic);
|
||||
void Tag_PlayerDisconnect(edict_t *ent);
|
||||
int Tag_ChangeDamage(edict_t *targ, edict_t *attacker, int damage, int mod);
|
||||
|
||||
void DBall_GameInit(void);
|
||||
void DBall_ClientBegin(edict_t *ent);
|
||||
void DBall_SelectSpawnPoint(edict_t *ent, vec3_t origin, vec3_t angles);
|
||||
int DBall_ChangeKnockback(edict_t *targ, edict_t *attacker, int knockback, int mod);
|
||||
int DBall_ChangeDamage(edict_t *targ, edict_t *attacker, int damage, int mod);
|
||||
void DBall_PostInitSetup(void);
|
||||
int DBall_CheckDMRules(void);
|
||||
|
||||
#endif /* XATRIX_LOCAL_H */
|
||||
|
|
|
@ -471,7 +471,7 @@ berserk_die(edict_t *self, edict_t *inflictor /* unsued */, edict_t *attacker /*
|
|||
|
||||
if (self->health <= self->gib_health)
|
||||
{
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
|
|
|
@ -414,7 +414,7 @@ G_SetStats(edict_t *ent)
|
|||
{
|
||||
/* ran out of cells for power armor */
|
||||
ent->flags &= ~FL_POWER_ARMOR;
|
||||
gi.sound(ent, CHAN_ITEM, gi.soundindex( "misc/power2.wav"),
|
||||
gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/power2.wav"),
|
||||
1, ATTN_NORM, 0);
|
||||
power_armor_type = 0;
|
||||
}
|
||||
|
|
|
@ -400,7 +400,7 @@ GetPCXPalette24to8(byte *d_8to24table, byte** d_16to8table)
|
|||
if (!(*d_16to8table))
|
||||
{
|
||||
Com_Error(ERR_FATAL, "%s: Couldn't allocate memory for d_16to8table", __func__);
|
||||
// code never returns after ERR_FATAL
|
||||
/* code never returns after ERR_FATAL */
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -468,14 +468,14 @@ GetPCXPalette(byte **colormap, unsigned *d_8to24table)
|
|||
int i;
|
||||
|
||||
memcpy(d_8to24table, pic, 256 * 4);
|
||||
d_8to24table[255] &= LittleLong(0xffffff); // 255 is transparent
|
||||
d_8to24table[255] &= LittleLong(0xffffff); /* 255 is transparent */
|
||||
|
||||
/* generate colormap */
|
||||
*colormap = malloc(256 * 320);
|
||||
if (!(*colormap))
|
||||
{
|
||||
Com_Error(ERR_FATAL, "%s: Couldn't allocate memory for colormap", __func__);
|
||||
// code never returns after ERR_FATAL
|
||||
/* code never returns after ERR_FATAL */
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -516,14 +516,14 @@ GetPCXPalette(byte **colormap, unsigned *d_8to24table)
|
|||
d_8to24table[i] = LittleLong(v);
|
||||
}
|
||||
|
||||
d_8to24table[255] &= LittleLong(0xffffff); // 255 is transparent
|
||||
d_8to24table[255] &= LittleLong(0xffffff); /* 255 is transparent */
|
||||
|
||||
/* generate colormap */
|
||||
*colormap = malloc(256 * 320);
|
||||
if (!(*colormap))
|
||||
{
|
||||
Com_Error(ERR_FATAL, "%s: Couldn't allocate memory for colormap", __func__);
|
||||
// code never returns after ERR_FATAL
|
||||
/* code never returns after ERR_FATAL */
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -531,7 +531,7 @@ GetPCXPalette(byte **colormap, unsigned *d_8to24table)
|
|||
return;
|
||||
}
|
||||
|
||||
for (i=0 ; i<256 ; i++)
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
unsigned v;
|
||||
int r, g, b;
|
||||
|
|
|
@ -275,7 +275,7 @@ R_LoadPic8 (char *name, byte *pic, int width, int realwidth, int height, int rea
|
|||
if (!image->pixels[0])
|
||||
{
|
||||
Com_Error(ERR_FATAL, "%s: Can't allocate image.", __func__);
|
||||
// code never returns after ERR_FATAL
|
||||
/* code never returns after ERR_FATAL */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -339,7 +339,7 @@ R_LoadPic (char *name, byte *pic, int width, int realwidth, int height, int real
|
|||
if (!pic8)
|
||||
{
|
||||
Com_Error(ERR_FATAL, "%s: Can't allocate image.", __func__);
|
||||
// code never returns after ERR_FATAL
|
||||
/* code never returns after ERR_FATAL */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -2407,7 +2407,7 @@ SWimp_CreateRender(int width, int height)
|
|||
if (!swap_buffers)
|
||||
{
|
||||
Com_Error(ERR_FATAL, "%s: Can't allocate swapbuffer.", __func__);
|
||||
// code never returns after ERR_FATAL
|
||||
/* code never returns after ERR_FATAL */
|
||||
return;
|
||||
}
|
||||
swap_frames[0] = swap_buffers;
|
||||
|
|
|
@ -293,7 +293,7 @@ R_InitCaches (void)
|
|||
if (!sc_base)
|
||||
{
|
||||
Com_Error(ERR_FATAL, "%s: Can't allocate cache.", __func__);
|
||||
// code never returns after ERR_FATAL
|
||||
/* code never returns after ERR_FATAL */
|
||||
return;
|
||||
}
|
||||
sc_rover = sc_base;
|
||||
|
|
|
@ -882,7 +882,8 @@ Returns number of mip levels and scales native resolution
|
|||
if vk_picmip is set. Does not use power of 2 scaling.
|
||||
===============
|
||||
*/
|
||||
static uint32_t Vk_Upload32Native (byte *data, int width, int height, imagetype_t type,
|
||||
static uint32_t
|
||||
Vk_Upload32Native(byte *data, int width, int height, imagetype_t type,
|
||||
byte **texBuffer, int *upload_width, int *upload_height)
|
||||
{
|
||||
int scaled_width = width, scaled_height = height;
|
||||
|
@ -1018,7 +1019,8 @@ Returns number of mip levels
|
|||
===============
|
||||
*/
|
||||
|
||||
static uint32_t Vk_Upload8 (const byte *data, int width, int height, imagetype_t type,
|
||||
static uint32_t
|
||||
Vk_Upload8(const byte *data, int width, int height, imagetype_t type,
|
||||
byte **texBuffer, int *upload_width, int *upload_height)
|
||||
{
|
||||
unsigned *trans;
|
||||
|
@ -1052,16 +1054,27 @@ static uint32_t Vk_Upload8 (const byte *data, int width, int height, imagetype_t
|
|||
// to avoid alpha fringes
|
||||
// FIXME: do a full flood fill so mips work...
|
||||
if (i > width && data[i - width] != 255)
|
||||
{
|
||||
p = data[i - width];
|
||||
}
|
||||
else if (i < s - width && data[i + width] != 255)
|
||||
{
|
||||
p = data[i + width];
|
||||
}
|
||||
else if (i > 0 && data[i - 1] != 255)
|
||||
{
|
||||
p = data[i - 1];
|
||||
}
|
||||
else if (i < s - 1 && data[i + 1] != 255)
|
||||
{
|
||||
p = data[i + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
p = 0;
|
||||
// copy rgb components
|
||||
}
|
||||
|
||||
/* copy rgb components */
|
||||
((byte *)&trans[i])[0] = ((byte *)&d_8to24table[p])[0];
|
||||
((byte *)&trans[i])[1] = ((byte *)&d_8to24table[p])[1];
|
||||
((byte *)&trans[i])[2] = ((byte *)&d_8to24table[p])[2];
|
||||
|
@ -1075,11 +1088,14 @@ static uint32_t Vk_Upload8 (const byte *data, int width, int height, imagetype_t
|
|||
SmoothColorImage(trans, s, s >> 7);
|
||||
}
|
||||
|
||||
miplevel = Vk_Upload32Native((byte *)trans, width, height, type, texBuffer, upload_width, upload_height);
|
||||
miplevel = Vk_Upload32Native((byte *)trans, width, height, type, texBuffer,
|
||||
upload_width, upload_height);
|
||||
|
||||
// Only free if *texBuffer isn't the image data we sent
|
||||
if (!texBuffer || *texBuffer != (byte *)trans)
|
||||
{
|
||||
free(trans);
|
||||
}
|
||||
|
||||
return miplevel;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
qboolean Pickup_Weapon(edict_t *ent, edict_t *other);
|
||||
void Use_Weapon(edict_t *ent, gitem_t *inv);
|
||||
void Use_Weapon2(edict_t *ent, gitem_t *inv);
|
||||
void Drop_Weapon(edict_t *ent, gitem_t *inv);
|
||||
|
||||
void Weapon_Blaster(edict_t *ent);
|
||||
|
@ -56,6 +57,8 @@ static int power_screen_index;
|
|||
static int power_shield_index;
|
||||
|
||||
void Use_Quad(edict_t *ent, gitem_t *item);
|
||||
void Use_QuadFire(edict_t *ent, gitem_t *item);
|
||||
|
||||
static int quad_drop_timeout_hack;
|
||||
|
||||
/* ====================================================================== */
|
||||
|
@ -587,7 +590,7 @@ Use_Invulnerability(edict_t *ent, gitem_t *item)
|
|||
ent->client->invincible_framenum = level.framenum + 300;
|
||||
}
|
||||
|
||||
gi.sound(ent, CHAN_ITEM, gi.soundindex( "items/protect.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(ent, CHAN_ITEM, gi.soundindex("items/protect.wav"), 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
/* ====================================================================== */
|
||||
|
@ -2681,6 +2684,28 @@ SP_item_health_mega(edict_t *self)
|
|||
self->style = HEALTH_IGNORE_MAX | HEALTH_TIMED;
|
||||
}
|
||||
|
||||
void
|
||||
SP_item_foodcube(edict_t *self)
|
||||
{
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH))
|
||||
{
|
||||
G_FreeEdict(self);
|
||||
return;
|
||||
}
|
||||
|
||||
self->model = "models/objects/trapfx/tris.md2";
|
||||
SpawnItem(self, FindItem("Health"));
|
||||
self->spawnflags |= DROPPED_ITEM;
|
||||
self->style = HEALTH_IGNORE_MAX;
|
||||
gi.soundindex("items/s_health.wav");
|
||||
self->classname = "foodcube";
|
||||
}
|
||||
|
||||
void
|
||||
InitItems(void)
|
||||
{
|
||||
|
|
|
@ -349,11 +349,11 @@ trigger_key_use(edict_t *self, edict_t *other /* unused */,
|
|||
|
||||
self->touch_debounce_time = level.time + 5.0;
|
||||
gi.centerprintf(activator, "You need the %s", self->item->pickup_name);
|
||||
gi.sound(activator, CHAN_AUTO, gi.soundindex( "misc/keytry.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(activator, CHAN_AUTO, gi.soundindex("misc/keytry.wav"), 1, ATTN_NORM, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
gi.sound(activator, CHAN_AUTO, gi.soundindex( "misc/keyuse.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(activator, CHAN_AUTO, gi.soundindex("misc/keyuse.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
if (coop->value)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
@ -28,6 +29,11 @@
|
|||
|
||||
#define MAXCHOICES 8
|
||||
|
||||
static vec3_t VEC_UP = {0, -1, 0};
|
||||
static vec3_t MOVEDIR_UP = {0, 0, 1};
|
||||
static vec3_t VEC_DOWN = {0, -2, 0};
|
||||
static vec3_t MOVEDIR_DOWN = {0, 0, -1};
|
||||
|
||||
void
|
||||
G_ProjectSource(vec3_t point, vec3_t distance, vec3_t forward,
|
||||
vec3_t right, vec3_t result)
|
||||
|
@ -38,6 +44,18 @@ G_ProjectSource(vec3_t point, vec3_t distance, vec3_t forward,
|
|||
distance[2];
|
||||
}
|
||||
|
||||
void
|
||||
G_ProjectSource2(vec3_t point, vec3_t distance, vec3_t forward,
|
||||
vec3_t right, vec3_t up, vec3_t result)
|
||||
{
|
||||
result[0] = point[0] + forward[0] * distance[0] + right[0] * distance[1] +
|
||||
up[0] * distance[2];
|
||||
result[1] = point[1] + forward[1] * distance[0] + right[1] * distance[1] +
|
||||
up[1] * distance[2];
|
||||
result[2] = point[2] + forward[2] * distance[0] + right[2] * distance[1] +
|
||||
up[2] * distance[2];
|
||||
}
|
||||
|
||||
/*
|
||||
* Searches all active entities for the next
|
||||
* one that holds the matching string at fieldofs
|
||||
|
@ -52,6 +70,11 @@ G_Find(edict_t *from, int fieldofs, char *match)
|
|||
{
|
||||
char *s;
|
||||
|
||||
if (!match)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!from)
|
||||
{
|
||||
from = g_edicts;
|
||||
|
@ -61,11 +84,6 @@ G_Find(edict_t *from, int fieldofs, char *match)
|
|||
from++;
|
||||
}
|
||||
|
||||
if (!match)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for ( ; from < &g_edicts[globals.num_edicts]; from++)
|
||||
{
|
||||
if (!from->inuse)
|
||||
|
@ -137,6 +155,63 @@ findradius(edict_t *from, vec3_t org, float rad)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns entities that have origins within a spherical area
|
||||
*/
|
||||
edict_t *
|
||||
findradius2(edict_t *from, vec3_t org, float rad)
|
||||
{
|
||||
/* rad must be positive */
|
||||
vec3_t eorg;
|
||||
int j;
|
||||
|
||||
if (!from)
|
||||
{
|
||||
from = g_edicts;
|
||||
}
|
||||
else
|
||||
{
|
||||
from++;
|
||||
}
|
||||
|
||||
for ( ; from < &g_edicts[globals.num_edicts]; from++)
|
||||
{
|
||||
if (!from->inuse)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (from->solid == SOLID_NOT)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!from->takedamage)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(from->svflags & SVF_DAMAGEABLE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
eorg[j] = org[j] - (from->s.origin[j] + (from->mins[j] + from->maxs[j]) * 0.5);
|
||||
}
|
||||
|
||||
if (VectorLength(eorg) > rad)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return from;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Searches all active entities for
|
||||
* the next one that holds the matching
|
||||
|
@ -371,10 +446,18 @@ vtos(vec3_t v)
|
|||
return s;
|
||||
}
|
||||
|
||||
static vec3_t VEC_UP = {0, -1, 0};
|
||||
static vec3_t MOVEDIR_UP = {0, 0, 1};
|
||||
static vec3_t VEC_DOWN = {0, -2, 0};
|
||||
static vec3_t MOVEDIR_DOWN = {0, 0, -1};
|
||||
void
|
||||
get_normal_vector(const cplane_t *p, vec3_t normal)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
VectorCopy(p->normal, normal);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy(vec3_origin, normal);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
G_SetMovedir(vec3_t angles, vec3_t movedir)
|
||||
|
@ -426,6 +509,39 @@ vectoyaw(vec3_t vec)
|
|||
return yaw;
|
||||
}
|
||||
|
||||
float
|
||||
vectoyaw2(vec3_t vec)
|
||||
{
|
||||
float yaw;
|
||||
|
||||
if (vec[PITCH] == 0)
|
||||
{
|
||||
if (vec[YAW] == 0)
|
||||
{
|
||||
yaw = 0;
|
||||
}
|
||||
else if (vec[YAW] > 0)
|
||||
{
|
||||
yaw = 90;
|
||||
}
|
||||
else
|
||||
{
|
||||
yaw = 270;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
yaw = (atan2(vec[YAW], vec[PITCH]) * 180 / M_PI);
|
||||
|
||||
if (yaw < 0)
|
||||
{
|
||||
yaw += 360;
|
||||
}
|
||||
}
|
||||
|
||||
return yaw;
|
||||
}
|
||||
|
||||
void
|
||||
vectoangles(vec3_t value1, vec3_t angles)
|
||||
{
|
||||
|
@ -479,11 +595,69 @@ vectoangles(vec3_t value1, vec3_t angles)
|
|||
angles[ROLL] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
vectoangles2(vec3_t value1, vec3_t angles)
|
||||
{
|
||||
float forward;
|
||||
float yaw, pitch;
|
||||
|
||||
if ((value1[1] == 0) && (value1[0] == 0))
|
||||
{
|
||||
yaw = 0;
|
||||
|
||||
if (value1[2] > 0)
|
||||
{
|
||||
pitch = 90;
|
||||
}
|
||||
else
|
||||
{
|
||||
pitch = 270;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value1[0])
|
||||
{
|
||||
yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
|
||||
}
|
||||
else if (value1[1] > 0)
|
||||
{
|
||||
yaw = 90;
|
||||
}
|
||||
else
|
||||
{
|
||||
yaw = 270;
|
||||
}
|
||||
|
||||
if (yaw < 0)
|
||||
{
|
||||
yaw += 360;
|
||||
}
|
||||
|
||||
forward = sqrt(value1[0] * value1[0] + value1[1] * value1[1]);
|
||||
pitch = (atan2(value1[2], forward) * 180 / M_PI);
|
||||
|
||||
if (pitch < 0)
|
||||
{
|
||||
pitch += 360;
|
||||
}
|
||||
}
|
||||
|
||||
angles[PITCH] = -pitch;
|
||||
angles[YAW] = yaw;
|
||||
angles[ROLL] = 0;
|
||||
}
|
||||
|
||||
char *
|
||||
G_CopyString(char *in)
|
||||
{
|
||||
char *out;
|
||||
|
||||
if (!in)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out = gi.TagMalloc(strlen(in) + 1, TAG_LEVEL);
|
||||
strcpy(out, in);
|
||||
return out;
|
||||
|
@ -492,10 +666,24 @@ G_CopyString(char *in)
|
|||
void
|
||||
G_InitEdict(edict_t *e)
|
||||
{
|
||||
if (!e)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e->nextthink)
|
||||
{
|
||||
e->nextthink = 0;
|
||||
}
|
||||
|
||||
e->inuse = true;
|
||||
e->classname = "noclass";
|
||||
e->gravity = 1.0;
|
||||
e->s.number = e - g_edicts;
|
||||
|
||||
e->gravityVector[0] = 0.0;
|
||||
e->gravityVector[1] = 0.0;
|
||||
e->gravityVector[2] = -1.0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -568,6 +756,11 @@ G_Spawn(void)
|
|||
void
|
||||
G_FreeEdict(edict_t *ed)
|
||||
{
|
||||
if (!ed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gi.unlinkentity(ed); /* unlink from world */
|
||||
|
||||
if (deathmatch->value || coop->value)
|
||||
|
|
|
@ -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
|
||||
|
@ -26,6 +27,8 @@
|
|||
|
||||
#include "header/local.h"
|
||||
|
||||
extern void SP_item_foodcube(edict_t *best);
|
||||
|
||||
/*
|
||||
* This is a support routine used when a client is firing
|
||||
* a non-instant attack weapon. It checks to see if a
|
||||
|
@ -378,6 +381,7 @@ void
|
|||
blaster_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
int mod;
|
||||
vec3_t normal;
|
||||
|
||||
if (!self || !other) /* plane and surf can be NULL */
|
||||
{
|
||||
|
@ -401,6 +405,8 @@ blaster_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT);
|
||||
}
|
||||
|
||||
get_normal_vector(plane, normal);
|
||||
|
||||
if (other->takedamage)
|
||||
{
|
||||
if (self->spawnflags & 1)
|
||||
|
@ -412,32 +418,15 @@ blaster_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
mod = MOD_BLASTER;
|
||||
}
|
||||
|
||||
if (plane)
|
||||
{
|
||||
T_Damage(other, self, self->owner, self->velocity, self->s.origin,
|
||||
plane->normal, self->dmg, 1, DAMAGE_ENERGY, mod);
|
||||
}
|
||||
else
|
||||
{
|
||||
T_Damage(other, self, self->owner, self->velocity, self->s.origin,
|
||||
vec3_origin, self->dmg, 1, DAMAGE_ENERGY, mod);
|
||||
}
|
||||
normal, self->dmg, 1, DAMAGE_ENERGY, mod);
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.WriteByte(svc_temp_entity);
|
||||
gi.WriteByte(TE_BLASTER);
|
||||
gi.WritePosition(self->s.origin);
|
||||
|
||||
if (!plane)
|
||||
{
|
||||
gi.WriteDir(vec3_origin);
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.WriteDir(plane->normal);
|
||||
}
|
||||
|
||||
gi.WriteDir(normal);
|
||||
gi.multicast(self->s.origin, MULTICAST_PVS);
|
||||
}
|
||||
|
||||
|
@ -507,6 +496,56 @@ fire_blaster(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
fire_blueblaster(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int effect)
|
||||
{
|
||||
edict_t *bolt;
|
||||
trace_t tr;
|
||||
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VectorNormalize(dir);
|
||||
|
||||
bolt = G_Spawn();
|
||||
VectorCopy(start, bolt->s.origin);
|
||||
VectorCopy(start, bolt->s.old_origin);
|
||||
vectoangles(dir, bolt->s.angles);
|
||||
VectorScale(dir, speed, bolt->velocity);
|
||||
bolt->movetype = MOVETYPE_FLYMISSILE;
|
||||
bolt->clipmask = MASK_SHOT;
|
||||
bolt->solid = SOLID_BBOX;
|
||||
bolt->s.effects |= effect;
|
||||
VectorClear(bolt->mins);
|
||||
VectorClear(bolt->maxs);
|
||||
|
||||
bolt->s.modelindex = gi.modelindex("models/objects/blaser/tris.md2");
|
||||
bolt->s.sound = gi.soundindex("misc/lasfly.wav");
|
||||
bolt->owner = self;
|
||||
bolt->touch = blaster_touch;
|
||||
bolt->nextthink = level.time + 2;
|
||||
bolt->think = G_FreeEdict;
|
||||
bolt->dmg = damage;
|
||||
bolt->classname = "bolt";
|
||||
gi.linkentity(bolt);
|
||||
|
||||
if (self->client)
|
||||
{
|
||||
check_dodge(self, bolt->s.origin, dir, speed);
|
||||
}
|
||||
|
||||
tr = gi.trace(self->s.origin, NULL, NULL, bolt->s.origin, bolt, MASK_SHOT);
|
||||
|
||||
if (tr.fraction < 1.0)
|
||||
{
|
||||
VectorMA(bolt->s.origin, -10, dir, bolt->s.origin);
|
||||
bolt->touch(bolt, tr.ent, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Grenade_Explode(edict_t *ent)
|
||||
{
|
||||
|
@ -747,6 +786,7 @@ void
|
|||
rocket_touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
vec3_t origin;
|
||||
vec3_t normal;
|
||||
int n;
|
||||
|
||||
if (!ent || !other) /* plane and surf can be NULL */
|
||||
|
@ -776,16 +816,10 @@ rocket_touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
|
||||
if (other->takedamage)
|
||||
{
|
||||
if (plane)
|
||||
{
|
||||
get_normal_vector(plane, normal);
|
||||
|
||||
T_Damage(other, ent, ent->owner, ent->velocity, ent->s.origin,
|
||||
plane->normal, ent->dmg, 0, 0, MOD_ROCKET);
|
||||
}
|
||||
else
|
||||
{
|
||||
T_Damage(other, ent, ent->owner, ent->velocity, ent->s.origin,
|
||||
vec3_origin, ent->dmg, 0, 0, MOD_ROCKET);
|
||||
}
|
||||
normal, ent->dmg, 0, 0, MOD_ROCKET);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -851,7 +885,7 @@ fire_rocket(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
|||
rocket->s.modelindex = gi.modelindex("models/objects/rocket/tris.md2");
|
||||
rocket->owner = self;
|
||||
rocket->touch = rocket_touch;
|
||||
rocket->nextthink = level.time + 8000 / speed;
|
||||
rocket->nextthink = level.time + (8000.0f / (float)speed);
|
||||
rocket->think = G_FreeEdict;
|
||||
rocket->dmg = damage;
|
||||
rocket->radius_dmg = radius_damage;
|
||||
|
@ -899,7 +933,9 @@ fire_rail(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* -added so rail goes through SOLID_BBOX entities (gibs, etc) */
|
||||
if ((tr.ent->svflags & SVF_MONSTER) || (tr.ent->client) ||
|
||||
(tr.ent->svflags & SVF_DAMAGEABLE) ||
|
||||
(tr.ent->solid == SOLID_BBOX))
|
||||
{
|
||||
ignore = tr.ent;
|
||||
|
@ -1000,8 +1036,8 @@ bfg_explode(edict_t *self)
|
|||
gi.WriteByte(TE_BFG_EXPLOSION);
|
||||
gi.WritePosition(ent->s.origin);
|
||||
gi.multicast(ent->s.origin, MULTICAST_PHS);
|
||||
T_Damage(ent, self, self->owner, self->velocity, ent->s.origin, vec3_origin,
|
||||
(int)points, 0, DAMAGE_ENERGY, MOD_BFG_EFFECT);
|
||||
T_Damage(ent, self, self->owner, self->velocity, ent->s.origin,
|
||||
vec3_origin, (int)points, 0, DAMAGE_ENERGY, MOD_BFG_EFFECT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1017,6 +1053,8 @@ bfg_explode(edict_t *self)
|
|||
void
|
||||
bfg_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
vec3_t normal;
|
||||
|
||||
if (!self || !other) /* plane and surf can be NULL */
|
||||
{
|
||||
G_FreeEdict(self);
|
||||
|
@ -1042,9 +1080,10 @@ bfg_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|||
/* core explosion - prevents firing it into the wall/floor */
|
||||
if (other->takedamage)
|
||||
{
|
||||
get_normal_vector(plane, normal);
|
||||
|
||||
T_Damage(other, self, self->owner, self->velocity, self->s.origin,
|
||||
(plane) ? plane->normal : vec3_origin,
|
||||
200, 0, 0, MOD_BFG_BLAST);
|
||||
normal, 200, 0, 0, MOD_BFG_BLAST);
|
||||
}
|
||||
|
||||
T_RadiusDamage(self, self->owner, 200, other, 100, MOD_BFG_BLAST);
|
||||
|
@ -1125,8 +1164,8 @@ bfg_think(edict_t *self)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!(ent->svflags & SVF_MONSTER) && (!ent->client) &&
|
||||
(strcmp(ent->classname, "misc_explobox") != 0))
|
||||
if (!(ent->svflags & SVF_MONSTER) && !(ent->svflags & SVF_DAMAGEABLE) &&
|
||||
(!ent->client) && (strcmp(ent->classname, "misc_explobox") != 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -1159,7 +1198,8 @@ bfg_think(edict_t *self)
|
|||
}
|
||||
|
||||
/* if we hit something that's not a monster or player we're done */
|
||||
if (!(tr.ent->svflags & SVF_MONSTER) && (!tr.ent->client))
|
||||
if (!(tr.ent->svflags & SVF_MONSTER) &&
|
||||
!(tr.ent->svflags & SVF_DAMAGEABLE) && (!tr.ent->client))
|
||||
{
|
||||
gi.WriteByte(svc_temp_entity);
|
||||
gi.WriteByte(TE_LASER_SPARKS);
|
||||
|
@ -1210,7 +1250,7 @@ fire_bfg(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
|||
bfg->s.modelindex = gi.modelindex("sprites/s_bfg1.sp2");
|
||||
bfg->owner = self;
|
||||
bfg->touch = bfg_touch;
|
||||
bfg->nextthink = level.time + 8000 / speed;
|
||||
bfg->nextthink = level.time + (8000.0f / (float)speed);
|
||||
bfg->think = G_FreeEdict;
|
||||
bfg->radius_dmg = damage;
|
||||
bfg->dmg_radius = damage_radius;
|
||||
|
@ -1229,3 +1269,604 @@ fire_bfg(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
|||
|
||||
gi.linkentity(bfg);
|
||||
}
|
||||
|
||||
void
|
||||
ionripper_sparks(edict_t *self)
|
||||
{
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gi.WriteByte(svc_temp_entity);
|
||||
gi.WriteByte(TE_WELDING_SPARKS);
|
||||
gi.WriteByte(0);
|
||||
gi.WritePosition(self->s.origin);
|
||||
gi.WriteDir(vec3_origin);
|
||||
gi.WriteByte(0xe4 + (rand() & 3));
|
||||
gi.multicast(self->s.origin, MULTICAST_PVS);
|
||||
|
||||
G_FreeEdict(self);
|
||||
}
|
||||
|
||||
void
|
||||
ionripper_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
vec3_t normal;
|
||||
|
||||
if (!self || !other)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (other == self->owner)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (surf && (surf->flags & SURF_SKY))
|
||||
{
|
||||
G_FreeEdict(self);
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->owner->client)
|
||||
{
|
||||
PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT);
|
||||
}
|
||||
|
||||
if (other->takedamage)
|
||||
{
|
||||
get_normal_vector(plane, normal);
|
||||
|
||||
T_Damage(other, self, self->owner, self->velocity, self->s.origin,
|
||||
normal, self->dmg, 1, DAMAGE_ENERGY, MOD_RIPPER);
|
||||
|
||||
G_FreeEdict(self);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fire_ionripper(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int effect)
|
||||
{
|
||||
edict_t *ion;
|
||||
trace_t tr;
|
||||
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VectorNormalize(dir);
|
||||
|
||||
ion = G_Spawn();
|
||||
VectorCopy(start, ion->s.origin);
|
||||
VectorCopy(start, ion->s.old_origin);
|
||||
vectoangles(dir, ion->s.angles);
|
||||
VectorScale(dir, speed, ion->velocity);
|
||||
|
||||
ion->movetype = MOVETYPE_WALLBOUNCE;
|
||||
ion->clipmask = MASK_SHOT;
|
||||
ion->solid = SOLID_BBOX;
|
||||
ion->s.effects |= effect;
|
||||
|
||||
ion->s.renderfx |= RF_FULLBRIGHT;
|
||||
|
||||
VectorClear(ion->mins);
|
||||
VectorClear(ion->maxs);
|
||||
ion->s.modelindex = gi.modelindex("models/objects/boomrang/tris.md2");
|
||||
ion->s.sound = gi.soundindex("misc/lasfly.wav");
|
||||
ion->owner = self;
|
||||
ion->touch = ionripper_touch;
|
||||
ion->nextthink = level.time + 3;
|
||||
ion->think = ionripper_sparks;
|
||||
ion->dmg = damage;
|
||||
ion->dmg_radius = 100;
|
||||
gi.linkentity(ion);
|
||||
|
||||
if (self->client)
|
||||
{
|
||||
check_dodge(self, ion->s.origin, dir, speed);
|
||||
}
|
||||
|
||||
tr = gi.trace(self->s.origin, NULL, NULL, ion->s.origin, ion, MASK_SHOT);
|
||||
|
||||
if (tr.fraction < 1.0)
|
||||
{
|
||||
VectorMA(ion->s.origin, -10, dir, ion->s.origin);
|
||||
ion->touch(ion, tr.ent, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
heat_think(edict_t *self)
|
||||
{
|
||||
edict_t *target = NULL;
|
||||
edict_t *aquire = NULL;
|
||||
vec3_t vec;
|
||||
float len;
|
||||
float oldlen = 0;
|
||||
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* aquire new target */
|
||||
while ((target = findradius(target, self->s.origin, 1024)) != NULL)
|
||||
{
|
||||
if (self->owner == target)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!target->client)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (target->health <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!infront(self, target))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!visible(self, target))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
VectorSubtract(self->s.origin, target->s.origin, vec);
|
||||
len = VectorLength(vec);
|
||||
|
||||
if ((!aquire) || (len < oldlen))
|
||||
{
|
||||
aquire = target;
|
||||
oldlen = len;
|
||||
}
|
||||
}
|
||||
|
||||
if (aquire)
|
||||
{
|
||||
VectorSubtract(aquire->s.origin, self->s.origin, vec);
|
||||
vectoangles(vec, self->s.angles);
|
||||
VectorNormalize(vec);
|
||||
VectorScale(vec, 500, self->velocity);
|
||||
}
|
||||
|
||||
self->nextthink = level.time + 0.1;
|
||||
}
|
||||
|
||||
void
|
||||
fire_heat(edict_t *self, vec3_t start, vec3_t dir, int damage, int speed,
|
||||
float damage_radius, int radius_damage)
|
||||
{
|
||||
edict_t *heat;
|
||||
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
heat = G_Spawn();
|
||||
VectorCopy(start, heat->s.origin);
|
||||
VectorCopy(dir, heat->movedir);
|
||||
vectoangles(dir, heat->s.angles);
|
||||
VectorScale(dir, speed, heat->velocity);
|
||||
heat->movetype = MOVETYPE_FLYMISSILE;
|
||||
heat->clipmask = MASK_SHOT;
|
||||
heat->solid = SOLID_BBOX;
|
||||
heat->s.effects |= EF_ROCKET;
|
||||
VectorClear(heat->mins);
|
||||
VectorClear(heat->maxs);
|
||||
heat->s.modelindex = gi.modelindex("models/objects/rocket/tris.md2");
|
||||
heat->owner = self;
|
||||
heat->touch = rocket_touch;
|
||||
|
||||
heat->nextthink = level.time + 0.1;
|
||||
heat->think = heat_think;
|
||||
|
||||
heat->dmg = damage;
|
||||
heat->radius_dmg = radius_damage;
|
||||
heat->dmg_radius = damage_radius;
|
||||
heat->s.sound = gi.soundindex("weapons/rockfly.wav");
|
||||
|
||||
if (self->client)
|
||||
{
|
||||
check_dodge(self, heat->s.origin, dir, speed);
|
||||
}
|
||||
|
||||
gi.linkentity(heat);
|
||||
}
|
||||
|
||||
void
|
||||
plasma_touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
vec3_t origin;
|
||||
vec3_t normal;
|
||||
|
||||
if (!ent || !other)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (other == ent->owner)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (surf && (surf->flags & SURF_SKY))
|
||||
{
|
||||
G_FreeEdict(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent->owner->client)
|
||||
{
|
||||
PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT);
|
||||
}
|
||||
|
||||
/* calculate position for the explosion entity */
|
||||
VectorMA(ent->s.origin, -0.02, ent->velocity, origin);
|
||||
|
||||
if (other->takedamage)
|
||||
{
|
||||
get_normal_vector(plane, normal);
|
||||
|
||||
T_Damage(other, ent, ent->owner, ent->velocity, ent->s.origin,
|
||||
normal, ent->dmg, 0, 0, MOD_PHALANX);
|
||||
}
|
||||
|
||||
T_RadiusDamage(ent, ent->owner, ent->radius_dmg, other,
|
||||
ent->dmg_radius, MOD_PHALANX);
|
||||
|
||||
gi.WriteByte(svc_temp_entity);
|
||||
gi.WriteByte(TE_PLASMA_EXPLOSION);
|
||||
gi.WritePosition(origin);
|
||||
gi.multicast(ent->s.origin, MULTICAST_PVS);
|
||||
|
||||
G_FreeEdict(ent);
|
||||
}
|
||||
|
||||
void
|
||||
fire_plasma(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, float damage_radius, int radius_damage)
|
||||
{
|
||||
edict_t *plasma;
|
||||
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
plasma = G_Spawn();
|
||||
VectorCopy(start, plasma->s.origin);
|
||||
VectorCopy(dir, plasma->movedir);
|
||||
vectoangles(dir, plasma->s.angles);
|
||||
VectorScale(dir, speed, plasma->velocity);
|
||||
plasma->movetype = MOVETYPE_FLYMISSILE;
|
||||
plasma->clipmask = MASK_SHOT;
|
||||
plasma->solid = SOLID_BBOX;
|
||||
|
||||
VectorClear(plasma->mins);
|
||||
VectorClear(plasma->maxs);
|
||||
|
||||
plasma->owner = self;
|
||||
plasma->touch = plasma_touch;
|
||||
plasma->nextthink = level.time + (8000.0f / (float)speed);
|
||||
plasma->think = G_FreeEdict;
|
||||
plasma->dmg = damage;
|
||||
plasma->radius_dmg = radius_damage;
|
||||
plasma->dmg_radius = damage_radius;
|
||||
plasma->s.sound = gi.soundindex("weapons/rockfly.wav");
|
||||
|
||||
plasma->s.modelindex = gi.modelindex("sprites/s_photon.sp2");
|
||||
plasma->s.effects |= EF_PLASMA | EF_ANIM_ALLFAST;
|
||||
|
||||
if (self->client)
|
||||
{
|
||||
check_dodge(self, plasma->s.origin, dir, speed);
|
||||
}
|
||||
|
||||
gi.linkentity(plasma);
|
||||
}
|
||||
|
||||
void
|
||||
Trap_Think(edict_t *ent)
|
||||
{
|
||||
edict_t *target = NULL;
|
||||
edict_t *best = NULL;
|
||||
vec3_t vec;
|
||||
int len, i;
|
||||
int oldlen = 8000;
|
||||
vec3_t forward, right, up;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent->timestamp < level.time)
|
||||
{
|
||||
BecomeExplosion1(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
ent->nextthink = level.time + 0.1;
|
||||
|
||||
if (!ent->groundentity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* ok lets do the blood effect */
|
||||
if (ent->s.frame > 4)
|
||||
{
|
||||
if (ent->s.frame == 5)
|
||||
{
|
||||
if (ent->wait == 64)
|
||||
{
|
||||
gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/trapdown.wav"),
|
||||
1, ATTN_IDLE, 0);
|
||||
}
|
||||
|
||||
ent->wait -= 2;
|
||||
ent->delay += level.time;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
best = G_Spawn();
|
||||
|
||||
if (strcmp(ent->enemy->classname, "monster_gekk") == 0)
|
||||
{
|
||||
best->s.modelindex = gi.modelindex("models/objects/gekkgib/torso/tris.md2");
|
||||
best->s.effects |= TE_GREENBLOOD;
|
||||
}
|
||||
else if (ent->mass > 200)
|
||||
{
|
||||
best->s.modelindex = gi.modelindex("models/objects/gibs/chest/tris.md2");
|
||||
best->s.effects |= TE_BLOOD;
|
||||
}
|
||||
else
|
||||
{
|
||||
best->s.modelindex = gi.modelindex("models/objects/gibs/sm_meat/tris.md2");
|
||||
best->s.effects |= TE_BLOOD;
|
||||
}
|
||||
|
||||
AngleVectors(ent->s.angles, forward, right, up);
|
||||
|
||||
RotatePointAroundVector(vec, up, right, ((360.0 / 3) * i) + ent->delay);
|
||||
VectorMA(vec, ent->wait / 2, vec, vec);
|
||||
VectorAdd(vec, ent->s.origin, vec);
|
||||
VectorAdd(vec, forward, best->s.origin);
|
||||
|
||||
best->s.origin[2] = ent->s.origin[2] + ent->wait;
|
||||
|
||||
VectorCopy(ent->s.angles, best->s.angles);
|
||||
|
||||
best->solid = SOLID_NOT;
|
||||
best->s.effects |= EF_GIB;
|
||||
best->takedamage = DAMAGE_YES;
|
||||
|
||||
best->movetype = MOVETYPE_TOSS;
|
||||
best->svflags |= SVF_MONSTER;
|
||||
best->deadflag = DEAD_DEAD;
|
||||
|
||||
VectorClear(best->mins);
|
||||
VectorClear(best->maxs);
|
||||
|
||||
best->watertype = gi.pointcontents(best->s.origin);
|
||||
|
||||
if (best->watertype & MASK_WATER)
|
||||
{
|
||||
best->waterlevel = 1;
|
||||
}
|
||||
|
||||
best->nextthink = level.time + 0.1;
|
||||
best->think = G_FreeEdict;
|
||||
gi.linkentity(best);
|
||||
}
|
||||
|
||||
if (ent->wait < 19)
|
||||
{
|
||||
ent->s.frame++;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ent->s.frame++;
|
||||
|
||||
if (ent->s.frame == 8)
|
||||
{
|
||||
ent->nextthink = level.time + 1.0;
|
||||
ent->think = G_FreeEdict;
|
||||
|
||||
best = G_Spawn();
|
||||
SP_item_foodcube(best);
|
||||
VectorCopy(ent->s.origin, best->s.origin);
|
||||
best->s.origin[2] += 16;
|
||||
best->velocity[2] = 400;
|
||||
best->count = ent->mass;
|
||||
gi.linkentity(best);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ent->s.effects &= ~EF_TRAP;
|
||||
|
||||
if (ent->s.frame >= 4)
|
||||
{
|
||||
ent->s.effects |= EF_TRAP;
|
||||
VectorClear(ent->mins);
|
||||
VectorClear(ent->maxs);
|
||||
}
|
||||
|
||||
if (ent->s.frame < 4)
|
||||
{
|
||||
ent->s.frame++;
|
||||
}
|
||||
|
||||
while ((target = findradius(target, ent->s.origin, 256)) != NULL)
|
||||
{
|
||||
if (target == ent)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(target->svflags & SVF_MONSTER) && !target->client)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (target->health <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!visible(ent, target))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!best)
|
||||
{
|
||||
best = target;
|
||||
continue;
|
||||
}
|
||||
|
||||
VectorSubtract(ent->s.origin, target->s.origin, vec);
|
||||
len = VectorLength(vec);
|
||||
|
||||
if (len < oldlen)
|
||||
{
|
||||
oldlen = len;
|
||||
best = target;
|
||||
}
|
||||
}
|
||||
|
||||
/* pull the enemy in */
|
||||
if (best)
|
||||
{
|
||||
vec3_t forward;
|
||||
|
||||
if (best->groundentity)
|
||||
{
|
||||
best->s.origin[2] += 1;
|
||||
best->groundentity = NULL;
|
||||
}
|
||||
|
||||
VectorSubtract(ent->s.origin, best->s.origin, vec);
|
||||
len = VectorLength(vec);
|
||||
|
||||
if (best->client)
|
||||
{
|
||||
VectorNormalize(vec);
|
||||
VectorMA(best->velocity, 250, vec, best->velocity);
|
||||
}
|
||||
else
|
||||
{
|
||||
best->ideal_yaw = vectoyaw(vec);
|
||||
M_ChangeYaw(best);
|
||||
AngleVectors(best->s.angles, forward, NULL, NULL);
|
||||
VectorScale(forward, 256, best->velocity);
|
||||
}
|
||||
|
||||
gi.sound(ent, CHAN_VOICE, gi.soundindex(
|
||||
"weapons/trapsuck.wav"), 1, ATTN_IDLE, 0);
|
||||
|
||||
if (len < 32)
|
||||
{
|
||||
if (best->mass < 400)
|
||||
{
|
||||
T_Damage(best, ent, ent->owner, vec3_origin, best->s.origin,
|
||||
vec3_origin, 100000, 1, 0, MOD_TRAP);
|
||||
ent->enemy = best;
|
||||
ent->wait = 64;
|
||||
VectorCopy(ent->s.origin, ent->s.old_origin);
|
||||
ent->timestamp = level.time + 30;
|
||||
|
||||
if (deathmatch->value)
|
||||
{
|
||||
ent->mass = best->mass / 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->mass = best->mass / 10;
|
||||
}
|
||||
|
||||
/* ok spawn the food cube */
|
||||
ent->s.frame = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
BecomeExplosion1(ent);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fire_trap(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, float timer, float damage_radius, qboolean held)
|
||||
{
|
||||
edict_t *trap;
|
||||
vec3_t dir;
|
||||
vec3_t forward, right, up;
|
||||
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vectoangles(aimdir, dir);
|
||||
AngleVectors(dir, forward, right, up);
|
||||
|
||||
trap = G_Spawn();
|
||||
VectorCopy(start, trap->s.origin);
|
||||
VectorScale(aimdir, speed, trap->velocity);
|
||||
VectorMA(trap->velocity, 200 + crandom() * 10.0, up, trap->velocity);
|
||||
VectorMA(trap->velocity, crandom() * 10.0, right, trap->velocity);
|
||||
VectorSet(trap->avelocity, 0, 300, 0);
|
||||
trap->movetype = MOVETYPE_BOUNCE;
|
||||
trap->clipmask = MASK_SHOT;
|
||||
trap->solid = SOLID_BBOX;
|
||||
VectorSet(trap->mins, -4, -4, 0);
|
||||
VectorSet(trap->maxs, 4, 4, 8);
|
||||
trap->s.modelindex = gi.modelindex("models/weapons/z_trap/tris.md2");
|
||||
trap->owner = self;
|
||||
trap->nextthink = level.time + 1.0;
|
||||
trap->think = Trap_Think;
|
||||
trap->dmg = damage;
|
||||
trap->dmg_radius = damage_radius;
|
||||
trap->classname = "htrap";
|
||||
trap->s.sound = gi.soundindex("weapons/traploop.wav");
|
||||
|
||||
if (held)
|
||||
{
|
||||
trap->spawnflags = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
trap->spawnflags = 1;
|
||||
}
|
||||
|
||||
if (timer <= 0.0)
|
||||
{
|
||||
Grenade_Explode(trap);
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.linkentity(trap);
|
||||
}
|
||||
|
||||
trap->timestamp = level.time + 30;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -39,6 +40,7 @@
|
|||
#define SVF_NOCLIENT 0x00000001 /* don't send entity to clients, even if it has effects */
|
||||
#define SVF_DEADMONSTER 0x00000002 /* treat as CONTENTS_DEADMONSTER for collision */
|
||||
#define SVF_MONSTER 0x00000004 /* treat as CONTENTS_MONSTER for collision */
|
||||
#define SVF_DAMAGEABLE 0x00000008
|
||||
|
||||
#define MAX_ENT_CLUSTERS 16
|
||||
|
||||
|
@ -86,6 +88,8 @@ struct edict_s
|
|||
int headnode; /* unused if num_clusters != -1 */
|
||||
int areanum, areanum2;
|
||||
|
||||
/* ================================ */
|
||||
|
||||
int svflags; /* SVF_NOCLIENT, SVF_DEADMONSTER, SVF_MONSTER, etc */
|
||||
vec3_t mins, maxs;
|
||||
vec3_t absmin, absmax, size;
|
||||
|
|
|
@ -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
|
||||
|
@ -59,6 +60,7 @@
|
|||
#define SPAWNFLAG_NOT_DEATHMATCH 0x00000800
|
||||
#define SPAWNFLAG_NOT_COOP 0x00001000
|
||||
|
||||
/* edict->flags */
|
||||
#define FL_FLY 0x00000001
|
||||
#define FL_SWIM 0x00000002 /* implied immunity to drowining */
|
||||
#define FL_IMMUNE_LASER 0x00000004
|
||||
|
@ -75,6 +77,11 @@
|
|||
#define FL_COOP_TAKEN 0x00002000 /* Another client has already taken it */
|
||||
#define FL_RESPAWN 0x80000000 /* used for item respawning */
|
||||
|
||||
#define FL_MECHANICAL 0x00002000 /* entity is mechanical, use sparks not blood */
|
||||
#define FL_SAM_RAIMI 0x00004000 /* entity is in sam raimi cam mode */
|
||||
#define FL_DISGUISED 0x00008000 /* entity is in disguise, monsters will not recognize. */
|
||||
#define FL_NOGIB 0x00010000 /* player has been vaporized by a nuke, drop no gibs */
|
||||
|
||||
#define FRAMETIME 0.1
|
||||
|
||||
/* memory tags to allow dynamic memory to be cleaned up */
|
||||
|
@ -106,7 +113,12 @@ typedef enum
|
|||
AMMO_ROCKETS,
|
||||
AMMO_GRENADES,
|
||||
AMMO_CELLS,
|
||||
AMMO_SLUGS
|
||||
AMMO_SLUGS,
|
||||
|
||||
AMMO_FLECHETTES,
|
||||
AMMO_TESLA,
|
||||
AMMO_PROX,
|
||||
AMMO_DISRUPTOR
|
||||
} ammo_t;
|
||||
|
||||
/* Maximum debris / gibs per frame */
|
||||
|
@ -145,12 +157,29 @@ typedef enum
|
|||
#define AI_COMBAT_POINT 0x00001000
|
||||
#define AI_MEDIC 0x00002000
|
||||
#define AI_RESURRECTING 0x00004000
|
||||
#define AI_IGNORE_PAIN 0x00008000
|
||||
|
||||
/* ROGUE */
|
||||
#define AI_WALK_WALLS 0x00008000
|
||||
#define AI_MANUAL_STEERING 0x00010000
|
||||
#define AI_TARGET_ANGER 0x00020000
|
||||
#define AI_DODGING 0x00040000
|
||||
#define AI_CHARGING 0x00080000
|
||||
#define AI_HINT_PATH 0x00100000
|
||||
#define AI_IGNORE_SHOTS 0x00200000
|
||||
#define AI_DO_NOT_COUNT 0x00400000 /* set for healed monsters */
|
||||
#define AI_SPAWNED_CARRIER 0x00800000 /* both do_not_count and spawned are set for spawned monsters */
|
||||
#define AI_SPAWNED_MEDIC_C 0x01000000 /* both do_not_count and spawned are set for spawned monsters */
|
||||
#define AI_SPAWNED_WIDOW 0x02000000 /* both do_not_count and spawned are set for spawned monsters */
|
||||
#define AI_SPAWNED_MASK 0x03800000 /* mask to catch all three flavors of spawned */
|
||||
#define AI_BLOCKED 0x04000000 /* used by blocked_checkattack: set to say I'm attacking while blocked */
|
||||
/* (prevents run-attacks) */
|
||||
/* monster attack state */
|
||||
#define AS_STRAIGHT 1
|
||||
#define AS_SLIDING 2
|
||||
#define AS_MELEE 3
|
||||
#define AS_MISSILE 4
|
||||
#define AS_BLIND 5
|
||||
|
||||
/* armor types */
|
||||
#define ARMOR_NONE 0
|
||||
|
@ -198,7 +227,9 @@ typedef enum
|
|||
MOVETYPE_FLY,
|
||||
MOVETYPE_TOSS, /* gravity */
|
||||
MOVETYPE_FLYMISSILE, /* extra size to monsters */
|
||||
MOVETYPE_BOUNCE
|
||||
MOVETYPE_BOUNCE, /* added this (the comma at the end of line) */
|
||||
MOVETYPE_WALLBOUNCE,
|
||||
MOVETYPE_NEWTOSS /* for deathball */
|
||||
} movetype_t;
|
||||
|
||||
typedef struct
|
||||
|
@ -210,13 +241,16 @@ typedef struct
|
|||
int armor;
|
||||
} gitem_armor_t;
|
||||
|
||||
#define IT_WEAPON 1 /* use makes active weapon */
|
||||
#define IT_AMMO 2
|
||||
#define IT_ARMOR 4
|
||||
#define IT_STAY_COOP 8
|
||||
#define IT_KEY 16
|
||||
#define IT_POWERUP 32
|
||||
#define IT_INSTANT_USE 64 /* item is insta-used on pickup if dmflag is set */
|
||||
/* gitem_t->flags */
|
||||
#define IT_WEAPON 0x00000001 /* use makes active weapon */
|
||||
#define IT_AMMO 0x00000002
|
||||
#define IT_ARMOR 0x00000004
|
||||
#define IT_STAY_COOP 0x00000008
|
||||
#define IT_KEY 0x00000010
|
||||
#define IT_POWERUP 0x00000020
|
||||
#define IT_MELEE 0x00000040
|
||||
#define IT_NOT_GIVEABLE 0x00000080 /* item can not be given */
|
||||
#define IT_INSTANT_USE 0x000000100 /* item is insta-used on pickup if dmflag is set */
|
||||
|
||||
/* gitem_t->weapmodel for weapons indicates model index */
|
||||
#define WEAP_BLASTER 1
|
||||
|
@ -230,6 +264,13 @@ typedef struct
|
|||
#define WEAP_HYPERBLASTER 9
|
||||
#define WEAP_RAILGUN 10
|
||||
#define WEAP_BFG 11
|
||||
#define WEAP_PHALANX 12
|
||||
#define WEAP_BOOMER 13
|
||||
#define WEAP_DISRUPTOR 14
|
||||
#define WEAP_ETFRIFLE 15
|
||||
#define WEAP_PLASMA 16
|
||||
#define WEAP_PROXLAUNCH 17
|
||||
#define WEAP_CHAINFIST 18
|
||||
|
||||
typedef struct gitem_s
|
||||
{
|
||||
|
@ -267,8 +308,8 @@ typedef struct
|
|||
{
|
||||
char helpmessage1[512];
|
||||
char helpmessage2[512];
|
||||
int helpchanged; /* flash F1 icon if non 0, play sound
|
||||
and increment only if 1, 2, or 3 */
|
||||
int helpchanged; /* flash F1 icon if non 0, play sound */
|
||||
/* and increment only if 1, 2, or 3 */
|
||||
|
||||
gclient_t *clients; /* [maxclients] */
|
||||
|
||||
|
@ -332,10 +373,13 @@ typedef struct
|
|||
int body_que; /* dead bodies */
|
||||
|
||||
int power_cubes; /* ugly necessity for coop */
|
||||
|
||||
edict_t *disguise_violator;
|
||||
int disguise_violation_framenum;
|
||||
} level_locals_t;
|
||||
|
||||
/* spawn_temp_t is only used to hold entity field values that
|
||||
can be set from the editor, but aren't actualy present
|
||||
can be set from the editor, but aren't actualy present/
|
||||
in edict_t during gameplay */
|
||||
typedef struct
|
||||
{
|
||||
|
@ -408,7 +452,7 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
mmove_t *currentmove;
|
||||
int aiflags;
|
||||
unsigned int aiflags; /* unsigned, since we're close to the max */
|
||||
int nextframe;
|
||||
float scale;
|
||||
|
||||
|
@ -437,8 +481,40 @@ typedef struct
|
|||
|
||||
int power_armor_type;
|
||||
int power_armor_power;
|
||||
|
||||
qboolean (*blocked)(edict_t *self, float dist);
|
||||
float last_hint_time; /* last time the monster checked for hintpaths. */
|
||||
edict_t *goal_hint; /* which hint_path we're trying to get to */
|
||||
int medicTries;
|
||||
edict_t *badMedic1, *badMedic2; /* these medics have declared this monster "unhealable" */
|
||||
edict_t *healer; /* this is who is healing this monster */
|
||||
void (*duck)(edict_t *self, float eta);
|
||||
void (*unduck)(edict_t *self);
|
||||
void (*sidestep)(edict_t *self);
|
||||
float base_height;
|
||||
float next_duck_time;
|
||||
float duck_wait_time;
|
||||
edict_t *last_player_enemy;
|
||||
qboolean blindfire; /* will the monster blindfire? */
|
||||
float blind_fire_delay;
|
||||
vec3_t blind_fire_target;
|
||||
|
||||
/* used by the spawners to not spawn too much and keep track of #s of monsters spawned */
|
||||
int monster_slots;
|
||||
int monster_used;
|
||||
edict_t *commander;
|
||||
|
||||
/* powerup timers, used by widow, our friend */
|
||||
float quad_framenum;
|
||||
float invincible_framenum;
|
||||
float double_framenum;
|
||||
} monsterinfo_t;
|
||||
|
||||
/* this determines how long to wait after a duck to duck again.
|
||||
this needs to be longer than the time after the monster_duck_up
|
||||
in all of the animation sequences */
|
||||
#define DUCK_INTERVAL 0.5
|
||||
|
||||
extern game_locals_t game;
|
||||
extern level_locals_t level;
|
||||
extern game_import_t gi;
|
||||
|
@ -486,7 +562,29 @@ extern int gibsthisframe;
|
|||
#define MOD_TRIGGER_HURT 31
|
||||
#define MOD_HIT 32
|
||||
#define MOD_TARGET_BLASTER 33
|
||||
#define MOD_RIPPER 34
|
||||
#define MOD_PHALANX 35
|
||||
#define MOD_BRAINTENTACLE 36
|
||||
#define MOD_BLASTOFF 37
|
||||
#define MOD_GEKK 38
|
||||
#define MOD_TRAP 39
|
||||
#define MOD_FRIENDLY_FIRE 0x8000000
|
||||
#define MOD_CHAINFIST 40
|
||||
#define MOD_DISINTEGRATOR 41
|
||||
#define MOD_ETF_RIFLE 42
|
||||
#define MOD_BLASTER2 43
|
||||
#define MOD_HEATBEAM 44
|
||||
#define MOD_TESLA 45
|
||||
#define MOD_PROX 46
|
||||
#define MOD_NUKE 47
|
||||
#define MOD_VENGEANCE_SPHERE 48
|
||||
#define MOD_HUNTER_SPHERE 49
|
||||
#define MOD_DEFENDER_SPHERE 50
|
||||
#define MOD_TRACKER 51
|
||||
#define MOD_DBALL_CRUSH 52
|
||||
#define MOD_DOPPLE_EXPLODE 53
|
||||
#define MOD_DOPPLE_VENGEANCE 54
|
||||
#define MOD_DOPPLE_HUNTER 55
|
||||
|
||||
/* Easier handling of AI skill levels */
|
||||
#define SKILL_EASY 0
|
||||
|
@ -495,7 +593,6 @@ extern int gibsthisframe;
|
|||
#define SKILL_HARDPLUS 3
|
||||
|
||||
extern int meansOfDeath;
|
||||
|
||||
extern edict_t *g_edicts;
|
||||
|
||||
#define FOFS(x) (size_t)&(((edict_t *)NULL)->x)
|
||||
|
@ -509,8 +606,10 @@ extern edict_t *g_edicts;
|
|||
extern cvar_t *maxentities;
|
||||
extern cvar_t *deathmatch;
|
||||
extern cvar_t *coop;
|
||||
extern cvar_t *coop_baseq2; /* treat spawnflags according to baseq2 rules */
|
||||
extern cvar_t *coop_pickup_weapons;
|
||||
extern cvar_t *coop_elevator_delay;
|
||||
extern cvar_t *coop_pickup_weapons;
|
||||
extern cvar_t *dmflags;
|
||||
extern cvar_t *skill;
|
||||
extern cvar_t *fraglimit;
|
||||
|
@ -550,10 +649,28 @@ extern cvar_t *flood_waitdelay;
|
|||
|
||||
extern cvar_t *sv_maplist;
|
||||
|
||||
extern cvar_t *sv_stopspeed;
|
||||
|
||||
extern cvar_t *g_showlogic;
|
||||
extern cvar_t *gamerules;
|
||||
extern cvar_t *huntercam;
|
||||
extern cvar_t *strong_mines;
|
||||
extern cvar_t *randomrespawn;
|
||||
|
||||
extern cvar_t *g_disruptor;
|
||||
|
||||
extern cvar_t *aimfix;
|
||||
extern cvar_t *g_machinegun_norecoil;
|
||||
extern cvar_t *g_swap_speed;
|
||||
|
||||
/* this is for the count of monsters */
|
||||
#define ENT_SLOTS_LEFT \
|
||||
(ent->monsterinfo.monster_slots - \
|
||||
ent->monsterinfo.monster_used)
|
||||
#define SELF_SLOTS_LEFT \
|
||||
(self->monsterinfo.monster_slots - \
|
||||
self->monsterinfo.monster_used)
|
||||
|
||||
#define world (&g_edicts[0])
|
||||
|
||||
/* item spawnflags */
|
||||
|
@ -627,7 +744,8 @@ int ArmorIndex(edict_t *ent);
|
|||
int PowerArmorType(edict_t *ent);
|
||||
gitem_t *GetItemByIndex(int index);
|
||||
qboolean Add_Ammo(edict_t *ent, gitem_t *item, int count);
|
||||
void Touch_Item(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf);
|
||||
void Touch_Item(edict_t *ent, edict_t *other, cplane_t *plane,
|
||||
csurface_t *surf);
|
||||
|
||||
/* g_utils.c */
|
||||
qboolean KillBox(edict_t *ent);
|
||||
|
@ -651,10 +769,17 @@ char *G_CopyString(char *in);
|
|||
|
||||
float *tv(float x, float y, float z);
|
||||
char *vtos(vec3_t v);
|
||||
void get_normal_vector(const cplane_t *p, vec3_t normal);
|
||||
|
||||
float vectoyaw(vec3_t vec);
|
||||
void vectoangles(vec3_t vec, vec3_t angles);
|
||||
|
||||
void G_ProjectSource2(vec3_t point, vec3_t distance, vec3_t forward, vec3_t right,
|
||||
vec3_t up, vec3_t result);
|
||||
float vectoyaw2(vec3_t vec);
|
||||
void vectoangles2(vec3_t vec, vec3_t angles);
|
||||
edict_t *findradius2(edict_t *from, vec3_t org, float rad);
|
||||
|
||||
/* g_spawn.c */
|
||||
void ED_CallSpawn(edict_t *ent);
|
||||
|
||||
|
@ -667,6 +792,11 @@ void T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker,
|
|||
void T_RadiusDamage(edict_t *inflictor, edict_t *attacker,
|
||||
float damage, edict_t *ignore, float radius,
|
||||
int mod);
|
||||
void T_RadiusNukeDamage(edict_t *inflictor, edict_t *attacker, float damage,
|
||||
edict_t *ignore, float radius, int mod);
|
||||
void T_RadiusClassDamage(edict_t *inflictor, edict_t *attacker, float damage,
|
||||
char *ignoreClass, float radius, int mod);
|
||||
void cleanupHealTarget(edict_t *ent);
|
||||
|
||||
/* damage flags */
|
||||
#define DAMAGE_RADIUS 0x00000001 /* damage was indirect */
|
||||
|
@ -675,6 +805,9 @@ void T_RadiusDamage(edict_t *inflictor, edict_t *attacker,
|
|||
#define DAMAGE_NO_KNOCKBACK 0x00000008 /* do not affect velocity, just view angles */
|
||||
#define DAMAGE_BULLET 0x00000010 /* damage is from a bullet (used for ricochets) */
|
||||
#define DAMAGE_NO_PROTECTION 0x00000020 /* armor, shields, invulnerability, and godmode have no effect */
|
||||
#define DAMAGE_DESTROY_ARMOR 0x00000040 /* damage is done to armor and health. */
|
||||
#define DAMAGE_NO_REG_ARMOR 0x00000080 /* damage skips regular armor */
|
||||
#define DAMAGE_NO_POWER_ARMOR 0x00000100 /* damage skips power armor */
|
||||
|
||||
#define DEFAULT_BULLET_HSPREAD 300
|
||||
#define DEFAULT_BULLET_VSPREAD 500
|
||||
|
@ -701,6 +834,12 @@ void monster_fire_railgun(edict_t *self, vec3_t start, vec3_t aimdir,
|
|||
void monster_fire_bfg(edict_t *self, vec3_t start, vec3_t aimdir,
|
||||
int damage, int speed, int kick, float damage_radius,
|
||||
int flashtype);
|
||||
void monster_fire_ionripper(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int flashtype, int effect);
|
||||
void monster_dabeam(edict_t *self);
|
||||
void monster_fire_blueblaster(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int flashtype, int effect);
|
||||
|
||||
void M_droptofloor(edict_t *ent);
|
||||
void monster_think(edict_t *self);
|
||||
void walkmonster_start(edict_t *self);
|
||||
|
@ -713,11 +852,20 @@ qboolean M_CheckAttack(edict_t *self);
|
|||
void M_FlyCheck(edict_t *self);
|
||||
void M_CheckGround(edict_t *ent);
|
||||
|
||||
void monster_fire_blaster2(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int flashtype, int effect);
|
||||
void monster_fire_tracker(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, edict_t *enemy, int flashtype);
|
||||
void stationarymonster_start(edict_t *self);
|
||||
void monster_done_dodge(edict_t *self);
|
||||
|
||||
/* g_misc.c */
|
||||
void ThrowHead(edict_t *self, char *gibname, int damage, int type);
|
||||
void ThrowClientHead(edict_t *self, int damage);
|
||||
void ThrowGib(edict_t *self, char *gibname, int damage, int type);
|
||||
void BecomeExplosion1(edict_t *self);
|
||||
void ThrowHeadACID(edict_t *self, char *gibname, int damage, int type);
|
||||
void ThrowGibACID(edict_t *self, char *gibname, int damage, int type);
|
||||
|
||||
/* g_ai.c */
|
||||
void AI_SetSightClient(void);
|
||||
|
@ -749,10 +897,19 @@ void fire_grenade(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
|||
void fire_grenade2(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, float timer, float damage_radius, qboolean held);
|
||||
void fire_rocket(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, float damage_radius, int radius_damage);
|
||||
int speed, float damage_radius,
|
||||
int radius_damage);
|
||||
void fire_rail(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick);
|
||||
void fire_bfg(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, float damage_radius);
|
||||
void fire_ionripper(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, int effect);
|
||||
void fire_blueblaster(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, int effect);
|
||||
void fire_plasma(edict_t *self, vec3_t start, vec3_t dir, int damage, int speed,
|
||||
float damage_radius, int radius_damage);
|
||||
void fire_trap(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, float timer, float damage_radius, qboolean held);
|
||||
|
||||
/* g_ptrail.c */
|
||||
void PlayerTrail_Init(void);
|
||||
|
@ -823,6 +980,87 @@ void ReadGame(const char *filename);
|
|||
void WriteGame(const char *filename, qboolean autosave);
|
||||
void SpawnEntities(const char *mapname, char *entities, const char *spawnpoint);
|
||||
|
||||
void fire_flechette(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int kick);
|
||||
void fire_prox(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed);
|
||||
void fire_nuke(edict_t *self, vec3_t start, vec3_t aimdir, int speed);
|
||||
void fire_flame(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed);
|
||||
void fire_burst(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed);
|
||||
void fire_maintain(edict_t *, edict_t *, vec3_t start, vec3_t aimdir,
|
||||
int damage, int speed);
|
||||
void fire_incendiary_grenade(edict_t *self, vec3_t start, vec3_t aimdir,
|
||||
int damage, int speed, float timer, float damage_radius);
|
||||
void fire_player_melee(edict_t *self, vec3_t start, vec3_t aim, int reach,
|
||||
int damage, int kick, int quiet, int mod);
|
||||
void fire_tesla(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed);
|
||||
void fire_blaster2(edict_t *self, vec3_t start, vec3_t aimdir, int damage,
|
||||
int speed, int effect, qboolean hyper);
|
||||
void fire_tracker(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, edict_t *enemy);
|
||||
|
||||
/* g_newai.c */
|
||||
qboolean blocked_checkplat(edict_t *self, float dist);
|
||||
qboolean blocked_checkjump(edict_t *self, float dist, float maxDown, float maxUp);
|
||||
qboolean blocked_checknewenemy(edict_t *self);
|
||||
qboolean monsterlost_checkhint(edict_t *self);
|
||||
qboolean inback(edict_t *self, edict_t *other);
|
||||
float realrange(edict_t *self, edict_t *other);
|
||||
edict_t *SpawnBadArea(vec3_t mins, vec3_t maxs, float lifespan, edict_t *owner);
|
||||
edict_t *CheckForBadArea(edict_t *ent);
|
||||
qboolean MarkTeslaArea(edict_t *self, edict_t *tesla);
|
||||
void InitHintPaths(void);
|
||||
void PredictAim(edict_t *target, vec3_t start, float bolt_speed, qboolean eye_height,
|
||||
float offset, vec3_t aimdir, vec3_t aimpoint);
|
||||
qboolean below(edict_t *self, edict_t *other);
|
||||
void drawbbox(edict_t *self);
|
||||
void M_MonsterDodge(edict_t *self, edict_t *attacker, float eta, trace_t *tr);
|
||||
void monster_duck_down(edict_t *self);
|
||||
void monster_duck_hold(edict_t *self);
|
||||
void monster_duck_up(edict_t *self);
|
||||
qboolean has_valid_enemy(edict_t *self);
|
||||
void TargetTesla(edict_t *self, edict_t *tesla);
|
||||
void hintpath_stop(edict_t *self);
|
||||
edict_t *PickCoopTarget(edict_t *self);
|
||||
int CountPlayers(void);
|
||||
void monster_jump_start(edict_t *self);
|
||||
qboolean monster_jump_finished(edict_t *self);
|
||||
|
||||
/* g_sphere.c */
|
||||
void Defender_Launch(edict_t *self);
|
||||
void Vengeance_Launch(edict_t *self);
|
||||
void Hunter_Launch(edict_t *self);
|
||||
|
||||
/* g_newdm.c */
|
||||
void InitGameRules(void);
|
||||
edict_t *DoRandomRespawn(edict_t *ent);
|
||||
void PrecacheForRandomRespawn(void);
|
||||
qboolean Tag_PickupToken(edict_t *ent, edict_t *other);
|
||||
void Tag_DropToken(edict_t *ent, gitem_t *item);
|
||||
void Tag_PlayerDeath(edict_t *targ, edict_t *inflictor, edict_t *attacker);
|
||||
void fire_doppleganger(edict_t *ent, vec3_t start, vec3_t aimdir);
|
||||
|
||||
/* g_spawn.c */
|
||||
edict_t *CreateMonster(vec3_t origin, vec3_t angles, char *classname);
|
||||
edict_t *CreateFlyMonster(vec3_t origin, vec3_t angles, vec3_t mins,
|
||||
vec3_t maxs, char *classname);
|
||||
edict_t *CreateGroundMonster(vec3_t origin, vec3_t angles, vec3_t mins,
|
||||
vec3_t maxs, char *classname, int height);
|
||||
qboolean FindSpawnPoint(vec3_t startpoint, vec3_t mins, vec3_t maxs,
|
||||
vec3_t spawnpoint, float maxMoveUp);
|
||||
qboolean CheckSpawnPoint(vec3_t origin, vec3_t mins, vec3_t maxs);
|
||||
qboolean CheckGroundSpawnPoint(vec3_t origin, vec3_t entMins, vec3_t entMaxs,
|
||||
float height, float gravity);
|
||||
void DetermineBBox(char *classname, vec3_t mins, vec3_t maxs);
|
||||
void SpawnGrow_Spawn(vec3_t startpos, int size);
|
||||
void Widowlegs_Spawn(vec3_t startpos, vec3_t angles);
|
||||
|
||||
/* p_client.c */
|
||||
void RemoveAttackingPainDaemons(edict_t *self);
|
||||
|
||||
/* ============================================================================ */
|
||||
|
||||
/* client_t->anim_priority */
|
||||
|
@ -844,8 +1082,8 @@ typedef struct
|
|||
qboolean connected; /* a loadgame will leave valid entities that
|
||||
just don't have a connection yet */
|
||||
|
||||
/* values saved and restored
|
||||
from edicts when changing levels */
|
||||
/* values saved and restored from
|
||||
edicts when changing levels */
|
||||
int health;
|
||||
int max_health;
|
||||
int savedFlags;
|
||||
|
@ -860,6 +1098,8 @@ typedef struct
|
|||
int max_grenades;
|
||||
int max_cells;
|
||||
int max_slugs;
|
||||
int max_magslug;
|
||||
int max_trap;
|
||||
|
||||
gitem_t *weapon;
|
||||
gitem_t *lastweapon;
|
||||
|
@ -871,6 +1111,12 @@ typedef struct
|
|||
int helpchanged;
|
||||
|
||||
qboolean spectator; /* client is a spectator */
|
||||
|
||||
int max_tesla;
|
||||
int max_prox;
|
||||
int max_mines;
|
||||
int max_flechettes;
|
||||
int max_rounds;
|
||||
} client_persistant_t;
|
||||
|
||||
/* client data that stays across deathmatch respawns */
|
||||
|
@ -884,8 +1130,8 @@ typedef struct
|
|||
qboolean spectator; /* client is a spectator */
|
||||
} client_respawn_t;
|
||||
|
||||
/* this structure is cleared on each PutClientInServer(),
|
||||
except for 'client->pers' */
|
||||
/* this structure is cleared on each
|
||||
PutClientInServer(), except for 'client->pers' */
|
||||
struct gclient_s
|
||||
{
|
||||
/* known to server */
|
||||
|
@ -955,6 +1201,10 @@ struct gclient_s
|
|||
|
||||
qboolean grenade_blew_up;
|
||||
float grenade_time;
|
||||
float quadfire_framenum;
|
||||
qboolean trap_blew_up;
|
||||
float trap_time;
|
||||
|
||||
int silencer_shots;
|
||||
int weapon_sound;
|
||||
|
||||
|
@ -968,15 +1218,21 @@ struct gclient_s
|
|||
|
||||
edict_t *chase_target; /* player we are chasing */
|
||||
qboolean update_chase; /* need to update chase info? */
|
||||
|
||||
float double_framenum;
|
||||
float ir_framenum;
|
||||
float nuke_framenum;
|
||||
float tracker_pain_framenum;
|
||||
|
||||
edict_t *owned_sphere; /* this points to the player's sphere */
|
||||
};
|
||||
|
||||
struct edict_s
|
||||
{
|
||||
entity_state_t s;
|
||||
struct gclient_s *client; /* NULL if not a player
|
||||
the server expects the first part
|
||||
of gclient_s to be a player_state_t
|
||||
but the rest of it is opaque */
|
||||
struct gclient_s *client; /* NULL if not a player the server expects the first part
|
||||
of gclient_s to be a player_state_t but the rest of it is
|
||||
opaque */
|
||||
|
||||
qboolean inuse;
|
||||
int linkcount;
|
||||
|
@ -1001,6 +1257,7 @@ struct edict_s
|
|||
/* EXPECTS THE FIELDS IN THAT ORDER! */
|
||||
|
||||
/* ================================ */
|
||||
|
||||
int movetype;
|
||||
int flags;
|
||||
|
||||
|
@ -1032,8 +1289,8 @@ struct edict_s
|
|||
vec3_t avelocity;
|
||||
int mass;
|
||||
float air_finished;
|
||||
float gravity; /* per entity gravity multiplier (1.0 is normal)
|
||||
use for lowgrav artifact, flares */
|
||||
float gravity; /* per entity gravity multiplier (1.0 is normal) */
|
||||
/* use for lowgrav artifact, flares */
|
||||
|
||||
edict_t *goalentity;
|
||||
edict_t *movetarget;
|
||||
|
@ -1043,7 +1300,7 @@ struct edict_s
|
|||
float nextthink;
|
||||
void (*prethink)(edict_t *ent);
|
||||
void (*think)(edict_t *self);
|
||||
void (*blocked)(edict_t *self, edict_t *other);
|
||||
void (*blocked)(edict_t *self, edict_t *other); /* move to moveinfo? */
|
||||
void (*touch)(edict_t *self, edict_t *other, cplane_t *plane,
|
||||
csurface_t *surf);
|
||||
void (*use)(edict_t *self, edict_t *other, edict_t *activator);
|
||||
|
@ -1051,10 +1308,11 @@ struct edict_s
|
|||
void (*die)(edict_t *self, edict_t *inflictor, edict_t *attacker,
|
||||
int damage, vec3_t point);
|
||||
|
||||
float touch_debounce_time;
|
||||
float touch_debounce_time; /* now also used by fixbots for timeouts when getting stuck */
|
||||
float pain_debounce_time;
|
||||
float damage_debounce_time;
|
||||
float fly_sound_debounce_time; /* now also used by insane marines to store pain sound timeout */
|
||||
/* and by fixbots for storing object_repair timeout when getting stuck */
|
||||
float last_move_time;
|
||||
|
||||
int health;
|
||||
|
@ -1107,7 +1365,6 @@ struct edict_s
|
|||
|
||||
/* move this to clientinfo? */
|
||||
int light_level;
|
||||
|
||||
int style; /* also used as areaportal number */
|
||||
|
||||
gitem_t *item; /* for bonus items */
|
||||
|
@ -1115,8 +1372,67 @@ struct edict_s
|
|||
/* common data blocks */
|
||||
moveinfo_t moveinfo;
|
||||
monsterinfo_t monsterinfo;
|
||||
|
||||
int orders;
|
||||
|
||||
int plat2flags;
|
||||
vec3_t offset;
|
||||
vec3_t gravityVector;
|
||||
edict_t *bad_area;
|
||||
edict_t *hint_chain;
|
||||
edict_t *monster_hint_chain;
|
||||
edict_t *target_hint_chain;
|
||||
int hint_chain_id;
|
||||
float lastMoveTime;
|
||||
};
|
||||
|
||||
#define SPHERE_DEFENDER 0x0001
|
||||
#define SPHERE_HUNTER 0x0002
|
||||
#define SPHERE_VENGEANCE 0x0004
|
||||
#define SPHERE_DOPPLEGANGER 0x0100
|
||||
|
||||
#define SPHERE_TYPE 0x00FF
|
||||
#define SPHERE_FLAGS 0xFF00
|
||||
|
||||
/* deathmatch games */
|
||||
#define RDM_TAG 2
|
||||
#define RDM_DEATHBALL 3
|
||||
|
||||
typedef struct dm_game_rs
|
||||
{
|
||||
void (*GameInit)(void);
|
||||
void (*PostInitSetup)(void);
|
||||
void (*ClientBegin)(edict_t *ent);
|
||||
void (*SelectSpawnPoint)(edict_t *ent, vec3_t origin, vec3_t angles);
|
||||
void (*PlayerDeath)(edict_t *targ, edict_t *inflictor, edict_t *attacker);
|
||||
void (*Score)(edict_t *attacker, edict_t *victim, int scoreChange);
|
||||
void (*PlayerEffects)(edict_t *ent);
|
||||
void (*DogTag)(edict_t *ent, edict_t *killer, char **pic);
|
||||
void (*PlayerDisconnect)(edict_t *ent);
|
||||
int (*ChangeDamage)(edict_t *targ, edict_t *attacker, int damage, int mod);
|
||||
int (*ChangeKnockback)(edict_t *targ, edict_t *attacker, int knockback, int mod);
|
||||
int (*CheckDMRules)(void);
|
||||
} dm_game_rt;
|
||||
|
||||
extern dm_game_rt DMGame;
|
||||
|
||||
void Tag_GameInit(void);
|
||||
void Tag_PostInitSetup(void);
|
||||
void Tag_PlayerDeath(edict_t *targ, edict_t *inflictor, edict_t *attacker);
|
||||
void Tag_Score(edict_t *attacker, edict_t *victim, int scoreChange);
|
||||
void Tag_PlayerEffects(edict_t *ent);
|
||||
void Tag_DogTag(edict_t *ent, edict_t *killer, char **pic);
|
||||
void Tag_PlayerDisconnect(edict_t *ent);
|
||||
int Tag_ChangeDamage(edict_t *targ, edict_t *attacker, int damage, int mod);
|
||||
|
||||
void DBall_GameInit(void);
|
||||
void DBall_ClientBegin(edict_t *ent);
|
||||
void DBall_SelectSpawnPoint(edict_t *ent, vec3_t origin, vec3_t angles);
|
||||
int DBall_ChangeKnockback(edict_t *targ, edict_t *attacker, int knockback, int mod);
|
||||
int DBall_ChangeDamage(edict_t *targ, edict_t *attacker, int damage, int mod);
|
||||
void DBall_PostInitSetup(void);
|
||||
int DBall_CheckDMRules(void);
|
||||
|
||||
/*
|
||||
* Uncomment for check that exported functions declarations are same as in
|
||||
* implementation. (-Wmissing-prototypes )
|
||||
|
|
|
@ -521,7 +521,7 @@ berserk_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /*
|
|||
|
||||
if (self->health <= self->gib_health)
|
||||
{
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
|
|
|
@ -873,7 +873,7 @@ makron_torso_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attack
|
|||
return;
|
||||
}
|
||||
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
|
@ -960,7 +960,7 @@ makron_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /*
|
|||
/* check for gib */
|
||||
if (self->health <= self->gib_health)
|
||||
{
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2",
|
||||
damage, GIB_ORGANIC);
|
||||
|
|
|
@ -767,7 +767,7 @@ brain_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* u
|
|||
/* check for gib */
|
||||
if (self->health <= self->gib_health)
|
||||
{
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
|
|
|
@ -517,7 +517,7 @@ chick_die(edict_t *self, edict_t *inflictor /* unused */,
|
|||
/* check for gib */
|
||||
if (self->health <= self->gib_health)
|
||||
{
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
|
|
|
@ -477,7 +477,7 @@ flipper_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /*
|
|||
/* check for gib */
|
||||
if (self->health <= self->gib_health)
|
||||
{
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
|
|
|
@ -497,7 +497,7 @@ gladiator_die(edict_t *self, edict_t *inflictor /* unused */,
|
|||
/* check for gib */
|
||||
if (self->health <= self->gib_health)
|
||||
{
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
|
|
|
@ -513,7 +513,7 @@ gunner_die(edict_t *self, edict_t *inflictor /* unused */,
|
|||
/* check for gib */
|
||||
if (self->health <= self->gib_health)
|
||||
{
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
|
|
|
@ -527,7 +527,7 @@ infantry_die(edict_t *self, edict_t *inflictor /* unused */,
|
|||
/* check for gib */
|
||||
if (self->health <= self->gib_health)
|
||||
{
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
|
|
|
@ -888,7 +888,7 @@ 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++)
|
||||
{
|
||||
|
|
|
@ -593,7 +593,7 @@ medic_die(edict_t *self, edict_t *inflictor /* unused */,
|
|||
/* check for gib */
|
||||
if (self->health <= self->gib_health)
|
||||
{
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex( "misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
|
|
|
@ -790,7 +790,7 @@ mutant_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_NORM, 0);
|
||||
gi.sound(self, CHAN_VOICE, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue