mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-10 07:12:07 +00:00
game: sync with ctf g_svcmds, g_target, g_trigger
This commit is contained in:
parent
d68c31e0e4
commit
c41b72125a
13 changed files with 261 additions and 2246 deletions
6
Makefile
6
Makefile
|
@ -1500,9 +1500,9 @@ CTF_OBJS_ = \
|
|||
src/ctf/g_save.o \
|
||||
src/game/g_sphere.o \
|
||||
src/ctf/g_spawn.o \
|
||||
src/ctf/g_svcmds.o \
|
||||
src/ctf/g_target.o \
|
||||
src/ctf/g_trigger.o \
|
||||
src/game/g_svcmds.o \
|
||||
src/game/g_target.o \
|
||||
src/game/g_trigger.o \
|
||||
src/game/g_utils.o \
|
||||
src/game/g_weapon.o \
|
||||
src/game/menu/menu.o \
|
||||
|
|
|
@ -122,7 +122,7 @@ void
|
|||
monster_fire_ionripper(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int flashtype, int effect)
|
||||
{
|
||||
if (!self)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ void
|
|||
monster_fire_heat(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int flashtype)
|
||||
{
|
||||
if (!self)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ dabeam_hit(edict_t *self)
|
|||
vec3_t end;
|
||||
trace_t tr;
|
||||
|
||||
if (!self)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ monster_dabeam(edict_t *self)
|
|||
vec3_t last_movedir;
|
||||
vec3_t point;
|
||||
|
||||
if (!self)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -27,21 +28,20 @@
|
|||
#include "header/local.h"
|
||||
|
||||
/*
|
||||
* pushmove objects do not obey gravity, and do not interact with
|
||||
* each other or trigger fields, but block normal movement and push
|
||||
* normal objects when they move.
|
||||
* pushmove objects do not obey gravity, and do not interact with each other or
|
||||
* trigger fields, but block normal movement and push normal objects when they move.
|
||||
*
|
||||
* onground is set for toss objects when they come to a complete rest.
|
||||
* It is set for steping or walking objects.
|
||||
* onground is set for toss objects when they come to a complete rest. it is set for
|
||||
* steping or walking objects
|
||||
*
|
||||
* doors, plats, etc are SOLID_BSP, and MOVETYPE_PUSH
|
||||
* bonus items are SOLID_TRIGGER touch, and MOVETYPE_TOSS
|
||||
* corpses are SOLID_NOT and MOVETYPE_TOSS
|
||||
* crates are SOLID_BBOX and MOVETYPE_TOSS
|
||||
* walking monsters are SOLID_SLIDEBOX and MOVETYPE_STEP
|
||||
* flying/floating monsters are SOLID_SLIDEBOX and MOVETYPE_FLY
|
||||
* - doors, plats, etc are SOLID_BSP, and MOVETYPE_PUSH
|
||||
* - bonus items are SOLID_TRIGGER touch, and MOVETYPE_TOSS
|
||||
* - corpses are SOLID_NOT and MOVETYPE_TOSS
|
||||
* - crates are SOLID_BBOX and MOVETYPE_TOSS
|
||||
* - walking monsters are SOLID_SLIDEBOX and MOVETYPE_STEP
|
||||
* - flying/floating monsters are SOLID_SLIDEBOX and MOVETYPE_FLY
|
||||
* - solid_edge items only clip against bsp models.
|
||||
*
|
||||
* solid_edge items only clip against bsp models.
|
||||
*/
|
||||
|
||||
edict_t *
|
||||
|
@ -50,7 +50,15 @@ SV_TestEntityPosition(edict_t *ent)
|
|||
trace_t trace;
|
||||
int mask;
|
||||
|
||||
if (ent->clipmask)
|
||||
if (!ent)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* dead bodies are supposed to not be solid so lets
|
||||
ensure they only collide with BSP during pushmoves
|
||||
*/
|
||||
if (ent->clipmask && !(ent->svflags & SVF_DEADMONSTER))
|
||||
{
|
||||
mask = ent->clipmask;
|
||||
}
|
||||
|
@ -90,13 +98,19 @@ SV_CheckVelocity(edict_t *ent)
|
|||
}
|
||||
|
||||
/*
|
||||
* Runs thinking code for this frame if necessary
|
||||
* Runs thinking code for
|
||||
* this frame if necessary
|
||||
*/
|
||||
qboolean
|
||||
SV_RunThink(edict_t *ent)
|
||||
{
|
||||
float thinktime;
|
||||
|
||||
if (!ent)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
thinktime = ent->nextthink;
|
||||
|
||||
if (thinktime <= 0)
|
||||
|
@ -122,13 +136,19 @@ SV_RunThink(edict_t *ent)
|
|||
}
|
||||
|
||||
/*
|
||||
* Two entities have touched, so run their touch functions
|
||||
* Two entities have touched, so
|
||||
* run their touch functions
|
||||
*/
|
||||
void
|
||||
SV_Impact(edict_t *e1, trace_t *trace)
|
||||
{
|
||||
edict_t *e2;
|
||||
|
||||
if (!e1 || !trace)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
e2 = trace->ent;
|
||||
|
||||
if (e1->touch && (e1->solid != SOLID_NOT))
|
||||
|
|
|
@ -94,6 +94,8 @@ void SP_target_help(edict_t *ent);
|
|||
void SP_target_actor(edict_t *ent);
|
||||
void SP_target_lightramp(edict_t *self);
|
||||
void SP_target_earthquake(edict_t *ent);
|
||||
void SP_target_music(edict_t *ent);
|
||||
void SP_target_sky(edict_t *ent);
|
||||
void SP_target_character(edict_t *ent);
|
||||
void SP_target_string(edict_t *ent);
|
||||
|
||||
|
@ -149,6 +151,7 @@ void SP_monster_mutant(edict_t *self);
|
|||
void SP_monster_supertank(edict_t *self);
|
||||
void SP_monster_boss2(edict_t *self);
|
||||
void SP_monster_jorg(edict_t *self);
|
||||
void SP_monster_makron(edict_t *self);
|
||||
void SP_monster_boss3_stand(edict_t *self);
|
||||
|
||||
void SP_monster_commander_body(edict_t *self);
|
||||
|
@ -157,6 +160,62 @@ void SP_turret_breach(edict_t *self);
|
|||
void SP_turret_base(edict_t *self);
|
||||
void SP_turret_driver(edict_t *self);
|
||||
|
||||
void SP_monster_soldier_hypergun(edict_t *self);
|
||||
void SP_monster_soldier_lasergun(edict_t *self);
|
||||
void SP_monster_soldier_ripper(edict_t *self);
|
||||
void SP_monster_fixbot(edict_t *self);
|
||||
void SP_monster_gekk(edict_t *self);
|
||||
void SP_monster_chick_heat(edict_t *self);
|
||||
void SP_monster_gladb(edict_t *self);
|
||||
void SP_monster_boss5(edict_t *self);
|
||||
void SP_rotating_light(edict_t *self);
|
||||
void SP_object_repair(edict_t *self);
|
||||
void SP_misc_crashviper(edict_t *ent);
|
||||
void SP_misc_viper_missile(edict_t *self);
|
||||
void SP_misc_amb4(edict_t *ent);
|
||||
void SP_target_mal_laser(edict_t *ent);
|
||||
void SP_misc_transport(edict_t *ent);
|
||||
|
||||
void SP_misc_nuke(edict_t *ent);
|
||||
void SP_func_plat2(edict_t *ent);
|
||||
void SP_func_door_secret2(edict_t *ent);
|
||||
void SP_func_force_wall(edict_t *ent);
|
||||
void SP_info_player_coop_lava(edict_t *self);
|
||||
void SP_info_teleport_destination(edict_t *self);
|
||||
void SP_trigger_teleport(edict_t *self);
|
||||
void SP_trigger_disguise(edict_t *self);
|
||||
void SP_monster_stalker(edict_t *self);
|
||||
void SP_monster_turret(edict_t *self);
|
||||
void SP_target_steam(edict_t *self);
|
||||
void SP_target_anger(edict_t *self);
|
||||
void SP_target_killplayers(edict_t *self);
|
||||
|
||||
void SP_target_blacklight(edict_t *self);
|
||||
void SP_target_orb(edict_t *self);
|
||||
|
||||
void SP_hint_path(edict_t *self);
|
||||
void SP_monster_carrier(edict_t *self);
|
||||
void SP_monster_widow(edict_t *self);
|
||||
void SP_monster_widow2(edict_t *self);
|
||||
void SP_dm_tag_token(edict_t *self);
|
||||
void SP_dm_dball_goal(edict_t *self);
|
||||
void SP_dm_dball_ball(edict_t *self);
|
||||
void SP_dm_dball_team1_start(edict_t *self);
|
||||
void SP_dm_dball_team2_start(edict_t *self);
|
||||
void SP_dm_dball_ball_start(edict_t *self);
|
||||
void SP_dm_dball_speed_change(edict_t *self);
|
||||
void SP_monster_kamikaze(edict_t *self);
|
||||
void SP_turret_invisible_brain(edict_t *self);
|
||||
void SP_xatrix_item(edict_t *self);
|
||||
void SP_misc_nuke_core(edict_t *self);
|
||||
|
||||
void ThrowMoreStuff(edict_t *self, vec3_t point);
|
||||
void ThrowSmallStuff(edict_t *self, vec3_t point);
|
||||
void ThrowWidowGibLoc(edict_t *self, char *gibname, int damage,
|
||||
int type, vec3_t startpos, qboolean fade);
|
||||
void ThrowWidowGibSized(edict_t *self, char *gibname, int damage, int type,
|
||||
vec3_t startpos, int hitsound, qboolean fade);
|
||||
|
||||
static spawn_t spawns[] = {
|
||||
{"item_health", SP_item_health},
|
||||
{"item_health_small", SP_item_health_small},
|
||||
|
@ -843,128 +902,129 @@ SpawnEntities(const char *mapname, char *entities, const char *spawnpoint)
|
|||
|
||||
/* =================================================================== */
|
||||
|
||||
char *single_statusbar =
|
||||
"yb -24 "
|
||||
static char *single_statusbar =
|
||||
"yb -24 "
|
||||
|
||||
/* health */
|
||||
"xv 0 "
|
||||
"hnum "
|
||||
"xv 50 "
|
||||
"pic 0 "
|
||||
"xv 0 "
|
||||
"hnum "
|
||||
"xv 50 "
|
||||
"pic 0 "
|
||||
|
||||
/* ammo */
|
||||
"if 2 "
|
||||
" xv 100 "
|
||||
" anum "
|
||||
" xv 150 "
|
||||
" pic 2 "
|
||||
"endif "
|
||||
"if 2 "
|
||||
" xv 100 "
|
||||
" anum "
|
||||
" xv 150 "
|
||||
" pic 2 "
|
||||
"endif "
|
||||
|
||||
/* armor */
|
||||
"if 4 "
|
||||
" xv 200 "
|
||||
" rnum "
|
||||
" xv 250 "
|
||||
" pic 4 "
|
||||
"endif "
|
||||
"if 4 "
|
||||
" xv 200 "
|
||||
" rnum "
|
||||
" xv 250 "
|
||||
" pic 4 "
|
||||
"endif "
|
||||
|
||||
/* selected item */
|
||||
"if 6 "
|
||||
" xv 296 "
|
||||
" pic 6 "
|
||||
"endif "
|
||||
"if 6 "
|
||||
" xv 296 "
|
||||
" pic 6 "
|
||||
"endif "
|
||||
|
||||
"yb -50 "
|
||||
"yb -50 "
|
||||
|
||||
/* picked up item */
|
||||
"if 7 "
|
||||
" xv 0 "
|
||||
" pic 7 "
|
||||
" xv 26 "
|
||||
" yb -42 "
|
||||
" stat_string 8 "
|
||||
" yb -50 "
|
||||
"endif "
|
||||
"if 7 "
|
||||
" xv 0 "
|
||||
" pic 7 "
|
||||
" xv 26 "
|
||||
" yb -42 "
|
||||
" stat_string 8 "
|
||||
" yb -50 "
|
||||
"endif "
|
||||
|
||||
/* timer */
|
||||
"if 9 "
|
||||
" xv 262 "
|
||||
" num 2 10 "
|
||||
" xv 296 "
|
||||
" pic 9 "
|
||||
"endif "
|
||||
"if 9 "
|
||||
" xv 262 "
|
||||
" num 2 10 "
|
||||
" xv 296 "
|
||||
" pic 9 "
|
||||
"endif "
|
||||
|
||||
/* help / weapon icon */
|
||||
"if 11 "
|
||||
" xv 148 "
|
||||
" pic 11 "
|
||||
"endif "
|
||||
"if 11 "
|
||||
" xv 148 "
|
||||
" pic 11 "
|
||||
"endif "
|
||||
;
|
||||
|
||||
char *dm_statusbar =
|
||||
"yb -24 "
|
||||
static char *dm_statusbar =
|
||||
"yb -24 "
|
||||
|
||||
/* health */
|
||||
"xv 0 "
|
||||
"hnum "
|
||||
"xv 50 "
|
||||
"pic 0 "
|
||||
"xv 0 "
|
||||
"hnum "
|
||||
"xv 50 "
|
||||
"pic 0 "
|
||||
|
||||
/* ammo */
|
||||
"if 2 "
|
||||
" xv 100 "
|
||||
" anum "
|
||||
" xv 150 "
|
||||
" pic 2 "
|
||||
"endif "
|
||||
"if 2 "
|
||||
" xv 100 "
|
||||
" anum "
|
||||
" xv 150 "
|
||||
" pic 2 "
|
||||
"endif "
|
||||
|
||||
/* armor */
|
||||
"if 4 "
|
||||
" xv 200 "
|
||||
" rnum "
|
||||
" xv 250 "
|
||||
" pic 4 "
|
||||
"endif "
|
||||
"if 4 "
|
||||
" xv 200 "
|
||||
" rnum "
|
||||
" xv 250 "
|
||||
" pic 4 "
|
||||
"endif "
|
||||
|
||||
/* selected item */
|
||||
"if 6 "
|
||||
" xv 296 "
|
||||
" pic 6 "
|
||||
"endif "
|
||||
"if 6 "
|
||||
" xv 296 "
|
||||
" pic 6 "
|
||||
"endif "
|
||||
|
||||
"yb -50 "
|
||||
"yb -50 "
|
||||
|
||||
/* picked up item */
|
||||
"if 7 "
|
||||
" xv 0 "
|
||||
" pic 7 "
|
||||
" xv 26 "
|
||||
" yb -42 "
|
||||
" stat_string 8 "
|
||||
" yb -50 "
|
||||
"endif "
|
||||
"if 7 "
|
||||
" xv 0 "
|
||||
" pic 7 "
|
||||
" xv 26 "
|
||||
" yb -42 "
|
||||
" stat_string 8 "
|
||||
" yb -50 "
|
||||
"endif "
|
||||
|
||||
/* timer */
|
||||
"if 9 "
|
||||
" xv 246 "
|
||||
" num 2 10 "
|
||||
" xv 296 "
|
||||
" pic 9 "
|
||||
"endif "
|
||||
"if 9 "
|
||||
" xv 246 "
|
||||
" num 2 10 "
|
||||
" xv 296 "
|
||||
" pic 9 "
|
||||
"endif "
|
||||
|
||||
/* help / weapon icon */
|
||||
"if 11 "
|
||||
" xv 148 "
|
||||
" pic 11 "
|
||||
"endif "
|
||||
"if 11 "
|
||||
" xv 148 "
|
||||
" pic 11 "
|
||||
"endif "
|
||||
|
||||
/* frags */
|
||||
"xr -50 "
|
||||
"yt 2 "
|
||||
"num 3 14"
|
||||
"xr -50 "
|
||||
"yt 2 "
|
||||
"num 3 14"
|
||||
;
|
||||
|
||||
/*QUAKED worldspawn (0 0 0) ?
|
||||
/*
|
||||
* QUAKED worldspawn (0 0 0) ?
|
||||
*
|
||||
* Only used for the world.
|
||||
* "sky" environment map name
|
||||
|
|
|
@ -1,344 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Game side of server CMDs. At this time only the ipfilter.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
#include "header/local.h"
|
||||
|
||||
void
|
||||
Svcmd_Test_f(void)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Svcmd_Test_f()\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* ==============================================================================
|
||||
*
|
||||
* PACKET FILTERING
|
||||
*
|
||||
*
|
||||
* You can add or remove addresses from the filter list with:
|
||||
*
|
||||
* addip <ip>
|
||||
* removeip <ip>
|
||||
*
|
||||
* The ip address is specified in dot format, and any unspecified
|
||||
* digits will match any value, so you can specify an entire class C
|
||||
* network with "addip 192.246.40".
|
||||
*
|
||||
* Removeip will only remove an address specified exactly the same way.
|
||||
* You cannot addip a subnet, then removeip a single host.
|
||||
*
|
||||
* listip
|
||||
* Prints the current list of filters.
|
||||
*
|
||||
* writeip
|
||||
* Dumps "addip <ip>" commands to listip.cfg so it can be execed at a
|
||||
* later date. The filter lists are not saved and restored by default,
|
||||
* because I beleive it would cause too much confusion.
|
||||
*
|
||||
* filterban <0 or 1>
|
||||
*
|
||||
* If 1 (the default), then ip addresses matching the current list will
|
||||
* be prohibited from entering the game. This is the default setting.
|
||||
*
|
||||
* If 0, then only addresses matching the list will be allowed. This lets
|
||||
* you easily set up a private game, or a game that only allows players
|
||||
* from your local network.
|
||||
*
|
||||
*
|
||||
* ==============================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned mask;
|
||||
unsigned compare;
|
||||
} ipfilter_t;
|
||||
|
||||
#define MAX_IPFILTERS 1024
|
||||
|
||||
ipfilter_t ipfilters[MAX_IPFILTERS];
|
||||
int numipfilters;
|
||||
|
||||
static qboolean
|
||||
StringToFilter(char *s, ipfilter_t *f)
|
||||
{
|
||||
char num[128];
|
||||
int i, j;
|
||||
byte b[4];
|
||||
byte m[4];
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
b[i] = 0;
|
||||
m[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if ((*s < '0') || (*s > '9'))
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Bad filter address: %s\n", s);
|
||||
return false;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
|
||||
while (*s >= '0' && *s <= '9')
|
||||
{
|
||||
num[j++] = *s++;
|
||||
}
|
||||
|
||||
num[j] = 0;
|
||||
b[i] = atoi(num);
|
||||
|
||||
if (b[i] != 0)
|
||||
{
|
||||
m[i] = 255;
|
||||
}
|
||||
|
||||
if (!*s)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
s++;
|
||||
}
|
||||
|
||||
f->mask = *(unsigned *)m;
|
||||
f->compare = *(unsigned *)b;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
qboolean
|
||||
SV_FilterPacket(char *from)
|
||||
{
|
||||
int i;
|
||||
unsigned in;
|
||||
byte m[4];
|
||||
char *p;
|
||||
|
||||
i = 0;
|
||||
p = from;
|
||||
|
||||
while (*p && i < 4)
|
||||
{
|
||||
m[i] = 0;
|
||||
|
||||
while (*p >= '0' && *p <= '9')
|
||||
{
|
||||
m[i] = m[i] * 10 + (*p - '0');
|
||||
p++;
|
||||
}
|
||||
|
||||
if (!*p || (*p == ':'))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
i++, p++;
|
||||
}
|
||||
|
||||
in = *(unsigned *)m;
|
||||
|
||||
for (i = 0; i < numipfilters; i++)
|
||||
{
|
||||
if ((in & ipfilters[i].mask) == ipfilters[i].compare)
|
||||
{
|
||||
return (int)filterban->value;
|
||||
}
|
||||
}
|
||||
|
||||
return (int)!filterban->value;
|
||||
}
|
||||
|
||||
void
|
||||
SVCmd_AddIP_f(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (gi.argc() < 3)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Usage: addip <ip-mask>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < numipfilters; i++)
|
||||
{
|
||||
if (ipfilters[i].compare == 0xffffffff)
|
||||
{
|
||||
break; /* free spot */
|
||||
}
|
||||
}
|
||||
|
||||
if (i == numipfilters)
|
||||
{
|
||||
if (numipfilters == MAX_IPFILTERS)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "IP filter list is full\n");
|
||||
return;
|
||||
}
|
||||
|
||||
numipfilters++;
|
||||
}
|
||||
|
||||
if (!StringToFilter(gi.argv(2), &ipfilters[i]))
|
||||
{
|
||||
ipfilters[i].compare = 0xffffffff;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SVCmd_RemoveIP_f(void)
|
||||
{
|
||||
ipfilter_t f;
|
||||
int i, j;
|
||||
|
||||
if (gi.argc() < 3)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Usage: sv removeip <ip-mask>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!StringToFilter(gi.argv(2), &f))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < numipfilters; i++)
|
||||
{
|
||||
if ((ipfilters[i].mask == f.mask) &&
|
||||
(ipfilters[i].compare == f.compare))
|
||||
{
|
||||
for (j = i + 1; j < numipfilters; j++)
|
||||
{
|
||||
ipfilters[j - 1] = ipfilters[j];
|
||||
}
|
||||
|
||||
numipfilters--;
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Removed.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Didn't find %s.\n", gi.argv(2));
|
||||
}
|
||||
|
||||
void
|
||||
SVCmd_ListIP_f(void)
|
||||
{
|
||||
int i;
|
||||
byte b[4];
|
||||
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Filter list:\n");
|
||||
|
||||
for (i = 0; i < numipfilters; i++)
|
||||
{
|
||||
*(unsigned *)b = ipfilters[i].compare;
|
||||
gi.cprintf(NULL, PRINT_HIGH, "%3i.%3i.%3i.%3i\n", b[0],
|
||||
b[1], b[2], b[3]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SVCmd_WriteIP_f(void)
|
||||
{
|
||||
FILE *f;
|
||||
char name[MAX_OSPATH];
|
||||
byte b[4];
|
||||
int i;
|
||||
cvar_t *game;
|
||||
|
||||
game = gi.cvar("game", "", 0);
|
||||
|
||||
if (!*game->string)
|
||||
{
|
||||
sprintf(name, "%s/listip.cfg", GAMEVERSION);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(name, "%s/listip.cfg", game->string);
|
||||
}
|
||||
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Writing %s.\n", name);
|
||||
|
||||
f = fopen(name, "wb");
|
||||
|
||||
if (!f)
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Couldn't open %s\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(f, "set filterban %d\n", (int)filterban->value);
|
||||
|
||||
for (i = 0; i < numipfilters; i++)
|
||||
{
|
||||
*(unsigned *)b = ipfilters[i].compare;
|
||||
fprintf(f, "sv addip %i.%i.%i.%i\n", b[0], b[1], b[2], b[3]);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
/*
|
||||
* ServerCommand will be called when an "sv" command is issued.
|
||||
* The game can issue gi.argc() / gi.argv() commands to get the rest
|
||||
* of the parameters
|
||||
*/
|
||||
void
|
||||
ServerCommand(void)
|
||||
{
|
||||
char *cmd;
|
||||
|
||||
cmd = gi.argv(1);
|
||||
|
||||
if (Q_stricmp(cmd, "test") == 0)
|
||||
{
|
||||
Svcmd_Test_f();
|
||||
}
|
||||
else if (Q_stricmp(cmd, "addip") == 0)
|
||||
{
|
||||
SVCmd_AddIP_f();
|
||||
}
|
||||
else if (Q_stricmp(cmd, "removeip") == 0)
|
||||
{
|
||||
SVCmd_RemoveIP_f();
|
||||
}
|
||||
else if (Q_stricmp(cmd, "listip") == 0)
|
||||
{
|
||||
SVCmd_ListIP_f();
|
||||
}
|
||||
else if (Q_stricmp(cmd, "writeip") == 0)
|
||||
{
|
||||
SVCmd_WriteIP_f();
|
||||
}
|
||||
else
|
||||
{
|
||||
gi.cprintf(NULL, PRINT_HIGH, "Unknown server command \"%s\"\n", cmd);
|
||||
}
|
||||
}
|
||||
|
1022
src/ctf/g_target.c
1022
src/ctf/g_target.c
File diff suppressed because it is too large
Load diff
|
@ -1,756 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Trigger.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
#include "header/local.h"
|
||||
|
||||
void
|
||||
InitTrigger(edict_t *self)
|
||||
{
|
||||
if (!VectorCompare(self->s.angles, vec3_origin))
|
||||
{
|
||||
G_SetMovedir(self->s.angles, self->movedir);
|
||||
}
|
||||
|
||||
self->solid = SOLID_TRIGGER;
|
||||
self->movetype = MOVETYPE_NONE;
|
||||
gi.setmodel(self, self->model);
|
||||
self->svflags = SVF_NOCLIENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* The wait time has passed, so set
|
||||
* back up for another activation
|
||||
*/
|
||||
void
|
||||
multi_wait(edict_t *ent)
|
||||
{
|
||||
ent->nextthink = 0;
|
||||
}
|
||||
|
||||
void
|
||||
multi_trigger(edict_t *ent)
|
||||
{
|
||||
if (ent->nextthink)
|
||||
{
|
||||
return; /* already been triggered */
|
||||
}
|
||||
|
||||
G_UseTargets(ent, ent->activator);
|
||||
|
||||
if (ent->wait > 0)
|
||||
{
|
||||
ent->think = multi_wait;
|
||||
ent->nextthink = level.time + ent->wait;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we can't just remove (self) here, because this is
|
||||
a touch function called while looping through area links... */
|
||||
ent->touch = NULL;
|
||||
ent->nextthink = level.time + FRAMETIME;
|
||||
ent->think = G_FreeEdict;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Use_Multi(edict_t *ent, edict_t *other, edict_t *activator)
|
||||
{
|
||||
ent->activator = activator;
|
||||
multi_trigger(ent);
|
||||
}
|
||||
|
||||
void
|
||||
Touch_Multi(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
if (other->client)
|
||||
{
|
||||
if (self->spawnflags & 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (other->svflags & SVF_MONSTER)
|
||||
{
|
||||
if (!(self->spawnflags & 1))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VectorCompare(self->movedir, vec3_origin))
|
||||
{
|
||||
vec3_t forward;
|
||||
|
||||
AngleVectors(other->s.angles, forward, NULL, NULL);
|
||||
|
||||
if (_DotProduct(forward, self->movedir) < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
self->activator = other;
|
||||
multi_trigger(self);
|
||||
}
|
||||
|
||||
/*
|
||||
* QUAKED trigger_multiple (.5 .5 .5) ? MONSTER NOT_PLAYER TRIGGERED
|
||||
* Variable sized repeatable trigger. Must be targeted at one or more entities.
|
||||
* If "delay" is set, the trigger waits some time after activating before firing.
|
||||
* "wait" : Seconds between triggerings. (.2 default)
|
||||
*
|
||||
* sounds
|
||||
* 1) secret
|
||||
* 2) beep beep
|
||||
* 3) large switch
|
||||
* 4)
|
||||
*
|
||||
* set "message" to text string
|
||||
*/
|
||||
void
|
||||
trigger_enable(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
self->solid = SOLID_TRIGGER;
|
||||
self->use = Use_Multi;
|
||||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
void
|
||||
SP_trigger_multiple(edict_t *ent)
|
||||
{
|
||||
if (ent->sounds == 1)
|
||||
{
|
||||
ent->noise_index = gi.soundindex("misc/secret.wav");
|
||||
}
|
||||
else if (ent->sounds == 2)
|
||||
{
|
||||
ent->noise_index = gi.soundindex("misc/talk.wav");
|
||||
}
|
||||
else if (ent->sounds == 3)
|
||||
{
|
||||
ent->noise_index = gi.soundindex("misc/trigger1.wav");
|
||||
}
|
||||
|
||||
if (!ent->wait)
|
||||
{
|
||||
ent->wait = 0.2;
|
||||
}
|
||||
|
||||
ent->touch = Touch_Multi;
|
||||
ent->movetype = MOVETYPE_NONE;
|
||||
ent->svflags |= SVF_NOCLIENT;
|
||||
|
||||
if (ent->spawnflags & 4)
|
||||
{
|
||||
ent->solid = SOLID_NOT;
|
||||
ent->use = trigger_enable;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->solid = SOLID_TRIGGER;
|
||||
ent->use = Use_Multi;
|
||||
}
|
||||
|
||||
if (!VectorCompare(ent->s.angles, vec3_origin))
|
||||
{
|
||||
G_SetMovedir(ent->s.angles, ent->movedir);
|
||||
}
|
||||
|
||||
gi.setmodel(ent, ent->model);
|
||||
gi.linkentity(ent);
|
||||
}
|
||||
|
||||
/*
|
||||
* QUAKED trigger_once (.5 .5 .5) ? x x TRIGGERED
|
||||
* Triggers once, then removes itself.
|
||||
* You must set the key "target" to the name of another object
|
||||
* in the level that has a matching "targetname".
|
||||
*
|
||||
* If TRIGGERED, this trigger must be triggered before it is live.
|
||||
*
|
||||
* sounds
|
||||
* 1) secret
|
||||
* 2) beep beep
|
||||
* 3) large switch
|
||||
* 4)
|
||||
*
|
||||
* "message" string to be displayed when triggered
|
||||
*/
|
||||
|
||||
void
|
||||
SP_trigger_once(edict_t *ent)
|
||||
{
|
||||
/* make old maps work because I messed up on flag assignments here
|
||||
triggered was on bit 1 when it should have been on bit 4 */
|
||||
if (ent->spawnflags & 1)
|
||||
{
|
||||
vec3_t v;
|
||||
|
||||
VectorMA(ent->mins, 0.5, ent->size, v);
|
||||
ent->spawnflags &= ~1;
|
||||
ent->spawnflags |= 4;
|
||||
gi.dprintf("fixed TRIGGERED flag on %s at %s\n", ent->classname, vtos(v));
|
||||
}
|
||||
|
||||
ent->wait = -1;
|
||||
SP_trigger_multiple(ent);
|
||||
}
|
||||
|
||||
/*
|
||||
* QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8)
|
||||
* This fixed size trigger cannot be touched, it can only be fired by other events.
|
||||
*/
|
||||
void
|
||||
trigger_relay_use(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
G_UseTargets(self, activator);
|
||||
}
|
||||
|
||||
void
|
||||
SP_trigger_relay(edict_t *self)
|
||||
{
|
||||
self->use = trigger_relay_use;
|
||||
}
|
||||
|
||||
/*
|
||||
* ==============================================================================
|
||||
*
|
||||
* trigger_key
|
||||
*
|
||||
* ==============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* QUAKED trigger_key (.5 .5 .5) (-8 -8 -8) (8 8 8)
|
||||
* A relay trigger that only fires it's targets if player has the proper key.
|
||||
* Use "item" to specify the required key, for example "key_data_cd"
|
||||
*/
|
||||
void
|
||||
trigger_key_use(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
int index;
|
||||
|
||||
if (!self->item)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!activator->client)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
index = ITEM_INDEX(self->item);
|
||||
|
||||
if (!activator->client->pers.inventory[index])
|
||||
{
|
||||
if (level.time < self->touch_debounce_time)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
gi.sound(activator, CHAN_AUTO, gi.soundindex("misc/keyuse.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
if (coop->value)
|
||||
{
|
||||
int player;
|
||||
edict_t *ent;
|
||||
|
||||
if (strcmp(self->item->classname, "key_power_cube") == 0)
|
||||
{
|
||||
int cube;
|
||||
|
||||
for (cube = 0; cube < 8; cube++)
|
||||
{
|
||||
if (activator->client->pers.power_cubes & (1 << cube))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (player = 1; player <= game.maxclients; player++)
|
||||
{
|
||||
ent = &g_edicts[player];
|
||||
|
||||
if (!ent->inuse)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ent->client)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ent->client->pers.power_cubes & (1 << cube))
|
||||
{
|
||||
ent->client->pers.inventory[index]--;
|
||||
ent->client->pers.power_cubes &= ~(1 << cube);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (player = 1; player <= game.maxclients; player++)
|
||||
{
|
||||
ent = &g_edicts[player];
|
||||
|
||||
if (!ent->inuse)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ent->client)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ent->client->pers.inventory[index] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
activator->client->pers.inventory[index]--;
|
||||
}
|
||||
|
||||
G_UseTargets(self, activator);
|
||||
|
||||
self->use = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
SP_trigger_key(edict_t *self)
|
||||
{
|
||||
if (!st.item)
|
||||
{
|
||||
gi.dprintf("no key item for trigger_key at %s\n", vtos(self->s.origin));
|
||||
return;
|
||||
}
|
||||
|
||||
self->item = FindItemByClassname(st.item);
|
||||
|
||||
if (!self->item)
|
||||
{
|
||||
gi.dprintf("item %s not found for trigger_key at %s\n", st.item,
|
||||
vtos(self->s.origin));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!self->target)
|
||||
{
|
||||
gi.dprintf("%s at %s has no target\n", self->classname,
|
||||
vtos(self->s.origin));
|
||||
return;
|
||||
}
|
||||
|
||||
gi.soundindex("misc/keytry.wav");
|
||||
gi.soundindex("misc/keyuse.wav");
|
||||
|
||||
self->use = trigger_key_use;
|
||||
}
|
||||
|
||||
/*
|
||||
* ==============================================================================
|
||||
*
|
||||
* trigger_counter
|
||||
*
|
||||
* ==============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* QUAKED trigger_counter (.5 .5 .5) ? nomessage
|
||||
* Acts as an intermediary for an action that takes multiple inputs.
|
||||
*
|
||||
* If nomessage is not set, t will print "1 more.. " etc when triggered
|
||||
* and "sequence complete" when finished.
|
||||
*
|
||||
* After the counter has been triggered "count" times (default 2), it
|
||||
* will fire all of it's targets and remove itself.
|
||||
*/
|
||||
void
|
||||
trigger_counter_use(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if (self->count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self->count--;
|
||||
|
||||
if (self->count)
|
||||
{
|
||||
if (!(self->spawnflags & 1))
|
||||
{
|
||||
gi.centerprintf(activator, "%i more to go...", self->count);
|
||||
gi.sound(activator, CHAN_AUTO, gi.soundindex("misc/talk1.wav"), 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(self->spawnflags & 1))
|
||||
{
|
||||
gi.centerprintf(activator, "Sequence completed!");
|
||||
gi.sound(activator, CHAN_AUTO, gi.soundindex("misc/talk1.wav"), 1, ATTN_NORM, 0);
|
||||
}
|
||||
|
||||
self->activator = activator;
|
||||
multi_trigger(self);
|
||||
}
|
||||
|
||||
void
|
||||
SP_trigger_counter(edict_t *self)
|
||||
{
|
||||
self->wait = -1;
|
||||
|
||||
if (!self->count)
|
||||
{
|
||||
self->count = 2;
|
||||
}
|
||||
|
||||
self->use = trigger_counter_use;
|
||||
}
|
||||
|
||||
/*
|
||||
* ==============================================================================
|
||||
*
|
||||
* trigger_always
|
||||
*
|
||||
* ==============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* QUAKED trigger_always (.5 .5 .5) (-8 -8 -8) (8 8 8)
|
||||
* This trigger will always fire. It is activated by the world.
|
||||
*/
|
||||
void
|
||||
SP_trigger_always(edict_t *ent)
|
||||
{
|
||||
/* we must have some delay to make sure our use targets are present */
|
||||
if (ent->delay < 0.2)
|
||||
{
|
||||
ent->delay = 0.2;
|
||||
}
|
||||
|
||||
G_UseTargets(ent, ent);
|
||||
}
|
||||
|
||||
/*
|
||||
* ==============================================================================
|
||||
*
|
||||
* trigger_push
|
||||
*
|
||||
* ==============================================================================
|
||||
*/
|
||||
|
||||
#define PUSH_ONCE 1
|
||||
|
||||
static int windsound;
|
||||
|
||||
void
|
||||
trigger_push_touch(edict_t *self, edict_t *other, cplane_t *plane,
|
||||
csurface_t *surf)
|
||||
{
|
||||
if (strcmp(other->classname, "grenade") == 0)
|
||||
{
|
||||
VectorScale(self->movedir, self->speed * 10, other->velocity);
|
||||
}
|
||||
else if (other->health > 0)
|
||||
{
|
||||
VectorScale(self->movedir, self->speed * 10, other->velocity);
|
||||
|
||||
if (other->client)
|
||||
{
|
||||
/* don't take falling damage immediately from this */
|
||||
VectorCopy(other->velocity, other->client->oldvelocity);
|
||||
|
||||
if (other->fly_sound_debounce_time < level.time)
|
||||
{
|
||||
other->fly_sound_debounce_time = level.time + 1.5;
|
||||
gi.sound(other, CHAN_AUTO, windsound, 1, ATTN_NORM, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (self->spawnflags & PUSH_ONCE)
|
||||
{
|
||||
G_FreeEdict(self);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE
|
||||
* Pushes the player
|
||||
* "speed" defaults to 1000
|
||||
*/
|
||||
void
|
||||
SP_trigger_push(edict_t *self)
|
||||
{
|
||||
InitTrigger(self);
|
||||
windsound = gi.soundindex("misc/windfly.wav");
|
||||
self->touch = trigger_push_touch;
|
||||
|
||||
if (!self->speed)
|
||||
{
|
||||
self->speed = 1000;
|
||||
}
|
||||
|
||||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
/*
|
||||
* ==============================================================================
|
||||
*
|
||||
* trigger_hurt
|
||||
*
|
||||
* ==============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* QUAKED trigger_hurt (.5 .5 .5) ? START_OFF TOGGLE SILENT NO_PROTECTION SLOW
|
||||
* Any entity that touches this will be hurt.
|
||||
*
|
||||
* It does dmg points of damage each server frame
|
||||
*
|
||||
* SILENT supresses playing the sound
|
||||
* SLOW changes the damage rate to once per second
|
||||
* NO_PROTECTION *nothing* stops the damage
|
||||
*
|
||||
* "dmg" default 5 (whole numbers only)
|
||||
*
|
||||
*/
|
||||
void
|
||||
hurt_use(edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if (self->solid == SOLID_NOT)
|
||||
{
|
||||
self->solid = SOLID_TRIGGER;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->solid = SOLID_NOT;
|
||||
}
|
||||
|
||||
gi.linkentity(self);
|
||||
|
||||
if (!(self->spawnflags & 2))
|
||||
{
|
||||
self->use = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
hurt_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
int dflags;
|
||||
|
||||
if (!other->takedamage)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->timestamp > level.time)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->spawnflags & 16)
|
||||
{
|
||||
self->timestamp = level.time + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->timestamp = level.time + FRAMETIME;
|
||||
}
|
||||
|
||||
if (!(self->spawnflags & 4))
|
||||
{
|
||||
if ((level.framenum % 10) == 0)
|
||||
{
|
||||
gi.sound(other, CHAN_AUTO, self->noise_index, 1, ATTN_NORM, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (self->spawnflags & 8)
|
||||
{
|
||||
dflags = DAMAGE_NO_PROTECTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
dflags = 0;
|
||||
}
|
||||
|
||||
T_Damage(other, self, self, vec3_origin, other->s.origin, vec3_origin,
|
||||
self->dmg, self->dmg, dflags, MOD_TRIGGER_HURT);
|
||||
}
|
||||
|
||||
void
|
||||
SP_trigger_hurt(edict_t *self)
|
||||
{
|
||||
InitTrigger(self);
|
||||
|
||||
self->noise_index = gi.soundindex("world/electro.wav");
|
||||
self->touch = hurt_touch;
|
||||
|
||||
if (!self->dmg)
|
||||
{
|
||||
self->dmg = 5;
|
||||
}
|
||||
|
||||
if (self->spawnflags & 1)
|
||||
{
|
||||
self->solid = SOLID_NOT;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->solid = SOLID_TRIGGER;
|
||||
}
|
||||
|
||||
if (self->spawnflags & 2)
|
||||
{
|
||||
self->use = hurt_use;
|
||||
}
|
||||
|
||||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
/*
|
||||
* ==============================================================================
|
||||
*
|
||||
* trigger_gravity
|
||||
*
|
||||
* ==============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* QUAKED trigger_gravity (.5 .5 .5) ?
|
||||
* Changes the touching entites gravity to
|
||||
* the value of "gravity". 1.0 is standard
|
||||
* gravity for the level.
|
||||
*/
|
||||
|
||||
void
|
||||
trigger_gravity_touch(edict_t *self, edict_t *other, cplane_t *plane,
|
||||
csurface_t *surf)
|
||||
{
|
||||
other->gravity = self->gravity;
|
||||
}
|
||||
|
||||
void
|
||||
SP_trigger_gravity(edict_t *self)
|
||||
{
|
||||
if (st.gravity == 0)
|
||||
{
|
||||
gi.dprintf("trigger_gravity without gravity set at %s\n", vtos(self->s.origin));
|
||||
G_FreeEdict(self);
|
||||
return;
|
||||
}
|
||||
|
||||
InitTrigger(self);
|
||||
self->gravity = atoi(st.gravity);
|
||||
self->touch = trigger_gravity_touch;
|
||||
}
|
||||
|
||||
/*
|
||||
* ==============================================================================
|
||||
*
|
||||
* trigger_monsterjump
|
||||
*
|
||||
* ==============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* QUAKED trigger_monsterjump (.5 .5 .5) ?
|
||||
* Walking monsters that touch this will jump in the direction of the trigger's angle
|
||||
* "speed" default to 200, the speed thrown forward
|
||||
* "height" default to 200, the speed thrown upwards
|
||||
*/
|
||||
void
|
||||
trigger_monsterjump_touch(edict_t *self, edict_t *other, cplane_t *plane,
|
||||
csurface_t *surf)
|
||||
{
|
||||
if (other->flags & (FL_FLY | FL_SWIM))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (other->svflags & SVF_DEADMONSTER)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(other->svflags & SVF_MONSTER))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* set XY even if not on ground, so the jump will clear lips */
|
||||
other->velocity[0] = self->movedir[0] * self->speed;
|
||||
other->velocity[1] = self->movedir[1] * self->speed;
|
||||
|
||||
if (!other->groundentity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
other->groundentity = NULL;
|
||||
other->velocity[2] = self->movedir[2];
|
||||
}
|
||||
|
||||
void
|
||||
SP_trigger_monsterjump(edict_t *self)
|
||||
{
|
||||
if (!self->speed)
|
||||
{
|
||||
self->speed = 200;
|
||||
}
|
||||
|
||||
if (!st.height)
|
||||
{
|
||||
st.height = 200;
|
||||
}
|
||||
|
||||
if (self->s.angles[YAW] == 0)
|
||||
{
|
||||
self->s.angles[YAW] = 360;
|
||||
}
|
||||
|
||||
InitTrigger(self);
|
||||
self->touch = trigger_monsterjump_touch;
|
||||
self->movedir[2] = st.height;
|
||||
}
|
||||
|
|
@ -386,7 +386,7 @@ range(edict_t *self, edict_t *other)
|
|||
vec3_t v;
|
||||
float len;
|
||||
|
||||
if (!self || !other)
|
||||
if (!self || !other)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1152,7 +1152,7 @@ plat2_operate(edict_t *ent, edict_t *other)
|
|||
float platCenter;
|
||||
edict_t *trigger;
|
||||
|
||||
if (!ent || !other)
|
||||
if (!ent || !other)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ void
|
|||
monster_fire_ionripper(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int flashtype, int effect)
|
||||
{
|
||||
if (!self)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ void
|
|||
monster_fire_heat(edict_t *self, vec3_t start, vec3_t dir, int damage,
|
||||
int speed, int flashtype)
|
||||
{
|
||||
if (!self)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ dabeam_hit(edict_t *self)
|
|||
vec3_t end;
|
||||
trace_t tr;
|
||||
|
||||
if (!self)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ monster_dabeam(edict_t *self)
|
|||
vec3_t last_movedir;
|
||||
vec3_t point;
|
||||
|
||||
if (!self)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1139,13 +1139,13 @@ static char *dm_statusbar =
|
|||
" pic 9 "
|
||||
"endif "
|
||||
|
||||
/* help / weapon icon */
|
||||
/* help / weapon icon */
|
||||
"if 11 "
|
||||
" xv 148 "
|
||||
" pic 11 "
|
||||
"endif "
|
||||
|
||||
/* frags */
|
||||
/* frags */
|
||||
"xr -50 "
|
||||
"yt 2 "
|
||||
"num 3 14 "
|
||||
|
|
|
@ -290,7 +290,8 @@ SP_target_secret(edict_t *ent)
|
|||
|
||||
/* Map quirk for mine3 */
|
||||
if (!Q_stricmp(level.mapname, "mine3") && (ent->s.origin[0] == 280) &&
|
||||
(ent->s.origin[1] == -2048) && (ent->s.origin[2] == -624))
|
||||
(ent->s.origin[1] == -2048) &&
|
||||
(ent->s.origin[2] == -624))
|
||||
{
|
||||
ent->message = "You have found a secret area.";
|
||||
}
|
||||
|
@ -1036,7 +1037,7 @@ SP_target_laser(edict_t *self)
|
|||
void
|
||||
target_mal_laser_on(edict_t *self)
|
||||
{
|
||||
if (!self)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1054,7 +1055,7 @@ target_mal_laser_on(edict_t *self)
|
|||
void
|
||||
target_mal_laser_off(edict_t *self)
|
||||
{
|
||||
if (!self)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1087,7 +1088,7 @@ target_mal_laser_use(edict_t *self, edict_t *other /* unused */, edict_t *activa
|
|||
void
|
||||
mal_laser_think(edict_t *self)
|
||||
{
|
||||
if (!self)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1100,7 +1101,7 @@ mal_laser_think(edict_t *self)
|
|||
void
|
||||
SP_target_mal_laser(edict_t *self)
|
||||
{
|
||||
if (!self)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -341,6 +341,14 @@ SP_trigger_relay(edict_t *self)
|
|||
self->use = trigger_relay_use;
|
||||
}
|
||||
|
||||
/*
|
||||
* ==============================================================================
|
||||
*
|
||||
* trigger_key
|
||||
*
|
||||
* ==============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* QUAKED trigger_key (.5 .5 .5) (-8 -8 -8) (8 8 8)
|
||||
* A relay trigger that only fires it's targets if player
|
||||
|
@ -489,6 +497,14 @@ SP_trigger_key(edict_t *self)
|
|||
self->use = trigger_key_use;
|
||||
}
|
||||
|
||||
/*
|
||||
* ==============================================================================
|
||||
*
|
||||
* trigger_counter
|
||||
*
|
||||
* ==============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* QUAKED trigger_counter (.5 .5 .5) ? nomessage
|
||||
*
|
||||
|
@ -558,6 +574,14 @@ SP_trigger_counter(edict_t *self)
|
|||
self->use = trigger_counter_use;
|
||||
}
|
||||
|
||||
/*
|
||||
* ==============================================================================
|
||||
*
|
||||
* trigger_always
|
||||
*
|
||||
* ==============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* QUAKED trigger_always (.5 .5 .5) (-8 -8 -8) (8 8 8)
|
||||
*
|
||||
|
@ -581,6 +605,14 @@ SP_trigger_always(edict_t *ent)
|
|||
G_UseTargets(ent, ent);
|
||||
}
|
||||
|
||||
/*
|
||||
* ==============================================================================
|
||||
*
|
||||
* trigger_push
|
||||
*
|
||||
* ==============================================================================
|
||||
*/
|
||||
|
||||
void
|
||||
trigger_push_touch(edict_t *self, edict_t *other, cplane_t *plane /* unused */,
|
||||
csurface_t *surf /* unused */)
|
||||
|
@ -632,7 +664,7 @@ trigger_effect(edict_t *self)
|
|||
vec3_t size;
|
||||
int i;
|
||||
|
||||
if (!self)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -656,7 +688,7 @@ trigger_effect(edict_t *self)
|
|||
void
|
||||
trigger_push_inactive(edict_t *self)
|
||||
{
|
||||
if (!self)
|
||||
if (!self)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -776,6 +808,14 @@ SP_trigger_push(edict_t *self)
|
|||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
/*
|
||||
* ==============================================================================
|
||||
*
|
||||
* trigger_hurt
|
||||
*
|
||||
* ==============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* QUAKED trigger_hurt (.5 .5 .5) ? START_OFF TOGGLE SILENT NO_PROTECTION SLOW
|
||||
*
|
||||
|
@ -805,7 +845,7 @@ hurt_use(edict_t *self, edict_t *other /* unused */,
|
|||
edict_t *touch[MAX_EDICTS], *hurtme;
|
||||
|
||||
self->solid = SOLID_TRIGGER;
|
||||
num = gi.BoxEdicts (self->absmin, self->absmax,
|
||||
num = gi.BoxEdicts(self->absmin, self->absmax,
|
||||
touch, MAX_EDICTS, AREA_SOLID);
|
||||
|
||||
/* Check for idle monsters in
|
||||
|
@ -915,6 +955,14 @@ SP_trigger_hurt(edict_t *self)
|
|||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
/*
|
||||
* ==============================================================================
|
||||
*
|
||||
* trigger_gravity
|
||||
*
|
||||
* ==============================================================================
|
||||
*/
|
||||
|
||||
void
|
||||
trigger_gravity_use(edict_t *self, edict_t *other /* unused */, edict_t *activator /* unused */)
|
||||
{
|
||||
|
@ -996,6 +1044,14 @@ SP_trigger_gravity(edict_t *self)
|
|||
gi.linkentity(self);
|
||||
}
|
||||
|
||||
/*
|
||||
* ==============================================================================
|
||||
*
|
||||
* trigger_monsterjump
|
||||
*
|
||||
* ==============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* QUAKED trigger_monsterjump (.5 .5 .5) ?
|
||||
* Walking monsters that touch this will jump in the direction of the trigger's angle
|
||||
|
|
Loading…
Reference in a new issue