diff --git a/Makefile b/Makefile index 3d8af15f..e03f4cfa 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,6 @@ # # # Dependencies: # # - SDL 1.2 # -# - libX11 # # - libGL # # - libvorbis # # - libogg # @@ -398,7 +397,7 @@ SDL_OPENGL_OBJS = $(patsubst %,build/refresher/%,$(SDL_OPENGL_OBJS_)) BASEQ2_OBJS = $(patsubst %,build/baseq2/%,$(BASEQ2_OBJS_)) -CTF_OBJS = $(patsubst %,build/baseq2/%,$(CTF_OBJS_)) +CTF_OBJS = $(patsubst %,build/ctf/%,$(CTF_OBJS_)) # ---------- diff --git a/src/game/baseq2/g_combat.c b/src/game/baseq2/g_combat.c index 4071f7a2..f9a015e4 100644 --- a/src/game/baseq2/g_combat.c +++ b/src/game/baseq2/g_combat.c @@ -288,7 +288,12 @@ CheckPowerArmor(edict_t *ent, vec3_t point, vec3_t normal, int damage, } else { +#ifdef CTF + damagePerCell = 1; +#else damagePerCell = 2; +#endif + pa_te_type = TE_SHIELD_SPARKS; damage = (2 * damage) / 3; } @@ -461,6 +466,15 @@ M_ReactToDamage(edict_t *targ, edict_t *attacker) (strcmp(attacker->classname, "monster_makron") != 0) && (strcmp(attacker->classname, "monster_jorg") != 0)) { +#ifdef CTF + if (targ->enemy) + { + if (targ->enemy->client) + { + targ->oldenemy = targ->enemy; + } + } +#else if (targ->enemy && targ->enemy->client) { targ->oldenemy = targ->enemy; @@ -480,6 +494,7 @@ M_ReactToDamage(edict_t *targ, edict_t *attacker) { targ->oldenemy = targ->enemy; } +#endif targ->enemy = attacker; @@ -729,7 +744,14 @@ T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker, SpawnDamage(te_sparks, point, normal); } +#ifdef CTF + if (!CTFMatchSetup()) + { + targ->health = targ->health - take; + } +#else targ->health = targ->health - take; +#endif if (targ->health <= 0) { @@ -760,7 +782,11 @@ T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker, } else if (client) { - if (!(targ->flags & FL_GODMODE) && (take)) + if (!(targ->flags & FL_GODMODE) && (take) +#ifdef CTF + && !CTFMatchSetup() +#endif + ) { targ->pain(targ, attacker, knockback, take); } diff --git a/src/game/baseq2/g_items.c b/src/game/baseq2/g_items.c index 23deada0..3422cabe 100644 --- a/src/game/baseq2/g_items.c +++ b/src/game/baseq2/g_items.c @@ -822,6 +822,7 @@ Drop_Ammo(edict_t *ent, gitem_t *item) dropped->count = ent->client->pers.inventory[index]; } +#ifndef CTF if (ent->client->pers.weapon && (ent->client->pers.weapon->tag == AMMO_GRENADES) && (item->tag == AMMO_GRENADES) && @@ -831,6 +832,7 @@ Drop_Ammo(edict_t *ent, gitem_t *item) G_FreeEdict(dropped); return; } +#endif ent->client->pers.inventory[index] -= dropped->count; ValidateSelectedItem(ent); @@ -1855,6 +1857,33 @@ gitem_t itemlist[] = { "misc/power2.wav misc/power1.wav" }, +#ifdef CTF + /* + * weapon_grapple (.3 .3 1) (-16 -16 -16) (16 16 16) + * always owned, never in the world + */ + { + "weapon_grapple", + NULL, + Use_Weapon, + NULL, + CTFWeapon_Grapple, + "misc/w_pkup.wav", + NULL, 0, + "models/weapons/grapple/tris.md2", + "w_grapple", + "Grapple", + 0, + 0, + NULL, + IT_WEAPON, + WEAP_GRAPPLE, + NULL, + 0, + "weapons/grapple/grfire.wav weapons/grapple/grpull.wav weapons/grapple/grhang.wav weapons/grapple/grreset.wav weapons/grapple/grhit.wav" + }, +#endif + /* weapon_blaster (.3 .3 1) (-16 -16 -16) (16 16 16) always owned, never in the world */ { diff --git a/src/game/baseq2/g_main.c b/src/game/baseq2/g_main.c index c7274f30..4c0df47e 100644 --- a/src/game/baseq2/g_main.c +++ b/src/game/baseq2/g_main.c @@ -234,6 +234,14 @@ EndDMLevel(void) return; } +#ifdef CTF + if (*level.forcemap) + { + BeginIntermission(CreateTargetChangeLevel(level.forcemap)); + return; + } +#endif + /* see if it's in the map list */ if (*sv_maplist->string) { @@ -393,13 +401,31 @@ ExitLevel(void) edict_t *ent; char command[256]; +#ifndef CTF Com_sprintf(command, sizeof(command), "gamemap \"%s\"\n", level.changemap); gi.AddCommandString(command); level.changemap = NULL; +#endif + level.exitintermission = 0; level.intermissiontime = 0; + +#ifdef CTF + if (CTFNextMap()) + { + return; + } + + Com_sprintf(command, sizeof(command), "gamemap \"%s\"\n", level.changemap); + gi.AddCommandString(command); +#endif + ClientEndServerFrames(); +#ifdef CTF + level.changemap = NULL; +#endif + /* clear some things before going to next level */ for (i = 0; i < maxclients->value; i++) { diff --git a/src/game/baseq2/g_misc.c b/src/game/baseq2/g_misc.c index 5b9ce12f..55d711a0 100644 --- a/src/game/baseq2/g_misc.c +++ b/src/game/baseq2/g_misc.c @@ -526,7 +526,9 @@ path_corner_touch(edict_t *self, edict_t *other, cplane_t *plane /* unused */, v[2] -= other->mins[2]; VectorCopy(v, other->s.origin); next = G_PickTarget(next->target); +#ifndef CTF other->s.event = EV_OTHER_TELEPORT; +#endif } other->goalentity = other->movetarget = next; @@ -697,6 +699,19 @@ TH_viewthing(edict_t *ent) ent->s.frame = (ent->s.frame + 1) % 7; ent->nextthink = level.time + FRAMETIME; + +#ifdef CTF + static int robotron[4]; + + if (ent->spawnflags) + { + if (ent->s.frame == 0) + { + ent->spawnflags = (ent->spawnflags + 1) % 4 + 1; + ent->s.modelindex = robotron[ent->spawnflags - 1]; + } + } +#endif } void @@ -2500,8 +2515,10 @@ func_clock_think(edict_t *self) if (!(self->spawnflags & 8)) { +#ifndef CTF self->think = G_FreeEdict; self->nextthink = level.time + 1; +#endif return; } diff --git a/src/game/baseq2/g_phys.c b/src/game/baseq2/g_phys.c index cac79a9c..a2d1d1c6 100644 --- a/src/game/baseq2/g_phys.c +++ b/src/game/baseq2/g_phys.c @@ -76,10 +76,12 @@ SV_TestEntityPosition(edict_t *ent) if (trace.startsolid) { +#ifndef CTF if ((ent->svflags & SVF_DEADMONSTER) && (trace.ent->client || (trace.ent->svflags & SVF_MONSTER))) { return NULL; } +#endif return g_edicts; } @@ -526,11 +528,13 @@ retry: trace = gi.trace(start, ent->mins, ent->maxs, end, ent, mask); +#ifndef CTF if (trace.startsolid || trace.allsolid) { mask ^= CONTENTS_DEADMONSTER; trace = gi.trace (start, ent->mins, ent->maxs, end, ent, mask); } +#endif VectorCopy(trace.endpos, ent->s.origin); gi.linkentity(ent); diff --git a/src/game/baseq2/g_spawn.c b/src/game/baseq2/g_spawn.c index 016826b1..306a301f 100644 --- a/src/game/baseq2/g_spawn.c +++ b/src/game/baseq2/g_spawn.c @@ -1026,6 +1026,7 @@ SP_worldspawn(edict_t *ent) gi.modelindex("#w_hyperblaster.md2"); gi.modelindex("#w_railgun.md2"); gi.modelindex("#w_bfg.md2"); + gi.modelindex("#w_grapple.md2"); /* ------------------- */ diff --git a/src/game/ctf/g_combat.c b/src/game/ctf/g_combat.c index 1d33ca85..83503136 100644 --- a/src/game/ctf/g_combat.c +++ b/src/game/ctf/g_combat.c @@ -1,98 +1,156 @@ /* -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. - -*/ -// g_combat.c + * 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. + * + */ +/* g_combat.c */ #include "g_local.h" /* -============ -CanDamage - -Returns true if the inflictor can directly damage the target. Used for -explosions and melee attacks. -============ -*/ -qboolean CanDamage (edict_t *targ, edict_t *inflictor) + * ============ + * CanDamage + * + * Returns true if the inflictor can directly damage the target. Used for + * explosions and melee attacks. + * ============ + */ +qboolean +CanDamage(edict_t *targ, edict_t *inflictor) { - vec3_t dest; - trace_t trace; + vec3_t dest; + trace_t trace; - // bmodels need special checking because their origin is 0,0,0 + /* bmodels need special checking because their origin is 0,0,0 */ if (targ->movetype == MOVETYPE_PUSH) { - VectorAdd (targ->absmin, targ->absmax, dest); - VectorScale (dest, 0.5, dest); - trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID); + VectorAdd(targ->absmin, targ->absmax, dest); + VectorScale(dest, 0.5, dest); + trace = gi.trace(inflictor->s.origin, + vec3_origin, + vec3_origin, + dest, + inflictor, + MASK_SOLID); + if (trace.fraction == 1.0) + { return true; + } + if (trace.ent == targ) + { return true; + } + return false; } - - trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, targ->s.origin, inflictor, MASK_SOLID); - if (trace.fraction == 1.0) - return true; - VectorCopy (targ->s.origin, dest); + trace = gi.trace(inflictor->s.origin, + vec3_origin, + vec3_origin, + targ->s.origin, + inflictor, + MASK_SOLID); + + if (trace.fraction == 1.0) + { + return true; + } + + VectorCopy(targ->s.origin, dest); dest[0] += 15.0; dest[1] += 15.0; - trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID); - if (trace.fraction == 1.0) - return true; + trace = gi.trace(inflictor->s.origin, + vec3_origin, + vec3_origin, + dest, + inflictor, + MASK_SOLID); - VectorCopy (targ->s.origin, dest); + if (trace.fraction == 1.0) + { + return true; + } + + VectorCopy(targ->s.origin, dest); dest[0] += 15.0; dest[1] -= 15.0; - trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID); - if (trace.fraction == 1.0) - return true; + trace = gi.trace(inflictor->s.origin, + vec3_origin, + vec3_origin, + dest, + inflictor, + MASK_SOLID); - VectorCopy (targ->s.origin, dest); + if (trace.fraction == 1.0) + { + return true; + } + + VectorCopy(targ->s.origin, dest); dest[0] -= 15.0; dest[1] += 15.0; - trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID); - if (trace.fraction == 1.0) - return true; + trace = gi.trace(inflictor->s.origin, + vec3_origin, + vec3_origin, + dest, + inflictor, + MASK_SOLID); - VectorCopy (targ->s.origin, dest); + if (trace.fraction == 1.0) + { + return true; + } + + VectorCopy(targ->s.origin, dest); dest[0] -= 15.0; dest[1] -= 15.0; - trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID); - if (trace.fraction == 1.0) - return true; + trace = gi.trace(inflictor->s.origin, + vec3_origin, + vec3_origin, + dest, + inflictor, + MASK_SOLID); + if (trace.fraction == 1.0) + { + return true; + } return false; } - /* -============ -Killed -============ -*/ -void Killed (edict_t *targ, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) + * ============ + * Killed + * ============ + */ +void +Killed(edict_t *targ, + edict_t *inflictor, + edict_t *attacker, + int damage, + vec3_t point) { if (targ->health < -999) + { targ->health = -999; + } targ->enemy = attacker; @@ -101,93 +159,112 @@ void Killed (edict_t *targ, edict_t *inflictor, edict_t *attacker, int damage, v if (!(targ->monsterinfo.aiflags & AI_GOOD_GUY)) { level.killed_monsters++; + if (coop->value && attacker->client) + { attacker->client->resp.score++; - // medics won't heal monsters that they kill themselves + } + + /* medics won't heal monsters that they kill themselves */ if (strcmp(attacker->classname, "monster_medic") == 0) + { targ->owner = attacker; + } } } - if (targ->movetype == MOVETYPE_PUSH || targ->movetype == MOVETYPE_STOP || targ->movetype == MOVETYPE_NONE) - { // doors, triggers, etc - targ->die (targ, inflictor, attacker, damage, point); + if ((targ->movetype == MOVETYPE_PUSH) || + (targ->movetype == MOVETYPE_STOP) || (targ->movetype == MOVETYPE_NONE)) + { /* doors, triggers, etc */ + targ->die(targ, inflictor, attacker, damage, point); return; } if ((targ->svflags & SVF_MONSTER) && (targ->deadflag != DEAD_DEAD)) { targ->touch = NULL; - monster_death_use (targ); + monster_death_use(targ); } - targ->die (targ, inflictor, attacker, damage, point); + targ->die(targ, inflictor, attacker, damage, point); } - /* -================ -SpawnDamage -================ -*/ -void SpawnDamage (int type, vec3_t origin, vec3_t normal, int damage) + * ================ + * SpawnDamage + * ================ + */ +void +SpawnDamage(int type, vec3_t origin, vec3_t normal, int damage) { if (damage > 255) + { damage = 255; - gi.WriteByte (svc_temp_entity); - gi.WriteByte (type); - gi.WritePosition (origin); - gi.WriteDir (normal); - gi.multicast (origin, MULTICAST_PVS); + } + + gi.WriteByte(svc_temp_entity); + gi.WriteByte(type); + gi.WritePosition(origin); + gi.WriteDir(normal); + gi.multicast(origin, MULTICAST_PVS); } - /* -============ -T_Damage - -targ entity that is being damaged -inflictor entity that is causing the damage -attacker entity that caused the inflictor to damage targ - example: targ=monster, inflictor=rocket, attacker=player - -dir direction of the attack -point point at which the damage is being inflicted -normal normal vector from that point -damage amount of damage being inflicted -knockback force to be applied against targ as a result of the damage - -dflags these flags are used to control how T_Damage works - DAMAGE_RADIUS damage was indirect (from a nearby explosion) - DAMAGE_NO_ARMOR armor does not protect from this damage - DAMAGE_ENERGY damage is from an energy based weapon - DAMAGE_NO_KNOCKBACK do not affect velocity, just view angles - DAMAGE_BULLET damage is from a bullet (used for ricochets) - DAMAGE_NO_PROTECTION kills godmode, armor, everything -============ -*/ -static int CheckPowerArmor (edict_t *ent, vec3_t point, vec3_t normal, int damage, int dflags) + * ============ + * T_Damage + * + * targ entity that is being damaged + * inflictor entity that is causing the damage + * attacker entity that caused the inflictor to damage targ + * example: targ=monster, inflictor=rocket, attacker=player + * + * dir direction of the attack + * point point at which the damage is being inflicted + * normal normal vector from that point + * damage amount of damage being inflicted + * knockback force to be applied against targ as a result of the damage + * + * dflags these flags are used to control how T_Damage works + * DAMAGE_RADIUS damage was indirect (from a nearby explosion) + * DAMAGE_NO_ARMOR armor does not protect from this damage + * DAMAGE_ENERGY damage is from an energy based weapon + * DAMAGE_NO_KNOCKBACK do not affect velocity, just view angles + * DAMAGE_BULLET damage is from a bullet (used for ricochets) + * DAMAGE_NO_PROTECTION kills godmode, armor, everything + * ============ + */ +static int +CheckPowerArmor(edict_t *ent, + vec3_t point, + vec3_t normal, + int damage, + int dflags) { - gclient_t *client; - int save; - int power_armor_type; - int index = 0; - int damagePerCell; - int pa_te_type; - int power = 0; - int power_used; + gclient_t *client; + int save; + int power_armor_type; + int index = 0; + int damagePerCell; + int pa_te_type; + int power = 0; + int power_used; if (!damage) + { return 0; + } client = ent->client; if (dflags & DAMAGE_NO_ARMOR) + { return 0; + } if (client) { - power_armor_type = PowerArmorType (ent); + power_armor_type = PowerArmorType(ent); + if (power_armor_type != POWER_ARMOR_NONE) { index = ITEM_INDEX(FindItem("Cells")); @@ -201,26 +278,36 @@ static int CheckPowerArmor (edict_t *ent, vec3_t point, vec3_t normal, int damag index = 0; } else + { return 0; + } if (power_armor_type == POWER_ARMOR_NONE) + { return 0; + } + if (!power) + { return 0; + } if (power_armor_type == POWER_ARMOR_SCREEN) { - vec3_t vec; - float dot; - vec3_t forward; + vec3_t vec; + float dot; + vec3_t forward; + + /* only works if damage point is in front */ + AngleVectors(ent->s.angles, forward, NULL, NULL); + VectorSubtract(point, ent->s.origin, vec); + VectorNormalize(vec); + dot = DotProduct(vec, forward); - // only works if damage point is in front - AngleVectors (ent->s.angles, forward, NULL, NULL); - VectorSubtract (point, ent->s.origin, vec); - VectorNormalize (vec); - dot = DotProduct (vec, forward); if (dot <= 0.3) + { return 0; + } damagePerCell = 1; pa_te_type = TE_SCREEN_SPARKS; @@ -228,92 +315,134 @@ static int CheckPowerArmor (edict_t *ent, vec3_t point, vec3_t normal, int damag } else { - damagePerCell = 1; // power armor is weaker in CTF + damagePerCell = 1; /* power armor is weaker in CTF */ pa_te_type = TE_SHIELD_SPARKS; damage = (2 * damage) / 3; } save = power * damagePerCell; - if (!save) - return 0; - if (save > damage) - save = damage; - SpawnDamage (pa_te_type, point, normal, save); + if (!save) + { + return 0; + } + + if (save > damage) + { + save = damage; + } + + SpawnDamage(pa_te_type, point, normal, save); ent->powerarmor_time = level.time + 0.2; power_used = save / damagePerCell; if (client) + { client->pers.inventory[index] -= power_used; + } else + { ent->monsterinfo.power_armor_power -= power_used; + } + return save; } -static int CheckArmor (edict_t *ent, vec3_t point, vec3_t normal, int damage, int te_sparks, int dflags) +static int +CheckArmor(edict_t *ent, + vec3_t point, + vec3_t normal, + int damage, + int te_sparks, + int dflags) { - gclient_t *client; - int save; - int index; - gitem_t *armor; + gclient_t *client; + int save; + int index; + gitem_t *armor; if (!damage) + { return 0; + } client = ent->client; if (!client) + { return 0; + } if (dflags & DAMAGE_NO_ARMOR) + { return 0; + } + + index = ArmorIndex(ent); - index = ArmorIndex (ent); if (!index) + { return 0; + } - armor = GetItemByIndex (index); + armor = GetItemByIndex(index); if (dflags & DAMAGE_ENERGY) - save = ceil(((gitem_armor_t *)armor->info)->energy_protection*damage); + { + save = ceil(((gitem_armor_t *)armor->info)->energy_protection * damage); + } else - save = ceil(((gitem_armor_t *)armor->info)->normal_protection*damage); + { + save = ceil(((gitem_armor_t *)armor->info)->normal_protection * damage); + } + if (save >= client->pers.inventory[index]) + { save = client->pers.inventory[index]; + } if (!save) + { return 0; + } client->pers.inventory[index] -= save; - SpawnDamage (te_sparks, point, normal, save); + SpawnDamage(te_sparks, point, normal, save); return save; } -void M_ReactToDamage (edict_t *targ, edict_t *attacker) +void +M_ReactToDamage(edict_t *targ, edict_t *attacker) { if (!(attacker->client) && !(attacker->svflags & SVF_MONSTER)) + { return; + } - if (attacker == targ || attacker == targ->enemy) + if ((attacker == targ) || (attacker == targ->enemy)) + { return; + } - // if we are a good guy monster and our attacker is a player - // or another good guy, do not get mad at them + /* if we are a good guy monster and our attacker is a player */ + /* or another good guy, do not get mad at them */ if (targ->monsterinfo.aiflags & AI_GOOD_GUY) { if (attacker->client || (attacker->monsterinfo.aiflags & AI_GOOD_GUY)) + { return; + } } - // we now know that we are not both good guys + /* we now know that we are not both good guys */ - // if attacker is a client, get mad at them because he's good and we're not + /* if attacker is a client, get mad at them because he's good and we're not */ if (attacker->client) { - // this can only happen in coop (both new and old enemies are clients) - // only switch if can't see the current enemy + /* this can only happen in coop (both new and old enemies are clients) */ + /* only switch if can't see the current enemy */ if (targ->enemy && targ->enemy->client) { if (visible(targ, targ->enemy)) @@ -321,273 +450,391 @@ void M_ReactToDamage (edict_t *targ, edict_t *attacker) targ->oldenemy = attacker; return; } + targ->oldenemy = targ->enemy; } + targ->enemy = attacker; + if (!(targ->monsterinfo.aiflags & AI_DUCKED)) - FoundTarget (targ); + { + FoundTarget(targ); + } + return; } - // it's the same base (walk/swim/fly) type and a different classname and it's not a tank - // (they spray too much), get mad at them - if (((targ->flags & (FL_FLY|FL_SWIM)) == (attacker->flags & (FL_FLY|FL_SWIM))) && - (strcmp (targ->classname, attacker->classname) != 0) && - (strcmp(attacker->classname, "monster_tank") != 0) && - (strcmp(attacker->classname, "monster_supertank") != 0) && - (strcmp(attacker->classname, "monster_makron") != 0) && - (strcmp(attacker->classname, "monster_jorg") != 0) ) + /* it's the same base (walk/swim/fly) type and a different classname and it's not a tank */ + /* (they spray too much), get mad at them */ + if (((targ->flags & (FL_FLY | FL_SWIM)) == + (attacker->flags & (FL_FLY | FL_SWIM))) && + (strcmp(targ->classname, attacker->classname) != 0) && + (strcmp(attacker->classname, "monster_tank") != 0) && + (strcmp(attacker->classname, "monster_supertank") != 0) && + (strcmp(attacker->classname, "monster_makron") != 0) && + (strcmp(attacker->classname, "monster_jorg") != 0)) { if (targ->enemy) + { if (targ->enemy->client) + { targ->oldenemy = targ->enemy; + } + } + targ->enemy = attacker; + if (!(targ->monsterinfo.aiflags & AI_DUCKED)) - FoundTarget (targ); + { + FoundTarget(targ); + } } else - // otherwise get mad at whoever they are mad at (help our buddy) + /* otherwise get mad at whoever they are mad at (help our buddy) */ { if (targ->enemy) + { if (targ->enemy->client) + { targ->oldenemy = targ->enemy; + } + } + targ->enemy = attacker->enemy; - FoundTarget (targ); + FoundTarget(targ); } } -qboolean CheckTeamDamage (edict_t *targ, edict_t *attacker) +qboolean +CheckTeamDamage(edict_t *targ, edict_t *attacker) { - //ZOID + /* ZOID */ if (ctf->value && targ->client && attacker->client) - if (targ->client->resp.ctf_team == attacker->client->resp.ctf_team && - targ != attacker) + { + if ((targ->client->resp.ctf_team == attacker->client->resp.ctf_team) && + (targ != attacker)) + { return true; - //ZOID + } + } - //FIXME make the next line real and uncomment this block + /* ZOID */ + + /* FIXME make the next line real and uncomment this block */ return false; } -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_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) { - gclient_t *client; - int take; - int save; - int asave; - int psave; - int te_sparks; + gclient_t *client; + int take; + int save; + int asave; + int psave; + int te_sparks; if (!targ->takedamage) - return; - - // friendly fire avoidance - // if enabled you can't hurt teammates (but you can hurt yourself) - // knockback still occurs - if ((targ != attacker) && ((deathmatch->value && ((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS))) || coop->value)) { - if (OnSameTeam (targ, attacker)) + return; + } + + /* friendly fire avoidance */ + /* if enabled you can't hurt teammates (but you can hurt yourself) */ + /* knockback still occurs */ + if ((targ != attacker) && + ((deathmatch->value && + ((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS))) || + coop->value)) + { + if (OnSameTeam(targ, attacker)) { if ((int)(dmflags->value) & DF_NO_FRIENDLY_FIRE) + { damage = 0; + } else + { mod |= MOD_FRIENDLY_FIRE; + } } } + meansOfDeath = mod; - // easy mode takes half damage - if (skill->value == 0 && deathmatch->value == 0 && targ->client) + /* easy mode takes half damage */ + if ((skill->value == 0) && (deathmatch->value == 0) && targ->client) { damage *= 0.5; + if (!damage) + { damage = 1; + } } client = targ->client; if (dflags & DAMAGE_BULLET) + { te_sparks = TE_BULLET_SPARKS; + } else + { te_sparks = TE_SPARKS; + } VectorNormalize(dir); - // bonus damage for suprising a monster - if (!(dflags & DAMAGE_RADIUS) && (targ->svflags & SVF_MONSTER) && (attacker->client) && (!targ->enemy) && (targ->health > 0)) + /* bonus damage for suprising a monster */ + if (!(dflags & DAMAGE_RADIUS) && (targ->svflags & SVF_MONSTER) && + (attacker->client) && (!targ->enemy) && (targ->health > 0)) + { damage *= 2; + } - //ZOID - //strength tech + /* ZOID */ + /* strength tech */ damage = CTFApplyStrength(attacker, damage); - //ZOID + /* ZOID */ if (targ->flags & FL_NO_KNOCKBACK) + { knockback = 0; + } - // figure momentum add + /* figure momentum add */ if (!(dflags & DAMAGE_NO_KNOCKBACK)) { - if ((knockback) && (targ->movetype != MOVETYPE_NONE) && (targ->movetype != MOVETYPE_BOUNCE) && (targ->movetype != MOVETYPE_PUSH) && (targ->movetype != MOVETYPE_STOP)) + if ((knockback) && (targ->movetype != MOVETYPE_NONE) && + (targ->movetype != MOVETYPE_BOUNCE) && + (targ->movetype != MOVETYPE_PUSH) && + (targ->movetype != MOVETYPE_STOP)) { - vec3_t kvel; - float mass; + vec3_t kvel; + float mass; if (targ->mass < 50) + { mass = 50; + } else + { mass = targ->mass; + } - if (targ->client && attacker == targ) - VectorScale (dir, 1600.0 * (float)knockback / mass, kvel); // the rocket jump hack... + if (targ->client && (attacker == targ)) + { + VectorScale(dir, 1600.0 * (float)knockback / mass, kvel); /* the rocket jump hack... */ + } else - VectorScale (dir, 500.0 * (float)knockback / mass, kvel); + { + VectorScale(dir, 500.0 * (float)knockback / mass, kvel); + } - VectorAdd (targ->velocity, kvel, targ->velocity); + VectorAdd(targ->velocity, kvel, targ->velocity); } } take = damage; save = 0; - // check for godmode - if ( (targ->flags & FL_GODMODE) && !(dflags & DAMAGE_NO_PROTECTION) ) + /* check for godmode */ + if ((targ->flags & FL_GODMODE) && !(dflags & DAMAGE_NO_PROTECTION)) { take = 0; save = damage; - SpawnDamage (te_sparks, point, normal, save); + SpawnDamage(te_sparks, point, normal, save); } - // check for invincibility - if ((client && client->invincible_framenum > level.framenum ) && !(dflags & DAMAGE_NO_PROTECTION)) + /* check for invincibility */ + if ((client && + (client->invincible_framenum > level.framenum)) && + !(dflags & DAMAGE_NO_PROTECTION)) { 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; } + take = 0; save = damage; } - //ZOID - //team armor protect + /* ZOID */ + /* team armor protect */ if (ctf->value && targ->client && attacker->client && - targ->client->resp.ctf_team == attacker->client->resp.ctf_team && - targ != attacker && ((int)dmflags->value & DF_ARMOR_PROTECT)) { + (targ->client->resp.ctf_team == attacker->client->resp.ctf_team) && + (targ != attacker) && ((int)dmflags->value & DF_ARMOR_PROTECT)) + { psave = asave = 0; - } else { - //ZOID - psave = CheckPowerArmor (targ, point, normal, take, dflags); + } + else + { + /* ZOID */ + psave = CheckPowerArmor(targ, point, normal, take, dflags); take -= psave; - asave = CheckArmor (targ, point, normal, take, te_sparks, dflags); + asave = CheckArmor(targ, point, normal, take, te_sparks, dflags); take -= asave; } - //treat cheat/powerup savings the same as armor + /* treat cheat/powerup savings the same as armor */ asave += save; - //ZOID - //resistance tech + /* ZOID */ + /* resistance tech */ take = CTFApplyResistance(targ, take); - //ZOID + /* ZOID */ - // team damage avoidance - if (!(dflags & DAMAGE_NO_PROTECTION) && CheckTeamDamage (targ, attacker)) + /* team damage avoidance */ + if (!(dflags & DAMAGE_NO_PROTECTION) && CheckTeamDamage(targ, attacker)) + { return; + } - //ZOID + /* ZOID */ CTFCheckHurtCarrier(targ, attacker); - //ZOID + /* ZOID */ - // do the damage + /* do the damage */ if (take) { if ((targ->svflags & SVF_MONSTER) || (client)) - SpawnDamage (TE_BLOOD, point, normal, take); + { + SpawnDamage(TE_BLOOD, point, normal, take); + } else - SpawnDamage (te_sparks, point, normal, take); + { + SpawnDamage(te_sparks, point, normal, take); + } if (!CTFMatchSetup()) + { targ->health = targ->health - take; - + } + if (targ->health <= 0) { if ((targ->svflags & SVF_MONSTER) || (client)) + { targ->flags |= FL_NO_KNOCKBACK; - Killed (targ, inflictor, attacker, take, point); + } + + Killed(targ, inflictor, attacker, take, point); return; } } if (targ->svflags & SVF_MONSTER) { - M_ReactToDamage (targ, attacker); + M_ReactToDamage(targ, attacker); + if (!(targ->monsterinfo.aiflags & AI_DUCKED) && (take)) { - targ->pain (targ, attacker, knockback, take); - // nightmare mode monsters don't go into pain frames often + targ->pain(targ, attacker, knockback, take); + + /* nightmare mode monsters don't go into pain frames often */ if (skill->value == 3) + { targ->pain_debounce_time = level.time + 5; + } } } else if (client) { if (!(targ->flags & FL_GODMODE) && (take) && !CTFMatchSetup()) - targ->pain (targ, attacker, knockback, take); + { + targ->pain(targ, attacker, knockback, take); + } } else if (take) { if (targ->pain) - targ->pain (targ, attacker, knockback, take); + { + targ->pain(targ, attacker, knockback, take); + } } - // add to the damage inflicted on a player this frame - // the total will be turned into screen blends and view angle kicks - // at the end of the frame + /* add to the damage inflicted on a player this frame */ + /* the total will be turned into screen blends and view angle kicks */ + /* at the end of the frame */ if (client) { client->damage_parmor += psave; client->damage_armor += asave; client->damage_blood += take; client->damage_knockback += knockback; - VectorCopy (point, client->damage_from); + VectorCopy(point, client->damage_from); } } - /* -============ -T_RadiusDamage -============ -*/ -void T_RadiusDamage (edict_t *inflictor, edict_t *attacker, float damage, edict_t *ignore, float radius, int mod) + * ============ + * T_RadiusDamage + * ============ + */ +void +T_RadiusDamage(edict_t *inflictor, + edict_t *attacker, + float damage, + edict_t *ignore, + float radius, + int mod) { - float points; - edict_t *ent = NULL; - vec3_t v; - vec3_t dir; + float points; + edict_t *ent = NULL; + vec3_t v; + vec3_t dir; while ((ent = findradius(ent, inflictor->s.origin, radius)) != NULL) { if (ent == ignore) + { continue; - if (!ent->takedamage) - continue; + } + + if (!ent->takedamage) + { + continue; + } + + VectorAdd(ent->mins, ent->maxs, v); + VectorMA(ent->s.origin, 0.5, v, v); + VectorSubtract(inflictor->s.origin, v, v); + points = damage - 0.5 * VectorLength(v); - VectorAdd (ent->mins, ent->maxs, v); - VectorMA (ent->s.origin, 0.5, v, v); - VectorSubtract (inflictor->s.origin, v, v); - points = damage - 0.5 * VectorLength (v); if (ent == attacker) + { points = points * 0.5; + } + if (points > 0) { - if (CanDamage (ent, inflictor)) + if (CanDamage(ent, inflictor)) { - VectorSubtract (ent->s.origin, inflictor->s.origin, dir); - T_Damage (ent, inflictor, attacker, dir, inflictor->s.origin, vec3_origin, (int)points, (int)points, DAMAGE_RADIUS, mod); + VectorSubtract(ent->s.origin, inflictor->s.origin, dir); + T_Damage(ent, + inflictor, + attacker, + dir, + inflictor->s.origin, + vec3_origin, + (int)points, + (int)points, + DAMAGE_RADIUS, + mod); } } } diff --git a/src/game/ctf/g_func.c b/src/game/ctf/g_func.c index ccdc00db..7e41aae6 100644 --- a/src/game/ctf/g_func.c +++ b/src/game/ctf/g_func.c @@ -1,128 +1,139 @@ /* -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. - -*/ + * 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. + * + */ #include "g_local.h" /* -========================================================= + * ========================================================= + * + * PLATS + * + * movement options: + * + * linear + * smooth start, hard stop + * smooth start, smooth stop + * + * start + * end + * acceleration + * speed + * deceleration + * begin sound + * end sound + * target fired when reaching end + * wait at end + * + * object characteristics that use move segments + * --------------------------------------------- + * movetype_push, or movetype_stop + * action when touched + * action when blocked + * action when used + * disabled? + * auto trigger spawning + * + * + * ========================================================= + */ - PLATS +#define PLAT_LOW_TRIGGER 1 - movement options: +#define STATE_TOP 0 +#define STATE_BOTTOM 1 +#define STATE_UP 2 +#define STATE_DOWN 3 - linear - smooth start, hard stop - smooth start, smooth stop +#define DOOR_START_OPEN 1 +#define DOOR_REVERSE 2 +#define DOOR_CRUSHER 4 +#define DOOR_NOMONSTER 8 +#define DOOR_TOGGLE 32 +#define DOOR_X_AXIS 64 +#define DOOR_Y_AXIS 128 - start - end - acceleration - speed - deceleration - begin sound - end sound - target fired when reaching end - wait at end +/* */ +/* Support routines for movement (changes in origin using velocity) */ +/* */ - object characteristics that use move segments - --------------------------------------------- - movetype_push, or movetype_stop - action when touched - action when blocked - action when used - disabled? - auto trigger spawning - - -========================================================= -*/ - -#define PLAT_LOW_TRIGGER 1 - -#define STATE_TOP 0 -#define STATE_BOTTOM 1 -#define STATE_UP 2 -#define STATE_DOWN 3 - -#define DOOR_START_OPEN 1 -#define DOOR_REVERSE 2 -#define DOOR_CRUSHER 4 -#define DOOR_NOMONSTER 8 -#define DOOR_TOGGLE 32 -#define DOOR_X_AXIS 64 -#define DOOR_Y_AXIS 128 - - -// -// Support routines for movement (changes in origin using velocity) -// - -void Move_Done (edict_t *ent) +void +Move_Done(edict_t *ent) { - VectorClear (ent->velocity); - ent->moveinfo.endfunc (ent); + VectorClear(ent->velocity); + ent->moveinfo.endfunc(ent); } -void Move_Final (edict_t *ent) +void +Move_Final(edict_t *ent) { if (ent->moveinfo.remaining_distance == 0) { - Move_Done (ent); + Move_Done(ent); return; } - VectorScale (ent->moveinfo.dir, ent->moveinfo.remaining_distance / FRAMETIME, ent->velocity); + VectorScale(ent->moveinfo.dir, + ent->moveinfo.remaining_distance / FRAMETIME, + ent->velocity); ent->think = Move_Done; ent->nextthink = level.time + FRAMETIME; } -void Move_Begin (edict_t *ent) +void +Move_Begin(edict_t *ent) { - float frames; + float frames; if ((ent->moveinfo.speed * FRAMETIME) >= ent->moveinfo.remaining_distance) { - Move_Final (ent); + Move_Final(ent); return; } - VectorScale (ent->moveinfo.dir, ent->moveinfo.speed, ent->velocity); - frames = floor((ent->moveinfo.remaining_distance / ent->moveinfo.speed) / FRAMETIME); - ent->moveinfo.remaining_distance -= frames * ent->moveinfo.speed * FRAMETIME; + + VectorScale(ent->moveinfo.dir, ent->moveinfo.speed, ent->velocity); + frames = floor( + (ent->moveinfo.remaining_distance / + ent->moveinfo.speed) / FRAMETIME); + ent->moveinfo.remaining_distance -= frames * ent->moveinfo.speed * + FRAMETIME; ent->nextthink = level.time + (frames * FRAMETIME); ent->think = Move_Final; } -void Think_AccelMove (edict_t *ent); +void Think_AccelMove(edict_t *ent); -void Move_Calc (edict_t *ent, vec3_t dest, void(*func)(edict_t*)) +void +Move_Calc(edict_t *ent, vec3_t dest, void (*func)(edict_t *)) { - VectorClear (ent->velocity); - VectorSubtract (dest, ent->s.origin, ent->moveinfo.dir); - ent->moveinfo.remaining_distance = VectorNormalize (ent->moveinfo.dir); + VectorClear(ent->velocity); + VectorSubtract(dest, ent->s.origin, ent->moveinfo.dir); + ent->moveinfo.remaining_distance = VectorNormalize(ent->moveinfo.dir); ent->moveinfo.endfunc = func; - if (ent->moveinfo.speed == ent->moveinfo.accel && ent->moveinfo.speed == ent->moveinfo.decel) + if ((ent->moveinfo.speed == ent->moveinfo.accel) && + (ent->moveinfo.speed == ent->moveinfo.decel)) { - if (level.current_entity == ((ent->flags & FL_TEAMSLAVE) ? ent->teammaster : ent)) + if (level.current_entity == + ((ent->flags & FL_TEAMSLAVE) ? ent->teammaster : ent)) { - Move_Begin (ent); + Move_Begin(ent); } else { @@ -132,87 +143,100 @@ void Move_Calc (edict_t *ent, vec3_t dest, void(*func)(edict_t*)) } else { - // accelerative + /* accelerative */ ent->moveinfo.current_speed = 0; ent->think = Think_AccelMove; ent->nextthink = level.time + FRAMETIME; } } +/* */ +/* Support routines for angular movement (changes in angle using avelocity) */ +/* */ -// -// Support routines for angular movement (changes in angle using avelocity) -// - -void AngleMove_Done (edict_t *ent) +void +AngleMove_Done(edict_t *ent) { - VectorClear (ent->avelocity); - ent->moveinfo.endfunc (ent); + VectorClear(ent->avelocity); + ent->moveinfo.endfunc(ent); } -void AngleMove_Final (edict_t *ent) +void +AngleMove_Final(edict_t *ent) { - vec3_t move; + vec3_t move; if (ent->moveinfo.state == STATE_UP) - VectorSubtract (ent->moveinfo.end_angles, ent->s.angles, move); - else - VectorSubtract (ent->moveinfo.start_angles, ent->s.angles, move); - - if (VectorCompare (move, vec3_origin)) { - AngleMove_Done (ent); + VectorSubtract(ent->moveinfo.end_angles, ent->s.angles, move); + } + else + { + VectorSubtract(ent->moveinfo.start_angles, ent->s.angles, move); + } + + if (VectorCompare(move, vec3_origin)) + { + AngleMove_Done(ent); return; } - VectorScale (move, 1.0/FRAMETIME, ent->avelocity); + VectorScale(move, 1.0 / FRAMETIME, ent->avelocity); ent->think = AngleMove_Done; ent->nextthink = level.time + FRAMETIME; } -void AngleMove_Begin (edict_t *ent) +void +AngleMove_Begin(edict_t *ent) { - vec3_t destdelta; - float len; - float traveltime; - float frames; + vec3_t destdelta; + float len; + float traveltime; + float frames; - // set destdelta to the vector needed to move + /* set destdelta to the vector needed to move */ if (ent->moveinfo.state == STATE_UP) - VectorSubtract (ent->moveinfo.end_angles, ent->s.angles, destdelta); + { + VectorSubtract(ent->moveinfo.end_angles, ent->s.angles, destdelta); + } else - VectorSubtract (ent->moveinfo.start_angles, ent->s.angles, destdelta); - - // calculate length of vector - len = VectorLength (destdelta); - - // divide by speed to get time to reach dest + { + VectorSubtract(ent->moveinfo.start_angles, ent->s.angles, destdelta); + } + + /* calculate length of vector */ + len = VectorLength(destdelta); + + /* divide by speed to get time to reach dest */ traveltime = len / ent->moveinfo.speed; if (traveltime < FRAMETIME) { - AngleMove_Final (ent); + AngleMove_Final(ent); return; } frames = floor(traveltime / FRAMETIME); - // scale the destdelta vector by the time spent traveling to get velocity - VectorScale (destdelta, 1.0 / traveltime, ent->avelocity); + /* scale the destdelta vector by the time spent traveling to get velocity */ + VectorScale(destdelta, 1.0 / traveltime, ent->avelocity); - // set nextthink to trigger a think when dest is reached + /* set nextthink to trigger a think when dest is reached */ ent->nextthink = level.time + frames * FRAMETIME; ent->think = AngleMove_Final; } -void AngleMove_Calc (edict_t *ent, void(*func)(edict_t*)) +void +AngleMove_Calc(edict_t *ent, void (*func)(edict_t *)) { - VectorClear (ent->avelocity); + VectorClear(ent->avelocity); ent->moveinfo.endfunc = func; - if (level.current_entity == ((ent->flags & FL_TEAMSLAVE) ? ent->teammaster : ent)) + + if (level.current_entity == + ((ent->flags & FL_TEAMSLAVE) ? ent->teammaster : ent)) { - AngleMove_Begin (ent); + AngleMove_Begin(ent); } else { @@ -221,21 +245,21 @@ void AngleMove_Calc (edict_t *ent, void(*func)(edict_t*)) } } - /* -============== -Think_AccelMove + * ============== + * Think_AccelMove + * + * The team has completed a frame of movement, so + * change the speed for the next frame + * ============== + */ +#define AccelerationDistance(target, rate) (target * ((target / rate) + 1) / 2) -The team has completed a frame of movement, so -change the speed for the next frame -============== -*/ -#define AccelerationDistance(target, rate) (target * ((target / rate) + 1) / 2) - -void plat_CalcAcceleratedMove(moveinfo_t *moveinfo) +void +plat_CalcAcceleratedMove(moveinfo_t *moveinfo) { - float accel_dist; - float decel_dist; + float accel_dist; + float decel_dist; moveinfo->move_speed = moveinfo->speed; @@ -245,24 +269,29 @@ void plat_CalcAcceleratedMove(moveinfo_t *moveinfo) return; } - accel_dist = AccelerationDistance (moveinfo->speed, moveinfo->accel); - decel_dist = AccelerationDistance (moveinfo->speed, moveinfo->decel); + accel_dist = AccelerationDistance(moveinfo->speed, moveinfo->accel); + decel_dist = AccelerationDistance(moveinfo->speed, moveinfo->decel); if ((moveinfo->remaining_distance - accel_dist - decel_dist) < 0) { - float f; + float f; - f = (moveinfo->accel + moveinfo->decel) / (moveinfo->accel * moveinfo->decel); - moveinfo->move_speed = (-2 + sqrt(4 - 4 * f * (-2 * moveinfo->remaining_distance))) / (2 * f); - decel_dist = AccelerationDistance (moveinfo->move_speed, moveinfo->decel); + f = + (moveinfo->accel + + moveinfo->decel) / (moveinfo->accel * moveinfo->decel); + moveinfo->move_speed = + (-2 + + sqrt(4 - 4 * f * (-2 * moveinfo->remaining_distance))) / (2 * f); + decel_dist = AccelerationDistance(moveinfo->move_speed, moveinfo->decel); } moveinfo->decel_distance = decel_dist; } -void plat_Accelerate (moveinfo_t *moveinfo) +void +plat_Accelerate(moveinfo_t *moveinfo) { - // are we decelerating? + /* are we decelerating? */ if (moveinfo->remaining_distance <= moveinfo->decel_distance) { if (moveinfo->remaining_distance < moveinfo->decel_distance) @@ -273,195 +302,302 @@ void plat_Accelerate (moveinfo_t *moveinfo) moveinfo->next_speed = 0; return; } + if (moveinfo->current_speed > moveinfo->decel) + { moveinfo->current_speed -= moveinfo->decel; + } } + return; } - // are we at full speed and need to start decelerating during this move? + /* are we at full speed and need to start decelerating during this move? */ if (moveinfo->current_speed == moveinfo->move_speed) - if ((moveinfo->remaining_distance - moveinfo->current_speed) < moveinfo->decel_distance) + { + if ((moveinfo->remaining_distance - moveinfo->current_speed) < + moveinfo->decel_distance) { - float p1_distance; - float p2_distance; - float distance; + float p1_distance; + float p2_distance; + float distance; - p1_distance = moveinfo->remaining_distance - moveinfo->decel_distance; - p2_distance = moveinfo->move_speed * (1.0 - (p1_distance / moveinfo->move_speed)); + p1_distance = moveinfo->remaining_distance - + moveinfo->decel_distance; + p2_distance = moveinfo->move_speed * + (1.0 - (p1_distance / moveinfo->move_speed)); distance = p1_distance + p2_distance; moveinfo->current_speed = moveinfo->move_speed; - moveinfo->next_speed = moveinfo->move_speed - moveinfo->decel * (p2_distance / distance); + moveinfo->next_speed = moveinfo->move_speed - moveinfo->decel * + (p2_distance / distance); return; } + } - // are we accelerating? + /* are we accelerating? */ if (moveinfo->current_speed < moveinfo->speed) { - float old_speed; - float p1_distance; - float p1_speed; - float p2_distance; - float distance; + float old_speed; + float p1_distance; + float p1_speed; + float p2_distance; + float distance; old_speed = moveinfo->current_speed; - // figure simple acceleration up to move_speed + /* figure simple acceleration up to move_speed */ moveinfo->current_speed += moveinfo->accel; + if (moveinfo->current_speed > moveinfo->speed) + { moveinfo->current_speed = moveinfo->speed; + } - // are we accelerating throughout this entire move? - if ((moveinfo->remaining_distance - moveinfo->current_speed) >= moveinfo->decel_distance) + /* are we accelerating throughout this entire move? */ + if ((moveinfo->remaining_distance - moveinfo->current_speed) >= + moveinfo->decel_distance) + { return; + } - // during this move we will accelrate from current_speed to move_speed - // and cross over the decel_distance; figure the average speed for the - // entire move + /* during this move we will accelrate from current_speed to move_speed */ + /* and cross over the decel_distance; figure the average speed for the */ + /* entire move */ p1_distance = moveinfo->remaining_distance - moveinfo->decel_distance; p1_speed = (old_speed + moveinfo->move_speed) / 2.0; p2_distance = moveinfo->move_speed * (1.0 - (p1_distance / p1_speed)); distance = p1_distance + p2_distance; - moveinfo->current_speed = (p1_speed * (p1_distance / distance)) + (moveinfo->move_speed * (p2_distance / distance)); - moveinfo->next_speed = moveinfo->move_speed - moveinfo->decel * (p2_distance / distance); + moveinfo->current_speed = + (p1_speed * + (p1_distance / + distance)) + (moveinfo->move_speed * (p2_distance / distance)); + moveinfo->next_speed = moveinfo->move_speed - moveinfo->decel * + (p2_distance / distance); return; } - // we are at constant velocity (move_speed) + /* we are at constant velocity (move_speed) */ return; } -void Think_AccelMove (edict_t *ent) +void +Think_AccelMove(edict_t *ent) { ent->moveinfo.remaining_distance -= ent->moveinfo.current_speed; - if (ent->moveinfo.current_speed == 0) // starting or blocked + if (ent->moveinfo.current_speed == 0) /* starting or blocked */ + { plat_CalcAcceleratedMove(&ent->moveinfo); + } - plat_Accelerate (&ent->moveinfo); + plat_Accelerate(&ent->moveinfo); - // will the entire move complete on next frame? + /* will the entire move complete on next frame? */ if (ent->moveinfo.remaining_distance <= ent->moveinfo.current_speed) { - Move_Final (ent); + Move_Final(ent); return; } - VectorScale (ent->moveinfo.dir, ent->moveinfo.current_speed*10, ent->velocity); + VectorScale(ent->moveinfo.dir, + ent->moveinfo.current_speed * 10, + ent->velocity); ent->nextthink = level.time + FRAMETIME; ent->think = Think_AccelMove; } +void plat_go_down(edict_t *ent); -void plat_go_down (edict_t *ent); - -void plat_hit_top (edict_t *ent) +void +plat_hit_top(edict_t *ent) { if (!(ent->flags & FL_TEAMSLAVE)) { if (ent->moveinfo.sound_end) - gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, ent->moveinfo.sound_end, 1, ATTN_STATIC, 0); + { + gi.sound(ent, + CHAN_NO_PHS_ADD + CHAN_VOICE, + ent->moveinfo.sound_end, + 1, + ATTN_STATIC, + 0); + } + ent->s.sound = 0; } + ent->moveinfo.state = STATE_TOP; ent->think = plat_go_down; ent->nextthink = level.time + 3; } -void plat_hit_bottom (edict_t *ent) +void +plat_hit_bottom(edict_t *ent) { if (!(ent->flags & FL_TEAMSLAVE)) { if (ent->moveinfo.sound_end) - gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, ent->moveinfo.sound_end, 1, ATTN_STATIC, 0); + { + gi.sound(ent, + CHAN_NO_PHS_ADD + CHAN_VOICE, + ent->moveinfo.sound_end, + 1, + ATTN_STATIC, + 0); + } + ent->s.sound = 0; } + ent->moveinfo.state = STATE_BOTTOM; } -void plat_go_down (edict_t *ent) +void +plat_go_down(edict_t *ent) { if (!(ent->flags & FL_TEAMSLAVE)) { if (ent->moveinfo.sound_start) - gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, ent->moveinfo.sound_start, 1, ATTN_STATIC, 0); + { + gi.sound(ent, + CHAN_NO_PHS_ADD + CHAN_VOICE, + ent->moveinfo.sound_start, + 1, + ATTN_STATIC, + 0); + } + ent->s.sound = ent->moveinfo.sound_middle; } + ent->moveinfo.state = STATE_DOWN; - Move_Calc (ent, ent->moveinfo.end_origin, plat_hit_bottom); + Move_Calc(ent, ent->moveinfo.end_origin, plat_hit_bottom); } -void plat_go_up (edict_t *ent) +void +plat_go_up(edict_t *ent) { if (!(ent->flags & FL_TEAMSLAVE)) { if (ent->moveinfo.sound_start) - gi.sound (ent, CHAN_NO_PHS_ADD+CHAN_VOICE, ent->moveinfo.sound_start, 1, ATTN_STATIC, 0); + { + gi.sound(ent, + CHAN_NO_PHS_ADD + CHAN_VOICE, + ent->moveinfo.sound_start, + 1, + ATTN_STATIC, + 0); + } + ent->s.sound = ent->moveinfo.sound_middle; } + ent->moveinfo.state = STATE_UP; - Move_Calc (ent, ent->moveinfo.start_origin, plat_hit_top); + Move_Calc(ent, ent->moveinfo.start_origin, plat_hit_top); } -void plat_blocked (edict_t *self, edict_t *other) +void +plat_blocked(edict_t *self, edict_t *other) { - if (!(other->svflags & SVF_MONSTER) && (!other->client) ) + if (!(other->svflags & SVF_MONSTER) && (!other->client)) { - // give it a chance to go away on it's own terms (like gibs) - T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH); - // if it's still there, nuke it + /* give it a chance to go away on it's own terms (like gibs) */ + T_Damage(other, + self, + self, + vec3_origin, + other->s.origin, + vec3_origin, + 100000, + 1, + 0, + MOD_CRUSH); + + /* if it's still there, nuke it */ if (other) - BecomeExplosion1 (other); + { + BecomeExplosion1(other); + } + return; } - T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH); + T_Damage(other, + self, + self, + vec3_origin, + other->s.origin, + vec3_origin, + self->dmg, + 1, + 0, + MOD_CRUSH); if (self->moveinfo.state == STATE_UP) - plat_go_down (self); + { + plat_go_down(self); + } else if (self->moveinfo.state == STATE_DOWN) - plat_go_up (self); + { + plat_go_up(self); + } } - -void Use_Plat (edict_t *ent, edict_t *other, edict_t *activator) -{ +void +Use_Plat(edict_t *ent, edict_t *other, edict_t *activator) +{ if (ent->think) - return; // already down - plat_go_down (ent); + { + return; /* already down */ + } + + plat_go_down(ent); } - -void Touch_Plat_Center (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) +void +Touch_Plat_Center(edict_t *ent, + edict_t *other, + cplane_t *plane, + csurface_t *surf) { if (!other->client) + { return; - - if (other->health <= 0) - return; + } + + if (other->health <= 0) + { + return; + } + + ent = ent->enemy; /* now point at the plat, not the trigger */ - ent = ent->enemy; // now point at the plat, not the trigger if (ent->moveinfo.state == STATE_BOTTOM) - plat_go_up (ent); + { + plat_go_up(ent); + } else if (ent->moveinfo.state == STATE_TOP) - ent->nextthink = level.time + 1; // the player is still on the plat, so delay going down + { + ent->nextthink = level.time + 1; /* the player is still on the plat, so delay going down */ + } } -void plat_spawn_inside_trigger (edict_t *ent) +void +plat_spawn_inside_trigger(edict_t *ent) { - edict_t *trigger; - vec3_t tmin, tmax; + edict_t *trigger; + vec3_t tmin, tmax; - // - // middle trigger - // + /* */ + /* middle trigger */ + /* */ trigger = G_Spawn(); trigger->touch = Touch_Plat_Center; trigger->movetype = MOVETYPE_NONE; trigger->solid = SOLID_TRIGGER; trigger->enemy = ent; - + tmin[0] = ent->mins[0] + 25; tmin[1] = ent->mins[1] + 25; tmin[2] = ent->mins[2]; @@ -473,85 +609,109 @@ void plat_spawn_inside_trigger (edict_t *ent) tmin[2] = tmax[2] - (ent->pos1[2] - ent->pos2[2] + st.lip); if (ent->spawnflags & PLAT_LOW_TRIGGER) + { tmax[2] = tmin[2] + 8; - + } + if (tmax[0] - tmin[0] <= 0) { - tmin[0] = (ent->mins[0] + ent->maxs[0]) *0.5; + tmin[0] = (ent->mins[0] + ent->maxs[0]) * 0.5; tmax[0] = tmin[0] + 1; } + if (tmax[1] - tmin[1] <= 0) { - tmin[1] = (ent->mins[1] + ent->maxs[1]) *0.5; + tmin[1] = (ent->mins[1] + ent->maxs[1]) * 0.5; tmax[1] = tmin[1] + 1; } - - VectorCopy (tmin, trigger->mins); - VectorCopy (tmax, trigger->maxs); - gi.linkentity (trigger); + VectorCopy(tmin, trigger->mins); + VectorCopy(tmax, trigger->maxs); + + gi.linkentity(trigger); } - /*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER -speed default 150 - -Plats are always drawn in the extended position, so they will light correctly. - -If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat. - -"speed" overrides default 200. -"accel" overrides default 500 -"lip" overrides default 8 pixel lip - -If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determoveinfoned by the model's height. - -Set "sounds" to one of the following: -1) base fast -2) chain slow -*/ -void SP_func_plat (edict_t *ent) + * speed default 150 + * + * Plats are always drawn in the extended position, so they will light correctly. + * + * If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat. + * + * "speed" overrides default 200. + * "accel" overrides default 500 + * "lip" overrides default 8 pixel lip + * + * If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determoveinfoned by the model's height. + * + * Set "sounds" to one of the following: + * 1) base fast + * 2) chain slow + */ +void +SP_func_plat(edict_t *ent) { - VectorClear (ent->s.angles); + VectorClear(ent->s.angles); ent->solid = SOLID_BSP; ent->movetype = MOVETYPE_PUSH; - gi.setmodel (ent, ent->model); + gi.setmodel(ent, ent->model); ent->blocked = plat_blocked; if (!ent->speed) + { ent->speed = 20; + } else + { ent->speed *= 0.1; + } if (!ent->accel) + { ent->accel = 5; + } else + { ent->accel *= 0.1; + } if (!ent->decel) + { ent->decel = 5; + } else + { ent->decel *= 0.1; + } if (!ent->dmg) + { ent->dmg = 2; + } if (!st.lip) + { st.lip = 8; + } + + /* pos1 is the top position, pos2 is the bottom */ + VectorCopy(ent->s.origin, ent->pos1); + VectorCopy(ent->s.origin, ent->pos2); - // pos1 is the top position, pos2 is the bottom - VectorCopy (ent->s.origin, ent->pos1); - VectorCopy (ent->s.origin, ent->pos2); if (st.height) + { ent->pos2[2] -= st.height; + } else + { ent->pos2[2] -= (ent->maxs[2] - ent->mins[2]) - st.lip; + } ent->use = Use_Plat; - plat_spawn_inside_trigger (ent); // the "start moving" trigger + plat_spawn_inside_trigger(ent); /* the "start moving" trigger */ if (ent->targetname) { @@ -559,8 +719,8 @@ void SP_func_plat (edict_t *ent) } else { - VectorCopy (ent->pos2, ent->s.origin); - gi.linkentity (ent); + VectorCopy(ent->pos2, ent->s.origin); + gi.linkentity(ent); ent->moveinfo.state = STATE_BOTTOM; } @@ -568,152 +728,214 @@ void SP_func_plat (edict_t *ent) ent->moveinfo.accel = ent->accel; ent->moveinfo.decel = ent->decel; ent->moveinfo.wait = ent->wait; - VectorCopy (ent->pos1, ent->moveinfo.start_origin); - VectorCopy (ent->s.angles, ent->moveinfo.start_angles); - VectorCopy (ent->pos2, ent->moveinfo.end_origin); - VectorCopy (ent->s.angles, ent->moveinfo.end_angles); + VectorCopy(ent->pos1, ent->moveinfo.start_origin); + VectorCopy(ent->s.angles, ent->moveinfo.start_angles); + VectorCopy(ent->pos2, ent->moveinfo.end_origin); + VectorCopy(ent->s.angles, ent->moveinfo.end_angles); - ent->moveinfo.sound_start = gi.soundindex ("plats/pt1_strt.wav"); - ent->moveinfo.sound_middle = gi.soundindex ("plats/pt1_mid.wav"); - ent->moveinfo.sound_end = gi.soundindex ("plats/pt1_end.wav"); + ent->moveinfo.sound_start = gi.soundindex("plats/pt1_strt.wav"); + ent->moveinfo.sound_middle = gi.soundindex("plats/pt1_mid.wav"); + ent->moveinfo.sound_end = gi.soundindex("plats/pt1_end.wav"); } -//==================================================================== +/* ==================================================================== */ /*QUAKED func_rotating (0 .5 .8) ? START_ON REVERSE X_AXIS Y_AXIS TOUCH_PAIN STOP ANIMATED ANIMATED_FAST -You need to have an origin brush as part of this entity. The center of that brush will be -the point around which it is rotated. It will rotate around the Z axis by default. You can -check either the X_AXIS or Y_AXIS box to change that. + * You need to have an origin brush as part of this entity. The center of that brush will be + * the point around which it is rotated. It will rotate around the Z axis by default. You can + * check either the X_AXIS or Y_AXIS box to change that. + * + * "speed" determines how fast it moves; default value is 100. + * "dmg" damage to inflict when blocked (2 default) + * + * REVERSE will cause the it to rotate in the opposite direction. + * STOP mean it will stop moving instead of pushing entities + */ -"speed" determines how fast it moves; default value is 100. -"dmg" damage to inflict when blocked (2 default) - -REVERSE will cause the it to rotate in the opposite direction. -STOP mean it will stop moving instead of pushing entities -*/ - -void rotating_blocked (edict_t *self, edict_t *other) +void +rotating_blocked(edict_t *self, edict_t *other) { - T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH); + T_Damage(other, + self, + self, + vec3_origin, + other->s.origin, + vec3_origin, + self->dmg, + 1, + 0, + MOD_CRUSH); } -void rotating_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +void +rotating_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { if (self->avelocity[0] || self->avelocity[1] || self->avelocity[2]) - T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH); + { + T_Damage(other, + self, + self, + vec3_origin, + other->s.origin, + vec3_origin, + self->dmg, + 1, + 0, + MOD_CRUSH); + } } -void rotating_use (edict_t *self, edict_t *other, edict_t *activator) +void +rotating_use(edict_t *self, edict_t *other, edict_t *activator) { - if (!VectorCompare (self->avelocity, vec3_origin)) + if (!VectorCompare(self->avelocity, vec3_origin)) { self->s.sound = 0; - VectorClear (self->avelocity); + VectorClear(self->avelocity); self->touch = NULL; } else { self->s.sound = self->moveinfo.sound_middle; - VectorScale (self->movedir, self->speed, self->avelocity); + VectorScale(self->movedir, self->speed, self->avelocity); + if (self->spawnflags & 16) + { self->touch = rotating_touch; + } } } -void SP_func_rotating (edict_t *ent) +void +SP_func_rotating(edict_t *ent) { ent->solid = SOLID_BSP; + if (ent->spawnflags & 32) + { ent->movetype = MOVETYPE_STOP; + } else + { ent->movetype = MOVETYPE_PUSH; + } - // set the axis of rotation + /* set the axis of rotation */ VectorClear(ent->movedir); - if (ent->spawnflags & 4) - ent->movedir[2] = 1.0; - else if (ent->spawnflags & 8) - ent->movedir[0] = 1.0; - else // Z_AXIS - ent->movedir[1] = 1.0; - // check for reverse rotation + if (ent->spawnflags & 4) + { + ent->movedir[2] = 1.0; + } + else if (ent->spawnflags & 8) + { + ent->movedir[0] = 1.0; + } + else /* Z_AXIS */ + { + ent->movedir[1] = 1.0; + } + + /* check for reverse rotation */ if (ent->spawnflags & 2) - VectorNegate (ent->movedir, ent->movedir); + { + VectorNegate(ent->movedir, ent->movedir); + } if (!ent->speed) + { ent->speed = 100; + } + if (!ent->dmg) + { ent->dmg = 2; + } ent->use = rotating_use; + if (ent->dmg) + { ent->blocked = rotating_blocked; + } if (ent->spawnflags & 1) - ent->use (ent, NULL, NULL); + { + ent->use(ent, NULL, NULL); + } if (ent->spawnflags & 64) + { ent->s.effects |= EF_ANIM_ALL; - if (ent->spawnflags & 128) - ent->s.effects |= EF_ANIM_ALLFAST; + } - gi.setmodel (ent, ent->model); - gi.linkentity (ent); + if (ent->spawnflags & 128) + { + ent->s.effects |= EF_ANIM_ALLFAST; + } + + gi.setmodel(ent, ent->model); + gi.linkentity(ent); } /* -====================================================================== - -BUTTONS - -====================================================================== -*/ + * ====================================================================== + * + * BUTTONS + * + * ====================================================================== + */ /*QUAKED func_button (0 .5 .8) ? -When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again. + * When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again. + * + * "angle" determines the opening direction + * "target" all entities with a matching targetname will be used + * "speed" override the default 40 speed + * "wait" override the default 1 second wait (-1 = never return) + * "lip" override the default 4 pixel lip remaining at end of move + * "health" if set, the button must be killed instead of touched + * "sounds" + * 1) silent + * 2) steam metal + * 3) wooden clunk + * 4) metallic click + * 5) in-out + */ -"angle" determines the opening direction -"target" all entities with a matching targetname will be used -"speed" override the default 40 speed -"wait" override the default 1 second wait (-1 = never return) -"lip" override the default 4 pixel lip remaining at end of move -"health" if set, the button must be killed instead of touched -"sounds" -1) silent -2) steam metal -3) wooden clunk -4) metallic click -5) in-out -*/ - -void button_done (edict_t *self) +void +button_done(edict_t *self) { self->moveinfo.state = STATE_BOTTOM; self->s.effects &= ~EF_ANIM23; self->s.effects |= EF_ANIM01; } -void button_return (edict_t *self) +void +button_return(edict_t *self) { self->moveinfo.state = STATE_DOWN; - Move_Calc (self, self->moveinfo.start_origin, button_done); + Move_Calc(self, self->moveinfo.start_origin, button_done); self->s.frame = 0; if (self->health) + { self->takedamage = DAMAGE_YES; + } } -void button_wait (edict_t *self) +void +button_wait(edict_t *self) { self->moveinfo.state = STATE_TOP; self->s.effects &= ~EF_ANIM01; self->s.effects |= EF_ANIM23; - G_UseTargets (self, self->activator); + G_UseTargets(self, self->activator); self->s.frame = 1; + if (self->moveinfo.wait >= 0) { self->nextthink = level.time + self->moveinfo.wait; @@ -721,74 +943,115 @@ void button_wait (edict_t *self) } } -void button_fire (edict_t *self) +void +button_fire(edict_t *self) { - if (self->moveinfo.state == STATE_UP || self->moveinfo.state == STATE_TOP) + if ((self->moveinfo.state == STATE_UP) || + (self->moveinfo.state == STATE_TOP)) + { return; + } self->moveinfo.state = STATE_UP; + if (self->moveinfo.sound_start && !(self->flags & FL_TEAMSLAVE)) - gi.sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self->moveinfo.sound_start, 1, ATTN_STATIC, 0); - Move_Calc (self, self->moveinfo.end_origin, button_wait); + { + gi.sound(self, + CHAN_NO_PHS_ADD + CHAN_VOICE, + self->moveinfo.sound_start, + 1, + ATTN_STATIC, + 0); + } + + Move_Calc(self, self->moveinfo.end_origin, button_wait); } -void button_use (edict_t *self, edict_t *other, edict_t *activator) +void +button_use(edict_t *self, edict_t *other, edict_t *activator) { self->activator = activator; - button_fire (self); + button_fire(self); } -void button_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +void +button_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { if (!other->client) + { return; + } if (other->health <= 0) + { return; + } self->activator = other; - button_fire (self); + button_fire(self); } -void button_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +void +button_killed(edict_t *self, + edict_t *inflictor, + edict_t *attacker, + int damage, + vec3_t point) { self->activator = attacker; self->health = self->max_health; self->takedamage = DAMAGE_NO; - button_fire (self); + button_fire(self); } -void SP_func_button (edict_t *ent) +void +SP_func_button(edict_t *ent) { - vec3_t abs_movedir; - float dist; + vec3_t abs_movedir; + float dist; - G_SetMovedir (ent->s.angles, ent->movedir); + G_SetMovedir(ent->s.angles, ent->movedir); ent->movetype = MOVETYPE_STOP; ent->solid = SOLID_BSP; - gi.setmodel (ent, ent->model); + gi.setmodel(ent, ent->model); if (ent->sounds != 1) - ent->moveinfo.sound_start = gi.soundindex ("switches/butn2.wav"); - + { + ent->moveinfo.sound_start = gi.soundindex("switches/butn2.wav"); + } + if (!ent->speed) + { ent->speed = 40; + } + if (!ent->accel) + { ent->accel = ent->speed; + } + if (!ent->decel) + { ent->decel = ent->speed; + } if (!ent->wait) + { ent->wait = 3; - if (!st.lip) - st.lip = 4; + } - VectorCopy (ent->s.origin, ent->pos1); + if (!st.lip) + { + st.lip = 4; + } + + VectorCopy(ent->s.origin, ent->pos1); abs_movedir[0] = fabs(ent->movedir[0]); abs_movedir[1] = fabs(ent->movedir[1]); abs_movedir[2] = fabs(ent->movedir[2]); - dist = abs_movedir[0] * ent->size[0] + abs_movedir[1] * ent->size[1] + abs_movedir[2] * ent->size[2] - st.lip; - VectorMA (ent->pos1, dist, ent->movedir, ent->pos2); + dist = abs_movedir[0] * ent->size[0] + abs_movedir[1] * ent->size[1] + + abs_movedir[2] * ent->size[2] - st.lip; + VectorMA(ent->pos1, dist, ent->movedir, ent->pos2); ent->use = button_use; ent->s.effects |= EF_ANIM01; @@ -799,8 +1062,10 @@ void SP_func_button (edict_t *ent) ent->die = button_killed; ent->takedamage = DAMAGE_YES; } - else if (! ent->targetname) + else if (!ent->targetname) + { ent->touch = button_touch; + } ent->moveinfo.state = STATE_BOTTOM; @@ -808,74 +1073,91 @@ void SP_func_button (edict_t *ent) ent->moveinfo.accel = ent->accel; ent->moveinfo.decel = ent->decel; ent->moveinfo.wait = ent->wait; - VectorCopy (ent->pos1, ent->moveinfo.start_origin); - VectorCopy (ent->s.angles, ent->moveinfo.start_angles); - VectorCopy (ent->pos2, ent->moveinfo.end_origin); - VectorCopy (ent->s.angles, ent->moveinfo.end_angles); + VectorCopy(ent->pos1, ent->moveinfo.start_origin); + VectorCopy(ent->s.angles, ent->moveinfo.start_angles); + VectorCopy(ent->pos2, ent->moveinfo.end_origin); + VectorCopy(ent->s.angles, ent->moveinfo.end_angles); - gi.linkentity (ent); + gi.linkentity(ent); } /* -====================================================================== - -DOORS - - spawn a trigger surrounding the entire team unless it is - allready targeted by another - -====================================================================== -*/ + * ====================================================================== + * + * DOORS + * + * spawn a trigger surrounding the entire team unless it is + * allready targeted by another + * + * ====================================================================== + */ /*QUAKED func_door (0 .5 .8) ? START_OPEN x CRUSHER NOMONSTER ANIMATED TOGGLE ANIMATED_FAST -TOGGLE wait in both the start and end states for a trigger event. -START_OPEN the door to moves to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors). -NOMONSTER monsters will not trigger this door + * TOGGLE wait in both the start and end states for a trigger event. + * START_OPEN the door to moves to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors). + * NOMONSTER monsters will not trigger this door + * + * "message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet + * "angle" determines the opening direction + * "targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door. + * "health" if set, door must be shot open + * "speed" movement speed (100 default) + * "wait" wait before returning (3 default, -1 = never return) + * "lip" lip remaining at end of move (8 default) + * "dmg" damage to inflict when blocked (2 default) + * "sounds" + * 1) silent + * 2) light + * 3) medium + * 4) heavy + */ -"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet -"angle" determines the opening direction -"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door. -"health" if set, door must be shot open -"speed" movement speed (100 default) -"wait" wait before returning (3 default, -1 = never return) -"lip" lip remaining at end of move (8 default) -"dmg" damage to inflict when blocked (2 default) -"sounds" -1) silent -2) light -3) medium -4) heavy -*/ - -void door_use_areaportals (edict_t *self, qboolean open) +void +door_use_areaportals(edict_t *self, qboolean open) { - edict_t *t = NULL; + edict_t *t = NULL; if (!self->target) + { return; + } - while ((t = G_Find (t, FOFS(targetname), self->target))) + while ((t = G_Find(t, FOFS(targetname), self->target))) { if (Q_stricmp(t->classname, "func_areaportal") == 0) { - gi.SetAreaPortalState (t->style, open); + gi.SetAreaPortalState(t->style, open); } } } -void door_go_down (edict_t *self); +void door_go_down(edict_t *self); -void door_hit_top (edict_t *self) +void +door_hit_top(edict_t *self) { if (!(self->flags & FL_TEAMSLAVE)) { if (self->moveinfo.sound_end) - gi.sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self->moveinfo.sound_end, 1, ATTN_STATIC, 0); + { + gi.sound(self, + CHAN_NO_PHS_ADD + CHAN_VOICE, + self->moveinfo.sound_end, + 1, + ATTN_STATIC, + 0); + } + self->s.sound = 0; } + self->moveinfo.state = STATE_TOP; + if (self->spawnflags & DOOR_TOGGLE) + { return; + } + if (self->moveinfo.wait >= 0) { self->think = door_go_down; @@ -883,306 +1165,454 @@ void door_hit_top (edict_t *self) } } -void door_hit_bottom (edict_t *self) +void +door_hit_bottom(edict_t *self) { if (!(self->flags & FL_TEAMSLAVE)) { if (self->moveinfo.sound_end) - gi.sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self->moveinfo.sound_end, 1, ATTN_STATIC, 0); + { + gi.sound(self, + CHAN_NO_PHS_ADD + CHAN_VOICE, + self->moveinfo.sound_end, + 1, + ATTN_STATIC, + 0); + } + self->s.sound = 0; } + self->moveinfo.state = STATE_BOTTOM; - door_use_areaportals (self, false); + door_use_areaportals(self, false); } -void door_go_down (edict_t *self) +void +door_go_down(edict_t *self) { if (!(self->flags & FL_TEAMSLAVE)) { if (self->moveinfo.sound_start) - gi.sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self->moveinfo.sound_start, 1, ATTN_STATIC, 0); + { + gi.sound(self, + CHAN_NO_PHS_ADD + CHAN_VOICE, + self->moveinfo.sound_start, + 1, + ATTN_STATIC, + 0); + } + self->s.sound = self->moveinfo.sound_middle; } + if (self->max_health) { self->takedamage = DAMAGE_YES; self->health = self->max_health; } - + self->moveinfo.state = STATE_DOWN; + if (strcmp(self->classname, "func_door") == 0) - Move_Calc (self, self->moveinfo.start_origin, door_hit_bottom); + { + Move_Calc(self, self->moveinfo.start_origin, door_hit_bottom); + } else if (strcmp(self->classname, "func_door_rotating") == 0) - AngleMove_Calc (self, door_hit_bottom); + { + AngleMove_Calc(self, door_hit_bottom); + } } -void door_go_up (edict_t *self, edict_t *activator) +void +door_go_up(edict_t *self, edict_t *activator) { if (self->moveinfo.state == STATE_UP) - return; // already going up + { + return; /* already going up */ + } if (self->moveinfo.state == STATE_TOP) - { // reset top wait time + { /* reset top wait time */ if (self->moveinfo.wait >= 0) + { self->nextthink = level.time + self->moveinfo.wait; + } + return; } - + if (!(self->flags & FL_TEAMSLAVE)) { if (self->moveinfo.sound_start) - gi.sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self->moveinfo.sound_start, 1, ATTN_STATIC, 0); + { + gi.sound(self, + CHAN_NO_PHS_ADD + CHAN_VOICE, + self->moveinfo.sound_start, + 1, + ATTN_STATIC, + 0); + } + self->s.sound = self->moveinfo.sound_middle; } - self->moveinfo.state = STATE_UP; - if (strcmp(self->classname, "func_door") == 0) - Move_Calc (self, self->moveinfo.end_origin, door_hit_top); - else if (strcmp(self->classname, "func_door_rotating") == 0) - AngleMove_Calc (self, door_hit_top); - G_UseTargets (self, activator); - door_use_areaportals (self, true); + self->moveinfo.state = STATE_UP; + + if (strcmp(self->classname, "func_door") == 0) + { + Move_Calc(self, self->moveinfo.end_origin, door_hit_top); + } + else if (strcmp(self->classname, "func_door_rotating") == 0) + { + AngleMove_Calc(self, door_hit_top); + } + + G_UseTargets(self, activator); + door_use_areaportals(self, true); } -void door_use (edict_t *self, edict_t *other, edict_t *activator) +void +door_use(edict_t *self, edict_t *other, edict_t *activator) { - edict_t *ent; + edict_t *ent; if (self->flags & FL_TEAMSLAVE) + { return; + } if (self->spawnflags & DOOR_TOGGLE) { - if (self->moveinfo.state == STATE_UP || self->moveinfo.state == STATE_TOP) + if ((self->moveinfo.state == STATE_UP) || + (self->moveinfo.state == STATE_TOP)) { - // trigger all paired doors - for (ent = self ; ent ; ent = ent->teamchain) + /* trigger all paired doors */ + for (ent = self; ent; ent = ent->teamchain) { ent->message = NULL; ent->touch = NULL; - door_go_down (ent); + door_go_down(ent); } + return; } } - - // trigger all paired doors - for (ent = self ; ent ; ent = ent->teamchain) + + /* trigger all paired doors */ + for (ent = self; ent; ent = ent->teamchain) { ent->message = NULL; ent->touch = NULL; - door_go_up (ent, activator); + door_go_up(ent, activator); } } -void Touch_DoorTrigger (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +void +Touch_DoorTrigger(edict_t *self, + edict_t *other, + cplane_t *plane, + csurface_t *surf) { if (other->health <= 0) + { return; + } if (!(other->svflags & SVF_MONSTER) && (!other->client)) + { return; + } - if ((self->owner->spawnflags & DOOR_NOMONSTER) && (other->svflags & SVF_MONSTER)) + if ((self->owner->spawnflags & DOOR_NOMONSTER) && + (other->svflags & SVF_MONSTER)) + { return; + } if (level.time < self->touch_debounce_time) + { return; + } + self->touch_debounce_time = level.time + 1.0; - door_use (self->owner, other, other); + door_use(self->owner, other, other); } -void Think_CalcMoveSpeed (edict_t *self) +void +Think_CalcMoveSpeed(edict_t *self) { - edict_t *ent; - float min; - float time; - float newspeed; - float ratio; - float dist; + edict_t *ent; + float min; + float time; + float newspeed; + float ratio; + float dist; if (self->flags & FL_TEAMSLAVE) - return; // only the team master does this + { + return; /* only the team master does this */ + } - // find the smallest distance any member of the team will be moving + /* find the smallest distance any member of the team will be moving */ min = fabs(self->moveinfo.distance); + for (ent = self->teamchain; ent; ent = ent->teamchain) { dist = fabs(ent->moveinfo.distance); + if (dist < min) + { min = dist; + } } time = min / self->moveinfo.speed; - // adjust speeds so they will all complete at the same time + /* adjust speeds so they will all complete at the same time */ for (ent = self; ent; ent = ent->teamchain) { newspeed = fabs(ent->moveinfo.distance) / time; ratio = newspeed / ent->moveinfo.speed; + if (ent->moveinfo.accel == ent->moveinfo.speed) + { ent->moveinfo.accel = newspeed; + } else + { ent->moveinfo.accel *= ratio; + } + if (ent->moveinfo.decel == ent->moveinfo.speed) + { ent->moveinfo.decel = newspeed; + } else + { ent->moveinfo.decel *= ratio; + } + ent->moveinfo.speed = newspeed; } } -void Think_SpawnDoorTrigger (edict_t *ent) +void +Think_SpawnDoorTrigger(edict_t *ent) { - edict_t *other; - vec3_t mins, maxs; + edict_t *other; + vec3_t mins, maxs; if (ent->flags & FL_TEAMSLAVE) - return; // only the team leader spawns a trigger - - VectorCopy (ent->absmin, mins); - VectorCopy (ent->absmax, maxs); - - for (other = ent->teamchain ; other ; other=other->teamchain) { - AddPointToBounds (other->absmin, mins, maxs); - AddPointToBounds (other->absmax, mins, maxs); + return; /* only the team leader spawns a trigger */ } - // expand + VectorCopy(ent->absmin, mins); + VectorCopy(ent->absmax, maxs); + + for (other = ent->teamchain; other; other = other->teamchain) + { + AddPointToBounds(other->absmin, mins, maxs); + AddPointToBounds(other->absmax, mins, maxs); + } + + /* expand */ mins[0] -= 60; mins[1] -= 60; maxs[0] += 60; maxs[1] += 60; - other = G_Spawn (); - VectorCopy (mins, other->mins); - VectorCopy (maxs, other->maxs); + other = G_Spawn(); + VectorCopy(mins, other->mins); + VectorCopy(maxs, other->maxs); other->owner = ent; other->solid = SOLID_TRIGGER; other->movetype = MOVETYPE_NONE; other->touch = Touch_DoorTrigger; - gi.linkentity (other); + gi.linkentity(other); if (ent->spawnflags & DOOR_START_OPEN) - door_use_areaportals (ent, true); + { + door_use_areaportals(ent, true); + } - Think_CalcMoveSpeed (ent); + Think_CalcMoveSpeed(ent); } -void door_blocked (edict_t *self, edict_t *other) +void +door_blocked(edict_t *self, edict_t *other) { - edict_t *ent; + edict_t *ent; - if (!(other->svflags & SVF_MONSTER) && (!other->client) ) + if (!(other->svflags & SVF_MONSTER) && (!other->client)) { - // give it a chance to go away on it's own terms (like gibs) - T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH); - // if it's still there, nuke it + /* give it a chance to go away on it's own terms (like gibs) */ + T_Damage(other, + self, + self, + vec3_origin, + other->s.origin, + vec3_origin, + 100000, + 1, + 0, + MOD_CRUSH); + + /* if it's still there, nuke it */ if (other) - BecomeExplosion1 (other); + { + BecomeExplosion1(other); + } + return; } - T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH); + T_Damage(other, + self, + self, + vec3_origin, + other->s.origin, + vec3_origin, + self->dmg, + 1, + 0, + MOD_CRUSH); if (self->spawnflags & DOOR_CRUSHER) + { return; + } - - // if a door has a negative wait, it would never come back if blocked, - // so let it just squash the object to death real fast + /* if a door has a negative wait, it would never come back if blocked, */ + /* so let it just squash the object to death real fast */ if (self->moveinfo.wait >= 0) { if (self->moveinfo.state == STATE_DOWN) { - for (ent = self->teammaster ; ent ; ent = ent->teamchain) - door_go_up (ent, ent->activator); + for (ent = self->teammaster; ent; ent = ent->teamchain) + { + door_go_up(ent, ent->activator); + } } else { - for (ent = self->teammaster ; ent ; ent = ent->teamchain) - door_go_down (ent); + for (ent = self->teammaster; ent; ent = ent->teamchain) + { + door_go_down(ent); + } } } } -void door_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +void +door_killed(edict_t *self, + edict_t *inflictor, + edict_t *attacker, + int damage, + vec3_t point) { - edict_t *ent; + edict_t *ent; - for (ent = self->teammaster ; ent ; ent = ent->teamchain) + for (ent = self->teammaster; ent; ent = ent->teamchain) { ent->health = ent->max_health; ent->takedamage = DAMAGE_NO; } - door_use (self->teammaster, attacker, attacker); + + door_use(self->teammaster, attacker, attacker); } -void door_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +void +door_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { if (!other->client) + { return; + } if (level.time < self->touch_debounce_time) + { return; + } + self->touch_debounce_time = level.time + 5.0; - gi.centerprintf (other, "%s", self->message); - gi.sound (other, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0); + gi.centerprintf(other, "%s", self->message); + gi.sound(other, CHAN_AUTO, gi.soundindex("misc/talk1.wav"), 1, ATTN_NORM, 0); } -void SP_func_door (edict_t *ent) +void +SP_func_door(edict_t *ent) { - vec3_t abs_movedir; + vec3_t abs_movedir; if (ent->sounds != 1) { - ent->moveinfo.sound_start = gi.soundindex ("doors/dr1_strt.wav"); - ent->moveinfo.sound_middle = gi.soundindex ("doors/dr1_mid.wav"); - ent->moveinfo.sound_end = gi.soundindex ("doors/dr1_end.wav"); + ent->moveinfo.sound_start = gi.soundindex("doors/dr1_strt.wav"); + ent->moveinfo.sound_middle = gi.soundindex("doors/dr1_mid.wav"); + ent->moveinfo.sound_end = gi.soundindex("doors/dr1_end.wav"); } - G_SetMovedir (ent->s.angles, ent->movedir); + G_SetMovedir(ent->s.angles, ent->movedir); ent->movetype = MOVETYPE_PUSH; ent->solid = SOLID_BSP; - gi.setmodel (ent, ent->model); + gi.setmodel(ent, ent->model); ent->blocked = door_blocked; ent->use = door_use; - + if (!ent->speed) + { ent->speed = 100; + } + if (deathmatch->value) + { ent->speed *= 2; + } if (!ent->accel) + { ent->accel = ent->speed; + } + if (!ent->decel) + { ent->decel = ent->speed; + } if (!ent->wait) + { ent->wait = 3; - if (!st.lip) - st.lip = 8; - if (!ent->dmg) - ent->dmg = 2; + } - // calculate second position - VectorCopy (ent->s.origin, ent->pos1); + if (!st.lip) + { + st.lip = 8; + } + + if (!ent->dmg) + { + ent->dmg = 2; + } + + /* calculate second position */ + VectorCopy(ent->s.origin, ent->pos1); abs_movedir[0] = fabs(ent->movedir[0]); abs_movedir[1] = fabs(ent->movedir[1]); abs_movedir[2] = fabs(ent->movedir[2]); - ent->moveinfo.distance = abs_movedir[0] * ent->size[0] + abs_movedir[1] * ent->size[1] + abs_movedir[2] * ent->size[2] - st.lip; - VectorMA (ent->pos1, ent->moveinfo.distance, ent->movedir, ent->pos2); + ent->moveinfo.distance = abs_movedir[0] * ent->size[0] + abs_movedir[1] * + ent->size[1] + abs_movedir[2] * ent->size[2] - + st.lip; + VectorMA(ent->pos1, ent->moveinfo.distance, ent->movedir, ent->pos2); - // if it starts open, switch the positions + /* if it starts open, switch the positions */ if (ent->spawnflags & DOOR_START_OPEN) { - VectorCopy (ent->pos2, ent->s.origin); - VectorCopy (ent->pos1, ent->pos2); - VectorCopy (ent->s.origin, ent->pos1); + VectorCopy(ent->pos2, ent->s.origin); + VectorCopy(ent->pos1, ent->pos2); + VectorCopy(ent->s.origin, ent->pos1); } ent->moveinfo.state = STATE_BOTTOM; @@ -1195,127 +1625,162 @@ void SP_func_door (edict_t *ent) } else if (ent->targetname && ent->message) { - gi.soundindex ("misc/talk.wav"); + gi.soundindex("misc/talk.wav"); ent->touch = door_touch; } - + ent->moveinfo.speed = ent->speed; ent->moveinfo.accel = ent->accel; ent->moveinfo.decel = ent->decel; ent->moveinfo.wait = ent->wait; - VectorCopy (ent->pos1, ent->moveinfo.start_origin); - VectorCopy (ent->s.angles, ent->moveinfo.start_angles); - VectorCopy (ent->pos2, ent->moveinfo.end_origin); - VectorCopy (ent->s.angles, ent->moveinfo.end_angles); + VectorCopy(ent->pos1, ent->moveinfo.start_origin); + VectorCopy(ent->s.angles, ent->moveinfo.start_angles); + VectorCopy(ent->pos2, ent->moveinfo.end_origin); + VectorCopy(ent->s.angles, ent->moveinfo.end_angles); if (ent->spawnflags & 16) + { ent->s.effects |= EF_ANIM_ALL; + } + if (ent->spawnflags & 64) + { ent->s.effects |= EF_ANIM_ALLFAST; + } - // to simplify logic elsewhere, make non-teamed doors into a team of one + /* to simplify logic elsewhere, make non-teamed doors into a team of one */ if (!ent->team) + { ent->teammaster = ent; + } - gi.linkentity (ent); + gi.linkentity(ent); ent->nextthink = level.time + FRAMETIME; + if (ent->health || ent->targetname) + { ent->think = Think_CalcMoveSpeed; + } else + { ent->think = Think_SpawnDoorTrigger; + } } - /*QUAKED func_door_rotating (0 .5 .8) ? START_OPEN REVERSE CRUSHER NOMONSTER ANIMATED TOGGLE X_AXIS Y_AXIS -TOGGLE causes the door to wait in both the start and end states for a trigger event. + * TOGGLE causes the door to wait in both the start and end states for a trigger event. + * + * START_OPEN the door to moves to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors). + * NOMONSTER monsters will not trigger this door + * + * You need to have an origin brush as part of this entity. The center of that brush will be + * the point around which it is rotated. It will rotate around the Z axis by default. You can + * check either the X_AXIS or Y_AXIS box to change that. + * + * "distance" is how many degrees the door will be rotated. + * "speed" determines how fast the door moves; default value is 100. + * + * REVERSE will cause the door to rotate in the opposite direction. + * + * "message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet + * "angle" determines the opening direction + * "targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door. + * "health" if set, door must be shot open + * "speed" movement speed (100 default) + * "wait" wait before returning (3 default, -1 = never return) + * "dmg" damage to inflict when blocked (2 default) + * "sounds" + * 1) silent + * 2) light + * 3) medium + * 4) heavy + */ -START_OPEN the door to moves to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors). -NOMONSTER monsters will not trigger this door - -You need to have an origin brush as part of this entity. The center of that brush will be -the point around which it is rotated. It will rotate around the Z axis by default. You can -check either the X_AXIS or Y_AXIS box to change that. - -"distance" is how many degrees the door will be rotated. -"speed" determines how fast the door moves; default value is 100. - -REVERSE will cause the door to rotate in the opposite direction. - -"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet -"angle" determines the opening direction -"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door. -"health" if set, door must be shot open -"speed" movement speed (100 default) -"wait" wait before returning (3 default, -1 = never return) -"dmg" damage to inflict when blocked (2 default) -"sounds" -1) silent -2) light -3) medium -4) heavy -*/ - -void SP_func_door_rotating (edict_t *ent) +void +SP_func_door_rotating(edict_t *ent) { - VectorClear (ent->s.angles); + VectorClear(ent->s.angles); - // set the axis of rotation + /* set the axis of rotation */ VectorClear(ent->movedir); - if (ent->spawnflags & DOOR_X_AXIS) - ent->movedir[2] = 1.0; - else if (ent->spawnflags & DOOR_Y_AXIS) - ent->movedir[0] = 1.0; - else // Z_AXIS - ent->movedir[1] = 1.0; - // check for reverse rotation + if (ent->spawnflags & DOOR_X_AXIS) + { + ent->movedir[2] = 1.0; + } + else if (ent->spawnflags & DOOR_Y_AXIS) + { + ent->movedir[0] = 1.0; + } + else /* Z_AXIS */ + { + ent->movedir[1] = 1.0; + } + + /* check for reverse rotation */ if (ent->spawnflags & DOOR_REVERSE) - VectorNegate (ent->movedir, ent->movedir); + { + VectorNegate(ent->movedir, ent->movedir); + } if (!st.distance) { - gi.dprintf("%s at %s with no distance set\n", ent->classname, vtos(ent->s.origin)); + gi.dprintf("%s at %s with no distance set\n", ent->classname, + vtos(ent->s.origin)); st.distance = 90; } - VectorCopy (ent->s.angles, ent->pos1); - VectorMA (ent->s.angles, st.distance, ent->movedir, ent->pos2); + VectorCopy(ent->s.angles, ent->pos1); + VectorMA(ent->s.angles, st.distance, ent->movedir, ent->pos2); ent->moveinfo.distance = st.distance; ent->movetype = MOVETYPE_PUSH; ent->solid = SOLID_BSP; - gi.setmodel (ent, ent->model); + gi.setmodel(ent, ent->model); ent->blocked = door_blocked; ent->use = door_use; if (!ent->speed) + { ent->speed = 100; + } + if (!ent->accel) + { ent->accel = ent->speed; + } + if (!ent->decel) + { ent->decel = ent->speed; + } if (!ent->wait) + { ent->wait = 3; + } + if (!ent->dmg) + { ent->dmg = 2; + } if (ent->sounds != 1) { - ent->moveinfo.sound_start = gi.soundindex ("doors/dr1_strt.wav"); - ent->moveinfo.sound_middle = gi.soundindex ("doors/dr1_mid.wav"); - ent->moveinfo.sound_end = gi.soundindex ("doors/dr1_end.wav"); + ent->moveinfo.sound_start = gi.soundindex("doors/dr1_strt.wav"); + ent->moveinfo.sound_middle = gi.soundindex("doors/dr1_mid.wav"); + ent->moveinfo.sound_end = gi.soundindex("doors/dr1_end.wav"); } - // if it starts open, switch the positions + /* if it starts open, switch the positions */ if (ent->spawnflags & DOOR_START_OPEN) { - VectorCopy (ent->pos2, ent->s.angles); - VectorCopy (ent->pos1, ent->pos2); - VectorCopy (ent->s.angles, ent->pos1); - VectorNegate (ent->movedir, ent->movedir); + VectorCopy(ent->pos2, ent->s.angles); + VectorCopy(ent->pos1, ent->pos2); + VectorCopy(ent->s.angles, ent->pos1); + VectorNegate(ent->movedir, ent->movedir); } if (ent->health) @@ -1324,10 +1789,10 @@ void SP_func_door_rotating (edict_t *ent) ent->die = door_killed; ent->max_health = ent->health; } - + if (ent->targetname && ent->message) { - gi.soundindex ("misc/talk.wav"); + gi.soundindex("misc/talk.wav"); ent->touch = door_touch; } @@ -1336,163 +1801,213 @@ void SP_func_door_rotating (edict_t *ent) ent->moveinfo.accel = ent->accel; ent->moveinfo.decel = ent->decel; ent->moveinfo.wait = ent->wait; - VectorCopy (ent->s.origin, ent->moveinfo.start_origin); - VectorCopy (ent->pos1, ent->moveinfo.start_angles); - VectorCopy (ent->s.origin, ent->moveinfo.end_origin); - VectorCopy (ent->pos2, ent->moveinfo.end_angles); + VectorCopy(ent->s.origin, ent->moveinfo.start_origin); + VectorCopy(ent->pos1, ent->moveinfo.start_angles); + VectorCopy(ent->s.origin, ent->moveinfo.end_origin); + VectorCopy(ent->pos2, ent->moveinfo.end_angles); if (ent->spawnflags & 16) + { ent->s.effects |= EF_ANIM_ALL; + } - // to simplify logic elsewhere, make non-teamed doors into a team of one + /* to simplify logic elsewhere, make non-teamed doors into a team of one */ if (!ent->team) + { ent->teammaster = ent; + } - gi.linkentity (ent); + gi.linkentity(ent); ent->nextthink = level.time + FRAMETIME; + if (ent->health || ent->targetname) + { ent->think = Think_CalcMoveSpeed; + } else + { ent->think = Think_SpawnDoorTrigger; + } } - /*QUAKED func_water (0 .5 .8) ? START_OPEN -func_water is a moveable water brush. It must be targeted to operate. Use a non-water texture at your own risk. + * func_water is a moveable water brush. It must be targeted to operate. Use a non-water texture at your own risk. + * + * START_OPEN causes the water to move to its destination when spawned and operate in reverse. + * + * "angle" determines the opening direction (up or down only) + * "speed" movement speed (25 default) + * "wait" wait before returning (-1 default, -1 = TOGGLE) + * "lip" lip remaining at end of move (0 default) + * "sounds" (yes, these need to be changed) + * 0) no sound + * 1) water + * 2) lava + */ -START_OPEN causes the water to move to its destination when spawned and operate in reverse. - -"angle" determines the opening direction (up or down only) -"speed" movement speed (25 default) -"wait" wait before returning (-1 default, -1 = TOGGLE) -"lip" lip remaining at end of move (0 default) -"sounds" (yes, these need to be changed) -0) no sound -1) water -2) lava -*/ - -void SP_func_water (edict_t *self) +void +SP_func_water(edict_t *self) { - vec3_t abs_movedir; + vec3_t abs_movedir; - G_SetMovedir (self->s.angles, self->movedir); + G_SetMovedir(self->s.angles, self->movedir); self->movetype = MOVETYPE_PUSH; self->solid = SOLID_BSP; - gi.setmodel (self, self->model); + gi.setmodel(self, self->model); switch (self->sounds) { default: break; - case 1: // water - self->moveinfo.sound_start = gi.soundindex ("world/mov_watr.wav"); - self->moveinfo.sound_end = gi.soundindex ("world/stp_watr.wav"); + case 1: /* water */ + self->moveinfo.sound_start = gi.soundindex("world/mov_watr.wav"); + self->moveinfo.sound_end = gi.soundindex("world/stp_watr.wav"); break; - case 2: // lava - self->moveinfo.sound_start = gi.soundindex ("world/mov_watr.wav"); - self->moveinfo.sound_end = gi.soundindex ("world/stp_watr.wav"); + case 2: /* lava */ + self->moveinfo.sound_start = gi.soundindex("world/mov_watr.wav"); + self->moveinfo.sound_end = gi.soundindex("world/stp_watr.wav"); break; } - // calculate second position - VectorCopy (self->s.origin, self->pos1); + /* calculate second position */ + VectorCopy(self->s.origin, self->pos1); abs_movedir[0] = fabs(self->movedir[0]); abs_movedir[1] = fabs(self->movedir[1]); abs_movedir[2] = fabs(self->movedir[2]); - self->moveinfo.distance = abs_movedir[0] * self->size[0] + abs_movedir[1] * self->size[1] + abs_movedir[2] * self->size[2] - st.lip; - VectorMA (self->pos1, self->moveinfo.distance, self->movedir, self->pos2); + self->moveinfo.distance = abs_movedir[0] * self->size[0] + abs_movedir[1] * + self->size[1] + abs_movedir[2] * self->size[2] - + st.lip; + VectorMA(self->pos1, self->moveinfo.distance, self->movedir, self->pos2); - // if it starts open, switch the positions + /* if it starts open, switch the positions */ if (self->spawnflags & DOOR_START_OPEN) { - VectorCopy (self->pos2, self->s.origin); - VectorCopy (self->pos1, self->pos2); - VectorCopy (self->s.origin, self->pos1); + VectorCopy(self->pos2, self->s.origin); + VectorCopy(self->pos1, self->pos2); + VectorCopy(self->s.origin, self->pos1); } - VectorCopy (self->pos1, self->moveinfo.start_origin); - VectorCopy (self->s.angles, self->moveinfo.start_angles); - VectorCopy (self->pos2, self->moveinfo.end_origin); - VectorCopy (self->s.angles, self->moveinfo.end_angles); + VectorCopy(self->pos1, self->moveinfo.start_origin); + VectorCopy(self->s.angles, self->moveinfo.start_angles); + VectorCopy(self->pos2, self->moveinfo.end_origin); + VectorCopy(self->s.angles, self->moveinfo.end_angles); self->moveinfo.state = STATE_BOTTOM; if (!self->speed) + { self->speed = 25; - self->moveinfo.accel = self->moveinfo.decel = self->moveinfo.speed = self->speed; + } + + self->moveinfo.accel = self->moveinfo.decel = self->moveinfo.speed = + self->speed; if (!self->wait) + { self->wait = -1; + } + self->moveinfo.wait = self->wait; self->use = door_use; if (self->wait == -1) + { self->spawnflags |= DOOR_TOGGLE; + } self->classname = "func_door"; - gi.linkentity (self); + gi.linkentity(self); } - -#define TRAIN_START_ON 1 -#define TRAIN_TOGGLE 2 -#define TRAIN_BLOCK_STOPS 4 +#define TRAIN_START_ON 1 +#define TRAIN_TOGGLE 2 +#define TRAIN_BLOCK_STOPS 4 /*QUAKED func_train (0 .5 .8) ? START_ON TOGGLE BLOCK_STOPS -Trains are moving platforms that players can ride. -The targets origin specifies the min point of the train at each corner. -The train spawns at the first target it is pointing at. -If the train is the target of a button or trigger, it will not begin moving until activated. -speed default 100 -dmg default 2 -noise looping sound to play when the train is in motion + * Trains are moving platforms that players can ride. + * The targets origin specifies the min point of the train at each corner. + * The train spawns at the first target it is pointing at. + * If the train is the target of a button or trigger, it will not begin moving until activated. + * speed default 100 + * dmg default 2 + * noise looping sound to play when the train is in motion + * + */ +void train_next(edict_t *self); -*/ -void train_next (edict_t *self); - -void train_blocked (edict_t *self, edict_t *other) +void +train_blocked(edict_t *self, edict_t *other) { - if (!(other->svflags & SVF_MONSTER) && (!other->client) ) + if (!(other->svflags & SVF_MONSTER) && (!other->client)) { - // give it a chance to go away on it's own terms (like gibs) - T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH); - // if it's still there, nuke it + /* give it a chance to go away on it's own terms (like gibs) */ + T_Damage(other, + self, + self, + vec3_origin, + other->s.origin, + vec3_origin, + 100000, + 1, + 0, + MOD_CRUSH); + + /* if it's still there, nuke it */ if (other) - BecomeExplosion1 (other); + { + BecomeExplosion1(other); + } + return; } if (level.time < self->touch_debounce_time) + { return; + } if (!self->dmg) + { return; + } + self->touch_debounce_time = level.time + 0.5; - T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH); + T_Damage(other, + self, + self, + vec3_origin, + other->s.origin, + vec3_origin, + self->dmg, + 1, + 0, + MOD_CRUSH); } -void train_wait (edict_t *self) +void +train_wait(edict_t *self) { if (self->target_ent->pathtarget) { - char *savetarget; - edict_t *ent; + char *savetarget; + edict_t *ent; ent = self->target_ent; savetarget = ent->target; ent->target = ent->pathtarget; - G_UseTargets (ent, self->activator); + G_UseTargets(ent, self->activator); ent->target = savetarget; - // make sure we didn't get killed by a killtarget + /* make sure we didn't get killed by a killtarget */ if (!self->inuse) + { return; + } } if (self->moveinfo.wait) @@ -1502,62 +2017,75 @@ void train_wait (edict_t *self) self->nextthink = level.time + self->moveinfo.wait; self->think = train_next; } - else if (self->spawnflags & TRAIN_TOGGLE) // && wait < 0 + else if (self->spawnflags & TRAIN_TOGGLE) /* && wait < 0 */ { - train_next (self); + train_next(self); self->spawnflags &= ~TRAIN_START_ON; - VectorClear (self->velocity); + VectorClear(self->velocity); self->nextthink = 0; } if (!(self->flags & FL_TEAMSLAVE)) { if (self->moveinfo.sound_end) - gi.sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self->moveinfo.sound_end, 1, ATTN_STATIC, 0); + { + gi.sound(self, + CHAN_NO_PHS_ADD + CHAN_VOICE, + self->moveinfo.sound_end, + 1, + ATTN_STATIC, + 0); + } + self->s.sound = 0; } } else { - train_next (self); + train_next(self); } - } -void train_next (edict_t *self) +void +train_next(edict_t *self) { - edict_t *ent; - vec3_t dest; - qboolean first; + edict_t *ent; + vec3_t dest; + qboolean first; first = true; again: + if (!self->target) { return; } - ent = G_PickTarget (self->target); + ent = G_PickTarget(self->target); + if (!ent) { - gi.dprintf ("train_next: bad target %s\n", self->target); + gi.dprintf("train_next: bad target %s\n", self->target); return; } self->target = ent->target; - // check for a teleport path_corner + /* check for a teleport path_corner */ if (ent->spawnflags & 1) { if (!first) { - gi.dprintf ("connected teleport path_corners, see %s at %s\n", ent->classname, vtos(ent->s.origin)); + gi.dprintf("connected teleport path_corners, see %s at %s\n", + ent->classname, + vtos(ent->s.origin)); return; } + first = false; - VectorSubtract (ent->s.origin, self->mins, self->s.origin); - VectorCopy (self->s.origin, self->s.old_origin); - gi.linkentity (self); + VectorSubtract(ent->s.origin, self->mins, self->s.origin); + VectorCopy(self->s.origin, self->s.old_origin); + gi.linkentity(self); goto again; } @@ -1567,56 +2095,71 @@ again: if (!(self->flags & FL_TEAMSLAVE)) { if (self->moveinfo.sound_start) - gi.sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self->moveinfo.sound_start, 1, ATTN_STATIC, 0); + { + gi.sound(self, + CHAN_NO_PHS_ADD + CHAN_VOICE, + self->moveinfo.sound_start, + 1, + ATTN_STATIC, + 0); + } + self->s.sound = self->moveinfo.sound_middle; } - VectorSubtract (ent->s.origin, self->mins, dest); + VectorSubtract(ent->s.origin, self->mins, dest); self->moveinfo.state = STATE_TOP; - VectorCopy (self->s.origin, self->moveinfo.start_origin); - VectorCopy (dest, self->moveinfo.end_origin); - Move_Calc (self, dest, train_wait); + VectorCopy(self->s.origin, self->moveinfo.start_origin); + VectorCopy(dest, self->moveinfo.end_origin); + Move_Calc(self, dest, train_wait); self->spawnflags |= TRAIN_START_ON; } -void train_resume (edict_t *self) +void +train_resume(edict_t *self) { - edict_t *ent; - vec3_t dest; + edict_t *ent; + vec3_t dest; ent = self->target_ent; - VectorSubtract (ent->s.origin, self->mins, dest); + VectorSubtract(ent->s.origin, self->mins, dest); self->moveinfo.state = STATE_TOP; - VectorCopy (self->s.origin, self->moveinfo.start_origin); - VectorCopy (dest, self->moveinfo.end_origin); - Move_Calc (self, dest, train_wait); + VectorCopy(self->s.origin, self->moveinfo.start_origin); + VectorCopy(dest, self->moveinfo.end_origin); + Move_Calc(self, dest, train_wait); self->spawnflags |= TRAIN_START_ON; } -void func_train_find (edict_t *self) +void +func_train_find(edict_t *self) { edict_t *ent; if (!self->target) { - gi.dprintf ("train_find: no target\n"); + gi.dprintf("train_find: no target\n"); return; } - ent = G_PickTarget (self->target); + + ent = G_PickTarget(self->target); + if (!ent) { - gi.dprintf ("train_find: target %s not found\n", self->target); + gi.dprintf("train_find: target %s not found\n", self->target); return; } + self->target = ent->target; - VectorSubtract (ent->s.origin, self->mins, self->s.origin); - gi.linkentity (self); + VectorSubtract(ent->s.origin, self->mins, self->s.origin); + gi.linkentity(self); - // if not triggered, start immediately + /* if not triggered, start immediately */ if (!self->targetname) + { self->spawnflags |= TRAIN_START_ON; + } if (self->spawnflags & TRAIN_START_ON) { @@ -1626,73 +2169,92 @@ void func_train_find (edict_t *self) } } -void train_use (edict_t *self, edict_t *other, edict_t *activator) +void +train_use(edict_t *self, edict_t *other, edict_t *activator) { self->activator = activator; if (self->spawnflags & TRAIN_START_ON) { if (!(self->spawnflags & TRAIN_TOGGLE)) + { return; + } + self->spawnflags &= ~TRAIN_START_ON; - VectorClear (self->velocity); + VectorClear(self->velocity); self->nextthink = 0; } else { if (self->target_ent) + { train_resume(self); + } else + { train_next(self); + } } } -void SP_func_train (edict_t *self) +void +SP_func_train(edict_t *self) { self->movetype = MOVETYPE_PUSH; - VectorClear (self->s.angles); + VectorClear(self->s.angles); self->blocked = train_blocked; + if (self->spawnflags & TRAIN_BLOCK_STOPS) + { self->dmg = 0; + } else { if (!self->dmg) + { self->dmg = 100; + } } + self->solid = SOLID_BSP; - gi.setmodel (self, self->model); + gi.setmodel(self, self->model); if (st.noise) - self->moveinfo.sound_middle = gi.soundindex (st.noise); + { + self->moveinfo.sound_middle = gi.soundindex(st.noise); + } if (!self->speed) + { self->speed = 100; + } self->moveinfo.speed = self->speed; self->moveinfo.accel = self->moveinfo.decel = self->moveinfo.speed; self->use = train_use; - gi.linkentity (self); + gi.linkentity(self); if (self->target) { - // start trains on the second frame, to make sure their targets have had - // a chance to spawn + /* start trains on the second frame, to make sure their targets have had */ + /* a chance to spawn */ self->nextthink = level.time + FRAMETIME; self->think = func_train_find; } else { - gi.dprintf ("func_train without a target at %s\n", vtos(self->absmin)); + gi.dprintf("func_train without a target at %s\n", vtos(self->absmin)); } } - /*QUAKED trigger_elevator (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) -*/ -void trigger_elevator_use (edict_t *self, edict_t *other, edict_t *activator) + */ +void +trigger_elevator_use(edict_t *self, edict_t *other, edict_t *activator) { edict_t *target; @@ -1707,7 +2269,8 @@ void trigger_elevator_use (edict_t *self, edict_t *other, edict_t *activator) return; } - target = G_PickTarget (other->pathtarget); + target = G_PickTarget(other->pathtarget); + if (!target) { gi.dprintf("elevator used with bad pathtarget: %s\n", other->pathtarget); @@ -1715,22 +2278,26 @@ void trigger_elevator_use (edict_t *self, edict_t *other, edict_t *activator) } self->movetarget->target_ent = target; - train_resume (self->movetarget); + train_resume(self->movetarget); } -void trigger_elevator_init (edict_t *self) +void +trigger_elevator_init(edict_t *self) { if (!self->target) { gi.dprintf("trigger_elevator has no target\n"); return; } - self->movetarget = G_PickTarget (self->target); + + self->movetarget = G_PickTarget(self->target); + if (!self->movetarget) { gi.dprintf("trigger_elevator unable to find target %s\n", self->target); return; } + if (strcmp(self->movetarget->classname, "func_train") != 0) { gi.dprintf("trigger_elevator target %s is not a train\n", self->target); @@ -1739,58 +2306,66 @@ void trigger_elevator_init (edict_t *self) self->use = trigger_elevator_use; self->svflags = SVF_NOCLIENT; - } -void SP_trigger_elevator (edict_t *self) +void +SP_trigger_elevator(edict_t *self) { self->think = trigger_elevator_init; self->nextthink = level.time + FRAMETIME; } - /*QUAKED func_timer (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) START_ON -"wait" base time between triggering all targets, default is 1 -"random" wait variance, default is 0 - -so, the basic time between firing is a random time between -(wait - random) and (wait + random) - -"delay" delay before first firing when turned on, default is 0 - -"pausetime" additional delay used only the very first time - and only if spawned with START_ON - -These can used but not touched. -*/ -void func_timer_think (edict_t *self) + * "wait" base time between triggering all targets, default is 1 + * "random" wait variance, default is 0 + * + * so, the basic time between firing is a random time between + * (wait - random) and (wait + random) + * + * "delay" delay before first firing when turned on, default is 0 + * + * "pausetime" additional delay used only the very first time + * and only if spawned with START_ON + * + * These can used but not touched. + */ +void +func_timer_think(edict_t *self) { - G_UseTargets (self, self->activator); + G_UseTargets(self, self->activator); self->nextthink = level.time + self->wait + crandom() * self->random; } -void func_timer_use (edict_t *self, edict_t *other, edict_t *activator) +void +func_timer_use(edict_t *self, edict_t *other, edict_t *activator) { self->activator = activator; - // if on, turn it off + /* if on, turn it off */ if (self->nextthink) { self->nextthink = 0; return; } - // turn it on + /* turn it on */ if (self->delay) + { self->nextthink = level.time + self->delay; + } else - func_timer_think (self); + { + func_timer_think(self); + } } -void SP_func_timer (edict_t *self) +void +SP_func_timer(edict_t *self) { if (!self->wait) + { self->wait = 1.0; + } self->use = func_timer_use; self->think = func_timer_think; @@ -1803,21 +2378,22 @@ void SP_func_timer (edict_t *self) if (self->spawnflags & 1) { - self->nextthink = level.time + 1.0 + st.pausetime + self->delay + self->wait + crandom() * self->random; + self->nextthink = level.time + 1.0 + st.pausetime + self->delay + + self->wait + crandom() * self->random; self->activator = self; } self->svflags = SVF_NOCLIENT; } - /*QUAKED func_conveyor (0 .5 .8) ? START_ON TOGGLE -Conveyors are stationary brushes that move what's on them. -The brush should be have a surface with at least one current content enabled. -speed default 100 -*/ + * Conveyors are stationary brushes that move what's on them. + * The brush should be have a surface with at least one current content enabled. + * speed default 100 + */ -void func_conveyor_use (edict_t *self, edict_t *other, edict_t *activator) +void +func_conveyor_use(edict_t *self, edict_t *other, edict_t *activator) { if (self->spawnflags & 1) { @@ -1831,13 +2407,18 @@ void func_conveyor_use (edict_t *self, edict_t *other, edict_t *activator) } if (!(self->spawnflags & 2)) + { self->count = 0; + } } -void SP_func_conveyor (edict_t *self) +void +SP_func_conveyor(edict_t *self) { if (!self->speed) + { self->speed = 100; + } if (!(self->spawnflags & 1)) { @@ -1847,131 +2428,176 @@ void SP_func_conveyor (edict_t *self) self->use = func_conveyor_use; - gi.setmodel (self, self->model); + gi.setmodel(self, self->model); self->solid = SOLID_BSP; - gi.linkentity (self); + gi.linkentity(self); } - /*QUAKED func_door_secret (0 .5 .8) ? always_shoot 1st_left 1st_down -A secret door. Slide back and then to the side. + * A secret door. Slide back and then to the side. + * + * open_once doors never closes + * 1st_left 1st move is left of arrow + * 1st_down 1st move is down from arrow + * always_shoot door is shootebale even if targeted + * + * "angle" determines the direction + * "dmg" damage to inflic when blocked (default 2) + * "wait" how long to hold in the open position (default 5, -1 means hold) + */ -open_once doors never closes -1st_left 1st move is left of arrow -1st_down 1st move is down from arrow -always_shoot door is shootebale even if targeted +#define SECRET_ALWAYS_SHOOT 1 +#define SECRET_1ST_LEFT 2 +#define SECRET_1ST_DOWN 4 -"angle" determines the direction -"dmg" damage to inflic when blocked (default 2) -"wait" how long to hold in the open position (default 5, -1 means hold) -*/ +void door_secret_move1(edict_t *self); +void door_secret_move2(edict_t *self); +void door_secret_move3(edict_t *self); +void door_secret_move4(edict_t *self); +void door_secret_move5(edict_t *self); +void door_secret_move6(edict_t *self); +void door_secret_done(edict_t *self); -#define SECRET_ALWAYS_SHOOT 1 -#define SECRET_1ST_LEFT 2 -#define SECRET_1ST_DOWN 4 - -void door_secret_move1 (edict_t *self); -void door_secret_move2 (edict_t *self); -void door_secret_move3 (edict_t *self); -void door_secret_move4 (edict_t *self); -void door_secret_move5 (edict_t *self); -void door_secret_move6 (edict_t *self); -void door_secret_done (edict_t *self); - -void door_secret_use (edict_t *self, edict_t *other, edict_t *activator) +void +door_secret_use(edict_t *self, edict_t *other, edict_t *activator) { - // make sure we're not already moving + /* make sure we're not already moving */ if (!VectorCompare(self->s.origin, vec3_origin)) + { return; + } - Move_Calc (self, self->pos1, door_secret_move1); - door_use_areaportals (self, true); + Move_Calc(self, self->pos1, door_secret_move1); + door_use_areaportals(self, true); } -void door_secret_move1 (edict_t *self) +void +door_secret_move1(edict_t *self) { self->nextthink = level.time + 1.0; self->think = door_secret_move2; } -void door_secret_move2 (edict_t *self) +void +door_secret_move2(edict_t *self) { - Move_Calc (self, self->pos2, door_secret_move3); + Move_Calc(self, self->pos2, door_secret_move3); } -void door_secret_move3 (edict_t *self) +void +door_secret_move3(edict_t *self) { if (self->wait == -1) + { return; + } + self->nextthink = level.time + self->wait; self->think = door_secret_move4; } -void door_secret_move4 (edict_t *self) +void +door_secret_move4(edict_t *self) { - Move_Calc (self, self->pos1, door_secret_move5); + Move_Calc(self, self->pos1, door_secret_move5); } -void door_secret_move5 (edict_t *self) +void +door_secret_move5(edict_t *self) { self->nextthink = level.time + 1.0; self->think = door_secret_move6; } -void door_secret_move6 (edict_t *self) +void +door_secret_move6(edict_t *self) { - Move_Calc (self, vec3_origin, door_secret_done); + Move_Calc(self, vec3_origin, door_secret_done); } -void door_secret_done (edict_t *self) +void +door_secret_done(edict_t *self) { if (!(self->targetname) || (self->spawnflags & SECRET_ALWAYS_SHOOT)) { self->health = 0; self->takedamage = DAMAGE_YES; } - door_use_areaportals (self, false); + + door_use_areaportals(self, false); } -void door_secret_blocked (edict_t *self, edict_t *other) +void +door_secret_blocked(edict_t *self, edict_t *other) { - if (!(other->svflags & SVF_MONSTER) && (!other->client) ) + if (!(other->svflags & SVF_MONSTER) && (!other->client)) { - // give it a chance to go away on it's own terms (like gibs) - T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 100000, 1, 0, MOD_CRUSH); - // if it's still there, nuke it + /* give it a chance to go away on it's own terms (like gibs) */ + T_Damage(other, + self, + self, + vec3_origin, + other->s.origin, + vec3_origin, + 100000, + 1, + 0, + MOD_CRUSH); + + /* if it's still there, nuke it */ if (other) - BecomeExplosion1 (other); + { + BecomeExplosion1(other); + } + return; } if (level.time < self->touch_debounce_time) + { return; + } + self->touch_debounce_time = level.time + 0.5; - T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH); + T_Damage(other, + self, + self, + vec3_origin, + other->s.origin, + vec3_origin, + self->dmg, + 1, + 0, + MOD_CRUSH); } -void door_secret_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +void +door_secret_die(edict_t *self, + edict_t *inflictor, + edict_t *attacker, + int damage, + vec3_t point) { self->takedamage = DAMAGE_NO; - door_secret_use (self, attacker, attacker); + door_secret_use(self, attacker, attacker); } -void SP_func_door_secret (edict_t *ent) +void +SP_func_door_secret(edict_t *ent) { - vec3_t forward, right, up; - float side; - float width; - float length; + vec3_t forward, right, up; + float side; + float width; + float length; - ent->moveinfo.sound_start = gi.soundindex ("doors/dr1_strt.wav"); - ent->moveinfo.sound_middle = gi.soundindex ("doors/dr1_mid.wav"); - ent->moveinfo.sound_end = gi.soundindex ("doors/dr1_end.wav"); + ent->moveinfo.sound_start = gi.soundindex("doors/dr1_strt.wav"); + ent->moveinfo.sound_middle = gi.soundindex("doors/dr1_mid.wav"); + ent->moveinfo.sound_end = gi.soundindex("doors/dr1_end.wav"); ent->movetype = MOVETYPE_PUSH; ent->solid = SOLID_BSP; - gi.setmodel (ent, ent->model); + gi.setmodel(ent, ent->model); ent->blocked = door_secret_blocked; ent->use = door_secret_use; @@ -1984,29 +2610,45 @@ void SP_func_door_secret (edict_t *ent) } if (!ent->dmg) + { ent->dmg = 2; + } if (!ent->wait) + { ent->wait = 5; + } ent->moveinfo.accel = - ent->moveinfo.decel = - ent->moveinfo.speed = 50; + ent->moveinfo.decel = + ent->moveinfo.speed = 50; - // calculate positions - AngleVectors (ent->s.angles, forward, right, up); - VectorClear (ent->s.angles); + /* calculate positions */ + AngleVectors(ent->s.angles, forward, right, up); + VectorClear(ent->s.angles); side = 1.0 - (ent->spawnflags & SECRET_1ST_LEFT); + if (ent->spawnflags & SECRET_1ST_DOWN) + { width = fabs(DotProduct(up, ent->size)); + } else + { width = fabs(DotProduct(right, ent->size)); + } + length = fabs(DotProduct(forward, ent->size)); + if (ent->spawnflags & SECRET_1ST_DOWN) - VectorMA (ent->s.origin, -1 * width, up, ent->pos1); + { + VectorMA(ent->s.origin, -1 * width, up, ent->pos1); + } else - VectorMA (ent->s.origin, side * width, right, ent->pos1); - VectorMA (ent->pos1, length, forward, ent->pos2); + { + VectorMA(ent->s.origin, side * width, right, ent->pos1); + } + + VectorMA(ent->pos1, length, forward, ent->pos2); if (ent->health) { @@ -2016,27 +2658,28 @@ void SP_func_door_secret (edict_t *ent) } else if (ent->targetname && ent->message) { - gi.soundindex ("misc/talk.wav"); + gi.soundindex("misc/talk.wav"); ent->touch = door_touch; } - + ent->classname = "func_door"; - gi.linkentity (ent); + gi.linkentity(ent); } - /*QUAKED func_killbox (1 0 0) ? -Kills everything inside when fired, irrespective of protection. -*/ -void use_killbox (edict_t *self, edict_t *other, edict_t *activator) + * Kills everything inside when fired, irrespective of protection. + */ +void +use_killbox(edict_t *self, edict_t *other, edict_t *activator) { - KillBox (self); + KillBox(self); } -void SP_func_killbox (edict_t *ent) +void +SP_func_killbox(edict_t *ent) { - gi.setmodel (ent, ent->model); + gi.setmodel(ent, ent->model); ent->use = use_killbox; ent->svflags = SVF_NOCLIENT; } diff --git a/src/game/ctf/g_items.c b/src/game/ctf/g_items.c index f705ceff..09fd5ec2 100644 --- a/src/game/ctf/g_items.c +++ b/src/game/ctf/g_items.c @@ -1,358 +1,492 @@ /* -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. - -*/ + * 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. + * + */ #include "g_local.h" +qboolean Pickup_Weapon(edict_t *ent, edict_t *other); +void Use_Weapon(edict_t *ent, gitem_t *inv); +void Drop_Weapon(edict_t *ent, gitem_t *inv); -qboolean Pickup_Weapon (edict_t *ent, edict_t *other); -void Use_Weapon (edict_t *ent, gitem_t *inv); -void Drop_Weapon (edict_t *ent, gitem_t *inv); +void Weapon_Blaster(edict_t *ent); +void Weapon_Shotgun(edict_t *ent); +void Weapon_SuperShotgun(edict_t *ent); +void Weapon_Machinegun(edict_t *ent); +void Weapon_Chaingun(edict_t *ent); +void Weapon_HyperBlaster(edict_t *ent); +void Weapon_RocketLauncher(edict_t *ent); +void Weapon_Grenade(edict_t *ent); +void Weapon_GrenadeLauncher(edict_t *ent); +void Weapon_Railgun(edict_t *ent); +void Weapon_BFG(edict_t *ent); -void Weapon_Blaster (edict_t *ent); -void Weapon_Shotgun (edict_t *ent); -void Weapon_SuperShotgun (edict_t *ent); -void Weapon_Machinegun (edict_t *ent); -void Weapon_Chaingun (edict_t *ent); -void Weapon_HyperBlaster (edict_t *ent); -void Weapon_RocketLauncher (edict_t *ent); -void Weapon_Grenade (edict_t *ent); -void Weapon_GrenadeLauncher (edict_t *ent); -void Weapon_Railgun (edict_t *ent); -void Weapon_BFG (edict_t *ent); +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}; -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}; +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; -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; +#define HEALTH_IGNORE_MAX 1 +#define HEALTH_TIMED 2 -#define HEALTH_IGNORE_MAX 1 -#define HEALTH_TIMED 2 +void Use_Quad(edict_t *ent, gitem_t *item); -void Use_Quad (edict_t *ent, gitem_t *item); -static int quad_drop_timeout_hack; +static int quad_drop_timeout_hack; -//====================================================================== +/* ====================================================================== */ /* -=============== -GetItemByIndex -=============== -*/ -gitem_t *GetItemByIndex (int index) + * =============== + * GetItemByIndex + * =============== + */ +gitem_t * +GetItemByIndex(int index) { - if (index == 0 || index >= game.num_items) + if ((index == 0) || (index >= game.num_items)) + { return NULL; + } return &itemlist[index]; } - /* -=============== -FindItemByClassname - -=============== -*/ -gitem_t *FindItemByClassname (char *classname) + * =============== + * FindItemByClassname + * + * =============== + */ +gitem_t * +FindItemByClassname(char *classname) { - int i; - gitem_t *it; + int i; + gitem_t *it; it = itemlist; - for (i=0 ; iclassname) + { continue; + } + if (!Q_stricmp(it->classname, classname)) + { return it; + } } return NULL; } /* -=============== -FindItem - -=============== -*/ -gitem_t *FindItem (char *pickup_name) + * =============== + * FindItem + * + * =============== + */ +gitem_t * +FindItem(char *pickup_name) { - int i; - gitem_t *it; + int i; + gitem_t *it; it = itemlist; - for (i=0 ; ipickup_name) + { continue; + } + if (!Q_stricmp(it->pickup_name, pickup_name)) + { return it; + } } return NULL; } -//====================================================================== +/* ====================================================================== */ -void DoRespawn (edict_t *ent) +void +DoRespawn(edict_t *ent) { if (ent->team) { - edict_t *master; - int count; + edict_t *master; + int count; int choice; master = ent->teammaster; - //ZOID - //in ctf, when we are weapons stay, only the master of a team of weapons - //is spawned + /* ZOID */ + /* in ctf, when we are weapons stay, only the master of a team of weapons */ + /* is spawned */ if (ctf->value && - ((int)dmflags->value & DF_WEAPONS_STAY) && - master->item && (master->item->flags & IT_WEAPON)) + ((int)dmflags->value & DF_WEAPONS_STAY) && + master->item && (master->item->flags & IT_WEAPON)) + { ent = master; - else { - //ZOID + } + else + { + /* ZOID */ for (count = 0, ent = master; ent; ent = ent->chain, count++) - ; + { + } choice = rand() % count; - for (count = 0, ent = master; count < choice; ent = ent->chain, count++) - ; + for (count = 0, ent = master; + count < choice; + ent = ent->chain, count++) + { + } } } ent->svflags &= ~SVF_NOCLIENT; ent->solid = SOLID_TRIGGER; - gi.linkentity (ent); + gi.linkentity(ent); - // send an effect + /* send an effect */ ent->s.event = EV_ITEM_RESPAWN; } -void SetRespawn (edict_t *ent, float delay) +void +SetRespawn(edict_t *ent, float delay) { ent->flags |= FL_RESPAWN; ent->svflags |= SVF_NOCLIENT; ent->solid = SOLID_NOT; ent->nextthink = level.time + delay; ent->think = DoRespawn; - gi.linkentity (ent); + gi.linkentity(ent); } +/* ====================================================================== */ -//====================================================================== - -qboolean Pickup_Powerup (edict_t *ent, edict_t *other) +qboolean +Pickup_Powerup(edict_t *ent, edict_t *other) { - int quantity; + int quantity; quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)]; - if ((skill->value == 1 && quantity >= 2) || (skill->value >= 2 && quantity >= 1)) + + if (((skill->value == 1) && + (quantity >= 2)) || ((skill->value >= 2) && (quantity >= 1))) + { return false; + } if ((coop->value) && (ent->item->flags & IT_STAY_COOP) && (quantity > 0)) + { return false; + } other->client->pers.inventory[ITEM_INDEX(ent->item)]++; if (deathmatch->value) { - if (!(ent->spawnflags & DROPPED_ITEM) ) - SetRespawn (ent, ent->item->quantity); - if (((int)dmflags->value & DF_INSTANT_ITEMS) || ((ent->item->use == Use_Quad) && (ent->spawnflags & DROPPED_PLAYER_ITEM))) + if (!(ent->spawnflags & DROPPED_ITEM)) { - if ((ent->item->use == Use_Quad) && (ent->spawnflags & DROPPED_PLAYER_ITEM)) - quad_drop_timeout_hack = (ent->nextthink - level.time) / FRAMETIME; - ent->item->use (other, ent->item); + SetRespawn(ent, ent->item->quantity); + } + + if (((int)dmflags->value & DF_INSTANT_ITEMS) || + ((ent->item->use == Use_Quad) && + (ent->spawnflags & DROPPED_PLAYER_ITEM))) + { + if ((ent->item->use == Use_Quad) && + (ent->spawnflags & DROPPED_PLAYER_ITEM)) + { + quad_drop_timeout_hack = + (ent->nextthink - level.time) / FRAMETIME; + } + + ent->item->use(other, ent->item); } } return true; } -void Drop_General (edict_t *ent, gitem_t *item) +void +Drop_General(edict_t *ent, gitem_t *item) { - Drop_Item (ent, item); + Drop_Item(ent, item); ent->client->pers.inventory[ITEM_INDEX(item)]--; - ValidateSelectedItem (ent); + ValidateSelectedItem(ent); } +/* ====================================================================== */ -//====================================================================== - -qboolean Pickup_Adrenaline (edict_t *ent, edict_t *other) +qboolean +Pickup_Adrenaline(edict_t *ent, edict_t *other) { if (!deathmatch->value) + { other->max_health += 1; + } if (other->health < other->max_health) + { other->health = other->max_health; + } if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value)) - SetRespawn (ent, ent->item->quantity); + { + SetRespawn(ent, ent->item->quantity); + } return true; } -qboolean Pickup_AncientHead (edict_t *ent, edict_t *other) +qboolean +Pickup_AncientHead(edict_t *ent, edict_t *other) { other->max_health += 2; if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value)) - SetRespawn (ent, ent->item->quantity); + { + SetRespawn(ent, ent->item->quantity); + } return true; } -qboolean Pickup_Bandolier (edict_t *ent, edict_t *other) +qboolean +Pickup_Bandolier(edict_t *ent, edict_t *other) { - gitem_t *item; - int index; + gitem_t *item; + int index; if (other->client->pers.max_bullets < 250) + { other->client->pers.max_bullets = 250; + } + if (other->client->pers.max_shells < 150) + { other->client->pers.max_shells = 150; + } + if (other->client->pers.max_cells < 250) + { other->client->pers.max_cells = 250; + } + if (other->client->pers.max_slugs < 75) + { other->client->pers.max_slugs = 75; + } item = FindItem("Bullets"); + if (item) { index = ITEM_INDEX(item); other->client->pers.inventory[index] += item->quantity; - if (other->client->pers.inventory[index] > other->client->pers.max_bullets) - other->client->pers.inventory[index] = other->client->pers.max_bullets; + + if (other->client->pers.inventory[index] > + other->client->pers.max_bullets) + { + other->client->pers.inventory[index] = + other->client->pers.max_bullets; + } } item = FindItem("Shells"); + if (item) { index = ITEM_INDEX(item); other->client->pers.inventory[index] += item->quantity; - if (other->client->pers.inventory[index] > other->client->pers.max_shells) - other->client->pers.inventory[index] = other->client->pers.max_shells; + + if (other->client->pers.inventory[index] > + other->client->pers.max_shells) + { + other->client->pers.inventory[index] = + other->client->pers.max_shells; + } } if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value)) - SetRespawn (ent, ent->item->quantity); + { + SetRespawn(ent, ent->item->quantity); + } return true; } -qboolean Pickup_Pack (edict_t *ent, edict_t *other) +qboolean +Pickup_Pack(edict_t *ent, edict_t *other) { - gitem_t *item; - int index; + gitem_t *item; + int index; if (other->client->pers.max_bullets < 300) + { other->client->pers.max_bullets = 300; + } + if (other->client->pers.max_shells < 200) + { other->client->pers.max_shells = 200; + } + if (other->client->pers.max_rockets < 100) + { other->client->pers.max_rockets = 100; + } + if (other->client->pers.max_grenades < 100) + { other->client->pers.max_grenades = 100; + } + if (other->client->pers.max_cells < 300) + { other->client->pers.max_cells = 300; + } + if (other->client->pers.max_slugs < 100) + { other->client->pers.max_slugs = 100; + } item = FindItem("Bullets"); + if (item) { index = ITEM_INDEX(item); other->client->pers.inventory[index] += item->quantity; - if (other->client->pers.inventory[index] > other->client->pers.max_bullets) - other->client->pers.inventory[index] = other->client->pers.max_bullets; + + if (other->client->pers.inventory[index] > + other->client->pers.max_bullets) + { + other->client->pers.inventory[index] = + other->client->pers.max_bullets; + } } item = FindItem("Shells"); + if (item) { index = ITEM_INDEX(item); other->client->pers.inventory[index] += item->quantity; - if (other->client->pers.inventory[index] > other->client->pers.max_shells) - other->client->pers.inventory[index] = other->client->pers.max_shells; + + if (other->client->pers.inventory[index] > + other->client->pers.max_shells) + { + other->client->pers.inventory[index] = + other->client->pers.max_shells; + } } item = FindItem("Cells"); + if (item) { index = ITEM_INDEX(item); other->client->pers.inventory[index] += item->quantity; - if (other->client->pers.inventory[index] > other->client->pers.max_cells) - other->client->pers.inventory[index] = other->client->pers.max_cells; + + if (other->client->pers.inventory[index] > + other->client->pers.max_cells) + { + other->client->pers.inventory[index] = + other->client->pers.max_cells; + } } item = FindItem("Grenades"); + if (item) { index = ITEM_INDEX(item); other->client->pers.inventory[index] += item->quantity; - if (other->client->pers.inventory[index] > other->client->pers.max_grenades) - other->client->pers.inventory[index] = other->client->pers.max_grenades; + + if (other->client->pers.inventory[index] > + other->client->pers.max_grenades) + { + other->client->pers.inventory[index] = + other->client->pers.max_grenades; + } } item = FindItem("Rockets"); + if (item) { index = ITEM_INDEX(item); other->client->pers.inventory[index] += item->quantity; - if (other->client->pers.inventory[index] > other->client->pers.max_rockets) - other->client->pers.inventory[index] = other->client->pers.max_rockets; + + if (other->client->pers.inventory[index] > + other->client->pers.max_rockets) + { + other->client->pers.inventory[index] = + other->client->pers.max_rockets; + } } item = FindItem("Slugs"); + if (item) { index = ITEM_INDEX(item); other->client->pers.inventory[index] += item->quantity; - if (other->client->pers.inventory[index] > other->client->pers.max_slugs) - other->client->pers.inventory[index] = other->client->pers.max_slugs; + + if (other->client->pers.inventory[index] > + other->client->pers.max_slugs) + { + other->client->pers.inventory[index] = + other->client->pers.max_slugs; + } } if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value)) - SetRespawn (ent, ent->item->quantity); + { + SetRespawn(ent, ent->item->quantity); + } return true; } -//====================================================================== +/* ====================================================================== */ -void Use_Quad (edict_t *ent, gitem_t *item) +void +Use_Quad(edict_t *ent, gitem_t *item) { - int timeout; + int timeout; ent->client->pers.inventory[ITEM_INDEX(item)]--; - ValidateSelectedItem (ent); + ValidateSelectedItem(ent); if (quad_drop_timeout_hack) { @@ -365,182 +499,258 @@ void Use_Quad (edict_t *ent, gitem_t *item) } if (ent->client->quad_framenum > level.framenum) + { ent->client->quad_framenum += timeout; + } else + { ent->client->quad_framenum = level.framenum + timeout; + } gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0); } -//====================================================================== +/* ====================================================================== */ -void Use_Breather (edict_t *ent, gitem_t *item) +void +Use_Breather(edict_t *ent, gitem_t *item) { ent->client->pers.inventory[ITEM_INDEX(item)]--; - ValidateSelectedItem (ent); + ValidateSelectedItem(ent); if (ent->client->breather_framenum > level.framenum) + { ent->client->breather_framenum += 300; + } else + { ent->client->breather_framenum = level.framenum + 300; - + } } -//====================================================================== +/* ====================================================================== */ -void Use_Envirosuit (edict_t *ent, gitem_t *item) +void +Use_Envirosuit(edict_t *ent, gitem_t *item) { ent->client->pers.inventory[ITEM_INDEX(item)]--; - ValidateSelectedItem (ent); + ValidateSelectedItem(ent); if (ent->client->enviro_framenum > level.framenum) + { ent->client->enviro_framenum += 300; + } else + { ent->client->enviro_framenum = level.framenum + 300; - + } } -//====================================================================== +/* ====================================================================== */ -void Use_Invulnerability (edict_t *ent, gitem_t *item) +void +Use_Invulnerability(edict_t *ent, gitem_t *item) { ent->client->pers.inventory[ITEM_INDEX(item)]--; - ValidateSelectedItem (ent); + ValidateSelectedItem(ent); if (ent->client->invincible_framenum > level.framenum) + { ent->client->invincible_framenum += 300; + } else + { 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); } -//====================================================================== +/* ====================================================================== */ -void Use_Silencer (edict_t *ent, gitem_t *item) +void +Use_Silencer(edict_t *ent, gitem_t *item) { ent->client->pers.inventory[ITEM_INDEX(item)]--; - ValidateSelectedItem (ent); + ValidateSelectedItem(ent); ent->client->silencer_shots += 30; } -//====================================================================== +/* ====================================================================== */ -qboolean Pickup_Key (edict_t *ent, edict_t *other) +qboolean +Pickup_Key(edict_t *ent, edict_t *other) { if (coop->value) { if (strcmp(ent->classname, "key_power_cube") == 0) { - if (other->client->pers.power_cubes & ((ent->spawnflags & 0x0000ff00)>> 8)) + if (other->client->pers.power_cubes & + ((ent->spawnflags & 0x0000ff00) >> 8)) + { return false; + } + other->client->pers.inventory[ITEM_INDEX(ent->item)]++; - other->client->pers.power_cubes |= ((ent->spawnflags & 0x0000ff00) >> 8); + other->client->pers.power_cubes |= + ((ent->spawnflags & 0x0000ff00) >> 8); } else { if (other->client->pers.inventory[ITEM_INDEX(ent->item)]) + { return false; + } + other->client->pers.inventory[ITEM_INDEX(ent->item)] = 1; } + return true; } + other->client->pers.inventory[ITEM_INDEX(ent->item)]++; return true; } -//====================================================================== +/* ====================================================================== */ -qboolean Add_Ammo (edict_t *ent, gitem_t *item, int count) +qboolean +Add_Ammo(edict_t *ent, gitem_t *item, int count) { - int index; - int max; + int index; + int max; if (!ent->client) + { return false; + } if (item->tag == AMMO_BULLETS) + { max = ent->client->pers.max_bullets; + } else if (item->tag == AMMO_SHELLS) + { max = ent->client->pers.max_shells; + } else if (item->tag == AMMO_ROCKETS) + { max = ent->client->pers.max_rockets; + } else if (item->tag == AMMO_GRENADES) + { max = ent->client->pers.max_grenades; + } else if (item->tag == AMMO_CELLS) + { max = ent->client->pers.max_cells; + } else if (item->tag == AMMO_SLUGS) + { max = ent->client->pers.max_slugs; + } else + { return false; + } index = ITEM_INDEX(item); if (ent->client->pers.inventory[index] == max) + { return false; + } ent->client->pers.inventory[index] += count; if (ent->client->pers.inventory[index] > max) + { ent->client->pers.inventory[index] = max; + } return true; } -qboolean Pickup_Ammo (edict_t *ent, edict_t *other) +qboolean +Pickup_Ammo(edict_t *ent, edict_t *other) { - int oldcount; - int count; - qboolean weapon; + int oldcount; + int count; + qboolean weapon; weapon = (ent->item->flags & IT_WEAPON); - if ( (weapon) && ( (int)dmflags->value & DF_INFINITE_AMMO ) ) + + if ((weapon) && ((int)dmflags->value & DF_INFINITE_AMMO)) + { count = 1000; + } else if (ent->count) + { count = ent->count; + } else + { count = ent->item->quantity; + } oldcount = other->client->pers.inventory[ITEM_INDEX(ent->item)]; - if (!Add_Ammo (other, ent->item, count)) + if (!Add_Ammo(other, ent->item, count)) + { return false; + } if (weapon && !oldcount) { - if (other->client->pers.weapon != ent->item && ( !deathmatch->value || other->client->pers.weapon == FindItem("blaster") ) ) + if ((other->client->pers.weapon != ent->item) && + (!deathmatch->value || + (other->client->pers.weapon == FindItem("blaster")))) + { other->client->newweapon = ent->item; + } + } + + if (!(ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM)) && + (deathmatch->value)) + { + SetRespawn(ent, 30); } - if (!(ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM)) && (deathmatch->value)) - SetRespawn (ent, 30); return true; } -void Drop_Ammo (edict_t *ent, gitem_t *item) +void +Drop_Ammo(edict_t *ent, gitem_t *item) { - edict_t *dropped; - int index; + edict_t *dropped; + int index; index = ITEM_INDEX(item); - dropped = Drop_Item (ent, item); + dropped = Drop_Item(ent, item); + if (ent->client->pers.inventory[index] >= item->quantity) + { dropped->count = item->quantity; + } else + { dropped->count = ent->client->pers.inventory[index]; + } + ent->client->pers.inventory[index] -= dropped->count; - ValidateSelectedItem (ent); + ValidateSelectedItem(ent); } +/* ====================================================================== */ -//====================================================================== - -void MegaHealth_think (edict_t *self) +void +MegaHealth_think(edict_t *self) { - if (self->owner->health > self->owner->max_health - //ZOID - && !CTFHasRegeneration(self->owner) - //ZOID + if ((self->owner->health > self->owner->max_health) + /* ZOID */ + && !CTFHasRegeneration(self->owner) + /* ZOID */ ) { self->nextthink = level.time + 1; @@ -549,40 +759,57 @@ void MegaHealth_think (edict_t *self) } if (!(self->spawnflags & DROPPED_ITEM) && (deathmatch->value)) - SetRespawn (self, 20); + { + SetRespawn(self, 20); + } else - G_FreeEdict (self); + { + G_FreeEdict(self); + } } -qboolean Pickup_Health (edict_t *ent, edict_t *other) +qboolean +Pickup_Health(edict_t *ent, edict_t *other) { if (!(ent->style & HEALTH_IGNORE_MAX)) + { if (other->health >= other->max_health) + { return false; + } + } - //ZOID - if (other->health >= 250 && ent->count > 25) + /* ZOID */ + if ((other->health >= 250) && (ent->count > 25)) + { return false; - //ZOID + } + + /* ZOID */ other->health += ent->count; - //ZOID - if (other->health > 250 && ent->count > 25) + /* ZOID */ + if ((other->health > 250) && (ent->count > 25)) + { other->health = 250; - //ZOID + } + + /* ZOID */ if (!(ent->style & HEALTH_IGNORE_MAX)) { if (other->health > other->max_health) + { other->health = other->max_health; + } } - //ZOID - if ((ent->style & HEALTH_TIMED) - && !CTFHasRegeneration(other) - //ZOID - ) + /* ZOID */ + if ((ent->style & HEALTH_TIMED) && + !CTFHasRegeneration(other) + /* ZOID */ + ) { ent->think = MegaHealth_think; ent->nextthink = level.time + 5; @@ -594,154 +821,204 @@ qboolean Pickup_Health (edict_t *ent, edict_t *other) else { if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value)) - SetRespawn (ent, 30); + { + SetRespawn(ent, 30); + } } return true; } -//====================================================================== +/* ====================================================================== */ -int ArmorIndex (edict_t *ent) +int +ArmorIndex(edict_t *ent) { if (!ent->client) + { return 0; + } if (ent->client->pers.inventory[jacket_armor_index] > 0) + { return jacket_armor_index; + } if (ent->client->pers.inventory[combat_armor_index] > 0) + { return combat_armor_index; + } if (ent->client->pers.inventory[body_armor_index] > 0) + { return body_armor_index; + } return 0; } -qboolean Pickup_Armor (edict_t *ent, edict_t *other) +qboolean +Pickup_Armor(edict_t *ent, edict_t *other) { - int old_armor_index; - gitem_armor_t *oldinfo; - gitem_armor_t *newinfo; - int newcount; - float salvage; - int salvagecount; + int old_armor_index; + gitem_armor_t *oldinfo; + gitem_armor_t *newinfo; + int newcount; + float salvage; + int salvagecount; - // get info on new armor + /* get info on new armor */ newinfo = (gitem_armor_t *)ent->item->info; - old_armor_index = ArmorIndex (other); + old_armor_index = ArmorIndex(other); - // handle armor shards specially + /* handle armor shards specially */ if (ent->item->tag == ARMOR_SHARD) { if (!old_armor_index) + { other->client->pers.inventory[jacket_armor_index] = 2; + } else + { other->client->pers.inventory[old_armor_index] += 2; + } } - // if player has no armor, just use it + /* if player has no armor, just use it */ else if (!old_armor_index) { - other->client->pers.inventory[ITEM_INDEX(ent->item)] = newinfo->base_count; + other->client->pers.inventory[ITEM_INDEX(ent->item)] = + newinfo->base_count; } - // use the better armor + /* use the better armor */ else { - // get info on old armor + /* get info on old armor */ if (old_armor_index == jacket_armor_index) + { oldinfo = &jacketarmor_info; + } else if (old_armor_index == combat_armor_index) + { oldinfo = &combatarmor_info; - else // (old_armor_index == body_armor_index) + } + else /* (old_armor_index == body_armor_index) */ + { oldinfo = &bodyarmor_info; + } if (newinfo->normal_protection > oldinfo->normal_protection) { - // calc new armor values + /* calc new armor values */ salvage = oldinfo->normal_protection / newinfo->normal_protection; - salvagecount = salvage * other->client->pers.inventory[old_armor_index]; + salvagecount = salvage * + other->client->pers.inventory[old_armor_index]; newcount = newinfo->base_count + salvagecount; - if (newcount > newinfo->max_count) - newcount = newinfo->max_count; - // zero count of old armor so it goes away + if (newcount > newinfo->max_count) + { + newcount = newinfo->max_count; + } + + /* zero count of old armor so it goes away */ other->client->pers.inventory[old_armor_index] = 0; - // change armor to new item with computed value + /* change armor to new item with computed value */ other->client->pers.inventory[ITEM_INDEX(ent->item)] = newcount; } else { - // calc new armor values + /* calc new armor values */ salvage = newinfo->normal_protection / oldinfo->normal_protection; salvagecount = salvage * newinfo->base_count; - newcount = other->client->pers.inventory[old_armor_index] + salvagecount; + newcount = other->client->pers.inventory[old_armor_index] + + salvagecount; + if (newcount > oldinfo->max_count) + { newcount = oldinfo->max_count; + } - // if we're already maxed out then we don't need the new armor + /* if we're already maxed out then we don't need the new armor */ if (other->client->pers.inventory[old_armor_index] >= newcount) + { return false; + } - // update current armor value + /* update current armor value */ other->client->pers.inventory[old_armor_index] = newcount; } } if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value)) - SetRespawn (ent, 20); + { + SetRespawn(ent, 20); + } return true; } -//====================================================================== +/* ====================================================================== */ -int PowerArmorType (edict_t *ent) +int +PowerArmorType(edict_t *ent) { if (!ent->client) + { return POWER_ARMOR_NONE; + } if (!(ent->flags & FL_POWER_ARMOR)) + { return POWER_ARMOR_NONE; + } if (ent->client->pers.inventory[power_shield_index] > 0) + { return POWER_ARMOR_SHIELD; + } if (ent->client->pers.inventory[power_screen_index] > 0) + { return POWER_ARMOR_SCREEN; + } return POWER_ARMOR_NONE; } -void Use_PowerArmor (edict_t *ent, gitem_t *item) +void +Use_PowerArmor(edict_t *ent, gitem_t *item) { - int index; + int index; 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 { index = ITEM_INDEX(FindItem("cells")); + if (!ent->client->pers.inventory[index]) { - gi.cprintf (ent, PRINT_HIGH, "No cells for power armor.\n"); + gi.cprintf(ent, PRINT_HIGH, "No cells for power armor.\n"); return; } + ent->flags |= FL_POWER_ARMOR; - gi.sound(ent, CHAN_AUTO, gi.soundindex("misc/power1.wav"), 1, ATTN_NORM, 0); + gi.sound(ent, CHAN_AUTO, gi.soundindex( + "misc/power1.wav"), 1, ATTN_NORM, 0); } } -qboolean Pickup_PowerArmor (edict_t *ent, edict_t *other) +qboolean +Pickup_PowerArmor(edict_t *ent, edict_t *other) { - int quantity; + int quantity; quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)]; @@ -749,108 +1026,161 @@ qboolean Pickup_PowerArmor (edict_t *ent, edict_t *other) if (deathmatch->value) { - if (!(ent->spawnflags & DROPPED_ITEM) ) - SetRespawn (ent, ent->item->quantity); - // auto-use for DM only if we didn't already have one + if (!(ent->spawnflags & DROPPED_ITEM)) + { + SetRespawn(ent, ent->item->quantity); + } + + /* auto-use for DM only if we didn't already have one */ if (!quantity) - ent->item->use (other, ent->item); + { + ent->item->use(other, ent->item); + } } return true; } -void Drop_PowerArmor (edict_t *ent, gitem_t *item) +void +Drop_PowerArmor(edict_t *ent, gitem_t *item) { - if ((ent->flags & FL_POWER_ARMOR) && (ent->client->pers.inventory[ITEM_INDEX(item)] == 1)) - Use_PowerArmor (ent, item); - Drop_General (ent, item); + if ((ent->flags & FL_POWER_ARMOR) && + (ent->client->pers.inventory[ITEM_INDEX(item)] == 1)) + { + Use_PowerArmor(ent, item); + } + + Drop_General(ent, item); } -//====================================================================== +/* ====================================================================== */ /* -=============== -Touch_Item -=============== -*/ -void Touch_Item (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) + * =============== + * Touch_Item + * =============== + */ +void +Touch_Item(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { - qboolean taken; + qboolean taken; if (!other->client) + { return; + } + if (other->health < 1) - return; // dead people can't pickup + { + return; /* dead people can't pickup */ + } + if (!ent->item->pickup) - return; // not a grabbable item? + { + return; /* not a grabbable item? */ + } if (CTFMatchSetup()) - return; // can't pick stuff up right now + { + return; /* can't pick stuff up right now */ + } taken = ent->item->pickup(ent, other); if (taken) { - // flash the screen - other->client->bonus_alpha = 0.25; + /* flash the screen */ + other->client->bonus_alpha = 0.25; - // show icon and name on status bar - other->client->ps.stats[STAT_PICKUP_ICON] = gi.imageindex(ent->item->icon); - other->client->ps.stats[STAT_PICKUP_STRING] = CS_ITEMS+ITEM_INDEX(ent->item); + /* show icon and name on status bar */ + other->client->ps.stats[STAT_PICKUP_ICON] = gi.imageindex( + ent->item->icon); + other->client->ps.stats[STAT_PICKUP_STRING] = CS_ITEMS + ITEM_INDEX( + ent->item); other->client->pickup_msg_time = level.time + 3.0; - // change selected item + /* change selected item */ if (ent->item->use) - other->client->pers.selected_item = other->client->ps.stats[STAT_SELECTED_ITEM] = ITEM_INDEX(ent->item); + { + other->client->pers.selected_item = + other->client->ps.stats[STAT_SELECTED_ITEM] = ITEM_INDEX( + ent->item); + } if (ent->item->pickup == Pickup_Health) { if (ent->count == 2) - gi.sound(other, CHAN_ITEM, gi.soundindex("items/s_health.wav"), 1, ATTN_NORM, 0); + { + gi.sound(other, CHAN_ITEM, gi.soundindex( + "items/s_health.wav"), 1, ATTN_NORM, 0); + } else if (ent->count == 10) - gi.sound(other, CHAN_ITEM, gi.soundindex("items/n_health.wav"), 1, ATTN_NORM, 0); + { + gi.sound(other, CHAN_ITEM, gi.soundindex( + "items/n_health.wav"), 1, ATTN_NORM, 0); + } else if (ent->count == 25) - gi.sound(other, CHAN_ITEM, gi.soundindex("items/l_health.wav"), 1, ATTN_NORM, 0); - else // (ent->count == 100) - gi.sound(other, CHAN_ITEM, gi.soundindex("items/m_health.wav"), 1, ATTN_NORM, 0); + { + gi.sound(other, CHAN_ITEM, gi.soundindex( + "items/l_health.wav"), 1, ATTN_NORM, 0); + } + else /* (ent->count == 100) */ + { + gi.sound(other, CHAN_ITEM, gi.soundindex( + "items/m_health.wav"), 1, ATTN_NORM, 0); + } } else if (ent->item->pickup_sound) { - gi.sound(other, CHAN_ITEM, gi.soundindex(ent->item->pickup_sound), 1, ATTN_NORM, 0); + gi.sound(other, CHAN_ITEM, gi.soundindex( + ent->item->pickup_sound), 1, ATTN_NORM, 0); } } if (!(ent->spawnflags & ITEM_TARGETS_USED)) { - G_UseTargets (ent, other); + G_UseTargets(ent, other); ent->spawnflags |= ITEM_TARGETS_USED; } if (!taken) + { return; + } - if (!((coop->value) && (ent->item->flags & IT_STAY_COOP)) || (ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM))) + if (!((coop->value) && + (ent->item->flags & IT_STAY_COOP)) || + (ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM))) { if (ent->flags & FL_RESPAWN) + { ent->flags &= ~FL_RESPAWN; + } else - G_FreeEdict (ent); + { + G_FreeEdict(ent); + } } } -//====================================================================== +/* ====================================================================== */ -static void drop_temp_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) +static void +drop_temp_touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { if (other == ent->owner) + { return; + } - Touch_Item (ent, other, plane, surf); + Touch_Item(ent, other, plane, surf); } -static void drop_make_touchable (edict_t *ent) +static void +drop_make_touchable(edict_t *ent) { ent->touch = Touch_Item; + if (deathmatch->value) { ent->nextthink = level.time + 29; @@ -858,11 +1188,12 @@ static void drop_make_touchable (edict_t *ent) } } -edict_t *Drop_Item (edict_t *ent, gitem_t *item) +edict_t * +Drop_Item(edict_t *ent, gitem_t *item) { - edict_t *dropped; - vec3_t forward, right; - vec3_t offset; + edict_t *dropped; + vec3_t forward, right; + vec3_t offset; dropped = G_Spawn(); @@ -871,43 +1202,48 @@ edict_t *Drop_Item (edict_t *ent, gitem_t *item) dropped->spawnflags = DROPPED_ITEM; dropped->s.effects = item->world_model_flags; dropped->s.renderfx = RF_GLOW; - VectorSet (dropped->mins, -15, -15, -15); - VectorSet (dropped->maxs, 15, 15, 15); - gi.setmodel (dropped, dropped->item->world_model); + VectorSet(dropped->mins, -15, -15, -15); + VectorSet(dropped->maxs, 15, 15, 15); + gi.setmodel(dropped, dropped->item->world_model); dropped->solid = SOLID_TRIGGER; - dropped->movetype = MOVETYPE_TOSS; + dropped->movetype = MOVETYPE_TOSS; dropped->touch = drop_temp_touch; dropped->owner = ent; if (ent->client) { - trace_t trace; + trace_t trace; - AngleVectors (ent->client->v_angle, forward, right, NULL); + AngleVectors(ent->client->v_angle, forward, right, NULL); VectorSet(offset, 24, 0, -16); - G_ProjectSource (ent->s.origin, offset, forward, right, dropped->s.origin); - trace = gi.trace (ent->s.origin, dropped->mins, dropped->maxs, - dropped->s.origin, ent, CONTENTS_SOLID); - VectorCopy (trace.endpos, dropped->s.origin); + G_ProjectSource(ent->s.origin, + offset, + forward, + right, + dropped->s.origin); + trace = gi.trace(ent->s.origin, dropped->mins, dropped->maxs, + dropped->s.origin, ent, CONTENTS_SOLID); + VectorCopy(trace.endpos, dropped->s.origin); } else { - AngleVectors (ent->s.angles, forward, right, NULL); - VectorCopy (ent->s.origin, dropped->s.origin); + AngleVectors(ent->s.angles, forward, right, NULL); + VectorCopy(ent->s.origin, dropped->s.origin); } - VectorScale (forward, 100, dropped->velocity); + VectorScale(forward, 100, dropped->velocity); dropped->velocity[2] = 300; dropped->think = drop_make_touchable; dropped->nextthink = level.time + 1; - gi.linkentity (dropped); + gi.linkentity(dropped); return dropped; } -void Use_Item (edict_t *ent, edict_t *other, edict_t *activator) +void +Use_Item(edict_t *ent, edict_t *other, edict_t *activator) { ent->svflags &= ~SVF_NOCLIENT; ent->use = NULL; @@ -923,47 +1259,55 @@ void Use_Item (edict_t *ent, edict_t *other, edict_t *activator) ent->touch = Touch_Item; } - gi.linkentity (ent); + gi.linkentity(ent); } -//====================================================================== +/* ====================================================================== */ /* -================ -droptofloor -================ -*/ -void droptofloor (edict_t *ent) + * ================ + * droptofloor + * ================ + */ +void +droptofloor(edict_t *ent) { - trace_t tr; - vec3_t dest; - float *v; + trace_t tr; + vec3_t dest; + float *v; - v = tv(-15,-15,-15); - VectorCopy (v, ent->mins); - v = tv(15,15,15); - VectorCopy (v, ent->maxs); + v = tv(-15, -15, -15); + VectorCopy(v, ent->mins); + v = tv(15, 15, 15); + VectorCopy(v, ent->maxs); if (ent->model) - gi.setmodel (ent, ent->model); + { + gi.setmodel(ent, ent->model); + } else - gi.setmodel (ent, ent->item->world_model); + { + gi.setmodel(ent, ent->item->world_model); + } + ent->solid = SOLID_TRIGGER; - ent->movetype = MOVETYPE_TOSS; + ent->movetype = MOVETYPE_TOSS; ent->touch = Touch_Item; - v = tv(0,0,-128); - VectorAdd (ent->s.origin, v, dest); + v = tv(0, 0, -128); + VectorAdd(ent->s.origin, v, dest); + + tr = gi.trace(ent->s.origin, ent->mins, ent->maxs, dest, ent, MASK_SOLID); - tr = gi.trace (ent->s.origin, ent->mins, ent->maxs, dest, ent, MASK_SOLID); if (tr.startsolid) { - gi.dprintf ("droptofloor: %s startsolid at %s\n", ent->classname, vtos(ent->s.origin)); - G_FreeEdict (ent); + gi.dprintf("droptofloor: %s startsolid at %s\n", ent->classname, + vtos(ent->s.origin)); + G_FreeEdict(ent); return; } - VectorCopy (tr.endpos, ent->s.origin); + VectorCopy(tr.endpos, ent->s.origin); if (ent->team) { @@ -973,6 +1317,7 @@ void droptofloor (edict_t *ent) ent->svflags |= SVF_NOCLIENT; ent->solid = SOLID_NOT; + if (ent == ent->teammaster) { ent->nextthink = level.time + FRAMETIME; @@ -995,132 +1340,180 @@ void droptofloor (edict_t *ent) ent->use = Use_Item; } - gi.linkentity (ent); + gi.linkentity(ent); } - /* -=============== -PrecacheItem - -Precaches all data needed for a given item. -This will be called for each item spawned in a level, -and for each item in each client's inventory. -=============== -*/ -void PrecacheItem (gitem_t *it) + * =============== + * PrecacheItem + * + * Precaches all data needed for a given item. + * This will be called for each item spawned in a level, + * and for each item in each client's inventory. + * =============== + */ +void +PrecacheItem(gitem_t *it) { - char *s, *start; - char data[MAX_QPATH]; - int len; - gitem_t *ammo; + char *s, *start; + char data[MAX_QPATH]; + int len; + gitem_t *ammo; if (!it) - return; - - if (it->pickup_sound) - gi.soundindex (it->pickup_sound); - if (it->world_model) - gi.modelindex (it->world_model); - if (it->view_model) - gi.modelindex (it->view_model); - if (it->icon) - gi.imageindex (it->icon); - - // parse everything for its ammo - if (it->ammo && it->ammo[0]) { - ammo = FindItem (it->ammo); - if (ammo != it) - PrecacheItem (ammo); + return; } - // parse the space seperated precache string for other items + if (it->pickup_sound) + { + gi.soundindex(it->pickup_sound); + } + + if (it->world_model) + { + gi.modelindex(it->world_model); + } + + if (it->view_model) + { + gi.modelindex(it->view_model); + } + + if (it->icon) + { + gi.imageindex(it->icon); + } + + /* parse everything for its ammo */ + if (it->ammo && it->ammo[0]) + { + ammo = FindItem(it->ammo); + + if (ammo != it) + { + PrecacheItem(ammo); + } + } + + /* parse the space seperated precache string for other items */ s = it->precaches; + if (!s || !s[0]) + { return; + } while (*s) { start = s; + while (*s && *s != ' ') + { s++; + } - len = s-start; - if (len >= MAX_QPATH || len < 5) - gi.error ("PrecacheItem: %s has bad precache string", it->classname); - memcpy (data, start, len); + len = s - start; + + if ((len >= MAX_QPATH) || (len < 5)) + { + gi.error("PrecacheItem: %s has bad precache string", it->classname); + } + + memcpy(data, start, len); data[len] = 0; - if (*s) - s++; - // determine type based on extension - if (!strcmp(data+len-3, "md2")) - gi.modelindex (data); - else if (!strcmp(data+len-3, "sp2")) - gi.modelindex (data); - else if (!strcmp(data+len-3, "wav")) - gi.soundindex (data); - if (!strcmp(data+len-3, "pcx")) - gi.imageindex (data); + if (*s) + { + s++; + } + + /* determine type based on extension */ + if (!strcmp(data + len - 3, "md2")) + { + gi.modelindex(data); + } + else if (!strcmp(data + len - 3, "sp2")) + { + gi.modelindex(data); + } + else if (!strcmp(data + len - 3, "wav")) + { + gi.soundindex(data); + } + + if (!strcmp(data + len - 3, "pcx")) + { + gi.imageindex(data); + } } } /* -============ -SpawnItem - -Sets the clipping size and plants the object on the floor. - -Items can't be immediately dropped to floor, because they might -be on an entity that hasn't spawned yet. -============ -*/ -void SpawnItem (edict_t *ent, gitem_t *item) + * ============ + * SpawnItem + * + * Sets the clipping size and plants the object on the floor. + * + * Items can't be immediately dropped to floor, because they might + * be on an entity that hasn't spawned yet. + * ============ + */ +void +SpawnItem(edict_t *ent, gitem_t *item) { - PrecacheItem (item); + PrecacheItem(item); if (ent->spawnflags) { if (strcmp(ent->classname, "key_power_cube") != 0) { ent->spawnflags = 0; - gi.dprintf("%s at %s has invalid spawnflags set\n", ent->classname, vtos(ent->s.origin)); + gi.dprintf("%s at %s has invalid spawnflags set\n", + ent->classname, + vtos(ent->s.origin)); } } - // some items will be prevented in deathmatch + /* some items will be prevented in deathmatch */ if (deathmatch->value) { - if ( (int)dmflags->value & DF_NO_ARMOR ) + if ((int)dmflags->value & DF_NO_ARMOR) { - if (item->pickup == Pickup_Armor || item->pickup == Pickup_PowerArmor) + if ((item->pickup == Pickup_Armor) || + (item->pickup == Pickup_PowerArmor)) { - G_FreeEdict (ent); + G_FreeEdict(ent); return; } } - if ( (int)dmflags->value & DF_NO_ITEMS ) + + if ((int)dmflags->value & DF_NO_ITEMS) { if (item->pickup == Pickup_Powerup) { - G_FreeEdict (ent); + G_FreeEdict(ent); return; } } - if ( (int)dmflags->value & DF_NO_HEALTH ) + + if ((int)dmflags->value & DF_NO_HEALTH) { - if (item->pickup == Pickup_Health || item->pickup == Pickup_Adrenaline || item->pickup == Pickup_AncientHead) + if ((item->pickup == Pickup_Health) || + (item->pickup == Pickup_Adrenaline) || + (item->pickup == Pickup_AncientHead)) { - G_FreeEdict (ent); + G_FreeEdict(ent); return; } } - if ( (int)dmflags->value & DF_INFINITE_AMMO ) + + if ((int)dmflags->value & DF_INFINITE_AMMO) { - if ( (item->flags == IT_AMMO) || (strcmp(ent->classname, "weapon_bfg") == 0) ) + if ((item->flags == IT_AMMO) || + (strcmp(ent->classname, "weapon_bfg") == 0)) { - G_FreeEdict (ent); + G_FreeEdict(ent); return; } } @@ -1132,56 +1525,61 @@ void SpawnItem (edict_t *ent, gitem_t *item) level.power_cubes++; } - // don't let them drop items that stay in a coop game + /* don't let them drop items that stay in a coop game */ if ((coop->value) && (item->flags & IT_STAY_COOP)) { item->drop = NULL; } - //ZOID - //Don't spawn the flags unless enabled + /* ZOID */ + /* Don't spawn the flags unless enabled */ if (!ctf->value && - (strcmp(ent->classname, "item_flag_team1") == 0 || - strcmp(ent->classname, "item_flag_team2") == 0)) { + ((strcmp(ent->classname, "item_flag_team1") == 0) || + (strcmp(ent->classname, "item_flag_team2") == 0))) + { G_FreeEdict(ent); return; } - //ZOID + + /* ZOID */ ent->item = item; - ent->nextthink = level.time + 2 * FRAMETIME; // items start after other solids + ent->nextthink = level.time + 2 * FRAMETIME; /* items start after other solids */ ent->think = droptofloor; ent->s.effects = item->world_model_flags; ent->s.renderfx = RF_GLOW; - if (ent->model) - gi.modelindex (ent->model); - //ZOID - //flags are server animated and have special handling - if (strcmp(ent->classname, "item_flag_team1") == 0 || - strcmp(ent->classname, "item_flag_team2") == 0) { + if (ent->model) + { + gi.modelindex(ent->model); + } + + /* ZOID */ + /* flags are server animated and have special handling */ + if ((strcmp(ent->classname, "item_flag_team1") == 0) || + (strcmp(ent->classname, "item_flag_team2") == 0)) + { ent->think = CTFFlagSetup; } - //ZOID + /* ZOID */ } -//====================================================================== +/* ====================================================================== */ -gitem_t itemlist[] = -{ +gitem_t itemlist[] = { { NULL - }, // leave index 0 alone + }, /* leave index 0 alone */ - // - // ARMOR - // + /* */ + /* ARMOR */ + /* */ /*QUAKED item_armor_body (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { - "item_armor_body", + "item_armor_body", Pickup_Armor, NULL, NULL, @@ -1189,9 +1587,9 @@ gitem_t itemlist[] = "misc/ar1_pkup.wav", "models/items/armor/body/tris.md2", EF_ROTATE, NULL, -/* icon */ "i_bodyarmor", -/* pickup */ "Body Armor", -/* width */ 3, +/* icon */ "i_bodyarmor", +/* pickup */ "Body Armor", +/* width */ 3, 0, NULL, IT_ARMOR, @@ -1202,9 +1600,9 @@ gitem_t itemlist[] = }, /*QUAKED item_armor_combat (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { - "item_armor_combat", + "item_armor_combat", Pickup_Armor, NULL, NULL, @@ -1212,9 +1610,9 @@ gitem_t itemlist[] = "misc/ar1_pkup.wav", "models/items/armor/combat/tris.md2", EF_ROTATE, NULL, -/* icon */ "i_combatarmor", -/* pickup */ "Combat Armor", -/* width */ 3, +/* icon */ "i_combatarmor", +/* pickup */ "Combat Armor", +/* width */ 3, 0, NULL, IT_ARMOR, @@ -1225,9 +1623,9 @@ gitem_t itemlist[] = }, /*QUAKED item_armor_jacket (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { - "item_armor_jacket", + "item_armor_jacket", Pickup_Armor, NULL, NULL, @@ -1235,9 +1633,9 @@ gitem_t itemlist[] = "misc/ar1_pkup.wav", "models/items/armor/jacket/tris.md2", EF_ROTATE, NULL, -/* icon */ "i_jacketarmor", -/* pickup */ "Jacket Armor", -/* width */ 3, +/* icon */ "i_jacketarmor", +/* pickup */ "Jacket Armor", +/* width */ 3, 0, NULL, IT_ARMOR, @@ -1248,9 +1646,9 @@ gitem_t itemlist[] = }, /*QUAKED item_armor_shard (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { - "item_armor_shard", + "item_armor_shard", Pickup_Armor, NULL, NULL, @@ -1258,9 +1656,9 @@ gitem_t itemlist[] = "misc/ar2_pkup.wav", "models/items/armor/shard/tris.md2", EF_ROTATE, NULL, -/* icon */ "i_jacketarmor", -/* pickup */ "Armor Shard", -/* width */ 3, +/* icon */ "i_jacketarmor", +/* pickup */ "Armor Shard", +/* width */ 3, 0, NULL, IT_ARMOR, @@ -1270,11 +1668,10 @@ gitem_t itemlist[] = /* precache */ "" }, - /*QUAKED item_power_screen (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { - "item_power_screen", + "item_power_screen", Pickup_PowerArmor, Use_PowerArmor, Drop_PowerArmor, @@ -1282,9 +1679,9 @@ gitem_t itemlist[] = "misc/ar3_pkup.wav", "models/items/armor/screen/tris.md2", EF_ROTATE, NULL, -/* icon */ "i_powerscreen", -/* pickup */ "Power Screen", -/* width */ 0, +/* icon */ "i_powerscreen", +/* pickup */ "Power Screen", +/* width */ 0, 60, NULL, IT_ARMOR, @@ -1295,7 +1692,7 @@ gitem_t itemlist[] = }, /*QUAKED item_power_shield (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { "item_power_shield", Pickup_PowerArmor, @@ -1305,9 +1702,9 @@ gitem_t itemlist[] = "misc/ar3_pkup.wav", "models/items/armor/shield/tris.md2", EF_ROTATE, NULL, -/* icon */ "i_powershield", -/* pickup */ "Power Shield", -/* width */ 0, +/* icon */ "i_powershield", +/* pickup */ "Power Shield", +/* width */ 0, 60, NULL, IT_ARMOR, @@ -1317,16 +1714,15 @@ gitem_t itemlist[] = /* precache */ "misc/power2.wav misc/power1.wav" }, - - // - // WEAPONS - // + /* */ + /* WEAPONS */ + /* */ /* weapon_grapple (.3 .3 1) (-16 -16 -16) (16 16 16) -always owned, never in the world -*/ + * always owned, never in the world + */ { - "weapon_grapple", + "weapon_grapple", NULL, Use_Weapon, NULL, @@ -1334,8 +1730,8 @@ always owned, never in the world "misc/w_pkup.wav", NULL, 0, "models/weapons/grapple/tris.md2", -/* icon */ "w_grapple", -/* pickup */ "Grapple", +/* icon */ "w_grapple", +/* pickup */ "Grapple", 0, 0, NULL, @@ -1343,14 +1739,15 @@ always owned, never in the world WEAP_GRAPPLE, NULL, 0, -/* precache */ "weapons/grapple/grfire.wav weapons/grapple/grpull.wav weapons/grapple/grhang.wav weapons/grapple/grreset.wav weapons/grapple/grhit.wav" +/* precache */ + "weapons/grapple/grfire.wav weapons/grapple/grpull.wav weapons/grapple/grhang.wav weapons/grapple/grreset.wav weapons/grapple/grhit.wav" }, /* weapon_blaster (.3 .3 1) (-16 -16 -16) (16 16 16) -always owned, never in the world -*/ + * always owned, never in the world + */ { - "weapon_blaster", + "weapon_blaster", NULL, Use_Weapon, NULL, @@ -1358,23 +1755,22 @@ always owned, never in the world "misc/w_pkup.wav", NULL, 0, "models/weapons/v_blast/tris.md2", -/* icon */ "w_blaster", -/* pickup */ "Blaster", +/* icon */ "w_blaster", +/* pickup */ "Blaster", 0, 0, NULL, - IT_WEAPON|IT_STAY_COOP, + IT_WEAPON | IT_STAY_COOP, WEAP_BLASTER, NULL, 0, /* precache */ "weapons/blastf1a.wav misc/lasfly.wav" }, - /*QUAKED weapon_shotgun (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { - "weapon_shotgun", + "weapon_shotgun", Pickup_Weapon, Use_Weapon, Drop_Weapon, @@ -1382,12 +1778,12 @@ always owned, never in the world "misc/w_pkup.wav", "models/weapons/g_shotg/tris.md2", EF_ROTATE, "models/weapons/v_shotg/tris.md2", -/* icon */ "w_shotgun", -/* pickup */ "Shotgun", +/* icon */ "w_shotgun", +/* pickup */ "Shotgun", 0, 1, "Shells", - IT_WEAPON|IT_STAY_COOP, + IT_WEAPON | IT_STAY_COOP, WEAP_SHOTGUN, NULL, 0, @@ -1395,9 +1791,9 @@ always owned, never in the world }, /*QUAKED weapon_supershotgun (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { - "weapon_supershotgun", + "weapon_supershotgun", Pickup_Weapon, Use_Weapon, Drop_Weapon, @@ -1405,12 +1801,12 @@ always owned, never in the world "misc/w_pkup.wav", "models/weapons/g_shotg2/tris.md2", EF_ROTATE, "models/weapons/v_shotg2/tris.md2", -/* icon */ "w_sshotgun", -/* pickup */ "Super Shotgun", +/* icon */ "w_sshotgun", +/* pickup */ "Super Shotgun", 0, 2, "Shells", - IT_WEAPON|IT_STAY_COOP, + IT_WEAPON | IT_STAY_COOP, WEAP_SUPERSHOTGUN, NULL, 0, @@ -1418,9 +1814,9 @@ always owned, never in the world }, /*QUAKED weapon_machinegun (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { - "weapon_machinegun", + "weapon_machinegun", Pickup_Weapon, Use_Weapon, Drop_Weapon, @@ -1428,22 +1824,23 @@ always owned, never in the world "misc/w_pkup.wav", "models/weapons/g_machn/tris.md2", EF_ROTATE, "models/weapons/v_machn/tris.md2", -/* icon */ "w_machinegun", -/* pickup */ "Machinegun", +/* icon */ "w_machinegun", +/* pickup */ "Machinegun", 0, 1, "Bullets", - IT_WEAPON|IT_STAY_COOP, + IT_WEAPON | IT_STAY_COOP, WEAP_MACHINEGUN, NULL, 0, -/* precache */ "weapons/machgf1b.wav weapons/machgf2b.wav weapons/machgf3b.wav weapons/machgf4b.wav weapons/machgf5b.wav" +/* precache */ + "weapons/machgf1b.wav weapons/machgf2b.wav weapons/machgf3b.wav weapons/machgf4b.wav weapons/machgf5b.wav" }, /*QUAKED weapon_chaingun (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { - "weapon_chaingun", + "weapon_chaingun", Pickup_Weapon, Use_Weapon, Drop_Weapon, @@ -1451,20 +1848,21 @@ always owned, never in the world "misc/w_pkup.wav", "models/weapons/g_chain/tris.md2", EF_ROTATE, "models/weapons/v_chain/tris.md2", -/* icon */ "w_chaingun", -/* pickup */ "Chaingun", +/* icon */ "w_chaingun", +/* pickup */ "Chaingun", 0, 1, "Bullets", - IT_WEAPON|IT_STAY_COOP, + IT_WEAPON | IT_STAY_COOP, WEAP_CHAINGUN, NULL, 0, -/* precache */ "weapons/chngnu1a.wav weapons/chngnl1a.wav weapons/machgf3b.wav` weapons/chngnd1a.wav" +/* precache */ + "weapons/chngnu1a.wav weapons/chngnl1a.wav weapons/machgf3b.wav` weapons/chngnd1a.wav" }, /*QUAKED ammo_grenades (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { "ammo_grenades", Pickup_Ammo, @@ -1474,20 +1872,21 @@ always owned, never in the world "misc/am_pkup.wav", "models/items/ammo/grenades/medium/tris.md2", 0, "models/weapons/v_handgr/tris.md2", -/* icon */ "a_grenades", -/* pickup */ "Grenades", -/* width */ 3, +/* icon */ "a_grenades", +/* pickup */ "Grenades", +/* width */ 3, 5, "grenades", - IT_AMMO|IT_WEAPON, + IT_AMMO | IT_WEAPON, WEAP_GRENADES, NULL, AMMO_GRENADES, -/* precache */ "weapons/hgrent1a.wav weapons/hgrena1b.wav weapons/hgrenc1b.wav weapons/hgrenb1a.wav weapons/hgrenb2a.wav " +/* precache */ + "weapons/hgrent1a.wav weapons/hgrena1b.wav weapons/hgrenc1b.wav weapons/hgrenb1a.wav weapons/hgrenb2a.wav " }, /*QUAKED weapon_grenadelauncher (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { "weapon_grenadelauncher", Pickup_Weapon, @@ -1497,20 +1896,21 @@ always owned, never in the world "misc/w_pkup.wav", "models/weapons/g_launch/tris.md2", EF_ROTATE, "models/weapons/v_launch/tris.md2", -/* icon */ "w_glauncher", -/* pickup */ "Grenade Launcher", +/* icon */ "w_glauncher", +/* pickup */ "Grenade Launcher", 0, 1, "Grenades", - IT_WEAPON|IT_STAY_COOP, + IT_WEAPON | IT_STAY_COOP, WEAP_GRENADELAUNCHER, NULL, 0, -/* precache */ "models/objects/grenade/tris.md2 weapons/grenlf1a.wav weapons/grenlr1b.wav weapons/grenlb1b.wav" +/* precache */ + "models/objects/grenade/tris.md2 weapons/grenlf1a.wav weapons/grenlr1b.wav weapons/grenlb1b.wav" }, /*QUAKED weapon_rocketlauncher (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { "weapon_rocketlauncher", Pickup_Weapon, @@ -1520,22 +1920,23 @@ always owned, never in the world "misc/w_pkup.wav", "models/weapons/g_rocket/tris.md2", EF_ROTATE, "models/weapons/v_rocket/tris.md2", -/* icon */ "w_rlauncher", -/* pickup */ "Rocket Launcher", +/* icon */ "w_rlauncher", +/* pickup */ "Rocket Launcher", 0, 1, "Rockets", - IT_WEAPON|IT_STAY_COOP, + IT_WEAPON | IT_STAY_COOP, WEAP_ROCKETLAUNCHER, NULL, 0, -/* precache */ "models/objects/rocket/tris.md2 weapons/rockfly.wav weapons/rocklf1a.wav weapons/rocklr1b.wav models/objects/debris2/tris.md2" +/* precache */ + "models/objects/rocket/tris.md2 weapons/rockfly.wav weapons/rocklf1a.wav weapons/rocklr1b.wav models/objects/debris2/tris.md2" }, /*QUAKED weapon_hyperblaster (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { - "weapon_hyperblaster", + "weapon_hyperblaster", Pickup_Weapon, Use_Weapon, Drop_Weapon, @@ -1543,22 +1944,23 @@ always owned, never in the world "misc/w_pkup.wav", "models/weapons/g_hyperb/tris.md2", EF_ROTATE, "models/weapons/v_hyperb/tris.md2", -/* icon */ "w_hyperblaster", -/* pickup */ "HyperBlaster", +/* icon */ "w_hyperblaster", +/* pickup */ "HyperBlaster", 0, 1, "Cells", - IT_WEAPON|IT_STAY_COOP, + IT_WEAPON | IT_STAY_COOP, WEAP_HYPERBLASTER, NULL, 0, -/* precache */ "weapons/hyprbu1a.wav weapons/hyprbl1a.wav weapons/hyprbf1a.wav weapons/hyprbd1a.wav misc/lasfly.wav" +/* precache */ + "weapons/hyprbu1a.wav weapons/hyprbl1a.wav weapons/hyprbf1a.wav weapons/hyprbd1a.wav misc/lasfly.wav" }, /*QUAKED weapon_railgun (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { - "weapon_railgun", + "weapon_railgun", Pickup_Weapon, Use_Weapon, Drop_Weapon, @@ -1566,12 +1968,12 @@ always owned, never in the world "misc/w_pkup.wav", "models/weapons/g_rail/tris.md2", EF_ROTATE, "models/weapons/v_rail/tris.md2", -/* icon */ "w_railgun", -/* pickup */ "Railgun", +/* icon */ "w_railgun", +/* pickup */ "Railgun", 0, 1, "Slugs", - IT_WEAPON|IT_STAY_COOP, + IT_WEAPON | IT_STAY_COOP, WEAP_RAILGUN, NULL, 0, @@ -1579,7 +1981,7 @@ always owned, never in the world }, /*QUAKED weapon_bfg (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { "weapon_bfg", Pickup_Weapon, @@ -1589,22 +1991,24 @@ always owned, never in the world "misc/w_pkup.wav", "models/weapons/g_bfg/tris.md2", EF_ROTATE, "models/weapons/v_bfg/tris.md2", -/* icon */ "w_bfg", -/* pickup */ "BFG10K", +/* icon */ "w_bfg", +/* pickup */ "BFG10K", 0, 50, "Cells", - IT_WEAPON|IT_STAY_COOP, + IT_WEAPON | IT_STAY_COOP, WEAP_BFG, NULL, 0, -/* precache */ "sprites/s_bfg1.sp2 sprites/s_bfg2.sp2 sprites/s_bfg3.sp2 weapons/bfg__f1y.wav weapons/bfg__l1a.wav weapons/bfg__x1b.wav weapons/bfg_hum.wav" +/* precache */ + "sprites/s_bfg1.sp2 sprites/s_bfg2.sp2 sprites/s_bfg3.sp2 weapons/bfg__f1y.wav weapons/bfg__l1a.wav weapons/bfg__x1b.wav weapons/bfg_hum.wav" }, #if 0 -//ZOID +/* ZOID */ + /*QUAKED weapon_laser (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { "weapon_laser", Pickup_Weapon, @@ -1614,8 +2018,8 @@ always owned, never in the world "misc/w_pkup.wav", "models/weapons/g_laser/tris.md2", EF_ROTATE, "models/weapons/v_laser/tris.md2", -/* icon */ "w_bfg", -/* pickup */ "Flashlight Laser", +/* icon */ "w_bfg", +/* pickup */ "Flashlight Laser", 0, 1, "Cells", @@ -1627,12 +2031,12 @@ always owned, never in the world }, #endif - // - // AMMO ITEMS - // + /* */ + /* AMMO ITEMS */ + /* */ /*QUAKED ammo_shells (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { "ammo_shells", Pickup_Ammo, @@ -1642,9 +2046,9 @@ always owned, never in the world "misc/am_pkup.wav", "models/items/ammo/shells/medium/tris.md2", 0, NULL, -/* icon */ "a_shells", -/* pickup */ "Shells", -/* width */ 3, +/* icon */ "a_shells", +/* pickup */ "Shells", +/* width */ 3, 10, NULL, IT_AMMO, @@ -1655,7 +2059,7 @@ always owned, never in the world }, /*QUAKED ammo_bullets (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { "ammo_bullets", Pickup_Ammo, @@ -1665,9 +2069,9 @@ always owned, never in the world "misc/am_pkup.wav", "models/items/ammo/bullets/medium/tris.md2", 0, NULL, -/* icon */ "a_bullets", -/* pickup */ "Bullets", -/* width */ 3, +/* icon */ "a_bullets", +/* pickup */ "Bullets", +/* width */ 3, 50, NULL, IT_AMMO, @@ -1678,7 +2082,7 @@ always owned, never in the world }, /*QUAKED ammo_cells (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { "ammo_cells", Pickup_Ammo, @@ -1688,9 +2092,9 @@ always owned, never in the world "misc/am_pkup.wav", "models/items/ammo/cells/medium/tris.md2", 0, NULL, -/* icon */ "a_cells", -/* pickup */ "Cells", -/* width */ 3, +/* icon */ "a_cells", +/* pickup */ "Cells", +/* width */ 3, 50, NULL, IT_AMMO, @@ -1701,7 +2105,7 @@ always owned, never in the world }, /*QUAKED ammo_rockets (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { "ammo_rockets", Pickup_Ammo, @@ -1711,9 +2115,9 @@ always owned, never in the world "misc/am_pkup.wav", "models/items/ammo/rockets/medium/tris.md2", 0, NULL, -/* icon */ "a_rockets", -/* pickup */ "Rockets", -/* width */ 3, +/* icon */ "a_rockets", +/* pickup */ "Rockets", +/* width */ 3, 5, NULL, IT_AMMO, @@ -1724,7 +2128,7 @@ always owned, never in the world }, /*QUAKED ammo_slugs (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { "ammo_slugs", Pickup_Ammo, @@ -1734,9 +2138,9 @@ always owned, never in the world "misc/am_pkup.wav", "models/items/ammo/slugs/medium/tris.md2", 0, NULL, -/* icon */ "a_slugs", -/* pickup */ "Slugs", -/* width */ 3, +/* icon */ "a_slugs", +/* pickup */ "Slugs", +/* width */ 3, 10, NULL, IT_AMMO, @@ -1746,14 +2150,14 @@ always owned, never in the world /* precache */ "" }, + /* */ + /* POWERUP ITEMS */ + /* */ - // - // POWERUP ITEMS - // /*QUAKED item_quad (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { - "item_quad", + "item_quad", Pickup_Powerup, Use_Quad, Drop_General, @@ -1761,9 +2165,9 @@ always owned, never in the world "items/pkup.wav", "models/items/quaddama/tris.md2", EF_ROTATE, NULL, -/* icon */ "p_quad", -/* pickup */ "Quad Damage", -/* width */ 2, +/* icon */ "p_quad", +/* pickup */ "Quad Damage", +/* width */ 2, 60, NULL, IT_POWERUP, @@ -1774,7 +2178,7 @@ always owned, never in the world }, /*QUAKED item_invulnerability (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { "item_invulnerability", Pickup_Powerup, @@ -1784,9 +2188,9 @@ always owned, never in the world "items/pkup.wav", "models/items/invulner/tris.md2", EF_ROTATE, NULL, -/* icon */ "p_invulnerability", -/* pickup */ "Invulnerability", -/* width */ 2, +/* icon */ "p_invulnerability", +/* pickup */ "Invulnerability", +/* width */ 2, 300, NULL, IT_POWERUP, @@ -1797,7 +2201,7 @@ always owned, never in the world }, /*QUAKED item_silencer (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { "item_silencer", Pickup_Powerup, @@ -1807,9 +2211,9 @@ always owned, never in the world "items/pkup.wav", "models/items/silencer/tris.md2", EF_ROTATE, NULL, -/* icon */ "p_silencer", -/* pickup */ "Silencer", -/* width */ 2, +/* icon */ "p_silencer", +/* pickup */ "Silencer", +/* width */ 2, 60, NULL, IT_POWERUP, @@ -1820,7 +2224,7 @@ always owned, never in the world }, /*QUAKED item_breather (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { "item_breather", Pickup_Powerup, @@ -1830,12 +2234,12 @@ always owned, never in the world "items/pkup.wav", "models/items/breather/tris.md2", EF_ROTATE, NULL, -/* icon */ "p_rebreather", -/* pickup */ "Rebreather", -/* width */ 2, +/* icon */ "p_rebreather", +/* pickup */ "Rebreather", +/* width */ 2, 60, NULL, - IT_STAY_COOP|IT_POWERUP, + IT_STAY_COOP | IT_POWERUP, 0, NULL, 0, @@ -1843,7 +2247,7 @@ always owned, never in the world }, /*QUAKED item_enviro (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { "item_enviro", Pickup_Powerup, @@ -1853,12 +2257,12 @@ always owned, never in the world "items/pkup.wav", "models/items/enviro/tris.md2", EF_ROTATE, NULL, -/* icon */ "p_envirosuit", -/* pickup */ "Environment Suit", -/* width */ 2, +/* icon */ "p_envirosuit", +/* pickup */ "Environment Suit", +/* width */ 2, 60, NULL, - IT_STAY_COOP|IT_POWERUP, + IT_STAY_COOP | IT_POWERUP, 0, NULL, 0, @@ -1866,8 +2270,8 @@ always owned, never in the world }, /*QUAKED item_ancient_head (.3 .3 1) (-16 -16 -16) (16 16 16) -Special item that gives +2 to maximum health -*/ + * Special item that gives +2 to maximum health + */ { "item_ancient_head", Pickup_AncientHead, @@ -1877,9 +2281,9 @@ Special item that gives +2 to maximum health "items/pkup.wav", "models/items/c_head/tris.md2", EF_ROTATE, NULL, -/* icon */ "i_fixme", -/* pickup */ "Ancient Head", -/* width */ 2, +/* icon */ "i_fixme", +/* pickup */ "Ancient Head", +/* width */ 2, 60, NULL, 0, @@ -1890,8 +2294,8 @@ Special item that gives +2 to maximum health }, /*QUAKED item_adrenaline (.3 .3 1) (-16 -16 -16) (16 16 16) -gives +1 to maximum health -*/ + * gives +1 to maximum health + */ { "item_adrenaline", Pickup_Adrenaline, @@ -1901,9 +2305,9 @@ gives +1 to maximum health "items/pkup.wav", "models/items/adrenal/tris.md2", EF_ROTATE, NULL, -/* icon */ "p_adrenaline", -/* pickup */ "Adrenaline", -/* width */ 2, +/* icon */ "p_adrenaline", +/* pickup */ "Adrenaline", +/* width */ 2, 60, NULL, 0, @@ -1914,7 +2318,7 @@ gives +1 to maximum health }, /*QUAKED item_bandolier (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { "item_bandolier", Pickup_Bandolier, @@ -1924,9 +2328,9 @@ gives +1 to maximum health "items/pkup.wav", "models/items/band/tris.md2", EF_ROTATE, NULL, -/* icon */ "p_bandolier", -/* pickup */ "Bandolier", -/* width */ 2, +/* icon */ "p_bandolier", +/* pickup */ "Bandolier", +/* width */ 2, 60, NULL, 0, @@ -1937,7 +2341,7 @@ gives +1 to maximum health }, /*QUAKED item_pack (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ + */ { "item_pack", Pickup_Pack, @@ -1947,9 +2351,9 @@ gives +1 to maximum health "items/pkup.wav", "models/items/pack/tris.md2", EF_ROTATE, NULL, -/* icon */ "i_pack", -/* pickup */ "Ammo Pack", -/* width */ 2, +/* icon */ "i_pack", +/* pickup */ "Ammo Pack", +/* width */ 2, 180, NULL, 0, @@ -1959,12 +2363,13 @@ gives +1 to maximum health /* precache */ "" }, - // - // KEYS - // + /* */ + /* KEYS */ + /* */ + /*QUAKED key_data_cd (0 .5 .8) (-16 -16 -16) (16 16 16) -key for computer centers -*/ + * key for computer centers + */ { "key_data_cd", Pickup_Key, @@ -1979,7 +2384,7 @@ key for computer centers 2, 0, NULL, - IT_STAY_COOP|IT_KEY, + IT_STAY_COOP | IT_KEY, 0, NULL, 0, @@ -1987,8 +2392,8 @@ key for computer centers }, /*QUAKED key_power_cube (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN NO_TOUCH -warehouse circuits -*/ + * warehouse circuits + */ { "key_power_cube", Pickup_Key, @@ -2003,7 +2408,7 @@ warehouse circuits 2, 0, NULL, - IT_STAY_COOP|IT_KEY, + IT_STAY_COOP | IT_KEY, 0, NULL, 0, @@ -2011,8 +2416,8 @@ warehouse circuits }, /*QUAKED key_pyramid (0 .5 .8) (-16 -16 -16) (16 16 16) -key for the entrance of jail3 -*/ + * key for the entrance of jail3 + */ { "key_pyramid", Pickup_Key, @@ -2027,7 +2432,7 @@ key for the entrance of jail3 2, 0, NULL, - IT_STAY_COOP|IT_KEY, + IT_STAY_COOP | IT_KEY, 0, NULL, 0, @@ -2035,8 +2440,8 @@ key for the entrance of jail3 }, /*QUAKED key_data_spinner (0 .5 .8) (-16 -16 -16) (16 16 16) -key for the city computer -*/ + * key for the city computer + */ { "key_data_spinner", Pickup_Key, @@ -2051,7 +2456,7 @@ key for the city computer 2, 0, NULL, - IT_STAY_COOP|IT_KEY, + IT_STAY_COOP | IT_KEY, 0, NULL, 0, @@ -2059,8 +2464,8 @@ key for the city computer }, /*QUAKED key_pass (0 .5 .8) (-16 -16 -16) (16 16 16) -security pass for the security level -*/ + * security pass for the security level + */ { "key_pass", Pickup_Key, @@ -2075,7 +2480,7 @@ security pass for the security level 2, 0, NULL, - IT_STAY_COOP|IT_KEY, + IT_STAY_COOP | IT_KEY, 0, NULL, 0, @@ -2083,8 +2488,8 @@ security pass for the security level }, /*QUAKED key_blue_key (0 .5 .8) (-16 -16 -16) (16 16 16) -normal door key - blue -*/ + * normal door key - blue + */ { "key_blue_key", Pickup_Key, @@ -2099,7 +2504,7 @@ normal door key - blue 2, 0, NULL, - IT_STAY_COOP|IT_KEY, + IT_STAY_COOP | IT_KEY, 0, NULL, 0, @@ -2107,8 +2512,8 @@ normal door key - blue }, /*QUAKED key_red_key (0 .5 .8) (-16 -16 -16) (16 16 16) -normal door key - red -*/ + * normal door key - red + */ { "key_red_key", Pickup_Key, @@ -2123,7 +2528,7 @@ normal door key - red 2, 0, NULL, - IT_STAY_COOP|IT_KEY, + IT_STAY_COOP | IT_KEY, 0, NULL, 0, @@ -2131,8 +2536,8 @@ normal door key - red }, /*QUAKED key_commander_head (0 .5 .8) (-16 -16 -16) (16 16 16) -tank commander's head -*/ + * tank commander's head + */ { "key_commander_head", Pickup_Key, @@ -2142,12 +2547,12 @@ tank commander's head "items/pkup.wav", "models/monsters/commandr/head/tris.md2", EF_GIB, NULL, -/* icon */ "k_comhead", -/* pickup */ "Commander's Head", -/* width */ 2, +/* icon */ "k_comhead", +/* pickup */ "Commander's Head", +/* width */ 2, 0, NULL, - IT_STAY_COOP|IT_KEY, + IT_STAY_COOP | IT_KEY, 0, NULL, 0, @@ -2155,8 +2560,8 @@ tank commander's head }, /*QUAKED key_airstrike_target (0 .5 .8) (-16 -16 -16) (16 16 16) -tank commander's head -*/ + * tank commander's head + */ { "key_airstrike_target", Pickup_Key, @@ -2166,12 +2571,12 @@ tank commander's head "items/pkup.wav", "models/items/keys/target/tris.md2", EF_ROTATE, NULL, -/* icon */ "i_airstrike", -/* pickup */ "Airstrike Marker", -/* width */ 2, +/* icon */ "i_airstrike", +/* pickup */ "Airstrike Marker", +/* width */ 2, 0, NULL, - IT_STAY_COOP|IT_KEY, + IT_STAY_COOP | IT_KEY, 0, NULL, 0, @@ -2187,34 +2592,35 @@ tank commander's head "items/pkup.wav", NULL, 0, NULL, -/* icon */ "i_health", -/* pickup */ "Health", -/* width */ 3, +/* icon */ "i_health", +/* pickup */ "Health", +/* width */ 3, 0, NULL, 0, 0, NULL, 0, -/* precache */ "items/s_health.wav items/n_health.wav items/l_health.wav items/m_health.wav" +/* precache */ + "items/s_health.wav items/n_health.wav items/l_health.wav items/m_health.wav" }, +/* ZOID */ -//ZOID /*QUAKED item_flag_team1 (1 0.2 0) (-16 -16 -24) (16 16 32) -*/ + */ { "item_flag_team1", CTFPickup_Flag, NULL, - CTFDrop_Flag, //Should this be null if we don't want players to drop it manually? + CTFDrop_Flag, /* Should this be null if we don't want players to drop it manually? */ NULL, "ctf/flagtk.wav", "players/male/flag1.md2", EF_FLAG1, NULL, -/* icon */ "i_ctf1", -/* pickup */ "Red Flag", -/* width */ 2, +/* icon */ "i_ctf1", +/* pickup */ "Red Flag", +/* width */ 2, 0, NULL, 0, @@ -2225,19 +2631,19 @@ tank commander's head }, /*QUAKED item_flag_team2 (1 0.2 0) (-16 -16 -24) (16 16 32) -*/ + */ { "item_flag_team2", CTFPickup_Flag, NULL, - CTFDrop_Flag, //Should this be null if we don't want players to drop it manually? + CTFDrop_Flag, /* Should this be null if we don't want players to drop it manually? */ NULL, "ctf/flagtk.wav", "players/male/flag2.md2", EF_FLAG2, NULL, -/* icon */ "i_ctf2", -/* pickup */ "Blue Flag", -/* width */ 2, +/* icon */ "i_ctf2", +/* pickup */ "Blue Flag", +/* width */ 2, 0, NULL, 0, @@ -2252,14 +2658,14 @@ tank commander's head "item_tech1", CTFPickup_Tech, NULL, - CTFDrop_Tech, //Should this be null if we don't want players to drop it manually? + CTFDrop_Tech, /* Should this be null if we don't want players to drop it manually? */ NULL, "items/pkup.wav", "models/ctf/resistance/tris.md2", EF_ROTATE, NULL, -/* icon */ "tech1", -/* pickup */ "Disruptor Shield", -/* width */ 2, +/* icon */ "tech1", +/* pickup */ "Disruptor Shield", +/* width */ 2, 0, NULL, IT_TECH, @@ -2274,14 +2680,14 @@ tank commander's head "item_tech2", CTFPickup_Tech, NULL, - CTFDrop_Tech, //Should this be null if we don't want players to drop it manually? + CTFDrop_Tech, /* Should this be null if we don't want players to drop it manually? */ NULL, "items/pkup.wav", "models/ctf/strength/tris.md2", EF_ROTATE, NULL, -/* icon */ "tech2", -/* pickup */ "Power Amplifier", -/* width */ 2, +/* icon */ "tech2", +/* pickup */ "Power Amplifier", +/* width */ 2, 0, NULL, IT_TECH, @@ -2296,14 +2702,14 @@ tank commander's head "item_tech3", CTFPickup_Tech, NULL, - CTFDrop_Tech, //Should this be null if we don't want players to drop it manually? + CTFDrop_Tech, /* Should this be null if we don't want players to drop it manually? */ NULL, "items/pkup.wav", "models/ctf/haste/tris.md2", EF_ROTATE, NULL, -/* icon */ "tech3", -/* pickup */ "Time Accel", -/* width */ 2, +/* icon */ "tech3", +/* pickup */ "Time Accel", +/* width */ 2, 0, NULL, IT_TECH, @@ -2318,14 +2724,14 @@ tank commander's head "item_tech4", CTFPickup_Tech, NULL, - CTFDrop_Tech, //Should this be null if we don't want players to drop it manually? + CTFDrop_Tech, /* Should this be null if we don't want players to drop it manually? */ NULL, "items/pkup.wav", "models/ctf/regeneration/tris.md2", EF_ROTATE, NULL, -/* icon */ "tech4", -/* pickup */ "AutoDoc", -/* width */ 2, +/* icon */ "tech4", +/* pickup */ "AutoDoc", +/* width */ 2, 0, NULL, IT_TECH, @@ -2335,108 +2741,110 @@ tank commander's head /* precache */ "ctf/tech4.wav" }, -//ZOID +/* ZOID */ - // end of list marker + /* end of list marker */ {NULL} }; - /*QUAKED item_health (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ -void SP_item_health (edict_t *self) + */ +void +SP_item_health(edict_t *self) { - if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) ) + if (deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH)) { - G_FreeEdict (self); + G_FreeEdict(self); return; } self->model = "models/items/healing/medium/tris.md2"; self->count = 10; - SpawnItem (self, FindItem ("Health")); - gi.soundindex ("items/n_health.wav"); + SpawnItem(self, FindItem("Health")); + gi.soundindex("items/n_health.wav"); } /*QUAKED item_health_small (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ -void SP_item_health_small (edict_t *self) + */ +void +SP_item_health_small(edict_t *self) { - if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) ) + if (deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH)) { - G_FreeEdict (self); + G_FreeEdict(self); return; } self->model = "models/items/healing/stimpack/tris.md2"; self->count = 2; - SpawnItem (self, FindItem ("Health")); + SpawnItem(self, FindItem("Health")); self->style = HEALTH_IGNORE_MAX; - gi.soundindex ("items/s_health.wav"); + gi.soundindex("items/s_health.wav"); } /*QUAKED item_health_large (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ -void SP_item_health_large (edict_t *self) + */ +void +SP_item_health_large(edict_t *self) { - if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) ) + if (deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH)) { - G_FreeEdict (self); + G_FreeEdict(self); return; } self->model = "models/items/healing/large/tris.md2"; self->count = 25; - SpawnItem (self, FindItem ("Health")); - gi.soundindex ("items/l_health.wav"); + SpawnItem(self, FindItem("Health")); + gi.soundindex("items/l_health.wav"); } /*QUAKED item_health_mega (.3 .3 1) (-16 -16 -16) (16 16 16) -*/ -void SP_item_health_mega (edict_t *self) + */ +void +SP_item_health_mega(edict_t *self) { - if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) ) + if (deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH)) { - G_FreeEdict (self); + G_FreeEdict(self); return; } self->model = "models/items/mega_h/tris.md2"; self->count = 100; - SpawnItem (self, FindItem ("Health")); - gi.soundindex ("items/m_health.wav"); - self->style = HEALTH_IGNORE_MAX|HEALTH_TIMED; + SpawnItem(self, FindItem("Health")); + gi.soundindex("items/m_health.wav"); + self->style = HEALTH_IGNORE_MAX | HEALTH_TIMED; } - -void InitItems (void) +void +InitItems(void) { - game.num_items = sizeof(itemlist)/sizeof(itemlist[0]) - 1; + game.num_items = sizeof(itemlist) / sizeof(itemlist[0]) - 1; } - - /* -=============== -SetItemNames - -Called by worldspawn -=============== -*/ -void SetItemNames (void) + * =============== + * SetItemNames + * + * Called by worldspawn + * =============== + */ +void +SetItemNames(void) { - int i; - gitem_t *it; + int i; + gitem_t *it; - for (i=0 ; ipickup_name); + gi.configstring(CS_ITEMS + i, it->pickup_name); } jacket_armor_index = ITEM_INDEX(FindItem("Jacket Armor")); combat_armor_index = ITEM_INDEX(FindItem("Combat Armor")); - body_armor_index = ITEM_INDEX(FindItem("Body Armor")); + body_armor_index = ITEM_INDEX(FindItem("Body Armor")); power_screen_index = ITEM_INDEX(FindItem("Power Screen")); power_shield_index = ITEM_INDEX(FindItem("Power Shield")); } diff --git a/src/game/ctf/g_main.c b/src/game/ctf/g_main.c index 6d9e478c..1cefd00e 100644 --- a/src/game/ctf/g_main.c +++ b/src/game/ctf/g_main.c @@ -1,115 +1,114 @@ /* -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. - -*/ + * 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. + * + */ #include "g_local.h" -game_locals_t game; -level_locals_t level; -game_import_t gi; -game_export_t globals; -spawn_temp_t st; +game_locals_t game; +level_locals_t level; +game_import_t gi; +game_export_t globals; +spawn_temp_t st; -int sm_meat_index; -int snd_fry; +int sm_meat_index; +int snd_fry; int meansOfDeath; -edict_t *g_edicts; +edict_t *g_edicts; -cvar_t *deathmatch; -cvar_t *coop; -cvar_t *dmflags; -cvar_t *skill; -cvar_t *fraglimit; -cvar_t *timelimit; -//ZOID -cvar_t *capturelimit; -cvar_t *instantweap; -//ZOID -cvar_t *password; -cvar_t *maxclients; -cvar_t *maxentities; -cvar_t *g_select_empty; -cvar_t *dedicated; +cvar_t *deathmatch; +cvar_t *coop; +cvar_t *dmflags; +cvar_t *skill; +cvar_t *fraglimit; +cvar_t *timelimit; +/* ZOID */ +cvar_t *capturelimit; +cvar_t *instantweap; +/* ZOID */ +cvar_t *password; +cvar_t *maxclients; +cvar_t *maxentities; +cvar_t *g_select_empty; +cvar_t *dedicated; -cvar_t *filterban; +cvar_t *filterban; -cvar_t *sv_maxvelocity; -cvar_t *sv_gravity; +cvar_t *sv_maxvelocity; +cvar_t *sv_gravity; -cvar_t *sv_rollspeed; -cvar_t *sv_rollangle; -cvar_t *gun_x; -cvar_t *gun_y; -cvar_t *gun_z; +cvar_t *sv_rollspeed; +cvar_t *sv_rollangle; +cvar_t *gun_x; +cvar_t *gun_y; +cvar_t *gun_z; -cvar_t *run_pitch; -cvar_t *run_roll; -cvar_t *bob_up; -cvar_t *bob_pitch; -cvar_t *bob_roll; +cvar_t *run_pitch; +cvar_t *run_roll; +cvar_t *bob_up; +cvar_t *bob_pitch; +cvar_t *bob_roll; -cvar_t *sv_cheats; +cvar_t *sv_cheats; -cvar_t *flood_msgs; -cvar_t *flood_persecond; -cvar_t *flood_waitdelay; +cvar_t *flood_msgs; +cvar_t *flood_persecond; +cvar_t *flood_waitdelay; -cvar_t *sv_maplist; +cvar_t *sv_maplist; -void SpawnEntities (char *mapname, char *entities, char *spawnpoint); -void ClientThink (edict_t *ent, usercmd_t *cmd); -qboolean ClientConnect (edict_t *ent, char *userinfo); -void ClientUserinfoChanged (edict_t *ent, char *userinfo); -void ClientDisconnect (edict_t *ent); -void ClientBegin (edict_t *ent); -void ClientCommand (edict_t *ent); -void RunEntity (edict_t *ent); -void WriteGame (char *filename, qboolean autosave); -void ReadGame (char *filename); -void WriteLevel (char *filename); -void ReadLevel (char *filename); -void InitGame (void); -void G_RunFrame (void); +void SpawnEntities(char *mapname, char *entities, char *spawnpoint); +void ClientThink(edict_t *ent, usercmd_t *cmd); +qboolean ClientConnect(edict_t *ent, char *userinfo); +void ClientUserinfoChanged(edict_t *ent, char *userinfo); +void ClientDisconnect(edict_t *ent); +void ClientBegin(edict_t *ent); +void ClientCommand(edict_t *ent); +void RunEntity(edict_t *ent); +void WriteGame(char *filename, qboolean autosave); +void ReadGame(char *filename); +void WriteLevel(char *filename); +void ReadLevel(char *filename); +void InitGame(void); +void G_RunFrame(void); +/* =================================================================== */ -//=================================================================== - - -void ShutdownGame (void) +void +ShutdownGame(void) { - gi.dprintf ("==== ShutdownGame ====\n"); + gi.dprintf("==== ShutdownGame ====\n"); - gi.FreeTags (TAG_LEVEL); - gi.FreeTags (TAG_GAME); + gi.FreeTags(TAG_LEVEL); + gi.FreeTags(TAG_GAME); } - /* -================= -GetGameAPI - -Returns a pointer to the structure with all entry points -and global variables -================= -*/ -game_export_t *GetGameAPI (game_import_t *import) + * ================= + * GetGameAPI + * + * Returns a pointer to the structure with all entry points + * and global variables + * ================= + */ +game_export_t * +GetGameAPI(game_import_t *import) { gi = *import; @@ -140,70 +139,76 @@ game_export_t *GetGameAPI (game_import_t *import) } #ifndef GAME_HARD_LINKED -// this is only here so the functions in q_shared.c and q_shwin.c can link -void Sys_Error (char *error, ...) +/* this is only here so the functions in q_shared.c and q_shwin.c can link */ +void +Sys_Error(char *error, ...) { - va_list argptr; - char text[1024]; + va_list argptr; + char text[1024]; - va_start (argptr, error); - vsprintf (text, error, argptr); - va_end (argptr); + va_start(argptr, error); + vsprintf(text, error, argptr); + va_end(argptr); - gi.error (ERR_FATAL, "%s", text); + gi.error(ERR_FATAL, "%s", text); } -void Com_Printf (char *msg, ...) +void +Com_Printf(char *msg, ...) { - va_list argptr; - char text[1024]; + va_list argptr; + char text[1024]; - va_start (argptr, msg); - vsprintf (text, msg, argptr); - va_end (argptr); + va_start(argptr, msg); + vsprintf(text, msg, argptr); + va_end(argptr); - gi.dprintf ("%s", text); + gi.dprintf("%s", text); } #endif -//====================================================================== - +/* ====================================================================== */ /* -================= -ClientEndServerFrames -================= -*/ -void ClientEndServerFrames (void) + * ================= + * ClientEndServerFrames + * ================= + */ +void +ClientEndServerFrames(void) { - int i; - edict_t *ent; + int i; + edict_t *ent; - // calc the player views now that all pushing - // and damage has been added - for (i=0 ; ivalue ; i++) + /* calc the player views now that all pushing */ + /* and damage has been added */ + for (i = 0; i < maxclients->value; i++) { ent = g_edicts + 1 + i; - if (!ent->inuse || !ent->client) - continue; - ClientEndServerFrame (ent); - } + if (!ent->inuse || !ent->client) + { + continue; + } + + ClientEndServerFrame(ent); + } } /* -================= -CreateTargetChangeLevel - -Returns the created target changelevel -================= -*/ -edict_t *CreateTargetChangeLevel(char *map) + * ================= + * CreateTargetChangeLevel + * + * Returns the created target changelevel + * ================= + */ +edict_t * +CreateTargetChangeLevel(char *map) { edict_t *ent; - ent = G_Spawn (); + ent = G_Spawn(); ent->classname = "target_changelevel"; Com_sprintf(level.nextmap, sizeof(level.nextmap), "%s", map); ent->map = level.nextmap; @@ -211,219 +216,275 @@ edict_t *CreateTargetChangeLevel(char *map) } /* -================= -EndDMLevel - -The timelimit or fraglimit has been exceeded -================= -*/ -void EndDMLevel (void) + * ================= + * EndDMLevel + * + * The timelimit or fraglimit has been exceeded + * ================= + */ +void +EndDMLevel(void) { - edict_t *ent; + edict_t *ent; char *s, *t, *f; static const char *seps = " ,\n\r"; - // stay on same level flag + /* stay on same level flag */ if ((int)dmflags->value & DF_SAME_LEVEL) { - BeginIntermission (CreateTargetChangeLevel (level.mapname) ); + BeginIntermission(CreateTargetChangeLevel(level.mapname)); return; } - if (*level.forcemap) { - BeginIntermission (CreateTargetChangeLevel (level.forcemap) ); + if (*level.forcemap) + { + BeginIntermission(CreateTargetChangeLevel(level.forcemap)); return; } - // see if it's in the map list - if (*sv_maplist->string) { + /* see if it's in the map list */ + if (*sv_maplist->string) + { s = strdup(sv_maplist->string); f = NULL; t = strtok(s, seps); - while (t != NULL) { - if (Q_stricmp(t, level.mapname) == 0) { - // it's in the list, go to the next one + + while (t != NULL) + { + if (Q_stricmp(t, level.mapname) == 0) + { + /* it's in the list, go to the next one */ t = strtok(NULL, seps); - if (t == NULL) { // end of list, go to first one - if (f == NULL) // there isn't a first one, same level - BeginIntermission (CreateTargetChangeLevel (level.mapname) ); + + if (t == NULL) /* end of list, go to first one */ + { + if (f == NULL) /* there isn't a first one, same level */ + { + BeginIntermission(CreateTargetChangeLevel(level.mapname)); + } else - BeginIntermission (CreateTargetChangeLevel (f) ); - } else - BeginIntermission (CreateTargetChangeLevel (t) ); + { + BeginIntermission(CreateTargetChangeLevel(f)); + } + } + else + { + BeginIntermission(CreateTargetChangeLevel(t)); + } + free(s); return; } + if (!f) + { f = t; + } + t = strtok(NULL, seps); } + free(s); } - if (level.nextmap[0]) // go to a specific map - BeginIntermission (CreateTargetChangeLevel (level.nextmap) ); - else { // search for a changelevel - ent = G_Find (NULL, FOFS(classname), "target_changelevel"); + if (level.nextmap[0]) /* go to a specific map */ + { + BeginIntermission(CreateTargetChangeLevel(level.nextmap)); + } + else /* search for a changelevel */ + { + ent = G_Find(NULL, FOFS(classname), "target_changelevel"); + if (!ent) - { // the map designer didn't include a changelevel, - // so create a fake ent that goes back to the same level - BeginIntermission (CreateTargetChangeLevel (level.mapname) ); + { /* the map designer didn't include a changelevel, */ + /* so create a fake ent that goes back to the same level */ + BeginIntermission(CreateTargetChangeLevel(level.mapname)); return; } - BeginIntermission (ent); + + BeginIntermission(ent); } } /* -================= -CheckDMRules -================= -*/ -void CheckDMRules (void) + * ================= + * CheckDMRules + * ================= + */ +void +CheckDMRules(void) { - int i; - gclient_t *cl; + int i; + gclient_t *cl; if (level.intermissiontime) - return; - - if (!deathmatch->value) - return; - - //ZOID - if (ctf->value && CTFCheckRules()) { - EndDMLevel (); + { return; } + + if (!deathmatch->value) + { + return; + } + + /* ZOID */ + if (ctf->value && CTFCheckRules()) + { + EndDMLevel(); + return; + } + if (CTFInMatch()) - return; // no checking in match mode - //ZOID + { + return; /* no checking in match mode */ + } + + /* ZOID */ if (timelimit->value) { - if (level.time >= timelimit->value*60) + if (level.time >= timelimit->value * 60) { - gi.bprintf (PRINT_HIGH, "Timelimit hit.\n"); - EndDMLevel (); + gi.bprintf(PRINT_HIGH, "Timelimit hit.\n"); + EndDMLevel(); return; } } if (fraglimit->value) - for (i=0 ; ivalue ; i++) + { + for (i = 0; i < maxclients->value; i++) { cl = game.clients + i; - if (!g_edicts[i+1].inuse) + + if (!g_edicts[i + 1].inuse) + { continue; + } if (cl->resp.score >= fraglimit->value) { - gi.bprintf (PRINT_HIGH, "Fraglimit hit.\n"); - EndDMLevel (); + gi.bprintf(PRINT_HIGH, "Fraglimit hit.\n"); + EndDMLevel(); return; } } + } } - /* -============= -ExitLevel -============= -*/ -void ExitLevel (void) + * ============= + * ExitLevel + * ============= + */ +void +ExitLevel(void) { - int i; - edict_t *ent; - char command [256]; + int i; + edict_t *ent; + char command[256]; level.exitintermission = 0; level.intermissiontime = 0; if (CTFNextMap()) + { return; + } - Com_sprintf (command, sizeof(command), "gamemap \"%s\"\n", level.changemap); - gi.AddCommandString (command); - ClientEndServerFrames (); + Com_sprintf(command, sizeof(command), "gamemap \"%s\"\n", level.changemap); + gi.AddCommandString(command); + ClientEndServerFrames(); level.changemap = NULL; - // clear some things before going to next level - for (i=0 ; ivalue ; i++) + /* clear some things before going to next level */ + for (i = 0; i < maxclients->value; i++) { ent = g_edicts + 1 + i; + if (!ent->inuse) + { continue; + } + if (ent->health > ent->client->pers.max_health) + { ent->health = ent->client->pers.max_health; + } } } /* -================ -G_RunFrame - -Advances the world by 0.1 seconds -================ -*/ -void G_RunFrame (void) + * ================ + * G_RunFrame + * + * Advances the world by 0.1 seconds + * ================ + */ +void +G_RunFrame(void) { - int i; - edict_t *ent; + int i; + edict_t *ent; level.framenum++; - level.time = level.framenum*FRAMETIME; + level.time = level.framenum * FRAMETIME; - // choose a client for monsters to target this frame - AI_SetSightClient (); + /* choose a client for monsters to target this frame */ + AI_SetSightClient(); - // exit intermissions + /* exit intermissions */ if (level.exitintermission) { - ExitLevel (); + ExitLevel(); return; } - // - // treat each object in turn - // even the world gets a chance to think - // + /* */ + /* treat each object in turn */ + /* even the world gets a chance to think */ + /* */ ent = &g_edicts[0]; - for (i=0 ; iinuse) + { continue; + } level.current_entity = ent; - VectorCopy (ent->s.origin, ent->s.old_origin); + VectorCopy(ent->s.origin, ent->s.old_origin); - // if the ground entity moved, make sure we are still on it - if ((ent->groundentity) && (ent->groundentity->linkcount != ent->groundentity_linkcount)) + /* if the ground entity moved, make sure we are still on it */ + if ((ent->groundentity) && + (ent->groundentity->linkcount != ent->groundentity_linkcount)) { ent->groundentity = NULL; - if ( !(ent->flags & (FL_SWIM|FL_FLY)) && (ent->svflags & SVF_MONSTER) ) + + if (!(ent->flags & (FL_SWIM | FL_FLY)) && + (ent->svflags & SVF_MONSTER)) { - M_CheckGround (ent); + M_CheckGround(ent); } } - if (i > 0 && i <= maxclients->value) + if ((i > 0) && (i <= maxclients->value)) { - ClientBeginServerFrame (ent); + ClientBeginServerFrame(ent); continue; } - G_RunEntity (ent); + G_RunEntity(ent); } - // see if it is time to end a deathmatch - CheckDMRules (); + /* see if it is time to end a deathmatch */ + CheckDMRules(); - // build the playerstate_t structures for all players - ClientEndServerFrames (); + /* build the playerstate_t structures for all players */ + ClientEndServerFrames(); } diff --git a/src/game/ctf/g_misc.c b/src/game/ctf/g_misc.c index 89069b91..20e01fad 100644 --- a/src/game/ctf/g_misc.c +++ b/src/game/ctf/g_misc.c @@ -1,95 +1,115 @@ /* -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. - -*/ -// g_misc.c + * 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. + * + */ +/* g_misc.c */ #include "g_local.h" - /*QUAKED func_group (0 0 0) ? -Used to group brushes together just for editor convenience. -*/ + * Used to group brushes together just for editor convenience. + */ -//===================================================== +/* ===================================================== */ -void Use_Areaportal (edict_t *ent, edict_t *other, edict_t *activator) +void +Use_Areaportal(edict_t *ent, edict_t *other, edict_t *activator) { - ent->count ^= 1; // toggle state -// gi.dprintf ("portalstate: %i = %i\n", ent->style, ent->count); - gi.SetAreaPortalState (ent->style, ent->count); + ent->count ^= 1; /* toggle state */ +/* gi.dprintf ("portalstate: %i = %i\n", ent->style, ent->count); */ + gi.SetAreaPortalState(ent->style, ent->count); } /*QUAKED func_areaportal (0 0 0) ? - -This is a non-visible object that divides the world into -areas that are seperated when this portal is not activated. -Usually enclosed in the middle of a door. -*/ -void SP_func_areaportal (edict_t *ent) + * + * This is a non-visible object that divides the world into + * areas that are seperated when this portal is not activated. + * Usually enclosed in the middle of a door. + */ +void +SP_func_areaportal(edict_t *ent) { ent->use = Use_Areaportal; - ent->count = 0; // allways start closed; + ent->count = 0; /* allways start closed; */ } -//===================================================== - +/* ===================================================== */ /* -================= -Misc functions -================= -*/ -void VelocityForDamage (int damage, vec3_t v) + * ================= + * Misc functions + * ================= + */ +void +VelocityForDamage(int damage, vec3_t v) { v[0] = 100.0 * crandom(); v[1] = 100.0 * crandom(); v[2] = 200.0 + 100.0 * random(); if (damage < 50) - VectorScale (v, 0.7, v); - else - VectorScale (v, 1.2, v); + { + VectorScale(v, 0.7, v); + } + else + { + VectorScale(v, 1.2, v); + } } -void ClipGibVelocity (edict_t *ent) +void +ClipGibVelocity(edict_t *ent) { if (ent->velocity[0] < -300) + { ent->velocity[0] = -300; + } else if (ent->velocity[0] > 300) + { ent->velocity[0] = 300; + } + if (ent->velocity[1] < -300) + { ent->velocity[1] = -300; + } else if (ent->velocity[1] > 300) + { ent->velocity[1] = 300; + } + if (ent->velocity[2] < 200) - ent->velocity[2] = 200; // always some upwards + { + ent->velocity[2] = 200; /* always some upwards */ + } else if (ent->velocity[2] > 500) + { ent->velocity[2] = 500; + } } - /* -================= -gibs -================= -*/ -void gib_think (edict_t *self) + * ================= + * gibs + * ================= + */ +void +gib_think(edict_t *self) { self->s.frame++; self->nextthink = level.time + FRAMETIME; @@ -97,26 +117,30 @@ void gib_think (edict_t *self) if (self->s.frame == 10) { self->think = G_FreeEdict; - self->nextthink = level.time + 8 + random()*10; + self->nextthink = level.time + 8 + random() * 10; } } -void gib_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +void +gib_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { - vec3_t normal_angles, right; + vec3_t normal_angles, right; if (!self->groundentity) + { return; + } self->touch = NULL; if (plane) { - gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/fhit3.wav"), 1, ATTN_NORM, 0); + gi.sound(self, CHAN_VOICE, gi.soundindex( + "misc/fhit3.wav"), 1, ATTN_NORM, 0); - vectoangles (plane->normal, normal_angles); - AngleVectors (normal_angles, NULL, right, NULL); - vectoangles (right, self->s.angles); + vectoangles(plane->normal, normal_angles); + AngleVectors(normal_angles, NULL, right, NULL); + vectoangles(right, self->s.angles); if (self->s.modelindex == sm_meat_index) { @@ -127,28 +151,34 @@ void gib_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf } } -void gib_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +void +gib_die(edict_t *self, + edict_t *inflictor, + edict_t *attacker, + int damage, + vec3_t point) { - G_FreeEdict (self); + G_FreeEdict(self); } -void ThrowGib (edict_t *self, char *gibname, int damage, int type) +void +ThrowGib(edict_t *self, char *gibname, int damage, int type) { edict_t *gib; - vec3_t vd; - vec3_t origin; - vec3_t size; - float vscale; + vec3_t vd; + vec3_t origin; + vec3_t size; + float vscale; gib = G_Spawn(); - VectorScale (self->size, 0.5, size); - VectorAdd (self->absmin, size, origin); + VectorScale(self->size, 0.5, size); + VectorAdd(self->absmin, size, origin); gib->s.origin[0] = origin[0] + crandom() * size[0]; gib->s.origin[1] = origin[1] + crandom() * size[1]; gib->s.origin[2] = origin[2] + crandom() * size[2]; - gi.setmodel (gib, gibname); + gi.setmodel(gib, gibname); gib->solid = SOLID_NOT; gib->s.effects |= EF_GIB; gib->flags |= FL_NO_KNOCKBACK; @@ -167,31 +197,32 @@ void ThrowGib (edict_t *self, char *gibname, int damage, int type) vscale = 1.0; } - VelocityForDamage (damage, vd); - VectorMA (self->velocity, vscale, vd, gib->velocity); - ClipGibVelocity (gib); - gib->avelocity[0] = random()*600; - gib->avelocity[1] = random()*600; - gib->avelocity[2] = random()*600; + VelocityForDamage(damage, vd); + VectorMA(self->velocity, vscale, vd, gib->velocity); + ClipGibVelocity(gib); + gib->avelocity[0] = random() * 600; + gib->avelocity[1] = random() * 600; + gib->avelocity[2] = random() * 600; gib->think = G_FreeEdict; - gib->nextthink = level.time + 10 + random()*10; + gib->nextthink = level.time + 10 + random() * 10; - gi.linkentity (gib); + gi.linkentity(gib); } -void ThrowHead (edict_t *self, char *gibname, int damage, int type) +void +ThrowHead(edict_t *self, char *gibname, int damage, int type) { - vec3_t vd; - float vscale; + vec3_t vd; + float vscale; self->s.skinnum = 0; self->s.frame = 0; - VectorClear (self->mins); - VectorClear (self->maxs); + VectorClear(self->mins); + VectorClear(self->maxs); self->s.modelindex2 = 0; - gi.setmodel (self, gibname); + gi.setmodel(self, gibname); self->solid = SOLID_NOT; self->s.effects |= EF_GIB; self->s.effects &= ~EF_FLIES; @@ -213,28 +244,28 @@ void ThrowHead (edict_t *self, char *gibname, int damage, int type) vscale = 1.0; } - VelocityForDamage (damage, vd); - VectorMA (self->velocity, vscale, vd, self->velocity); - ClipGibVelocity (self); + VelocityForDamage(damage, vd); + VectorMA(self->velocity, vscale, vd, self->velocity); + ClipGibVelocity(self); - self->avelocity[YAW] = crandom()*600; + self->avelocity[YAW] = crandom() * 600; self->think = G_FreeEdict; - self->nextthink = level.time + 10 + random()*10; + self->nextthink = level.time + 10 + random() * 10; - gi.linkentity (self); + gi.linkentity(self); } - -void ThrowClientHead (edict_t *self, int damage) +void +ThrowClientHead(edict_t *self, int damage) { - vec3_t vd; - char *gibname; + vec3_t vd; + char *gibname; - if (rand()&1) + if (rand() & 1) { gibname = "models/objects/gibs/head2/tris.md2"; - self->s.skinnum = 1; // second skin is player + self->s.skinnum = 1; /* second skin is player */ } else { @@ -244,9 +275,9 @@ void ThrowClientHead (edict_t *self, int damage) self->s.origin[2] += 32; self->s.frame = 0; - gi.setmodel (self, gibname); - VectorSet (self->mins, -16, -16, 0); - VectorSet (self->maxs, 16, 16, 16); + gi.setmodel(self, gibname); + VectorSet(self->mins, -16, -16, 0); + VectorSet(self->maxs, 16, 16, 16); self->takedamage = DAMAGE_NO; self->solid = SOLID_NOT; @@ -255,116 +286,134 @@ void ThrowClientHead (edict_t *self, int damage) self->flags |= FL_NO_KNOCKBACK; self->movetype = MOVETYPE_BOUNCE; - VelocityForDamage (damage, vd); - VectorAdd (self->velocity, vd, self->velocity); + VelocityForDamage(damage, vd); + VectorAdd(self->velocity, vd, self->velocity); - if (self->client) // bodies in the queue don't have a client anymore + if (self->client) /* bodies in the queue don't have a client anymore */ { self->client->anim_priority = ANIM_DEATH; self->client->anim_end = self->s.frame; } - gi.linkentity (self); + gi.linkentity(self); } - /* -================= -debris -================= -*/ -void debris_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) + * ================= + * debris + * ================= + */ +void +debris_die(edict_t *self, + edict_t *inflictor, + edict_t *attacker, + int damage, + vec3_t point) { - G_FreeEdict (self); + G_FreeEdict(self); } -void ThrowDebris (edict_t *self, char *modelname, float speed, vec3_t origin) +void +ThrowDebris(edict_t *self, char *modelname, float speed, vec3_t origin) { - edict_t *chunk; - vec3_t v; + edict_t *chunk; + vec3_t v; chunk = G_Spawn(); - VectorCopy (origin, chunk->s.origin); - gi.setmodel (chunk, modelname); + VectorCopy(origin, chunk->s.origin); + gi.setmodel(chunk, modelname); v[0] = 100 * crandom(); v[1] = 100 * crandom(); v[2] = 100 + 100 * crandom(); - VectorMA (self->velocity, speed, v, chunk->velocity); + VectorMA(self->velocity, speed, v, chunk->velocity); chunk->movetype = MOVETYPE_BOUNCE; chunk->solid = SOLID_NOT; - chunk->avelocity[0] = random()*600; - chunk->avelocity[1] = random()*600; - chunk->avelocity[2] = random()*600; + chunk->avelocity[0] = random() * 600; + chunk->avelocity[1] = random() * 600; + chunk->avelocity[2] = random() * 600; chunk->think = G_FreeEdict; - chunk->nextthink = level.time + 5 + random()*5; + chunk->nextthink = level.time + 5 + random() * 5; chunk->s.frame = 0; chunk->flags = 0; chunk->classname = "debris"; chunk->takedamage = DAMAGE_YES; chunk->die = debris_die; - gi.linkentity (chunk); + gi.linkentity(chunk); } - -void BecomeExplosion1 (edict_t *self) +void +BecomeExplosion1(edict_t *self) { - //ZOID - //flags are important - if (strcmp(self->classname, "item_flag_team1") == 0) { - CTFResetFlag(CTF_TEAM1); // this will free self! + /* ZOID */ + /* flags are important */ + if (strcmp(self->classname, "item_flag_team1") == 0) + { + CTFResetFlag(CTF_TEAM1); /* this will free self! */ gi.bprintf(PRINT_HIGH, "The %s flag has returned!\n", CTFTeamName(CTF_TEAM1)); return; } - if (strcmp(self->classname, "item_flag_team2") == 0) { - CTFResetFlag(CTF_TEAM2); // this will free self! + + if (strcmp(self->classname, "item_flag_team2") == 0) + { + CTFResetFlag(CTF_TEAM2); /* this will free self! */ gi.bprintf(PRINT_HIGH, "The %s flag has returned!\n", CTFTeamName(CTF_TEAM1)); return; } - // techs are important too - if (self->item && (self->item->flags & IT_TECH)) { - CTFRespawnTech(self); // this frees self! + + /* techs are important too */ + if (self->item && (self->item->flags & IT_TECH)) + { + CTFRespawnTech(self); /* this frees self! */ return; } - //ZOID - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_EXPLOSION1); - gi.WritePosition (self->s.origin); - gi.multicast (self->s.origin, MULTICAST_PVS); + /* ZOID */ - G_FreeEdict (self); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_EXPLOSION1); + gi.WritePosition(self->s.origin); + gi.multicast(self->s.origin, MULTICAST_PVS); + + G_FreeEdict(self); } - -void BecomeExplosion2 (edict_t *self) +void +BecomeExplosion2(edict_t *self) { - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_EXPLOSION2); - gi.WritePosition (self->s.origin); - gi.multicast (self->s.origin, MULTICAST_PVS); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_EXPLOSION2); + gi.WritePosition(self->s.origin); + gi.multicast(self->s.origin, MULTICAST_PVS); - G_FreeEdict (self); + G_FreeEdict(self); } - /*QUAKED path_corner (.5 .3 0) (-8 -8 -8) (8 8 8) TELEPORT -Target: next path corner -Pathtarget: gets used when an entity that has - this path_corner targeted touches it -*/ + * Target: next path corner + * Pathtarget: gets used when an entity that has + * this path_corner targeted touches it + */ -void path_corner_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +void +path_corner_touch(edict_t *self, + edict_t *other, + cplane_t *plane, + csurface_t *surf) { - vec3_t v; - edict_t *next; + vec3_t v; + edict_t *next; if (other->movetarget != self) + { return; - + } + if (other->enemy) + { return; + } if (self->pathtarget) { @@ -372,21 +421,25 @@ void path_corner_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface savetarget = self->target; self->target = self->pathtarget; - G_UseTargets (self, other); + G_UseTargets(self, other); self->target = savetarget; } if (self->target) + { next = G_PickTarget(self->target); + } else + { next = NULL; + } if ((next) && (next->spawnflags & 1)) { - VectorCopy (next->s.origin, v); + VectorCopy(next->s.origin, v); v[2] += next->mins[2]; v[2] -= other->mins[2]; - VectorCopy (v, other->s.origin); + VectorCopy(v, other->s.origin); next = G_PickTarget(next->target); } @@ -395,68 +448,80 @@ void path_corner_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface if (self->wait) { other->monsterinfo.pausetime = level.time + self->wait; - other->monsterinfo.stand (other); + other->monsterinfo.stand(other); return; } if (!other->movetarget) { other->monsterinfo.pausetime = level.time + 100000000; - other->monsterinfo.stand (other); + other->monsterinfo.stand(other); } else { - VectorSubtract (other->goalentity->s.origin, other->s.origin, v); - other->ideal_yaw = vectoyaw (v); + VectorSubtract(other->goalentity->s.origin, other->s.origin, v); + other->ideal_yaw = vectoyaw(v); } } -void SP_path_corner (edict_t *self) +void +SP_path_corner(edict_t *self) { if (!self->targetname) { - gi.dprintf ("path_corner with no targetname at %s\n", vtos(self->s.origin)); - G_FreeEdict (self); + gi.dprintf("path_corner with no targetname at %s\n", + vtos(self->s.origin)); + G_FreeEdict(self); return; } self->solid = SOLID_TRIGGER; self->touch = path_corner_touch; - VectorSet (self->mins, -8, -8, -8); - VectorSet (self->maxs, 8, 8, 8); + VectorSet(self->mins, -8, -8, -8); + VectorSet(self->maxs, 8, 8, 8); self->svflags |= SVF_NOCLIENT; - gi.linkentity (self); + gi.linkentity(self); } - /*QUAKED point_combat (0.5 0.3 0) (-8 -8 -8) (8 8 8) Hold -Makes this the target of a monster and it will head here -when first activated before going after the activator. If -hold is selected, it will stay here. -*/ -void point_combat_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) + * Makes this the target of a monster and it will head here + * when first activated before going after the activator. If + * hold is selected, it will stay here. + */ +void +point_combat_touch(edict_t *self, + edict_t *other, + cplane_t *plane, + csurface_t *surf) { - edict_t *activator; + edict_t *activator; if (other->movetarget != self) + { return; + } if (self->target) { other->target = self->target; other->goalentity = other->movetarget = G_PickTarget(other->target); + if (!other->goalentity) { - gi.dprintf("%s at %s target %s does not exist\n", self->classname, vtos(self->s.origin), self->target); + gi.dprintf("%s at %s target %s does not exist\n", + self->classname, + vtos(self->s.origin), + self->target); other->movetarget = self; } + self->target = NULL; } - else if ((self->spawnflags & 1) && !(other->flags & (FL_SWIM|FL_FLY))) + else if ((self->spawnflags & 1) && !(other->flags & (FL_SWIM | FL_FLY))) { other->monsterinfo.pausetime = level.time + 100000000; other->monsterinfo.aiflags |= AI_STAND_GROUND; - other->monsterinfo.stand (other); + other->monsterinfo.stand(other); } if (other->movetarget == self) @@ -473,41 +538,53 @@ void point_combat_touch (edict_t *self, edict_t *other, cplane_t *plane, csurfac savetarget = self->target; self->target = self->pathtarget; + if (other->enemy && other->enemy->client) + { activator = other->enemy; + } else if (other->oldenemy && other->oldenemy->client) + { activator = other->oldenemy; + } else if (other->activator && other->activator->client) + { activator = other->activator; + } else + { activator = other; - G_UseTargets (self, activator); + } + + G_UseTargets(self, activator); self->target = savetarget; } } -void SP_point_combat (edict_t *self) +void +SP_point_combat(edict_t *self) { if (deathmatch->value) { - G_FreeEdict (self); + G_FreeEdict(self); return; } + self->solid = SOLID_TRIGGER; self->touch = point_combat_touch; - VectorSet (self->mins, -8, -8, -16); - VectorSet (self->maxs, 8, 8, 16); + VectorSet(self->mins, -8, -8, -16); + VectorSet(self->maxs, 8, 8, 16); self->svflags = SVF_NOCLIENT; - gi.linkentity (self); + gi.linkentity(self); } - /*QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8) -Just for the debugging level. Don't use -*/ + * Just for the debugging level. Don't use + */ static int robotron[4]; -void TH_viewthing(edict_t *ent) +void +TH_viewthing(edict_t *ent) { ent->s.frame = (ent->s.frame + 1) % 7; ent->nextthink = level.time + FRAMETIME; @@ -522,144 +599,160 @@ void TH_viewthing(edict_t *ent) } } -void SP_viewthing(edict_t *ent) +void +SP_viewthing(edict_t *ent) { - gi.dprintf ("viewthing spawned\n"); + gi.dprintf("viewthing spawned\n"); ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; ent->s.renderfx = RF_FRAMELERP; - VectorSet (ent->mins, -16, -16, -24); - VectorSet (ent->maxs, 16, 16, 32); - ent->s.modelindex = gi.modelindex ("models/objects/banner/tris.md2"); - gi.linkentity (ent); + VectorSet(ent->mins, -16, -16, -24); + VectorSet(ent->maxs, 16, 16, 32); + ent->s.modelindex = gi.modelindex("models/objects/banner/tris.md2"); + gi.linkentity(ent); ent->nextthink = level.time + 0.5; ent->think = TH_viewthing; return; } - /*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4) -Used as a positional target for spotlights, etc. -*/ -void SP_info_null (edict_t *self) + * Used as a positional target for spotlights, etc. + */ +void +SP_info_null(edict_t *self) { - G_FreeEdict (self); + G_FreeEdict(self); } - /*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4) -Used as a positional target for lightning. -*/ -void SP_info_notnull (edict_t *self) + * Used as a positional target for lightning. + */ +void +SP_info_notnull(edict_t *self) { - VectorCopy (self->s.origin, self->absmin); - VectorCopy (self->s.origin, self->absmax); + VectorCopy(self->s.origin, self->absmin); + VectorCopy(self->s.origin, self->absmax); } - /*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF -Non-displayed light. -Default light value is 300. -Default style is 0. -If targeted, will toggle between on and off. -Default _cone value is 10 (used to set size of light for spotlights) -*/ + * Non-displayed light. + * Default light value is 300. + * Default style is 0. + * If targeted, will toggle between on and off. + * Default _cone value is 10 (used to set size of light for spotlights) + */ -#define START_OFF 1 +#define START_OFF 1 -static void light_use (edict_t *self, edict_t *other, edict_t *activator) +static void +light_use(edict_t *self, edict_t *other, edict_t *activator) { if (self->spawnflags & START_OFF) { - gi.configstring (CS_LIGHTS+self->style, "m"); + gi.configstring(CS_LIGHTS + self->style, "m"); self->spawnflags &= ~START_OFF; } else { - gi.configstring (CS_LIGHTS+self->style, "a"); + gi.configstring(CS_LIGHTS + self->style, "a"); self->spawnflags |= START_OFF; } } -void SP_light (edict_t *self) +void +SP_light(edict_t *self) { - // no targeted lights in deathmatch, because they cause global messages + /* no targeted lights in deathmatch, because they cause global messages */ if (!self->targetname || deathmatch->value) { - G_FreeEdict (self); + G_FreeEdict(self); return; } if (self->style >= 32) { self->use = light_use; + if (self->spawnflags & START_OFF) - gi.configstring (CS_LIGHTS+self->style, "a"); + { + gi.configstring(CS_LIGHTS + self->style, "a"); + } else - gi.configstring (CS_LIGHTS+self->style, "m"); + { + gi.configstring(CS_LIGHTS + self->style, "m"); + } } } - /*QUAKED func_wall (0 .5 .8) ? TRIGGER_SPAWN TOGGLE START_ON ANIMATED ANIMATED_FAST -This is just a solid wall if not inhibited + * This is just a solid wall if not inhibited + * + * TRIGGER_SPAWN the wall will not be present until triggered + * it will then blink in to existance; it will + * kill anything that was in it's way + * + * TOGGLE only valid for TRIGGER_SPAWN walls + * this allows the wall to be turned on and off + * + * START_ON only valid for TRIGGER_SPAWN walls + * the wall will initially be present + */ -TRIGGER_SPAWN the wall will not be present until triggered - it will then blink in to existance; it will - kill anything that was in it's way - -TOGGLE only valid for TRIGGER_SPAWN walls - this allows the wall to be turned on and off - -START_ON only valid for TRIGGER_SPAWN walls - the wall will initially be present -*/ - -void func_wall_use (edict_t *self, edict_t *other, edict_t *activator) +void +func_wall_use(edict_t *self, edict_t *other, edict_t *activator) { if (self->solid == SOLID_NOT) { self->solid = SOLID_BSP; self->svflags &= ~SVF_NOCLIENT; - KillBox (self); + KillBox(self); } else { self->solid = SOLID_NOT; self->svflags |= SVF_NOCLIENT; } - gi.linkentity (self); + + gi.linkentity(self); if (!(self->spawnflags & 2)) + { self->use = NULL; + } } -void SP_func_wall (edict_t *self) +void +SP_func_wall(edict_t *self) { self->movetype = MOVETYPE_PUSH; - gi.setmodel (self, self->model); + gi.setmodel(self, self->model); if (self->spawnflags & 8) + { self->s.effects |= EF_ANIM_ALL; - if (self->spawnflags & 16) - self->s.effects |= EF_ANIM_ALLFAST; + } - // just a wall + if (self->spawnflags & 16) + { + self->s.effects |= EF_ANIM_ALLFAST; + } + + /* just a wall */ if ((self->spawnflags & 7) == 0) { self->solid = SOLID_BSP; - gi.linkentity (self); + gi.linkentity(self); return; } - // it must be TRIGGER_SPAWN + /* it must be TRIGGER_SPAWN */ if (!(self->spawnflags & 1)) { self->spawnflags |= 1; } - // yell if the spawnflags are odd + /* yell if the spawnflags are odd */ if (self->spawnflags & 4) { if (!(self->spawnflags & 2)) @@ -670,6 +763,7 @@ void SP_func_wall (edict_t *self) } self->use = func_wall_use; + if (self->spawnflags & 4) { self->solid = SOLID_BSP; @@ -679,44 +773,69 @@ void SP_func_wall (edict_t *self) self->solid = SOLID_NOT; self->svflags |= SVF_NOCLIENT; } - gi.linkentity (self); -} + gi.linkentity(self); +} /*QUAKED func_object (0 .5 .8) ? TRIGGER_SPAWN ANIMATED ANIMATED_FAST -This is solid bmodel that will fall if it's support it removed. -*/ + * This is solid bmodel that will fall if it's support it removed. + */ -void func_object_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +void +func_object_touch(edict_t *self, + edict_t *other, + cplane_t *plane, + csurface_t *surf) { - // only squash thing we fall on top of + /* only squash thing we fall on top of */ if (!plane) + { return; + } + if (plane->normal[2] < 1.0) + { return; + } + if (other->takedamage == DAMAGE_NO) + { return; - T_Damage (other, self, self, vec3_origin, self->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH); + } + + T_Damage(other, + self, + self, + vec3_origin, + self->s.origin, + vec3_origin, + self->dmg, + 1, + 0, + MOD_CRUSH); } -void func_object_release (edict_t *self) +void +func_object_release(edict_t *self) { self->movetype = MOVETYPE_TOSS; self->touch = func_object_touch; } -void func_object_use (edict_t *self, edict_t *other, edict_t *activator) +void +func_object_use(edict_t *self, edict_t *other, edict_t *activator) { self->solid = SOLID_BSP; self->svflags &= ~SVF_NOCLIENT; self->use = NULL; - KillBox (self); - func_object_release (self); + KillBox(self); + func_object_release(self); } -void SP_func_object (edict_t *self) +void +SP_func_object(edict_t *self) { - gi.setmodel (self, self->model); + gi.setmodel(self, self->model); self->mins[0] += 1; self->mins[1] += 1; @@ -726,7 +845,9 @@ void SP_func_object (edict_t *self) self->maxs[2] -= 1; if (!self->dmg) + { self->dmg = 100; + } if (self->spawnflags == 0) { @@ -744,121 +865,155 @@ void SP_func_object (edict_t *self) } if (self->spawnflags & 2) + { self->s.effects |= EF_ANIM_ALL; + } + if (self->spawnflags & 4) + { self->s.effects |= EF_ANIM_ALLFAST; + } self->clipmask = MASK_MONSTERSOLID; - gi.linkentity (self); + gi.linkentity(self); } - /*QUAKED func_explosive (0 .5 .8) ? Trigger_Spawn ANIMATED ANIMATED_FAST -Any brush that you want to explode or break apart. If you want an -ex0plosion, set dmg and it will do a radius explosion of that amount -at the center of the bursh. - -If targeted it will not be shootable. - -health defaults to 100. - -mass defaults to 75. This determines how much debris is emitted when -it explodes. You get one large chunk per 100 of mass (up to 8) and -one small chunk per 25 of mass (up to 16). So 800 gives the most. -*/ -void func_explosive_explode (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) + * Any brush that you want to explode or break apart. If you want an + * ex0plosion, set dmg and it will do a radius explosion of that amount + * at the center of the bursh. + * + * If targeted it will not be shootable. + * + * health defaults to 100. + * + * mass defaults to 75. This determines how much debris is emitted when + * it explodes. You get one large chunk per 100 of mass (up to 8) and + * one small chunk per 25 of mass (up to 16). So 800 gives the most. + */ +void +func_explosive_explode(edict_t *self, + edict_t *inflictor, + edict_t *attacker, + int damage, + vec3_t point) { - vec3_t origin; - vec3_t chunkorigin; - vec3_t size; - int count; - int mass; + vec3_t origin; + vec3_t chunkorigin; + vec3_t size; + int count; + int mass; - // bmodel origins are (0 0 0), we need to adjust that here - VectorScale (self->size, 0.5, size); - VectorAdd (self->absmin, size, origin); - VectorCopy (origin, self->s.origin); + /* bmodel origins are (0 0 0), we need to adjust that here */ + VectorScale(self->size, 0.5, size); + VectorAdd(self->absmin, size, origin); + VectorCopy(origin, self->s.origin); self->takedamage = DAMAGE_NO; if (self->dmg) - T_RadiusDamage (self, attacker, self->dmg, NULL, self->dmg+40, MOD_EXPLOSIVE); + { + T_RadiusDamage(self, + attacker, + self->dmg, + NULL, + self->dmg + 40, + MOD_EXPLOSIVE); + } - VectorSubtract (self->s.origin, inflictor->s.origin, self->velocity); - VectorNormalize (self->velocity); - VectorScale (self->velocity, 150, self->velocity); + VectorSubtract(self->s.origin, inflictor->s.origin, self->velocity); + VectorNormalize(self->velocity); + VectorScale(self->velocity, 150, self->velocity); - // start chunks towards the center - VectorScale (size, 0.5, size); + /* start chunks towards the center */ + VectorScale(size, 0.5, size); mass = self->mass; - if (!mass) - mass = 75; - // big chunks + if (!mass) + { + mass = 75; + } + + /* big chunks */ if (mass >= 100) { count = mass / 100; + if (count > 8) + { count = 8; - while(count--) + } + + while (count--) { chunkorigin[0] = origin[0] + crandom() * size[0]; chunkorigin[1] = origin[1] + crandom() * size[1]; chunkorigin[2] = origin[2] + crandom() * size[2]; - ThrowDebris (self, "models/objects/debris1/tris.md2", 1, chunkorigin); + ThrowDebris(self, "models/objects/debris1/tris.md2", 1, chunkorigin); } } - // small chunks + /* small chunks */ count = mass / 25; + if (count > 16) + { count = 16; - while(count--) + } + + while (count--) { chunkorigin[0] = origin[0] + crandom() * size[0]; chunkorigin[1] = origin[1] + crandom() * size[1]; chunkorigin[2] = origin[2] + crandom() * size[2]; - ThrowDebris (self, "models/objects/debris2/tris.md2", 2, chunkorigin); + ThrowDebris(self, "models/objects/debris2/tris.md2", 2, chunkorigin); } - G_UseTargets (self, attacker); + G_UseTargets(self, attacker); if (self->dmg) - BecomeExplosion1 (self); + { + BecomeExplosion1(self); + } else - G_FreeEdict (self); + { + G_FreeEdict(self); + } } -void func_explosive_use(edict_t *self, edict_t *other, edict_t *activator) +void +func_explosive_use(edict_t *self, edict_t *other, edict_t *activator) { - func_explosive_explode (self, self, other, self->health, vec3_origin); + func_explosive_explode(self, self, other, self->health, vec3_origin); } -void func_explosive_spawn (edict_t *self, edict_t *other, edict_t *activator) +void +func_explosive_spawn(edict_t *self, edict_t *other, edict_t *activator) { self->solid = SOLID_BSP; self->svflags &= ~SVF_NOCLIENT; self->use = NULL; - KillBox (self); - gi.linkentity (self); + KillBox(self); + gi.linkentity(self); } -void SP_func_explosive (edict_t *self) +void +SP_func_explosive(edict_t *self) { if (deathmatch->value) - { // auto-remove for deathmatch - G_FreeEdict (self); + { /* auto-remove for deathmatch */ + G_FreeEdict(self); return; } self->movetype = MOVETYPE_PUSH; - gi.modelindex ("models/objects/debris1/tris.md2"); - gi.modelindex ("models/objects/debris2/tris.md2"); + gi.modelindex("models/objects/debris1/tris.md2"); + gi.modelindex("models/objects/debris2/tris.md2"); - gi.setmodel (self, self->model); + gi.setmodel(self, self->model); if (self->spawnflags & 1) { @@ -869,126 +1024,155 @@ void SP_func_explosive (edict_t *self) else { self->solid = SOLID_BSP; + if (self->targetname) + { self->use = func_explosive_use; + } } if (self->spawnflags & 2) + { self->s.effects |= EF_ANIM_ALL; + } + if (self->spawnflags & 4) + { self->s.effects |= EF_ANIM_ALLFAST; + } if (self->use != func_explosive_use) { if (!self->health) + { self->health = 100; + } + self->die = func_explosive_explode; self->takedamage = DAMAGE_YES; } - gi.linkentity (self); + gi.linkentity(self); } - /*QUAKED misc_explobox (0 .5 .8) (-16 -16 0) (16 16 40) -Large exploding box. You can override its mass (100), -health (80), and dmg (150). -*/ + * Large exploding box. You can override its mass (100), + * health (80), and dmg (150). + */ -void barrel_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +void +barrel_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { - float ratio; - vec3_t v; + float ratio; + vec3_t v; if ((!other->groundentity) || (other->groundentity == self)) + { return; + } ratio = (float)other->mass / (float)self->mass; - VectorSubtract (self->s.origin, other->s.origin, v); - M_walkmove (self, vectoyaw(v), 20 * ratio * FRAMETIME); + VectorSubtract(self->s.origin, other->s.origin, v); + M_walkmove(self, vectoyaw(v), 20 * ratio * FRAMETIME); } -void barrel_explode (edict_t *self) +void +barrel_explode(edict_t *self) { - vec3_t org; - float spd; - vec3_t save; + vec3_t org; + float spd; + vec3_t save; - T_RadiusDamage (self, self->activator, self->dmg, NULL, self->dmg+40, MOD_BARREL); + T_RadiusDamage(self, + self->activator, + self->dmg, + NULL, + self->dmg + 40, + MOD_BARREL); - VectorCopy (self->s.origin, save); - VectorMA (self->absmin, 0.5, self->size, self->s.origin); + VectorCopy(self->s.origin, save); + VectorMA(self->absmin, 0.5, self->size, self->s.origin); - // a few big chunks + /* a few big chunks */ spd = 1.5 * (float)self->dmg / 200.0; org[0] = self->s.origin[0] + crandom() * self->size[0]; org[1] = self->s.origin[1] + crandom() * self->size[1]; org[2] = self->s.origin[2] + crandom() * self->size[2]; - ThrowDebris (self, "models/objects/debris1/tris.md2", spd, org); + ThrowDebris(self, "models/objects/debris1/tris.md2", spd, org); org[0] = self->s.origin[0] + crandom() * self->size[0]; org[1] = self->s.origin[1] + crandom() * self->size[1]; org[2] = self->s.origin[2] + crandom() * self->size[2]; - ThrowDebris (self, "models/objects/debris1/tris.md2", spd, org); + ThrowDebris(self, "models/objects/debris1/tris.md2", spd, org); - // bottom corners + /* bottom corners */ spd = 1.75 * (float)self->dmg / 200.0; - VectorCopy (self->absmin, org); - ThrowDebris (self, "models/objects/debris3/tris.md2", spd, org); - VectorCopy (self->absmin, org); + VectorCopy(self->absmin, org); + ThrowDebris(self, "models/objects/debris3/tris.md2", spd, org); + VectorCopy(self->absmin, org); org[0] += self->size[0]; - ThrowDebris (self, "models/objects/debris3/tris.md2", spd, org); - VectorCopy (self->absmin, org); + ThrowDebris(self, "models/objects/debris3/tris.md2", spd, org); + VectorCopy(self->absmin, org); org[1] += self->size[1]; - ThrowDebris (self, "models/objects/debris3/tris.md2", spd, org); - VectorCopy (self->absmin, org); + ThrowDebris(self, "models/objects/debris3/tris.md2", spd, org); + VectorCopy(self->absmin, org); org[0] += self->size[0]; org[1] += self->size[1]; - ThrowDebris (self, "models/objects/debris3/tris.md2", spd, org); + ThrowDebris(self, "models/objects/debris3/tris.md2", spd, org); - // a bunch of little chunks + /* a bunch of little chunks */ spd = 2 * self->dmg / 200; org[0] = self->s.origin[0] + crandom() * self->size[0]; org[1] = self->s.origin[1] + crandom() * self->size[1]; org[2] = self->s.origin[2] + crandom() * self->size[2]; - ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org); + ThrowDebris(self, "models/objects/debris2/tris.md2", spd, org); org[0] = self->s.origin[0] + crandom() * self->size[0]; org[1] = self->s.origin[1] + crandom() * self->size[1]; org[2] = self->s.origin[2] + crandom() * self->size[2]; - ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org); + ThrowDebris(self, "models/objects/debris2/tris.md2", spd, org); org[0] = self->s.origin[0] + crandom() * self->size[0]; org[1] = self->s.origin[1] + crandom() * self->size[1]; org[2] = self->s.origin[2] + crandom() * self->size[2]; - ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org); + ThrowDebris(self, "models/objects/debris2/tris.md2", spd, org); org[0] = self->s.origin[0] + crandom() * self->size[0]; org[1] = self->s.origin[1] + crandom() * self->size[1]; org[2] = self->s.origin[2] + crandom() * self->size[2]; - ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org); + ThrowDebris(self, "models/objects/debris2/tris.md2", spd, org); org[0] = self->s.origin[0] + crandom() * self->size[0]; org[1] = self->s.origin[1] + crandom() * self->size[1]; org[2] = self->s.origin[2] + crandom() * self->size[2]; - ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org); + ThrowDebris(self, "models/objects/debris2/tris.md2", spd, org); org[0] = self->s.origin[0] + crandom() * self->size[0]; org[1] = self->s.origin[1] + crandom() * self->size[1]; org[2] = self->s.origin[2] + crandom() * self->size[2]; - ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org); + ThrowDebris(self, "models/objects/debris2/tris.md2", spd, org); org[0] = self->s.origin[0] + crandom() * self->size[0]; org[1] = self->s.origin[1] + crandom() * self->size[1]; org[2] = self->s.origin[2] + crandom() * self->size[2]; - ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org); + ThrowDebris(self, "models/objects/debris2/tris.md2", spd, org); org[0] = self->s.origin[0] + crandom() * self->size[0]; org[1] = self->s.origin[1] + crandom() * self->size[1]; org[2] = self->s.origin[2] + crandom() * self->size[2]; - ThrowDebris (self, "models/objects/debris2/tris.md2", spd, org); + ThrowDebris(self, "models/objects/debris2/tris.md2", spd, org); + + VectorCopy(save, self->s.origin); - VectorCopy (save, self->s.origin); if (self->groundentity) - BecomeExplosion2 (self); + { + BecomeExplosion2(self); + } else - BecomeExplosion1 (self); + { + BecomeExplosion1(self); + } } -void barrel_delay (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) +void +barrel_delay(edict_t *self, + edict_t *inflictor, + edict_t *attacker, + int damage, + vec3_t point) { self->takedamage = DAMAGE_NO; self->nextthink = level.time + 2 * FRAMETIME; @@ -996,32 +1180,41 @@ void barrel_delay (edict_t *self, edict_t *inflictor, edict_t *attacker, int dam self->activator = attacker; } -void SP_misc_explobox (edict_t *self) +void +SP_misc_explobox(edict_t *self) { if (deathmatch->value) - { // auto-remove for deathmatch - G_FreeEdict (self); + { /* auto-remove for deathmatch */ + G_FreeEdict(self); return; } - gi.modelindex ("models/objects/debris1/tris.md2"); - gi.modelindex ("models/objects/debris2/tris.md2"); - gi.modelindex ("models/objects/debris3/tris.md2"); + gi.modelindex("models/objects/debris1/tris.md2"); + gi.modelindex("models/objects/debris2/tris.md2"); + gi.modelindex("models/objects/debris3/tris.md2"); self->solid = SOLID_BBOX; self->movetype = MOVETYPE_STEP; self->model = "models/objects/barrels/tris.md2"; - self->s.modelindex = gi.modelindex (self->model); - VectorSet (self->mins, -16, -16, 0); - VectorSet (self->maxs, 16, 16, 40); + self->s.modelindex = gi.modelindex(self->model); + VectorSet(self->mins, -16, -16, 0); + VectorSet(self->maxs, 16, 16, 40); if (!self->mass) + { self->mass = 400; + } + if (!self->health) + { self->health = 10; + } + if (!self->dmg) + { self->dmg = 150; + } self->die = barrel_delay; self->takedamage = DAMAGE_YES; @@ -1032,351 +1225,416 @@ void SP_misc_explobox (edict_t *self) self->think = M_droptofloor; self->nextthink = level.time + 2 * FRAMETIME; - gi.linkentity (self); + gi.linkentity(self); } - -// -// miscellaneous specialty items -// +/* */ +/* miscellaneous specialty items */ +/* */ /*QUAKED misc_blackhole (1 .5 0) (-8 -8 -8) (8 8 8) -*/ + */ -void misc_blackhole_use (edict_t *ent, edict_t *other, edict_t *activator) +void +misc_blackhole_use(edict_t *ent, edict_t *other, edict_t *activator) { - G_FreeEdict (ent); + G_FreeEdict(ent); } -void misc_blackhole_think (edict_t *self) +void +misc_blackhole_think(edict_t *self) { if (++self->s.frame < 19) + { self->nextthink = level.time + FRAMETIME; + } else - { + { self->s.frame = 0; self->nextthink = level.time + FRAMETIME; } } -void SP_misc_blackhole (edict_t *ent) +void +SP_misc_blackhole(edict_t *ent) { ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_NOT; - VectorSet (ent->mins, -64, -64, 0); - VectorSet (ent->maxs, 64, 64, 8); - ent->s.modelindex = gi.modelindex ("models/objects/black/tris.md2"); + VectorSet(ent->mins, -64, -64, 0); + VectorSet(ent->maxs, 64, 64, 8); + ent->s.modelindex = gi.modelindex("models/objects/black/tris.md2"); ent->s.renderfx = RF_TRANSLUCENT; ent->use = misc_blackhole_use; ent->think = misc_blackhole_think; ent->nextthink = level.time + 2 * FRAMETIME; - gi.linkentity (ent); + gi.linkentity(ent); } /*QUAKED misc_eastertank (1 .5 0) (-32 -32 -16) (32 32 32) -*/ + */ -void misc_eastertank_think (edict_t *self) +void +misc_eastertank_think(edict_t *self) { if (++self->s.frame < 293) + { self->nextthink = level.time + FRAMETIME; + } else - { + { self->s.frame = 254; self->nextthink = level.time + FRAMETIME; } } -void SP_misc_eastertank (edict_t *ent) +void +SP_misc_eastertank(edict_t *ent) { ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; - VectorSet (ent->mins, -32, -32, -16); - VectorSet (ent->maxs, 32, 32, 32); - ent->s.modelindex = gi.modelindex ("models/monsters/tank/tris.md2"); + VectorSet(ent->mins, -32, -32, -16); + VectorSet(ent->maxs, 32, 32, 32); + ent->s.modelindex = gi.modelindex("models/monsters/tank/tris.md2"); ent->s.frame = 254; ent->think = misc_eastertank_think; ent->nextthink = level.time + 2 * FRAMETIME; - gi.linkentity (ent); + gi.linkentity(ent); } /*QUAKED misc_easterchick (1 .5 0) (-32 -32 0) (32 32 32) -*/ + */ - -void misc_easterchick_think (edict_t *self) +void +misc_easterchick_think(edict_t *self) { if (++self->s.frame < 247) + { self->nextthink = level.time + FRAMETIME; + } else - { + { self->s.frame = 208; self->nextthink = level.time + FRAMETIME; } } -void SP_misc_easterchick (edict_t *ent) +void +SP_misc_easterchick(edict_t *ent) { ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; - VectorSet (ent->mins, -32, -32, 0); - VectorSet (ent->maxs, 32, 32, 32); - ent->s.modelindex = gi.modelindex ("models/monsters/bitch/tris.md2"); + VectorSet(ent->mins, -32, -32, 0); + VectorSet(ent->maxs, 32, 32, 32); + ent->s.modelindex = gi.modelindex("models/monsters/bitch/tris.md2"); ent->s.frame = 208; ent->think = misc_easterchick_think; ent->nextthink = level.time + 2 * FRAMETIME; - gi.linkentity (ent); + gi.linkentity(ent); } /*QUAKED misc_easterchick2 (1 .5 0) (-32 -32 0) (32 32 32) -*/ + */ - -void misc_easterchick2_think (edict_t *self) +void +misc_easterchick2_think(edict_t *self) { if (++self->s.frame < 287) + { self->nextthink = level.time + FRAMETIME; + } else - { + { self->s.frame = 248; self->nextthink = level.time + FRAMETIME; } } -void SP_misc_easterchick2 (edict_t *ent) +void +SP_misc_easterchick2(edict_t *ent) { ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; - VectorSet (ent->mins, -32, -32, 0); - VectorSet (ent->maxs, 32, 32, 32); - ent->s.modelindex = gi.modelindex ("models/monsters/bitch/tris.md2"); + VectorSet(ent->mins, -32, -32, 0); + VectorSet(ent->maxs, 32, 32, 32); + ent->s.modelindex = gi.modelindex("models/monsters/bitch/tris.md2"); ent->s.frame = 248; ent->think = misc_easterchick2_think; ent->nextthink = level.time + 2 * FRAMETIME; - gi.linkentity (ent); + gi.linkentity(ent); } - /*QUAKED monster_commander_body (1 .5 0) (-32 -32 0) (32 32 48) -Not really a monster, this is the Tank Commander's decapitated body. -There should be a item_commander_head that has this as it's target. -*/ + * Not really a monster, this is the Tank Commander's decapitated body. + * There should be a item_commander_head that has this as it's target. + */ -void commander_body_think (edict_t *self) +void +commander_body_think(edict_t *self) { if (++self->s.frame < 24) + { self->nextthink = level.time + FRAMETIME; + } else + { self->nextthink = 0; + } if (self->s.frame == 22) - gi.sound (self, CHAN_BODY, gi.soundindex ("tank/thud.wav"), 1, ATTN_NORM, 0); + { + gi.sound(self, CHAN_BODY, gi.soundindex( + "tank/thud.wav"), 1, ATTN_NORM, 0); + } } -void commander_body_use (edict_t *self, edict_t *other, edict_t *activator) +void +commander_body_use(edict_t *self, edict_t *other, edict_t *activator) { self->think = commander_body_think; self->nextthink = level.time + FRAMETIME; - gi.sound (self, CHAN_BODY, gi.soundindex ("tank/pain.wav"), 1, ATTN_NORM, 0); + gi.sound(self, CHAN_BODY, gi.soundindex("tank/pain.wav"), 1, ATTN_NORM, 0); } -void commander_body_drop (edict_t *self) +void +commander_body_drop(edict_t *self) { self->movetype = MOVETYPE_TOSS; self->s.origin[2] += 2; } -void SP_monster_commander_body (edict_t *self) +void +SP_monster_commander_body(edict_t *self) { self->movetype = MOVETYPE_NONE; self->solid = SOLID_BBOX; self->model = "models/monsters/commandr/tris.md2"; - self->s.modelindex = gi.modelindex (self->model); - VectorSet (self->mins, -32, -32, 0); - VectorSet (self->maxs, 32, 32, 48); + self->s.modelindex = gi.modelindex(self->model); + VectorSet(self->mins, -32, -32, 0); + VectorSet(self->maxs, 32, 32, 48); self->use = commander_body_use; self->takedamage = DAMAGE_YES; self->flags = FL_GODMODE; self->s.renderfx |= RF_FRAMELERP; - gi.linkentity (self); + gi.linkentity(self); - gi.soundindex ("tank/thud.wav"); - gi.soundindex ("tank/pain.wav"); + gi.soundindex("tank/thud.wav"); + gi.soundindex("tank/pain.wav"); self->think = commander_body_drop; self->nextthink = level.time + 5 * FRAMETIME; } - /*QUAKED misc_banner (1 .5 0) (-4 -4 -4) (4 4 4) -The origin is the bottom of the banner. -The banner is 128 tall. -*/ -void misc_banner_think (edict_t *ent) + * The origin is the bottom of the banner. + * The banner is 128 tall. + */ +void +misc_banner_think(edict_t *ent) { ent->s.frame = (ent->s.frame + 1) % 16; ent->nextthink = level.time + FRAMETIME; } -void SP_misc_banner (edict_t *ent) +void +SP_misc_banner(edict_t *ent) { ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_NOT; - ent->s.modelindex = gi.modelindex ("models/objects/banner/tris.md2"); + ent->s.modelindex = gi.modelindex("models/objects/banner/tris.md2"); ent->s.frame = rand() % 16; - gi.linkentity (ent); + gi.linkentity(ent); ent->think = misc_banner_think; ent->nextthink = level.time + FRAMETIME; } /*QUAKED misc_deadsoldier (1 .5 0) (-16 -16 0) (16 16 16) ON_BACK ON_STOMACH BACK_DECAP FETAL_POS SIT_DECAP IMPALED -This is the dead player model. Comes in 6 exciting different poses! -*/ -void misc_deadsoldier_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) + * This is the dead player model. Comes in 6 exciting different poses! + */ +void +misc_deadsoldier_die(edict_t *self, + edict_t *inflictor, + edict_t *attacker, + int damage, + vec3_t point) { - int n; + int n; if (self->health > -80) + { return; + } - gi.sound (self, CHAN_BODY, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0); - for (n= 0; n < 4; n++) - ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); - ThrowHead (self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC); + gi.sound(self, CHAN_BODY, gi.soundindex("misc/udeath.wav"), 1, ATTN_NORM, 0); + + for (n = 0; n < 4; n++) + { + ThrowGib(self, + "models/objects/gibs/sm_meat/tris.md2", + damage, + GIB_ORGANIC); + } + + ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, GIB_ORGANIC); } -void SP_misc_deadsoldier (edict_t *ent) +void +SP_misc_deadsoldier(edict_t *ent) { if (deathmatch->value) - { // auto-remove for deathmatch - G_FreeEdict (ent); + { /* auto-remove for deathmatch */ + G_FreeEdict(ent); return; } ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; - ent->s.modelindex=gi.modelindex ("models/deadbods/dude/tris.md2"); + ent->s.modelindex = gi.modelindex("models/deadbods/dude/tris.md2"); - // Defaults to frame 0 + /* Defaults to frame 0 */ if (ent->spawnflags & 2) + { ent->s.frame = 1; + } else if (ent->spawnflags & 4) + { ent->s.frame = 2; + } else if (ent->spawnflags & 8) + { ent->s.frame = 3; + } else if (ent->spawnflags & 16) + { ent->s.frame = 4; + } else if (ent->spawnflags & 32) + { ent->s.frame = 5; + } else + { ent->s.frame = 0; + } - VectorSet (ent->mins, -16, -16, 0); - VectorSet (ent->maxs, 16, 16, 16); + VectorSet(ent->mins, -16, -16, 0); + VectorSet(ent->maxs, 16, 16, 16); ent->deadflag = DEAD_DEAD; ent->takedamage = DAMAGE_YES; - ent->svflags |= SVF_MONSTER|SVF_DEADMONSTER; + ent->svflags |= SVF_MONSTER | SVF_DEADMONSTER; ent->die = misc_deadsoldier_die; ent->monsterinfo.aiflags |= AI_GOOD_GUY; - gi.linkentity (ent); + gi.linkentity(ent); } /*QUAKED misc_viper (1 .5 0) (-16 -16 0) (16 16 32) -This is the Viper for the flyby bombing. -It is trigger_spawned, so you must have something use it for it to show up. -There must be a path for it to follow once it is activated. + * This is the Viper for the flyby bombing. + * It is trigger_spawned, so you must have something use it for it to show up. + * There must be a path for it to follow once it is activated. + * + * "speed" How fast the Viper should fly + */ -"speed" How fast the Viper should fly -*/ +extern void train_use(edict_t *self, edict_t *other, edict_t *activator); +extern void func_train_find(edict_t *self); -extern void train_use (edict_t *self, edict_t *other, edict_t *activator); -extern void func_train_find (edict_t *self); - -void misc_viper_use (edict_t *self, edict_t *other, edict_t *activator) +void +misc_viper_use(edict_t *self, edict_t *other, edict_t *activator) { self->svflags &= ~SVF_NOCLIENT; self->use = train_use; - train_use (self, other, activator); + train_use(self, other, activator); } -void SP_misc_viper (edict_t *ent) +void +SP_misc_viper(edict_t *ent) { if (!ent->target) { - gi.dprintf ("misc_viper without a target at %s\n", vtos(ent->absmin)); - G_FreeEdict (ent); + gi.dprintf("misc_viper without a target at %s\n", vtos(ent->absmin)); + G_FreeEdict(ent); return; } if (!ent->speed) + { ent->speed = 300; + } ent->movetype = MOVETYPE_PUSH; ent->solid = SOLID_NOT; - ent->s.modelindex = gi.modelindex ("models/ships/viper/tris.md2"); - VectorSet (ent->mins, -16, -16, 0); - VectorSet (ent->maxs, 16, 16, 32); + ent->s.modelindex = gi.modelindex("models/ships/viper/tris.md2"); + VectorSet(ent->mins, -16, -16, 0); + VectorSet(ent->maxs, 16, 16, 32); ent->think = func_train_find; ent->nextthink = level.time + FRAMETIME; ent->use = misc_viper_use; ent->svflags |= SVF_NOCLIENT; - ent->moveinfo.accel = ent->moveinfo.decel = ent->moveinfo.speed = ent->speed; + ent->moveinfo.accel = ent->moveinfo.decel = ent->moveinfo.speed = + ent->speed; - gi.linkentity (ent); + gi.linkentity(ent); } - -/*QUAKED misc_bigviper (1 .5 0) (-176 -120 -24) (176 120 72) -This is a large stationary viper as seen in Paul's intro -*/ -void SP_misc_bigviper (edict_t *ent) +/*QUAKED misc_bigviper (1 .5 0) (-176 -120 -24) (176 120 72) + * This is a large stationary viper as seen in Paul's intro + */ +void +SP_misc_bigviper(edict_t *ent) { ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; - VectorSet (ent->mins, -176, -120, -24); - VectorSet (ent->maxs, 176, 120, 72); - ent->s.modelindex = gi.modelindex ("models/ships/bigviper/tris.md2"); - gi.linkentity (ent); + VectorSet(ent->mins, -176, -120, -24); + VectorSet(ent->maxs, 176, 120, 72); + ent->s.modelindex = gi.modelindex("models/ships/bigviper/tris.md2"); + gi.linkentity(ent); } - /*QUAKED misc_viper_bomb (1 0 0) (-8 -8 -8) (8 8 8) -"dmg" how much boom should the bomb make? -*/ -void misc_viper_bomb_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) + * "dmg" how much boom should the bomb make? + */ +void +misc_viper_bomb_touch(edict_t *self, + edict_t *other, + cplane_t *plane, + csurface_t *surf) { - G_UseTargets (self, self->activator); + G_UseTargets(self, self->activator); self->s.origin[2] = self->absmin[2] + 1; - T_RadiusDamage (self, self, self->dmg, NULL, self->dmg+40, MOD_BOMB); - BecomeExplosion2 (self); + T_RadiusDamage(self, self, self->dmg, NULL, self->dmg + 40, MOD_BOMB); + BecomeExplosion2(self); } -void misc_viper_bomb_prethink (edict_t *self) +void +misc_viper_bomb_prethink(edict_t *self) { - vec3_t v; - float diff; + vec3_t v; + float diff; self->groundentity = NULL; diff = self->timestamp - level.time; - if (diff < -1.0) - diff = -1.0; - VectorScale (self->moveinfo.dir, 1.0 + diff, v); + if (diff < -1.0) + { + diff = -1.0; + } + + VectorScale(self->moveinfo.dir, 1.0 + diff, v); v[2] = diff; diff = self->s.angles[2]; - vectoangles (v, self->s.angles); + vectoangles(v, self->s.angles); self->s.angles[2] = diff + 10; } -void misc_viper_bomb_use (edict_t *self, edict_t *other, edict_t *activator) +void +misc_viper_bomb_use(edict_t *self, edict_t *other, edict_t *activator) { - edict_t *viper; + edict_t *viper; self->solid = SOLID_BBOX; self->svflags &= ~SVF_NOCLIENT; @@ -1387,134 +1645,147 @@ void misc_viper_bomb_use (edict_t *self, edict_t *other, edict_t *activator) self->touch = misc_viper_bomb_touch; self->activator = activator; - viper = G_Find (NULL, FOFS(classname), "misc_viper"); - VectorScale (viper->moveinfo.dir, viper->moveinfo.speed, self->velocity); + viper = G_Find(NULL, FOFS(classname), "misc_viper"); + VectorScale(viper->moveinfo.dir, viper->moveinfo.speed, self->velocity); self->timestamp = level.time; - VectorCopy (viper->moveinfo.dir, self->moveinfo.dir); + VectorCopy(viper->moveinfo.dir, self->moveinfo.dir); } -void SP_misc_viper_bomb (edict_t *self) +void +SP_misc_viper_bomb(edict_t *self) { self->movetype = MOVETYPE_NONE; self->solid = SOLID_NOT; - VectorSet (self->mins, -8, -8, -8); - VectorSet (self->maxs, 8, 8, 8); + VectorSet(self->mins, -8, -8, -8); + VectorSet(self->maxs, 8, 8, 8); - self->s.modelindex = gi.modelindex ("models/objects/bomb/tris.md2"); + self->s.modelindex = gi.modelindex("models/objects/bomb/tris.md2"); if (!self->dmg) + { self->dmg = 1000; + } self->use = misc_viper_bomb_use; self->svflags |= SVF_NOCLIENT; - gi.linkentity (self); + gi.linkentity(self); } - /*QUAKED misc_strogg_ship (1 .5 0) (-16 -16 0) (16 16 32) -This is a Storgg ship for the flybys. -It is trigger_spawned, so you must have something use it for it to show up. -There must be a path for it to follow once it is activated. + * This is a Storgg ship for the flybys. + * It is trigger_spawned, so you must have something use it for it to show up. + * There must be a path for it to follow once it is activated. + * + * "speed" How fast it should fly + */ -"speed" How fast it should fly -*/ +extern void train_use(edict_t *self, edict_t *other, edict_t *activator); +extern void func_train_find(edict_t *self); -extern void train_use (edict_t *self, edict_t *other, edict_t *activator); -extern void func_train_find (edict_t *self); - -void misc_strogg_ship_use (edict_t *self, edict_t *other, edict_t *activator) +void +misc_strogg_ship_use(edict_t *self, edict_t *other, edict_t *activator) { self->svflags &= ~SVF_NOCLIENT; self->use = train_use; - train_use (self, other, activator); + train_use(self, other, activator); } -void SP_misc_strogg_ship (edict_t *ent) +void +SP_misc_strogg_ship(edict_t *ent) { if (!ent->target) { - gi.dprintf ("%s without a target at %s\n", ent->classname, vtos(ent->absmin)); - G_FreeEdict (ent); + gi.dprintf("%s without a target at %s\n", ent->classname, + vtos(ent->absmin)); + G_FreeEdict(ent); return; } if (!ent->speed) + { ent->speed = 300; + } ent->movetype = MOVETYPE_PUSH; ent->solid = SOLID_NOT; - ent->s.modelindex = gi.modelindex ("models/ships/strogg1/tris.md2"); - VectorSet (ent->mins, -16, -16, 0); - VectorSet (ent->maxs, 16, 16, 32); + ent->s.modelindex = gi.modelindex("models/ships/strogg1/tris.md2"); + VectorSet(ent->mins, -16, -16, 0); + VectorSet(ent->maxs, 16, 16, 32); ent->think = func_train_find; ent->nextthink = level.time + FRAMETIME; ent->use = misc_strogg_ship_use; ent->svflags |= SVF_NOCLIENT; - ent->moveinfo.accel = ent->moveinfo.decel = ent->moveinfo.speed = ent->speed; + ent->moveinfo.accel = ent->moveinfo.decel = ent->moveinfo.speed = + ent->speed; - gi.linkentity (ent); + gi.linkentity(ent); } - /*QUAKED misc_satellite_dish (1 .5 0) (-64 -64 0) (64 64 128) -*/ -void misc_satellite_dish_think (edict_t *self) + */ +void +misc_satellite_dish_think(edict_t *self) { self->s.frame++; + if (self->s.frame < 38) + { self->nextthink = level.time + FRAMETIME; + } } -void misc_satellite_dish_use (edict_t *self, edict_t *other, edict_t *activator) +void +misc_satellite_dish_use(edict_t *self, edict_t *other, edict_t *activator) { self->s.frame = 0; self->think = misc_satellite_dish_think; self->nextthink = level.time + FRAMETIME; } -void SP_misc_satellite_dish (edict_t *ent) +void +SP_misc_satellite_dish(edict_t *ent) { ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; - VectorSet (ent->mins, -64, -64, 0); - VectorSet (ent->maxs, 64, 64, 128); - ent->s.modelindex = gi.modelindex ("models/objects/satellite/tris.md2"); + VectorSet(ent->mins, -64, -64, 0); + VectorSet(ent->maxs, 64, 64, 128); + ent->s.modelindex = gi.modelindex("models/objects/satellite/tris.md2"); ent->use = misc_satellite_dish_use; - gi.linkentity (ent); + gi.linkentity(ent); } - /*QUAKED light_mine1 (0 1 0) (-2 -2 -12) (2 2 12) -*/ -void SP_light_mine1 (edict_t *ent) + */ +void +SP_light_mine1(edict_t *ent) { ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; - ent->s.modelindex = gi.modelindex ("models/objects/minelite/light1/tris.md2"); - gi.linkentity (ent); + ent->s.modelindex = gi.modelindex("models/objects/minelite/light1/tris.md2"); + gi.linkentity(ent); } - /*QUAKED light_mine2 (0 1 0) (-2 -2 -12) (2 2 12) -*/ -void SP_light_mine2 (edict_t *ent) + */ +void +SP_light_mine2(edict_t *ent) { ent->movetype = MOVETYPE_NONE; ent->solid = SOLID_BBOX; - ent->s.modelindex = gi.modelindex ("models/objects/minelite/light2/tris.md2"); - gi.linkentity (ent); + ent->s.modelindex = gi.modelindex("models/objects/minelite/light2/tris.md2"); + gi.linkentity(ent); } - /*QUAKED misc_gib_arm (1 0 0) (-8 -8 -8) (8 8 8) -Intended for use with the target_spawner -*/ -void SP_misc_gib_arm (edict_t *ent) + * Intended for use with the target_spawner + */ +void +SP_misc_gib_arm(edict_t *ent) { - gi.setmodel (ent, "models/objects/gibs/arm/tris.md2"); + gi.setmodel(ent, "models/objects/gibs/arm/tris.md2"); ent->solid = SOLID_NOT; ent->s.effects |= EF_GIB; ent->takedamage = DAMAGE_YES; @@ -1522,20 +1793,21 @@ void SP_misc_gib_arm (edict_t *ent) ent->movetype = MOVETYPE_TOSS; ent->svflags |= SVF_MONSTER; ent->deadflag = DEAD_DEAD; - ent->avelocity[0] = random()*200; - ent->avelocity[1] = random()*200; - ent->avelocity[2] = random()*200; + ent->avelocity[0] = random() * 200; + ent->avelocity[1] = random() * 200; + ent->avelocity[2] = random() * 200; ent->think = G_FreeEdict; ent->nextthink = level.time + 30; - gi.linkentity (ent); + gi.linkentity(ent); } /*QUAKED misc_gib_leg (1 0 0) (-8 -8 -8) (8 8 8) -Intended for use with the target_spawner -*/ -void SP_misc_gib_leg (edict_t *ent) + * Intended for use with the target_spawner + */ +void +SP_misc_gib_leg(edict_t *ent) { - gi.setmodel (ent, "models/objects/gibs/leg/tris.md2"); + gi.setmodel(ent, "models/objects/gibs/leg/tris.md2"); ent->solid = SOLID_NOT; ent->s.effects |= EF_GIB; ent->takedamage = DAMAGE_YES; @@ -1543,20 +1815,21 @@ void SP_misc_gib_leg (edict_t *ent) ent->movetype = MOVETYPE_TOSS; ent->svflags |= SVF_MONSTER; ent->deadflag = DEAD_DEAD; - ent->avelocity[0] = random()*200; - ent->avelocity[1] = random()*200; - ent->avelocity[2] = random()*200; + ent->avelocity[0] = random() * 200; + ent->avelocity[1] = random() * 200; + ent->avelocity[2] = random() * 200; ent->think = G_FreeEdict; ent->nextthink = level.time + 30; - gi.linkentity (ent); + gi.linkentity(ent); } /*QUAKED misc_gib_head (1 0 0) (-8 -8 -8) (8 8 8) -Intended for use with the target_spawner -*/ -void SP_misc_gib_head (edict_t *ent) + * Intended for use with the target_spawner + */ +void +SP_misc_gib_head(edict_t *ent) { - gi.setmodel (ent, "models/objects/gibs/head/tris.md2"); + gi.setmodel(ent, "models/objects/gibs/head/tris.md2"); ent->solid = SOLID_NOT; ent->s.effects |= EF_GIB; ent->takedamage = DAMAGE_YES; @@ -1564,47 +1837,53 @@ void SP_misc_gib_head (edict_t *ent) ent->movetype = MOVETYPE_TOSS; ent->svflags |= SVF_MONSTER; ent->deadflag = DEAD_DEAD; - ent->avelocity[0] = random()*200; - ent->avelocity[1] = random()*200; - ent->avelocity[2] = random()*200; + ent->avelocity[0] = random() * 200; + ent->avelocity[1] = random() * 200; + ent->avelocity[2] = random() * 200; ent->think = G_FreeEdict; ent->nextthink = level.time + 30; - gi.linkentity (ent); + gi.linkentity(ent); } -//===================================================== +/* ===================================================== */ /*QUAKED target_character (0 0 1) ? -used with target_string (must be on same "team") -"count" is position in the string (starts at 1) -*/ + * used with target_string (must be on same "team") + * "count" is position in the string (starts at 1) + */ -void SP_target_character (edict_t *self) +void +SP_target_character(edict_t *self) { self->movetype = MOVETYPE_PUSH; - gi.setmodel (self, self->model); + gi.setmodel(self, self->model); self->solid = SOLID_BSP; self->s.frame = 12; - gi.linkentity (self); + gi.linkentity(self); return; } - /*QUAKED target_string (0 0 1) (-8 -8 -8) (8 8 8) -*/ + */ -void target_string_use (edict_t *self, edict_t *other, edict_t *activator) +void +target_string_use(edict_t *self, edict_t *other, edict_t *activator) { edict_t *e; - int n, l; - char c; + int n, l; + char c; l = strlen(self->message); + for (e = self->teammaster; e; e = e->teamchain) { if (!e->count) + { continue; + } + n = e->count - 1; + if (n > l) { e->s.frame = 12; @@ -1612,46 +1891,60 @@ void target_string_use (edict_t *self, edict_t *other, edict_t *activator) } c = self->message[n]; - if (c >= '0' && c <= '9') + + if ((c >= '0') && (c <= '9')) + { e->s.frame = c - '0'; + } else if (c == '-') + { e->s.frame = 10; + } else if (c == ':') + { e->s.frame = 11; + } else + { e->s.frame = 12; + } } } -void SP_target_string (edict_t *self) +void +SP_target_string(edict_t *self) { if (!self->message) + { self->message = ""; + } + self->use = target_string_use; } - /*QUAKED func_clock (0 0 1) (-8 -8 -8) (8 8 8) TIMER_UP TIMER_DOWN START_OFF MULTI_USE -target a target_string with this + * target a target_string with this + * + * The default is to be a time of day clock + * + * TIMER_UP and TIMER_DOWN run for "count" seconds and the fire "pathtarget" + * If START_OFF, this entity must be used before it starts + * + * "style" 0 "xx" + * 1 "xx:xx" + * 2 "xx:xx:xx" + */ -The default is to be a time of day clock +#define CLOCK_MESSAGE_SIZE 16 -TIMER_UP and TIMER_DOWN run for "count" seconds and the fire "pathtarget" -If START_OFF, this entity must be used before it starts +/* don't let field width of any clock messages change, or it */ +/* could cause an overwrite after a game load */ -"style" 0 "xx" - 1 "xx:xx" - 2 "xx:xx:xx" -*/ - -#define CLOCK_MESSAGE_SIZE 16 - -// don't let field width of any clock messages change, or it -// could cause an overwrite after a game load - -static void func_clock_reset (edict_t *self) +static void +func_clock_reset(edict_t *self) { self->activator = NULL; + if (self->spawnflags & 1) { self->health = 0; @@ -1664,68 +1957,104 @@ static void func_clock_reset (edict_t *self) } } -static void func_clock_format_countdown (edict_t *self) +static void +func_clock_format_countdown(edict_t *self) { if (self->style == 0) { - Com_sprintf (self->message, CLOCK_MESSAGE_SIZE, "%2i", self->health); + Com_sprintf(self->message, CLOCK_MESSAGE_SIZE, "%2i", self->health); return; } if (self->style == 1) { - Com_sprintf(self->message, CLOCK_MESSAGE_SIZE, "%2i:%2i", self->health / 60, self->health % 60); + Com_sprintf(self->message, + CLOCK_MESSAGE_SIZE, + "%2i:%2i", + self->health / 60, + self->health % 60); + if (self->message[3] == ' ') + { self->message[3] = '0'; + } + return; } if (self->style == 2) { - Com_sprintf(self->message, CLOCK_MESSAGE_SIZE, "%2i:%2i:%2i", self->health / 3600, (self->health - (self->health / 3600) * 3600) / 60, self->health % 60); + Com_sprintf(self->message, + CLOCK_MESSAGE_SIZE, + "%2i:%2i:%2i", + self->health / 3600, + (self->health - (self->health / 3600) * 3600) / 60, + self->health % 60); + if (self->message[3] == ' ') + { self->message[3] = '0'; + } + if (self->message[6] == ' ') + { self->message[6] = '0'; + } + return; } } -void func_clock_think (edict_t *self) +void +func_clock_think(edict_t *self) { if (!self->enemy) { - self->enemy = G_Find (NULL, FOFS(targetname), self->target); + self->enemy = G_Find(NULL, FOFS(targetname), self->target); + if (!self->enemy) + { return; + } } if (self->spawnflags & 1) { - func_clock_format_countdown (self); + func_clock_format_countdown(self); self->health++; } else if (self->spawnflags & 2) { - func_clock_format_countdown (self); + func_clock_format_countdown(self); self->health--; } else { - struct tm *ltime; - time_t gmtime; + struct tm *ltime; + time_t gmtime; time(&gmtime); ltime = localtime(&gmtime); - Com_sprintf (self->message, CLOCK_MESSAGE_SIZE, "%2i:%2i:%2i", ltime->tm_hour, ltime->tm_min, ltime->tm_sec); + Com_sprintf(self->message, + CLOCK_MESSAGE_SIZE, + "%2i:%2i:%2i", + ltime->tm_hour, + ltime->tm_min, + ltime->tm_sec); + if (self->message[3] == ' ') + { self->message[3] = '0'; + } + if (self->message[6] == ' ') + { self->message[6] = '0'; + } } self->enemy->message = self->message; - self->enemy->use (self->enemy, self, self); + self->enemy->use(self->enemy, self, self); if (((self->spawnflags & 1) && (self->health > self->wait)) || ((self->spawnflags & 2) && (self->health < self->wait))) @@ -1739,160 +2068,192 @@ void func_clock_think (edict_t *self) savemessage = self->message; self->target = self->pathtarget; self->message = NULL; - G_UseTargets (self, self->activator); + G_UseTargets(self, self->activator); self->target = savetarget; self->message = savemessage; } if (!(self->spawnflags & 8)) + { return; + } - func_clock_reset (self); + func_clock_reset(self); if (self->spawnflags & 4) + { return; + } } self->nextthink = level.time + 1; } -void func_clock_use (edict_t *self, edict_t *other, edict_t *activator) +void +func_clock_use(edict_t *self, edict_t *other, edict_t *activator) { if (!(self->spawnflags & 8)) + { self->use = NULL; + } + if (self->activator) + { return; + } + self->activator = activator; - self->think (self); + self->think(self); } -void SP_func_clock (edict_t *self) +void +SP_func_clock(edict_t *self) { if (!self->target) { - gi.dprintf("%s with no target at %s\n", self->classname, vtos(self->s.origin)); - G_FreeEdict (self); + gi.dprintf("%s with no target at %s\n", self->classname, + vtos(self->s.origin)); + G_FreeEdict(self); return; } if ((self->spawnflags & 2) && (!self->count)) { - gi.dprintf("%s with no count at %s\n", self->classname, vtos(self->s.origin)); - G_FreeEdict (self); + gi.dprintf("%s with no count at %s\n", self->classname, + vtos(self->s.origin)); + G_FreeEdict(self); return; } if ((self->spawnflags & 1) && (!self->count)) - self->count = 60*60;; + { + self->count = 60 * 60; + } - func_clock_reset (self); + func_clock_reset(self); - self->message = gi.TagMalloc (CLOCK_MESSAGE_SIZE, TAG_LEVEL); + self->message = gi.TagMalloc(CLOCK_MESSAGE_SIZE, TAG_LEVEL); self->think = func_clock_think; if (self->spawnflags & 4) + { self->use = func_clock_use; + } else + { self->nextthink = level.time + 1; + } } -//================================================================================= +/* ================================================================================= */ -void teleporter_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +void +teleporter_touch(edict_t *self, + edict_t *other, + cplane_t *plane, + csurface_t *surf) { - edict_t *dest; - int i; + edict_t *dest; + int i; if (!other->client) - return; - dest = G_Find (NULL, FOFS(targetname), self->target); - if (!dest) { - gi.dprintf ("Couldn't find destination\n"); return; } - //ZOID + dest = G_Find(NULL, FOFS(targetname), self->target); + + if (!dest) + { + gi.dprintf("Couldn't find destination\n"); + return; + } + + /* ZOID */ CTFPlayerResetGrapple(other); - //ZOID + /* ZOID */ - // unlink to make sure it can't possibly interfere with KillBox - gi.unlinkentity (other); + /* unlink to make sure it can't possibly interfere with KillBox */ + gi.unlinkentity(other); - VectorCopy (dest->s.origin, other->s.origin); - VectorCopy (dest->s.origin, other->s.old_origin); + VectorCopy(dest->s.origin, other->s.origin); + VectorCopy(dest->s.origin, other->s.old_origin); other->s.origin[2] += 10; - // clear the velocity and hold them in place briefly - VectorClear (other->velocity); - other->client->ps.pmove.pm_time = 160>>3; // hold time + /* clear the velocity and hold them in place briefly */ + VectorClear(other->velocity); + other->client->ps.pmove.pm_time = 160 >> 3; /* hold time */ other->client->ps.pmove.pm_flags |= PMF_TIME_TELEPORT; - // draw the teleport splash at source and on the player + /* draw the teleport splash at source and on the player */ self->owner->s.event = EV_PLAYER_TELEPORT; other->s.event = EV_PLAYER_TELEPORT; - // set angles - for (i=0 ; i<3 ; i++) - other->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(dest->s.angles[i] - other->client->resp.cmd_angles[i]); + /* set angles */ + for (i = 0; i < 3; i++) + { + other->client->ps.pmove.delta_angles[i] = ANGLE2SHORT( + dest->s.angles[i] - other->client->resp.cmd_angles[i]); + } - VectorClear (other->s.angles); - VectorClear (other->client->ps.viewangles); - VectorClear (other->client->v_angle); + VectorClear(other->s.angles); + VectorClear(other->client->ps.viewangles); + VectorClear(other->client->v_angle); - // kill anything at the destination - KillBox (other); + /* kill anything at the destination */ + KillBox(other); - gi.linkentity (other); + gi.linkentity(other); } /*QUAKED misc_teleporter (1 0 0) (-32 -32 -24) (32 32 -16) -Stepping onto this disc will teleport players to the targeted misc_teleporter_dest object. -*/ -void SP_misc_teleporter (edict_t *ent) + * Stepping onto this disc will teleport players to the targeted misc_teleporter_dest object. + */ +void +SP_misc_teleporter(edict_t *ent) { - edict_t *trig; + edict_t *trig; if (!ent->target) { - gi.dprintf ("teleporter without a target.\n"); - G_FreeEdict (ent); + gi.dprintf("teleporter without a target.\n"); + G_FreeEdict(ent); return; } - gi.setmodel (ent, "models/objects/dmspot/tris.md2"); + gi.setmodel(ent, "models/objects/dmspot/tris.md2"); ent->s.skinnum = 1; ent->s.effects = EF_TELEPORTER; - ent->s.sound = gi.soundindex ("world/amb10.wav"); + ent->s.sound = gi.soundindex("world/amb10.wav"); ent->solid = SOLID_BBOX; - VectorSet (ent->mins, -32, -32, -24); - VectorSet (ent->maxs, 32, 32, -16); - gi.linkentity (ent); + VectorSet(ent->mins, -32, -32, -24); + VectorSet(ent->maxs, 32, 32, -16); + gi.linkentity(ent); - trig = G_Spawn (); + trig = G_Spawn(); trig->touch = teleporter_touch; trig->solid = SOLID_TRIGGER; trig->target = ent->target; trig->owner = ent; - VectorCopy (ent->s.origin, trig->s.origin); - VectorSet (trig->mins, -8, -8, 8); - VectorSet (trig->maxs, 8, 8, 24); - gi.linkentity (trig); - + VectorCopy(ent->s.origin, trig->s.origin); + VectorSet(trig->mins, -8, -8, 8); + VectorSet(trig->maxs, 8, 8, 24); + gi.linkentity(trig); } /*QUAKED misc_teleporter_dest (1 0 0) (-32 -32 -24) (32 32 -16) -Point teleporters at these. -*/ -void SP_misc_teleporter_dest (edict_t *ent) + * Point teleporters at these. + */ +void +SP_misc_teleporter_dest(edict_t *ent) { - gi.setmodel (ent, "models/objects/dmspot/tris.md2"); + gi.setmodel(ent, "models/objects/dmspot/tris.md2"); ent->s.skinnum = 0; ent->solid = SOLID_BBOX; - VectorSet (ent->mins, -32, -32, -24); - VectorSet (ent->maxs, 32, 32, -16); - gi.linkentity (ent); + VectorSet(ent->mins, -32, -32, -24); + VectorSet(ent->maxs, 32, 32, -16); + gi.linkentity(ent); } diff --git a/src/game/ctf/g_monster.c b/src/game/ctf/g_monster.c index d7bcaea5..a06f82cf 100644 --- a/src/game/ctf/g_monster.c +++ b/src/game/ctf/g_monster.c @@ -1,150 +1,218 @@ /* -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. - -*/ + * 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. + * + */ #include "g_local.h" +/* */ +/* monster weapons */ +/* */ -// -// monster weapons -// - -//FIXME mosnters should call these with a totally accurate direction -// and we can mess it up based on skill. Spread should be for normal -// and we can tighten or loosen based on skill. We could muck with -// the damages too, but I'm not sure that's such a good idea. -void monster_fire_bullet (edict_t *self, vec3_t start, vec3_t dir, int damage, int kick, int hspread, int vspread, int flashtype) +/* FIXME mosnters should call these with a totally accurate direction */ +/* and we can mess it up based on skill. Spread should be for normal */ +/* and we can tighten or loosen based on skill. We could muck with */ +/* the damages too, but I'm not sure that's such a good idea. */ +void +monster_fire_bullet(edict_t *self, + vec3_t start, + vec3_t dir, + int damage, + int kick, + int hspread, + int vspread, + int flashtype) { - fire_bullet (self, start, dir, damage, kick, hspread, vspread, MOD_UNKNOWN); + fire_bullet(self, start, dir, damage, kick, hspread, vspread, MOD_UNKNOWN); - gi.WriteByte (svc_muzzleflash2); - gi.WriteShort (self - g_edicts); - gi.WriteByte (flashtype); - gi.multicast (start, MULTICAST_PVS); + gi.WriteByte(svc_muzzleflash2); + gi.WriteShort(self - g_edicts); + gi.WriteByte(flashtype); + gi.multicast(start, MULTICAST_PVS); } -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_shotgun(edict_t *self, + vec3_t start, + vec3_t aimdir, + int damage, + int kick, + int hspread, + int vspread, + int count, + int flashtype) { - fire_shotgun (self, start, aimdir, damage, kick, hspread, vspread, count, MOD_UNKNOWN); + fire_shotgun(self, + start, + aimdir, + damage, + kick, + hspread, + vspread, + count, + MOD_UNKNOWN); - gi.WriteByte (svc_muzzleflash2); - gi.WriteShort (self - g_edicts); - gi.WriteByte (flashtype); - gi.multicast (start, MULTICAST_PVS); + gi.WriteByte(svc_muzzleflash2); + gi.WriteShort(self - g_edicts); + gi.WriteByte(flashtype); + gi.multicast(start, MULTICAST_PVS); } -void monster_fire_blaster (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int flashtype, int effect) +void +monster_fire_blaster(edict_t *self, + vec3_t start, + vec3_t dir, + int damage, + int speed, + int flashtype, + int effect) { - fire_blaster (self, start, dir, damage, speed, effect, false); + fire_blaster(self, start, dir, damage, speed, effect, false); - gi.WriteByte (svc_muzzleflash2); - gi.WriteShort (self - g_edicts); - gi.WriteByte (flashtype); - gi.multicast (start, MULTICAST_PVS); -} - -void monster_fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int flashtype) -{ - fire_grenade (self, start, aimdir, damage, speed, 2.5, damage+40); - - gi.WriteByte (svc_muzzleflash2); - gi.WriteShort (self - g_edicts); - gi.WriteByte (flashtype); - gi.multicast (start, MULTICAST_PVS); + gi.WriteByte(svc_muzzleflash2); + gi.WriteShort(self - g_edicts); + gi.WriteByte(flashtype); + gi.multicast(start, MULTICAST_PVS); } -void monster_fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int flashtype) +void +monster_fire_grenade(edict_t *self, + vec3_t start, + vec3_t aimdir, + int damage, + int speed, + int flashtype) { - fire_rocket (self, start, dir, damage, speed, damage+20, damage); + fire_grenade(self, start, aimdir, damage, speed, 2.5, damage + 40); - gi.WriteByte (svc_muzzleflash2); - gi.WriteShort (self - g_edicts); - gi.WriteByte (flashtype); - gi.multicast (start, MULTICAST_PVS); -} - -void monster_fire_railgun (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int flashtype) -{ - fire_rail (self, start, aimdir, damage, kick); - - gi.WriteByte (svc_muzzleflash2); - gi.WriteShort (self - g_edicts); - gi.WriteByte (flashtype); - gi.multicast (start, MULTICAST_PVS); + gi.WriteByte(svc_muzzleflash2); + gi.WriteShort(self - g_edicts); + gi.WriteByte(flashtype); + gi.multicast(start, MULTICAST_PVS); } -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_rocket(edict_t *self, + vec3_t start, + vec3_t dir, + int damage, + int speed, + int flashtype) { - fire_bfg (self, start, aimdir, damage, speed, damage_radius); + fire_rocket(self, start, dir, damage, speed, damage + 20, damage); - gi.WriteByte (svc_muzzleflash2); - gi.WriteShort (self - g_edicts); - gi.WriteByte (flashtype); - gi.multicast (start, MULTICAST_PVS); + gi.WriteByte(svc_muzzleflash2); + gi.WriteShort(self - g_edicts); + gi.WriteByte(flashtype); + gi.multicast(start, MULTICAST_PVS); } +void +monster_fire_railgun(edict_t *self, + vec3_t start, + vec3_t aimdir, + int damage, + int kick, + int flashtype) +{ + fire_rail(self, start, aimdir, damage, kick); + gi.WriteByte(svc_muzzleflash2); + gi.WriteShort(self - g_edicts); + gi.WriteByte(flashtype); + gi.multicast(start, MULTICAST_PVS); +} -// -// Monster utility functions -// +void +monster_fire_bfg(edict_t *self, + vec3_t start, + vec3_t aimdir, + int damage, + int speed, + int kick, + float damage_radius, + int flashtype) +{ + fire_bfg(self, start, aimdir, damage, speed, damage_radius); -static void M_FliesOff (edict_t *self) + gi.WriteByte(svc_muzzleflash2); + gi.WriteShort(self - g_edicts); + gi.WriteByte(flashtype); + gi.multicast(start, MULTICAST_PVS); +} + +/* */ +/* Monster utility functions */ +/* */ + +static void +M_FliesOff(edict_t *self) { self->s.effects &= ~EF_FLIES; self->s.sound = 0; } -static void M_FliesOn (edict_t *self) +static void +M_FliesOn(edict_t *self) { if (self->waterlevel) + { return; + } + self->s.effects |= EF_FLIES; - self->s.sound = gi.soundindex ("infantry/inflies1.wav"); + self->s.sound = gi.soundindex("infantry/inflies1.wav"); self->think = M_FliesOff; self->nextthink = level.time + 60; } -void M_FlyCheck (edict_t *self) +void +M_FlyCheck(edict_t *self) { if (self->waterlevel) + { return; + } if (random() > 0.5) + { return; + } self->think = M_FliesOn; self->nextthink = level.time + 5 + 10 * random(); } -void AttackFinished (edict_t *self, float time) +void +AttackFinished(edict_t *self, float time) { self->monsterinfo.attack_finished = level.time + time; } - -void M_CheckGround (edict_t *ent) +void +M_CheckGround(edict_t *ent) { - vec3_t point; - trace_t trace; + vec3_t point; + trace_t trace; - if (ent->flags & (FL_SWIM|FL_FLY)) + if (ent->flags & (FL_SWIM | FL_FLY)) + { return; + } if (ent->velocity[2] > 100) { @@ -152,15 +220,20 @@ void M_CheckGround (edict_t *ent) return; } - // if the hull point one-quarter unit down is solid the entity is on ground + /* if the hull point one-quarter unit down is solid the entity is on ground */ point[0] = ent->s.origin[0]; point[1] = ent->s.origin[1]; point[2] = ent->s.origin[2] - 0.25; - trace = gi.trace (ent->s.origin, ent->mins, ent->maxs, point, ent, MASK_MONSTERSOLID); + trace = gi.trace(ent->s.origin, + ent->mins, + ent->maxs, + point, + ent, + MASK_MONSTERSOLID); - // check steepness - if ( trace.plane.normal[2] < 0.7 && !trace.startsolid) + /* check steepness */ + if ((trace.plane.normal[2] < 0.7) && !trace.startsolid) { ent->groundentity = NULL; return; @@ -168,26 +241,26 @@ void M_CheckGround (edict_t *ent) if (!trace.startsolid && !trace.allsolid) { - VectorCopy (trace.endpos, ent->s.origin); + VectorCopy(trace.endpos, ent->s.origin); ent->groundentity = trace.ent; ent->groundentity_linkcount = trace.ent->linkcount; ent->velocity[2] = 0; } } - -void M_CatagorizePosition (edict_t *ent) +void +M_CatagorizePosition(edict_t *ent) { - vec3_t point; - int cont; + vec3_t point; + int cont; - // - // get waterlevel - // + /* */ + /* get waterlevel */ + /* */ point[0] = ent->s.origin[0]; point[1] = ent->s.origin[1]; - point[2] = ent->s.origin[2] + ent->mins[2] + 1; - cont = gi.pointcontents (point); + point[2] = ent->s.origin[2] + ent->mins[2] + 1; + cont = gi.pointcontents(point); if (!(cont & MASK_WATER)) { @@ -199,21 +272,27 @@ void M_CatagorizePosition (edict_t *ent) ent->watertype = cont; ent->waterlevel = 1; point[2] += 26; - cont = gi.pointcontents (point); + cont = gi.pointcontents(point); + if (!(cont & MASK_WATER)) + { return; + } ent->waterlevel = 2; point[2] += 22; - cont = gi.pointcontents (point); + cont = gi.pointcontents(point); + if (cont & MASK_WATER) + { ent->waterlevel = 3; + } } - -void M_WorldEffects (edict_t *ent) +void +M_WorldEffects(edict_t *ent) { - int dmg; + int dmg; if (ent->health > 0) { @@ -224,13 +303,26 @@ void M_WorldEffects (edict_t *ent) ent->air_finished = level.time + 12; } else if (ent->air_finished < level.time) - { // drown! + { /* drown! */ if (ent->pain_debounce_time < level.time) { dmg = 2 + 2 * floor(level.time - ent->air_finished); + if (dmg > 15) + { dmg = 15; - T_Damage (ent, world, world, vec3_origin, ent->s.origin, vec3_origin, dmg, 0, DAMAGE_NO_ARMOR, MOD_WATER); + } + + T_Damage(ent, + world, + world, + vec3_origin, + ent->s.origin, + vec3_origin, + dmg, + 0, + DAMAGE_NO_ARMOR, + MOD_WATER); ent->pain_debounce_time = level.time + 1; } } @@ -242,26 +334,41 @@ void M_WorldEffects (edict_t *ent) ent->air_finished = level.time + 9; } else if (ent->air_finished < level.time) - { // suffocate! + { /* suffocate! */ if (ent->pain_debounce_time < level.time) { dmg = 2 + 2 * floor(level.time - ent->air_finished); + if (dmg > 15) + { dmg = 15; - T_Damage (ent, world, world, vec3_origin, ent->s.origin, vec3_origin, dmg, 0, DAMAGE_NO_ARMOR, MOD_WATER); + } + + T_Damage(ent, + world, + world, + vec3_origin, + ent->s.origin, + vec3_origin, + dmg, + 0, + DAMAGE_NO_ARMOR, + MOD_WATER); ent->pain_debounce_time = level.time + 1; } } } } - + if (ent->waterlevel == 0) { if (ent->flags & FL_INWATER) - { - gi.sound (ent, CHAN_BODY, gi.soundindex("player/watr_out.wav"), 1, ATTN_NORM, 0); + { + gi.sound(ent, CHAN_BODY, gi.soundindex( + "player/watr_out.wav"), 1, ATTN_NORM, 0); ent->flags &= ~FL_INWATER; } + return; } @@ -270,31 +377,64 @@ void M_WorldEffects (edict_t *ent) if (ent->damage_debounce_time < level.time) { ent->damage_debounce_time = level.time + 0.2; - T_Damage (ent, world, world, vec3_origin, ent->s.origin, vec3_origin, 10*ent->waterlevel, 0, 0, MOD_LAVA); + T_Damage(ent, + world, + world, + vec3_origin, + ent->s.origin, + vec3_origin, + 10 * ent->waterlevel, + 0, + 0, + MOD_LAVA); } } + if ((ent->watertype & CONTENTS_SLIME) && !(ent->flags & FL_IMMUNE_SLIME)) { if (ent->damage_debounce_time < level.time) { ent->damage_debounce_time = level.time + 1; - T_Damage (ent, world, world, vec3_origin, ent->s.origin, vec3_origin, 4*ent->waterlevel, 0, 0, MOD_SLIME); + T_Damage(ent, + world, + world, + vec3_origin, + ent->s.origin, + vec3_origin, + 4 * ent->waterlevel, + 0, + 0, + MOD_SLIME); } } - - if ( !(ent->flags & FL_INWATER) ) - { + + if (!(ent->flags & FL_INWATER)) + { if (!(ent->svflags & SVF_DEADMONSTER)) { if (ent->watertype & CONTENTS_LAVA) + { if (random() <= 0.5) - gi.sound (ent, CHAN_BODY, gi.soundindex("player/lava1.wav"), 1, ATTN_NORM, 0); + { + gi.sound(ent, CHAN_BODY, gi.soundindex( + "player/lava1.wav"), 1, ATTN_NORM, 0); + } else - gi.sound (ent, CHAN_BODY, gi.soundindex("player/lava2.wav"), 1, ATTN_NORM, 0); + { + gi.sound(ent, CHAN_BODY, gi.soundindex( + "player/lava2.wav"), 1, ATTN_NORM, 0); + } + } else if (ent->watertype & CONTENTS_SLIME) - gi.sound (ent, CHAN_BODY, gi.soundindex("player/watr_in.wav"), 1, ATTN_NORM, 0); + { + gi.sound(ent, CHAN_BODY, gi.soundindex( + "player/watr_in.wav"), 1, ATTN_NORM, 0); + } else if (ent->watertype & CONTENTS_WATER) - gi.sound (ent, CHAN_BODY, gi.soundindex("player/watr_in.wav"), 1, ATTN_NORM, 0); + { + gi.sound(ent, CHAN_BODY, gi.soundindex( + "player/watr_in.wav"), 1, ATTN_NORM, 0); + } } ent->flags |= FL_INWATER; @@ -302,33 +442,40 @@ void M_WorldEffects (edict_t *ent) } } - -void M_droptofloor (edict_t *ent) +void +M_droptofloor(edict_t *ent) { - vec3_t end; - trace_t trace; + vec3_t end; + trace_t trace; ent->s.origin[2] += 1; - VectorCopy (ent->s.origin, end); + VectorCopy(ent->s.origin, end); end[2] -= 256; - - trace = gi.trace (ent->s.origin, ent->mins, ent->maxs, end, ent, MASK_MONSTERSOLID); - if (trace.fraction == 1 || trace.allsolid) + trace = gi.trace(ent->s.origin, + ent->mins, + ent->maxs, + end, + ent, + MASK_MONSTERSOLID); + + if ((trace.fraction == 1) || trace.allsolid) + { return; + } - VectorCopy (trace.endpos, ent->s.origin); + VectorCopy(trace.endpos, ent->s.origin); - gi.linkentity (ent); - M_CheckGround (ent); - M_CatagorizePosition (ent); + gi.linkentity(ent); + M_CheckGround(ent); + M_CatagorizePosition(ent); } - -void M_SetEffects (edict_t *ent) +void +M_SetEffects(edict_t *ent) { - ent->s.effects &= ~(EF_COLOR_SHELL|EF_POWERSCREEN); - ent->s.renderfx &= ~(RF_SHELL_RED|RF_SHELL_GREEN|RF_SHELL_BLUE); + ent->s.effects &= ~(EF_COLOR_SHELL | EF_POWERSCREEN); + ent->s.renderfx &= ~(RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE); if (ent->monsterinfo.aiflags & AI_RESURRECTING) { @@ -337,7 +484,9 @@ void M_SetEffects (edict_t *ent) } if (ent->health <= 0) + { return; + } if (ent->powerarmor_time > level.time) { @@ -353,16 +502,18 @@ void M_SetEffects (edict_t *ent) } } - -void M_MoveFrame (edict_t *self) +void +M_MoveFrame(edict_t *self) { - mmove_t *move; - int index; + mmove_t *move; + int index; move = self->monsterinfo.currentmove; self->nextthink = level.time + FRAMETIME; - if ((self->monsterinfo.nextframe) && (self->monsterinfo.nextframe >= move->firstframe) && (self->monsterinfo.nextframe <= move->lastframe)) + if ((self->monsterinfo.nextframe) && + (self->monsterinfo.nextframe >= move->firstframe) && + (self->monsterinfo.nextframe <= move->lastframe)) { self->s.frame = self->monsterinfo.nextframe; self->monsterinfo.nextframe = 0; @@ -373,18 +524,21 @@ void M_MoveFrame (edict_t *self) { if (move->endfunc) { - move->endfunc (self); + move->endfunc(self); - // regrab move, endfunc is very likely to change it + /* regrab move, endfunc is very likely to change it */ move = self->monsterinfo.currentmove; - // check for death + /* check for death */ if (self->svflags & SVF_DEADMONSTER) + { return; + } } } - if (self->s.frame < move->firstframe || self->s.frame > move->lastframe) + if ((self->s.frame < move->firstframe) || + (self->s.frame > move->lastframe)) { self->monsterinfo.aiflags &= ~AI_HOLD_FRAME; self->s.frame = move->firstframe; @@ -394,82 +548,107 @@ void M_MoveFrame (edict_t *self) if (!(self->monsterinfo.aiflags & AI_HOLD_FRAME)) { self->s.frame++; + if (self->s.frame > move->lastframe) + { self->s.frame = move->firstframe; + } } } } index = self->s.frame - move->firstframe; + if (move->frame[index].aifunc) { if (!(self->monsterinfo.aiflags & AI_HOLD_FRAME)) - move->frame[index].aifunc (self, move->frame[index].dist * self->monsterinfo.scale); + { + move->frame[index].aifunc(self, + move->frame[index].dist * self->monsterinfo.scale); + } else - move->frame[index].aifunc (self, 0); + { + move->frame[index].aifunc(self, 0); + } } + if (move->frame[index].thinkfunc) - move->frame[index].thinkfunc (self); + { + move->frame[index].thinkfunc(self); + } } - -void monster_think (edict_t *self) +void +monster_think(edict_t *self) { - M_MoveFrame (self); + M_MoveFrame(self); + if (self->linkcount != self->monsterinfo.linkcount) { self->monsterinfo.linkcount = self->linkcount; - M_CheckGround (self); + M_CheckGround(self); } - M_CatagorizePosition (self); - M_WorldEffects (self); - M_SetEffects (self); -} + M_CatagorizePosition(self); + M_WorldEffects(self); + M_SetEffects(self); +} /* -================ -monster_use - -Using a monster makes it angry at the current activator -================ -*/ -void monster_use (edict_t *self, edict_t *other, edict_t *activator) + * ================ + * monster_use + * + * Using a monster makes it angry at the current activator + * ================ + */ +void +monster_use(edict_t *self, edict_t *other, edict_t *activator) { if (self->enemy) + { return; + } + if (self->health <= 0) + { return; + } + if (activator->flags & FL_NOTARGET) + { return; + } + if (!(activator->client) && !(activator->monsterinfo.aiflags & AI_GOOD_GUY)) + { return; - - // delay reaction so if the monster is teleported, its sound is still heard + } + + /* delay reaction so if the monster is teleported, its sound is still heard */ self->enemy = activator; - FoundTarget (self); + FoundTarget(self); } +void monster_start_go(edict_t *self); -void monster_start_go (edict_t *self); - - -void monster_triggered_spawn (edict_t *self) +void +monster_triggered_spawn(edict_t *self) { self->s.origin[2] += 1; - KillBox (self); + KillBox(self); self->solid = SOLID_BBOX; self->movetype = MOVETYPE_STEP; self->svflags &= ~SVF_NOCLIENT; self->air_finished = level.time + 12; - gi.linkentity (self); + gi.linkentity(self); - monster_start_go (self); + monster_start_go(self); - if (self->enemy && !(self->spawnflags & 1) && !(self->enemy->flags & FL_NOTARGET)) + if (self->enemy && !(self->spawnflags & 1) && + !(self->enemy->flags & FL_NOTARGET)) { - FoundTarget (self); + FoundTarget(self); } else { @@ -477,17 +656,23 @@ void monster_triggered_spawn (edict_t *self) } } -void monster_triggered_spawn_use (edict_t *self, edict_t *other, edict_t *activator) +void +monster_triggered_spawn_use(edict_t *self, edict_t *other, edict_t *activator) { - // we have a one frame delay here so we don't telefrag the guy who activated us + /* we have a one frame delay here so we don't telefrag the guy who activated us */ self->think = monster_triggered_spawn; self->nextthink = level.time + FRAMETIME; + if (activator->client) + { self->enemy = activator; + } + self->use = monster_use; } -void monster_triggered_start (edict_t *self) +void +monster_triggered_start(edict_t *self) { self->solid = SOLID_NOT; self->movetype = MOVETYPE_NONE; @@ -496,43 +681,47 @@ void monster_triggered_start (edict_t *self) self->use = monster_triggered_spawn_use; } - /* -================ -monster_death_use - -When a monster dies, it fires all of its targets with the current -enemy as activator. -================ -*/ -void monster_death_use (edict_t *self) + * ================ + * monster_death_use + * + * When a monster dies, it fires all of its targets with the current + * enemy as activator. + * ================ + */ +void +monster_death_use(edict_t *self) { - self->flags &= ~(FL_FLY|FL_SWIM); + self->flags &= ~(FL_FLY | FL_SWIM); self->monsterinfo.aiflags &= AI_GOOD_GUY; if (self->item) { - Drop_Item (self, self->item); + Drop_Item(self, self->item); self->item = NULL; } if (self->deathtarget) + { self->target = self->deathtarget; + } if (!self->target) + { return; + } - G_UseTargets (self, self->enemy); + G_UseTargets(self, self->enemy); } +/* ============================================================================ */ -//============================================================================ - -qboolean monster_start (edict_t *self) +qboolean +monster_start(edict_t *self) { if (deathmatch->value) { - G_FreeEdict (self); + G_FreeEdict(self); return false; } @@ -543,7 +732,9 @@ qboolean monster_start (edict_t *self) } if (!(self->monsterinfo.aiflags & AI_GOOD_GUY)) + { level.total_monsters++; + } self->nextthink = level.time + FRAMETIME; self->svflags |= SVF_MONSTER; @@ -559,41 +750,58 @@ qboolean monster_start (edict_t *self) self->svflags &= ~SVF_DEADMONSTER; if (!self->monsterinfo.checkattack) + { self->monsterinfo.checkattack = M_CheckAttack; - VectorCopy (self->s.origin, self->s.old_origin); + } + + VectorCopy(self->s.origin, self->s.old_origin); if (st.item) { - self->item = FindItemByClassname (st.item); + self->item = FindItemByClassname(st.item); + if (!self->item) - gi.dprintf("%s at %s has bad item: %s\n", self->classname, vtos(self->s.origin), st.item); + { + gi.dprintf("%s at %s has bad item: %s\n", self->classname, + vtos(self->s.origin), st.item); + } } - // randomize what frame they start on + /* randomize what frame they start on */ if (self->monsterinfo.currentmove) - self->s.frame = self->monsterinfo.currentmove->firstframe + (rand() % (self->monsterinfo.currentmove->lastframe - self->monsterinfo.currentmove->firstframe + 1)); + { + self->s.frame = self->monsterinfo.currentmove->firstframe + + (rand() % + (self->monsterinfo.currentmove->lastframe - + self->monsterinfo.currentmove->firstframe + 1)); + } return true; } -void monster_start_go (edict_t *self) +void +monster_start_go(edict_t *self) { - vec3_t v; + vec3_t v; if (self->health <= 0) + { return; + } - // check for target to combat_point and change to combattarget + /* check for target to combat_point and change to combattarget */ if (self->target) { - qboolean notcombat; - qboolean fixup; - edict_t *target; + qboolean notcombat; + qboolean fixup; + edict_t *target; target = NULL; notcombat = false; fixup = false; - while ((target = G_Find (target, FOFS(targetname), self->target)) != NULL) + + while ((target = + G_Find(target, FOFS(targetname), self->target)) != NULL) { if (strcmp(target->classname, "point_combat") == 0) { @@ -605,26 +813,44 @@ void monster_start_go (edict_t *self) notcombat = true; } } + if (notcombat && self->combattarget) - gi.dprintf("%s at %s has target with mixed types\n", self->classname, vtos(self->s.origin)); + { + gi.dprintf("%s at %s has target with mixed types\n", + self->classname, + vtos(self->s.origin)); + } + if (fixup) + { self->target = NULL; + } } - // validate combattarget + /* validate combattarget */ if (self->combattarget) { - edict_t *target; + edict_t *target; target = NULL; - while ((target = G_Find (target, FOFS(targetname), self->combattarget)) != NULL) + + while ((target = + G_Find(target, FOFS(targetname), + self->combattarget)) != NULL) { if (strcmp(target->classname, "point_combat") != 0) { - gi.dprintf("%s at (%i %i %i) has a bad combattarget %s : %s at (%i %i %i)\n", - self->classname, (int)self->s.origin[0], (int)self->s.origin[1], (int)self->s.origin[2], - self->combattarget, target->classname, (int)target->s.origin[0], (int)target->s.origin[1], - (int)target->s.origin[2]); + gi.dprintf( + "%s at (%i %i %i) has a bad combattarget %s : %s at (%i %i %i)\n", + self->classname, + (int)self->s.origin[0], + (int)self->s.origin[1], + (int)self->s.origin[2], + self->combattarget, + target->classname, + (int)target->s.origin[0], + (int)target->s.origin[1], + (int)target->s.origin[2]); } } } @@ -632,106 +858,134 @@ void monster_start_go (edict_t *self) if (self->target) { self->goalentity = self->movetarget = G_PickTarget(self->target); + if (!self->movetarget) { - gi.dprintf ("%s can't find target %s at %s\n", self->classname, self->target, vtos(self->s.origin)); + gi.dprintf("%s can't find target %s at %s\n", + self->classname, + self->target, + vtos(self->s.origin)); self->target = NULL; self->monsterinfo.pausetime = 100000000; - self->monsterinfo.stand (self); + self->monsterinfo.stand(self); } - else if (strcmp (self->movetarget->classname, "path_corner") == 0) + else if (strcmp(self->movetarget->classname, "path_corner") == 0) { - VectorSubtract (self->goalentity->s.origin, self->s.origin, v); + VectorSubtract(self->goalentity->s.origin, self->s.origin, v); self->ideal_yaw = self->s.angles[YAW] = vectoyaw(v); - self->monsterinfo.walk (self); + self->monsterinfo.walk(self); self->target = NULL; } else { self->goalentity = self->movetarget = NULL; self->monsterinfo.pausetime = 100000000; - self->monsterinfo.stand (self); + self->monsterinfo.stand(self); } } else { self->monsterinfo.pausetime = 100000000; - self->monsterinfo.stand (self); + self->monsterinfo.stand(self); } self->think = monster_think; self->nextthink = level.time + FRAMETIME; } - -void walkmonster_start_go (edict_t *self) +void +walkmonster_start_go(edict_t *self) { - if (!(self->spawnflags & 2) && level.time < 1) + if (!(self->spawnflags & 2) && (level.time < 1)) { - M_droptofloor (self); + M_droptofloor(self); if (self->groundentity) - if (!M_walkmove (self, 0, 0)) - gi.dprintf ("%s in solid at %s\n", self->classname, vtos(self->s.origin)); + { + if (!M_walkmove(self, 0, 0)) + { + gi.dprintf("%s in solid at %s\n", self->classname, + vtos(self->s.origin)); + } + } } - + if (!self->yaw_speed) + { self->yaw_speed = 20; + } + self->viewheight = 25; - monster_start_go (self); + monster_start_go(self); if (self->spawnflags & 2) - monster_triggered_start (self); + { + monster_triggered_start(self); + } } -void walkmonster_start (edict_t *self) +void +walkmonster_start(edict_t *self) { self->think = walkmonster_start_go; - monster_start (self); + monster_start(self); } - -void flymonster_start_go (edict_t *self) +void +flymonster_start_go(edict_t *self) { - if (!M_walkmove (self, 0, 0)) - gi.dprintf ("%s in solid at %s\n", self->classname, vtos(self->s.origin)); + if (!M_walkmove(self, 0, 0)) + { + gi.dprintf("%s in solid at %s\n", self->classname, vtos(self->s.origin)); + } if (!self->yaw_speed) + { self->yaw_speed = 10; + } + self->viewheight = 25; - monster_start_go (self); + monster_start_go(self); if (self->spawnflags & 2) - monster_triggered_start (self); + { + monster_triggered_start(self); + } } - -void flymonster_start (edict_t *self) +void +flymonster_start(edict_t *self) { self->flags |= FL_FLY; self->think = flymonster_start_go; - monster_start (self); + monster_start(self); } - -void swimmonster_start_go (edict_t *self) +void +swimmonster_start_go(edict_t *self) { if (!self->yaw_speed) + { self->yaw_speed = 10; + } + self->viewheight = 10; - monster_start_go (self); + monster_start_go(self); if (self->spawnflags & 2) - monster_triggered_start (self); + { + monster_triggered_start(self); + } } -void swimmonster_start (edict_t *self) +void +swimmonster_start(edict_t *self) { self->flags |= FL_SWIM; self->think = swimmonster_start_go; - monster_start (self); + monster_start(self); } diff --git a/src/game/ctf/g_phys.c b/src/game/ctf/g_phys.c index 2b7caa9c..8f35dd5e 100644 --- a/src/game/ctf/g_phys.c +++ b/src/game/ctf/g_phys.c @@ -1,309 +1,369 @@ /* -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. - -*/ -// g_phys.c + * 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. + * + */ +/* g_phys.c */ #include "g_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. - -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 - -solid_edge items only clip against bsp models. - -*/ - + * + * + * 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 + * + * 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. + * + */ /* -============ -SV_TestEntityPosition - -============ -*/ -edict_t *SV_TestEntityPosition (edict_t *ent) + * ============ + * SV_TestEntityPosition + * + * ============ + */ +edict_t * +SV_TestEntityPosition(edict_t *ent) { - trace_t trace; - int mask; + trace_t trace; + int mask; - if (ent->clipmask) + { mask = ent->clipmask; + } else + { mask = MASK_SOLID; - trace = gi.trace (ent->s.origin, ent->mins, ent->maxs, ent->s.origin, ent, mask); + } + + trace = gi.trace(ent->s.origin, + ent->mins, + ent->maxs, + ent->s.origin, + ent, + mask); if (trace.startsolid) + { return g_edicts; - + } + return NULL; } - /* -================ -SV_CheckVelocity -================ -*/ -void SV_CheckVelocity (edict_t *ent) + * ================ + * SV_CheckVelocity + * ================ + */ +void +SV_CheckVelocity(edict_t *ent) { - int i; + int i; - // - // bound velocity - // - for (i=0 ; i<3 ; i++) + /* */ + /* bound velocity */ + /* */ + for (i = 0; i < 3; i++) { if (ent->velocity[i] > sv_maxvelocity->value) + { ent->velocity[i] = sv_maxvelocity->value; + } else if (ent->velocity[i] < -sv_maxvelocity->value) + { ent->velocity[i] = -sv_maxvelocity->value; + } } } /* -============= -SV_RunThink - -Runs thinking code for this frame if necessary -============= -*/ -qboolean SV_RunThink (edict_t *ent) + * ============= + * SV_RunThink + * + * Runs thinking code for this frame if necessary + * ============= + */ +qboolean +SV_RunThink(edict_t *ent) { - float thinktime; + float thinktime; thinktime = ent->nextthink; + if (thinktime <= 0) + { return true; - if (thinktime > level.time+0.001) + } + + if (thinktime > level.time + 0.001) + { return true; - + } + ent->nextthink = 0; + if (!ent->think) - gi.error ("NULL ent->think"); - ent->think (ent); + { + gi.error("NULL ent->think"); + } + + ent->think(ent); return false; } /* -================== -SV_Impact - -Two entities have touched, so run their touch functions -================== -*/ -void SV_Impact (edict_t *e1, trace_t *trace) + * ================== + * SV_Impact + * + * Two entities have touched, so run their touch functions + * ================== + */ +void +SV_Impact(edict_t *e1, trace_t *trace) { - edict_t *e2; -// cplane_t backplane; + edict_t *e2; + +/* cplane_t backplane; */ e2 = trace->ent; - if (e1->touch && e1->solid != SOLID_NOT) - e1->touch (e1, e2, &trace->plane, trace->surface); - - if (e2->touch && e2->solid != SOLID_NOT) - e2->touch (e2, e1, NULL, NULL); + if (e1->touch && (e1->solid != SOLID_NOT)) + { + e1->touch(e1, e2, &trace->plane, trace->surface); + } + + if (e2->touch && (e2->solid != SOLID_NOT)) + { + e2->touch(e2, e1, NULL, NULL); + } } - /* -================== -ClipVelocity + * ================== + * ClipVelocity + * + * Slide off of the impacting object + * returns the blocked flags (1 = floor, 2 = step / wall) + * ================== + */ +#define STOP_EPSILON 0.1 -Slide off of the impacting object -returns the blocked flags (1 = floor, 2 = step / wall) -================== -*/ -#define STOP_EPSILON 0.1 - -int ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce) +int +ClipVelocity(vec3_t in, vec3_t normal, vec3_t out, float overbounce) { - float backoff; - float change; - int i, blocked; - - blocked = 0; - if (normal[2] > 0) - blocked |= 1; // floor - if (!normal[2]) - blocked |= 2; // step - - backoff = DotProduct (in, normal) * overbounce; + float backoff; + float change; + int i, blocked; - for (i=0 ; i<3 ; i++) + blocked = 0; + + if (normal[2] > 0) { - change = normal[i]*backoff; - out[i] = in[i] - change; - if (out[i] > -STOP_EPSILON && out[i] < STOP_EPSILON) - out[i] = 0; + blocked |= 1; /* floor */ } - + + if (!normal[2]) + { + blocked |= 2; /* step */ + } + + backoff = DotProduct(in, normal) * overbounce; + + for (i = 0; i < 3; i++) + { + change = normal[i] * backoff; + out[i] = in[i] - change; + + if ((out[i] > -STOP_EPSILON) && (out[i] < STOP_EPSILON)) + { + out[i] = 0; + } + } + return blocked; } - /* -============ -SV_FlyMove - -The basic solid body movement clip that slides along multiple planes -Returns the clipflags if the velocity was modified (hit something solid) -1 = floor -2 = wall / step -4 = dead stop -============ -*/ -#define MAX_CLIP_PLANES 5 -int SV_FlyMove (edict_t *ent, float time, int mask) + * ============ + * SV_FlyMove + * + * The basic solid body movement clip that slides along multiple planes + * Returns the clipflags if the velocity was modified (hit something solid) + * 1 = floor + * 2 = wall / step + * 4 = dead stop + * ============ + */ +#define MAX_CLIP_PLANES 5 +int +SV_FlyMove(edict_t *ent, float time, int mask) { - edict_t *hit; - int bumpcount, numbumps; - vec3_t dir; - float d; - int numplanes; - vec3_t planes[MAX_CLIP_PLANES]; - vec3_t primal_velocity, original_velocity, new_velocity; - int i, j; - trace_t trace; - vec3_t end; - float time_left; - int blocked; - + edict_t *hit; + int bumpcount, numbumps; + vec3_t dir; + float d; + int numplanes; + vec3_t planes[MAX_CLIP_PLANES]; + vec3_t primal_velocity, original_velocity, new_velocity; + int i, j; + trace_t trace; + vec3_t end; + float time_left; + int blocked; + numbumps = 4; - + blocked = 0; - VectorCopy (ent->velocity, original_velocity); - VectorCopy (ent->velocity, primal_velocity); + VectorCopy(ent->velocity, original_velocity); + VectorCopy(ent->velocity, primal_velocity); numplanes = 0; - + time_left = time; ent->groundentity = NULL; - for (bumpcount=0 ; bumpcounts.origin[i] + time_left * ent->velocity[i]; - trace = gi.trace (ent->s.origin, ent->mins, ent->maxs, end, ent, mask); + for (bumpcount = 0; bumpcount < numbumps; bumpcount++) + { + for (i = 0; i < 3; i++) + { + end[i] = ent->s.origin[i] + time_left * ent->velocity[i]; + } + + trace = gi.trace(ent->s.origin, ent->mins, ent->maxs, end, ent, mask); if (trace.allsolid) - { // entity is trapped in another solid - VectorCopy (vec3_origin, ent->velocity); + { /* entity is trapped in another solid */ + VectorCopy(vec3_origin, ent->velocity); return 3; } if (trace.fraction > 0) - { // actually covered some distance - VectorCopy (trace.endpos, ent->s.origin); - VectorCopy (ent->velocity, original_velocity); + { /* actually covered some distance */ + VectorCopy(trace.endpos, ent->s.origin); + VectorCopy(ent->velocity, original_velocity); numplanes = 0; } if (trace.fraction == 1) - break; // moved the entire distance + { + break; /* moved the entire distance */ + } hit = trace.ent; if (trace.plane.normal[2] > 0.7) { - blocked |= 1; // floor - if ( hit->solid == SOLID_BSP) + blocked |= 1; /* floor */ + + if (hit->solid == SOLID_BSP) { ent->groundentity = hit; ent->groundentity_linkcount = hit->linkcount; } } + if (!trace.plane.normal[2]) { - blocked |= 2; // step + blocked |= 2; /* step */ } - // - // run the impact function - // - SV_Impact (ent, &trace); - if (!ent->inuse) - break; // removed by the impact function + /* */ + /* run the impact function */ + /* */ + SV_Impact(ent, &trace); + + if (!ent->inuse) + { + break; /* removed by the impact function */ + } - time_left -= time_left * trace.fraction; - - // cliped to another plane + + /* cliped to another plane */ if (numplanes >= MAX_CLIP_PLANES) - { // this shouldn't really happen - VectorCopy (vec3_origin, ent->velocity); + { /* this shouldn't really happen */ + VectorCopy(vec3_origin, ent->velocity); return 3; } - VectorCopy (trace.plane.normal, planes[numplanes]); + VectorCopy(trace.plane.normal, planes[numplanes]); numplanes++; - // - // modify original_velocity so it parallels all of the clip planes - // - for (i=0 ; ivelocity); - } - else - { // go along the crease - if (numplanes != 2) - { - VectorCopy (vec3_origin, ent->velocity); - return 7; } - CrossProduct (planes[0], planes[1], dir); - d = DotProduct (dir, ent->velocity); - VectorScale (dir, d, ent->velocity); + + if (j == numplanes) + { + break; + } } - // - // if original velocity is against the original velocity, stop dead - // to avoid tiny occilations in sloping corners - // - if (DotProduct (ent->velocity, primal_velocity) <= 0) + if (i != numplanes) + { /* go along this plane */ + VectorCopy(new_velocity, ent->velocity); + } + else { - VectorCopy (vec3_origin, ent->velocity); + /* go along the crease */ + if (numplanes != 2) + { + VectorCopy(vec3_origin, ent->velocity); + return 7; + } + + CrossProduct(planes[0], planes[1], dir); + d = DotProduct(dir, ent->velocity); + VectorScale(dir, d, ent->velocity); + } + + /* */ + /* if original velocity is against the original velocity, stop dead */ + /* to avoid tiny occilations in sloping corners */ + /* */ + if (DotProduct(ent->velocity, primal_velocity) <= 0) + { + VectorCopy(vec3_origin, ent->velocity); return blocked; } } @@ -311,640 +371,784 @@ int SV_FlyMove (edict_t *ent, float time, int mask) return blocked; } - /* -============ -SV_AddGravity - -============ -*/ -void SV_AddGravity (edict_t *ent) + * ============ + * SV_AddGravity + * + * ============ + */ +void +SV_AddGravity(edict_t *ent) { ent->velocity[2] -= ent->gravity * sv_gravity->value * FRAMETIME; } /* -=============================================================================== - -PUSHMOVE - -=============================================================================== -*/ + * =============================================================================== + * + * PUSHMOVE + * + * =============================================================================== + */ /* -============ -SV_PushEntity - -Does not change the entities velocity at all -============ -*/ -trace_t SV_PushEntity (edict_t *ent, vec3_t push) + * ============ + * SV_PushEntity + * + * Does not change the entities velocity at all + * ============ + */ +trace_t +SV_PushEntity(edict_t *ent, vec3_t push) { - trace_t trace; - vec3_t start; - vec3_t end; - int mask; + trace_t trace; + vec3_t start; + vec3_t end; + int mask; - VectorCopy (ent->s.origin, start); - VectorAdd (start, push, end); + VectorCopy(ent->s.origin, start); + VectorAdd(start, push, end); retry: - if (ent->clipmask) - mask = ent->clipmask; - else - mask = MASK_SOLID; - trace = gi.trace (start, ent->mins, ent->maxs, end, ent, mask); - - VectorCopy (trace.endpos, ent->s.origin); - gi.linkentity (ent); + if (ent->clipmask) + { + mask = ent->clipmask; + } + else + { + mask = MASK_SOLID; + } + + trace = gi.trace(start, ent->mins, ent->maxs, end, ent, mask); + + VectorCopy(trace.endpos, ent->s.origin); + gi.linkentity(ent); if (trace.fraction != 1.0) { - SV_Impact (ent, &trace); + SV_Impact(ent, &trace); - // if the pushed entity went away and the pusher is still there + /* if the pushed entity went away and the pusher is still there */ if (!trace.ent->inuse && ent->inuse) { - // move the pusher back and try again - VectorCopy (start, ent->s.origin); - gi.linkentity (ent); + /* move the pusher back and try again */ + VectorCopy(start, ent->s.origin); + gi.linkentity(ent); goto retry; } } if (ent->inuse) - G_TouchTriggers (ent); + { + G_TouchTriggers(ent); + } return trace; -} - +} typedef struct { - edict_t *ent; - vec3_t origin; - vec3_t angles; - float deltayaw; + edict_t *ent; + vec3_t origin; + vec3_t angles; + float deltayaw; } pushed_t; -pushed_t pushed[MAX_EDICTS], *pushed_p; +pushed_t pushed[MAX_EDICTS], *pushed_p; -edict_t *obstacle; +edict_t *obstacle; /* -============ -SV_Push - -Objects need to be moved back on a failed push, -otherwise riders would continue to slide. -============ -*/ -qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove) + * ============ + * SV_Push + * + * Objects need to be moved back on a failed push, + * otherwise riders would continue to slide. + * ============ + */ +qboolean +SV_Push(edict_t *pusher, vec3_t move, vec3_t amove) { - int i, e; - edict_t *check, *block; - vec3_t mins, maxs; - pushed_t *p; - vec3_t org, org2, move2, forward, right, up; + int i, e; + edict_t *check, *block; + vec3_t mins, maxs; + pushed_t *p; + vec3_t org, org2, move2, forward, right, up; - // clamp the move to 1/8 units, so the position will - // be accurate for client side prediction - for (i=0 ; i<3 ; i++) + /* clamp the move to 1/8 units, so the position will */ + /* be accurate for client side prediction */ + for (i = 0; i < 3; i++) { - float temp; - temp = move[i]*8.0; + float temp; + temp = move[i] * 8.0; + if (temp > 0.0) + { temp += 0.5; + } else + { temp -= 0.5; + } + move[i] = 0.125 * (int)temp; } - // find the bounding box - for (i=0 ; i<3 ; i++) + /* find the bounding box */ + for (i = 0; i < 3; i++) { mins[i] = pusher->absmin[i] + move[i]; maxs[i] = pusher->absmax[i] + move[i]; } - // we need this for pushing things later - VectorSubtract (vec3_origin, amove, org); - AngleVectors (org, forward, right, up); + /* we need this for pushing things later */ + VectorSubtract(vec3_origin, amove, org); + AngleVectors(org, forward, right, up); - // save the pusher's original position + /* save the pusher's original position */ pushed_p->ent = pusher; - VectorCopy (pusher->s.origin, pushed_p->origin); - VectorCopy (pusher->s.angles, pushed_p->angles); + VectorCopy(pusher->s.origin, pushed_p->origin); + VectorCopy(pusher->s.angles, pushed_p->angles); + if (pusher->client) + { pushed_p->deltayaw = pusher->client->ps.pmove.delta_angles[YAW]; + } + pushed_p++; - // move the pusher to it's final position - VectorAdd (pusher->s.origin, move, pusher->s.origin); - VectorAdd (pusher->s.angles, amove, pusher->s.angles); - gi.linkentity (pusher); + /* move the pusher to it's final position */ + VectorAdd(pusher->s.origin, move, pusher->s.origin); + VectorAdd(pusher->s.angles, amove, pusher->s.angles); + gi.linkentity(pusher); + + /* see if any solid entities are inside the final position */ + check = g_edicts + 1; - // see if any solid entities are inside the final position - check = g_edicts+1; for (e = 1; e < globals.num_edicts; e++, check++) { if (!check->inuse) - continue; - if (check->movetype == MOVETYPE_PUSH - || check->movetype == MOVETYPE_STOP - || check->movetype == MOVETYPE_NONE - || check->movetype == MOVETYPE_NOCLIP) - continue; - - if (!check->area.prev) - continue; // not linked in anywhere - - // if the entity is standing on the pusher, it will definitely be moved - if (check->groundentity != pusher) { - // see if the ent needs to be tested - if ( check->absmin[0] >= maxs[0] - || check->absmin[1] >= maxs[1] - || check->absmin[2] >= maxs[2] - || check->absmax[0] <= mins[0] - || check->absmax[1] <= mins[1] - || check->absmax[2] <= mins[2] ) - continue; - - // see if the ent's bbox is inside the pusher's final position - if (!SV_TestEntityPosition (check)) - continue; + continue; } - if ((pusher->movetype == MOVETYPE_PUSH) || (check->groundentity == pusher)) + if ((check->movetype == MOVETYPE_PUSH) || + (check->movetype == MOVETYPE_STOP) || + (check->movetype == MOVETYPE_NONE) || + (check->movetype == MOVETYPE_NOCLIP)) { - // move this entity + continue; + } + + if (!check->area.prev) + { + continue; /* not linked in anywhere */ + } + + /* if the entity is standing on the pusher, it will definitely be moved */ + if (check->groundentity != pusher) + { + /* see if the ent needs to be tested */ + if ((check->absmin[0] >= maxs[0]) || + (check->absmin[1] >= maxs[1]) || + (check->absmin[2] >= maxs[2]) || + (check->absmax[0] <= mins[0]) || + (check->absmax[1] <= mins[1]) || + (check->absmax[2] <= mins[2])) + { + continue; + } + + /* see if the ent's bbox is inside the pusher's final position */ + if (!SV_TestEntityPosition(check)) + { + continue; + } + } + + if ((pusher->movetype == MOVETYPE_PUSH) || + (check->groundentity == pusher)) + { + /* move this entity */ pushed_p->ent = check; - VectorCopy (check->s.origin, pushed_p->origin); - VectorCopy (check->s.angles, pushed_p->angles); + VectorCopy(check->s.origin, pushed_p->origin); + VectorCopy(check->s.angles, pushed_p->angles); pushed_p++; - // try moving the contacted entity - VectorAdd (check->s.origin, move, check->s.origin); + /* try moving the contacted entity */ + VectorAdd(check->s.origin, move, check->s.origin); + if (check->client) - { // FIXME: doesn't rotate monsters? + { /* FIXME: doesn't rotate monsters? */ check->client->ps.pmove.delta_angles[YAW] += amove[YAW]; } - // figure movement due to the pusher's amove - VectorSubtract (check->s.origin, pusher->s.origin, org); - org2[0] = DotProduct (org, forward); - org2[1] = -DotProduct (org, right); - org2[2] = DotProduct (org, up); - VectorSubtract (org2, org, move2); - VectorAdd (check->s.origin, move2, check->s.origin); + /* figure movement due to the pusher's amove */ + VectorSubtract(check->s.origin, pusher->s.origin, org); + org2[0] = DotProduct(org, forward); + org2[1] = -DotProduct(org, right); + org2[2] = DotProduct(org, up); + VectorSubtract(org2, org, move2); + VectorAdd(check->s.origin, move2, check->s.origin); - // may have pushed them off an edge + /* may have pushed them off an edge */ if (check->groundentity != pusher) + { check->groundentity = NULL; + } + + block = SV_TestEntityPosition(check); - block = SV_TestEntityPosition (check); if (!block) - { // pushed ok - gi.linkentity (check); - // impact? + { /* pushed ok */ + gi.linkentity(check); + /* impact? */ continue; } - // if it is ok to leave in the old position, do it - // this is only relevent for riding entities, not pushed - // FIXME: this doesn't acount for rotation - VectorSubtract (check->s.origin, move, check->s.origin); - block = SV_TestEntityPosition (check); + /* if it is ok to leave in the old position, do it */ + /* this is only relevent for riding entities, not pushed */ + /* FIXME: this doesn't acount for rotation */ + VectorSubtract(check->s.origin, move, check->s.origin); + block = SV_TestEntityPosition(check); + if (!block) { pushed_p--; continue; } } - - // save off the obstacle so we can call the block function + + /* save off the obstacle so we can call the block function */ obstacle = check; - // move back any entities we already moved - // go backwards, so if the same entity was pushed - // twice, it goes back to the original position - for (p=pushed_p-1 ; p>=pushed ; p--) + /* move back any entities we already moved */ + /* go backwards, so if the same entity was pushed */ + /* twice, it goes back to the original position */ + for (p = pushed_p - 1; p >= pushed; p--) { - VectorCopy (p->origin, p->ent->s.origin); - VectorCopy (p->angles, p->ent->s.angles); + VectorCopy(p->origin, p->ent->s.origin); + VectorCopy(p->angles, p->ent->s.angles); + if (p->ent->client) { p->ent->client->ps.pmove.delta_angles[YAW] = p->deltayaw; } - gi.linkentity (p->ent); + + gi.linkentity(p->ent); } + return false; } - //FIXME: is there a better way to handle this? - // see if anything we moved has touched a trigger - for (p=pushed_p-1 ; p>=pushed ; p--) - G_TouchTriggers (p->ent); + /* FIXME: is there a better way to handle this? */ + /* see if anything we moved has touched a trigger */ + for (p = pushed_p - 1; p >= pushed; p--) + { + G_TouchTriggers(p->ent); + } return true; } /* -================ -SV_Physics_Pusher - -Bmodel objects don't interact with each other, but -push all box objects -================ -*/ -void SV_Physics_Pusher (edict_t *ent) + * ================ + * SV_Physics_Pusher + * + * Bmodel objects don't interact with each other, but + * push all box objects + * ================ + */ +void +SV_Physics_Pusher(edict_t *ent) { - vec3_t move, amove; - edict_t *part, *mv; + vec3_t move, amove; + edict_t *part, *mv; - // if not a team captain, so movement will be handled elsewhere - if ( ent->flags & FL_TEAMSLAVE) + /* if not a team captain, so movement will be handled elsewhere */ + if (ent->flags & FL_TEAMSLAVE) + { return; + } - // make sure all team slaves can move before commiting - // any moves or calling any think functions - // if the move is blocked, all moved objects will be backed out + /* make sure all team slaves can move before commiting */ + /* any moves or calling any think functions */ + /* if the move is blocked, all moved objects will be backed out */ pushed_p = pushed; - for (part = ent ; part ; part=part->teamchain) + + for (part = ent; part; part = part->teamchain) { if (part->velocity[0] || part->velocity[1] || part->velocity[2] || part->avelocity[0] || part->avelocity[1] || part->avelocity[2] ) - { // object is moving - VectorScale (part->velocity, FRAMETIME, move); - VectorScale (part->avelocity, FRAMETIME, amove); + { /* object is moving */ + VectorScale(part->velocity, FRAMETIME, move); + VectorScale(part->avelocity, FRAMETIME, amove); - if (!SV_Push (part, move, amove)) - break; // move was blocked + if (!SV_Push(part, move, amove)) + { + break; /* move was blocked */ + } } } + if (pushed_p > &pushed[MAX_EDICTS]) - gi.error (ERR_FATAL, "pushed_p > &pushed[MAX_EDICTS], memory corrupted"); + { + gi.error(ERR_FATAL, "pushed_p > &pushed[MAX_EDICTS], memory corrupted"); + } if (part) { - // the move failed, bump all nextthink times and back out moves - for (mv = ent ; mv ; mv=mv->teamchain) + /* the move failed, bump all nextthink times and back out moves */ + for (mv = ent; mv; mv = mv->teamchain) { if (mv->nextthink > 0) + { mv->nextthink += FRAMETIME; + } } - // if the pusher has a "blocked" function, call it - // otherwise, just stay in place until the obstacle is gone + /* if the pusher has a "blocked" function, call it */ + /* otherwise, just stay in place until the obstacle is gone */ if (part->blocked) - part->blocked (part, obstacle); + { + part->blocked(part, obstacle); + } } else { - // the move succeeded, so call all think functions - for (part = ent ; part ; part=part->teamchain) + /* the move succeeded, so call all think functions */ + for (part = ent; part; part = part->teamchain) { - SV_RunThink (part); + SV_RunThink(part); } } } -//================================================================== +/* ================================================================== */ /* -============= -SV_Physics_None - -Non moving objects can only think -============= -*/ -void SV_Physics_None (edict_t *ent) + * ============= + * SV_Physics_None + * + * Non moving objects can only think + * ============= + */ +void +SV_Physics_None(edict_t *ent) { - // regular thinking - SV_RunThink (ent); + /* regular thinking */ + SV_RunThink(ent); } /* -============= -SV_Physics_Noclip - -A moving object that doesn't obey physics -============= -*/ -void SV_Physics_Noclip (edict_t *ent) + * ============= + * SV_Physics_Noclip + * + * A moving object that doesn't obey physics + * ============= + */ +void +SV_Physics_Noclip(edict_t *ent) { - // regular thinking - if (!SV_RunThink (ent)) + /* regular thinking */ + if (!SV_RunThink(ent)) + { return; - - VectorMA (ent->s.angles, FRAMETIME, ent->avelocity, ent->s.angles); - VectorMA (ent->s.origin, FRAMETIME, ent->velocity, ent->s.origin); + } - gi.linkentity (ent); + VectorMA(ent->s.angles, FRAMETIME, ent->avelocity, ent->s.angles); + VectorMA(ent->s.origin, FRAMETIME, ent->velocity, ent->s.origin); + + gi.linkentity(ent); } /* -============================================================================== - -TOSS / BOUNCE - -============================================================================== -*/ + * ============================================================================== + * + * TOSS / BOUNCE + * + * ============================================================================== + */ /* -============= -SV_Physics_Toss - -Toss, bounce, and fly movement. When onground, do nothing. -============= -*/ -void SV_Physics_Toss (edict_t *ent) + * ============= + * SV_Physics_Toss + * + * Toss, bounce, and fly movement. When onground, do nothing. + * ============= + */ +void +SV_Physics_Toss(edict_t *ent) { - trace_t trace; - vec3_t move; - float backoff; - edict_t *slave; - qboolean wasinwater; - qboolean isinwater; - vec3_t old_origin; + trace_t trace; + vec3_t move; + float backoff; + edict_t *slave; + qboolean wasinwater; + qboolean isinwater; + vec3_t old_origin; - // regular thinking - SV_RunThink (ent); + /* regular thinking */ + SV_RunThink(ent); - // if not a team captain, so movement will be handled elsewhere - if ( ent->flags & FL_TEAMSLAVE) + /* if not a team captain, so movement will be handled elsewhere */ + if (ent->flags & FL_TEAMSLAVE) + { return; + } if (ent->velocity[2] > 0) + { ent->groundentity = NULL; + } - // check for the groundentity going away + /* check for the groundentity going away */ if (ent->groundentity) + { if (!ent->groundentity->inuse) + { ent->groundentity = NULL; + } + } - // if onground, return without moving - if ( ent->groundentity ) + /* if onground, return without moving */ + if (ent->groundentity) + { return; + } - VectorCopy (ent->s.origin, old_origin); + VectorCopy(ent->s.origin, old_origin); - SV_CheckVelocity (ent); + SV_CheckVelocity(ent); - // add gravity - if (ent->movetype != MOVETYPE_FLY - && ent->movetype != MOVETYPE_FLYMISSILE) - SV_AddGravity (ent); + /* add gravity */ + if ((ent->movetype != MOVETYPE_FLY) && + (ent->movetype != MOVETYPE_FLYMISSILE)) + { + SV_AddGravity(ent); + } - // move angles - VectorMA (ent->s.angles, FRAMETIME, ent->avelocity, ent->s.angles); + /* move angles */ + VectorMA(ent->s.angles, FRAMETIME, ent->avelocity, ent->s.angles); + + /* move origin */ + VectorScale(ent->velocity, FRAMETIME, move); + trace = SV_PushEntity(ent, move); - // move origin - VectorScale (ent->velocity, FRAMETIME, move); - trace = SV_PushEntity (ent, move); if (!ent->inuse) + { return; + } if (trace.fraction < 1) { if (ent->movetype == MOVETYPE_BOUNCE) + { backoff = 1.5; + } else + { backoff = 1; + } - ClipVelocity (ent->velocity, trace.plane.normal, ent->velocity, backoff); + ClipVelocity(ent->velocity, trace.plane.normal, ent->velocity, backoff); - // stop if on ground + /* stop if on ground */ if (trace.plane.normal[2] > 0.7) - { - if (ent->velocity[2] < 60 || ent->movetype != MOVETYPE_BOUNCE ) + { + if ((ent->velocity[2] < 60) || (ent->movetype != MOVETYPE_BOUNCE)) { ent->groundentity = trace.ent; ent->groundentity_linkcount = trace.ent->linkcount; - VectorCopy (vec3_origin, ent->velocity); - VectorCopy (vec3_origin, ent->avelocity); + VectorCopy(vec3_origin, ent->velocity); + VectorCopy(vec3_origin, ent->avelocity); } } } - - // check for water transition + + /* check for water transition */ wasinwater = (ent->watertype & MASK_WATER); - ent->watertype = gi.pointcontents (ent->s.origin); + ent->watertype = gi.pointcontents(ent->s.origin); isinwater = ent->watertype & MASK_WATER; if (isinwater) + { ent->waterlevel = 1; + } else + { ent->waterlevel = 0; + } if (!wasinwater && isinwater) - gi.positioned_sound (old_origin, g_edicts, CHAN_AUTO, gi.soundindex("misc/h2ohit1.wav"), 1, 1, 0); + { + gi.positioned_sound(old_origin, g_edicts, CHAN_AUTO, + gi.soundindex("misc/h2ohit1.wav"), 1, 1, 0); + } else if (wasinwater && !isinwater) - gi.positioned_sound (ent->s.origin, g_edicts, CHAN_AUTO, gi.soundindex("misc/h2ohit1.wav"), 1, 1, 0); + { + gi.positioned_sound(ent->s.origin, g_edicts, CHAN_AUTO, + gi.soundindex("misc/h2ohit1.wav"), 1, 1, 0); + } - // move teamslaves + /* move teamslaves */ for (slave = ent->teamchain; slave; slave = slave->teamchain) { - VectorCopy (ent->s.origin, slave->s.origin); - gi.linkentity (slave); + VectorCopy(ent->s.origin, slave->s.origin); + gi.linkentity(slave); } } /* -=============================================================================== - -STEPPING MOVEMENT - -=============================================================================== -*/ + * =============================================================================== + * + * STEPPING MOVEMENT + * + * =============================================================================== + */ /* -============= -SV_Physics_Step + * ============= + * SV_Physics_Step + * + * Monsters freefall when they don't have a ground entity, otherwise + * all movement is done with discrete steps. + * + * This is also used for objects that have become still on the ground, but + * will fall if the floor is pulled out from under them. + * FIXME: is this true? + * ============= + */ -Monsters freefall when they don't have a ground entity, otherwise -all movement is done with discrete steps. +/* FIXME: hacked in for E3 demo */ +#define sv_stopspeed 100 +#define sv_friction 6 +#define sv_waterfriction 1 -This is also used for objects that have become still on the ground, but -will fall if the floor is pulled out from under them. -FIXME: is this true? -============= -*/ - -//FIXME: hacked in for E3 demo -#define sv_stopspeed 100 -#define sv_friction 6 -#define sv_waterfriction 1 - -void SV_AddRotationalFriction (edict_t *ent) +void +SV_AddRotationalFriction(edict_t *ent) { - int n; - float adjustment; + int n; + float adjustment; - VectorMA (ent->s.angles, FRAMETIME, ent->avelocity, ent->s.angles); + VectorMA(ent->s.angles, FRAMETIME, ent->avelocity, ent->s.angles); adjustment = FRAMETIME * sv_stopspeed * sv_friction; + for (n = 0; n < 3; n++) { if (ent->avelocity[n] > 0) { ent->avelocity[n] -= adjustment; + if (ent->avelocity[n] < 0) + { ent->avelocity[n] = 0; + } } else { ent->avelocity[n] += adjustment; + if (ent->avelocity[n] > 0) + { ent->avelocity[n] = 0; + } } } } -void SV_Physics_Step (edict_t *ent) +void +SV_Physics_Step(edict_t *ent) { - qboolean wasonground; - qboolean hitsound = false; - float *vel; - float speed, newspeed, control; - float friction; - edict_t *groundentity; - int mask; + qboolean wasonground; + qboolean hitsound = false; + float *vel; + float speed, newspeed, control; + float friction; + edict_t *groundentity; + int mask; - // airborn monsters should always check for ground + /* airborn monsters should always check for ground */ if (!ent->groundentity) - M_CheckGround (ent); + { + M_CheckGround(ent); + } groundentity = ent->groundentity; - SV_CheckVelocity (ent); + SV_CheckVelocity(ent); if (groundentity) + { wasonground = true; + } else + { wasonground = false; - - if (ent->avelocity[0] || ent->avelocity[1] || ent->avelocity[2]) - SV_AddRotationalFriction (ent); + } - // add gravity except: - // flying monsters - // swimming monsters who are in the water - if (! wasonground) + if (ent->avelocity[0] || ent->avelocity[1] || ent->avelocity[2]) + { + SV_AddRotationalFriction(ent); + } + + /* add gravity except: */ + /* flying monsters */ + /* swimming monsters who are in the water */ + if (!wasonground) + { if (!(ent->flags & FL_FLY)) + { if (!((ent->flags & FL_SWIM) && (ent->waterlevel > 2))) { - if (ent->velocity[2] < sv_gravity->value*-0.1) + if (ent->velocity[2] < sv_gravity->value * -0.1) + { hitsound = true; - if (ent->waterlevel == 0) - SV_AddGravity (ent); - } + } - // friction for flying monsters that have been given vertical velocity + if (ent->waterlevel == 0) + { + SV_AddGravity(ent); + } + } + } + } + + /* friction for flying monsters that have been given vertical velocity */ if ((ent->flags & FL_FLY) && (ent->velocity[2] != 0)) { speed = fabs(ent->velocity[2]); control = speed < sv_stopspeed ? sv_stopspeed : speed; - friction = sv_friction/3; + friction = sv_friction / 3; newspeed = speed - (FRAMETIME * control * friction); + if (newspeed < 0) + { newspeed = 0; + } + newspeed /= speed; ent->velocity[2] *= newspeed; } - // friction for flying monsters that have been given vertical velocity + /* friction for flying monsters that have been given vertical velocity */ if ((ent->flags & FL_SWIM) && (ent->velocity[2] != 0)) { speed = fabs(ent->velocity[2]); control = speed < sv_stopspeed ? sv_stopspeed : speed; - newspeed = speed - (FRAMETIME * control * sv_waterfriction * ent->waterlevel); + newspeed = speed - + (FRAMETIME * control * sv_waterfriction * ent->waterlevel); + if (newspeed < 0) + { newspeed = 0; + } + newspeed /= speed; ent->velocity[2] *= newspeed; } if (ent->velocity[2] || ent->velocity[1] || ent->velocity[0]) { - // apply friction - // let dead monsters who aren't completely onground slide - if ((wasonground) || (ent->flags & (FL_SWIM|FL_FLY))) - if (!(ent->health <= 0.0 && !M_CheckBottom(ent))) + /* apply friction */ + /* let dead monsters who aren't completely onground slide */ + if ((wasonground) || (ent->flags & (FL_SWIM | FL_FLY))) + { + if (!((ent->health <= 0.0) && !M_CheckBottom(ent))) { vel = ent->velocity; - speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1]); + speed = sqrt(vel[0] * vel[0] + vel[1] * vel[1]); + if (speed) { friction = sv_friction; control = speed < sv_stopspeed ? sv_stopspeed : speed; - newspeed = speed - FRAMETIME*control*friction; + newspeed = speed - FRAMETIME * control * friction; if (newspeed < 0) + { newspeed = 0; + } + newspeed /= speed; vel[0] *= newspeed; vel[1] *= newspeed; } } + } if (ent->svflags & SVF_MONSTER) + { mask = MASK_MONSTERSOLID; + } else + { mask = MASK_SOLID; - SV_FlyMove (ent, FRAMETIME, mask); + } - gi.linkentity (ent); - G_TouchTriggers (ent); + SV_FlyMove(ent, FRAMETIME, mask); + + gi.linkentity(ent); + G_TouchTriggers(ent); if (ent->groundentity) + { if (!wasonground) + { if (hitsound) - gi.sound (ent, 0, gi.soundindex("world/land.wav"), 1, 1, 0); + { + gi.sound(ent, 0, gi.soundindex("world/land.wav"), 1, 1, 0); + } + } + } } -// regular thinking - SV_RunThink (ent); +/* regular thinking */ + SV_RunThink(ent); } -//============================================================================ -/* -================ -G_RunEntity +/* ============================================================================ */ -================ -*/ -void G_RunEntity (edict_t *ent) +/* + * ================ + * G_RunEntity + * + * ================ + */ +void +G_RunEntity(edict_t *ent) { if (ent->prethink) - ent->prethink (ent); - - switch ( (int)ent->movetype) { - case MOVETYPE_PUSH: - case MOVETYPE_STOP: - SV_Physics_Pusher (ent); - break; - case MOVETYPE_NONE: - SV_Physics_None (ent); - break; - case MOVETYPE_NOCLIP: - SV_Physics_Noclip (ent); - break; - case MOVETYPE_STEP: - SV_Physics_Step (ent); - break; - case MOVETYPE_TOSS: - case MOVETYPE_BOUNCE: - case MOVETYPE_FLY: - case MOVETYPE_FLYMISSILE: - SV_Physics_Toss (ent); - break; - default: - gi.error ("SV_Physics: bad movetype %i", (int)ent->movetype); + ent->prethink(ent); + } + + switch ((int)ent->movetype) + { + case MOVETYPE_PUSH: + case MOVETYPE_STOP: + SV_Physics_Pusher(ent); + break; + case MOVETYPE_NONE: + SV_Physics_None(ent); + break; + case MOVETYPE_NOCLIP: + SV_Physics_Noclip(ent); + break; + case MOVETYPE_STEP: + SV_Physics_Step(ent); + break; + case MOVETYPE_TOSS: + case MOVETYPE_BOUNCE: + case MOVETYPE_FLY: + case MOVETYPE_FLYMISSILE: + SV_Physics_Toss(ent); + break; + default: + gi.error("SV_Physics: bad movetype %i", (int)ent->movetype); } } diff --git a/src/game/ctf/g_spawn.c b/src/game/ctf/g_spawn.c index b4341d31..91e14d70 100644 --- a/src/game/ctf/g_spawn.c +++ b/src/game/ctf/g_spawn.c @@ -1,151 +1,149 @@ /* -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. - -*/ + * 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. + * + */ #include "g_local.h" typedef struct { - char *name; - void (*spawn)(edict_t *ent); + char *name; + void (*spawn)(edict_t *ent); } spawn_t; +void SP_item_health(edict_t *self); +void SP_item_health_small(edict_t *self); +void SP_item_health_large(edict_t *self); +void SP_item_health_mega(edict_t *self); -void SP_item_health (edict_t *self); -void SP_item_health_small (edict_t *self); -void SP_item_health_large (edict_t *self); -void SP_item_health_mega (edict_t *self); +void SP_info_player_start(edict_t *ent); +void SP_info_player_deathmatch(edict_t *ent); +void SP_info_player_coop(edict_t *ent); +void SP_info_player_intermission(edict_t *ent); -void SP_info_player_start (edict_t *ent); -void SP_info_player_deathmatch (edict_t *ent); -void SP_info_player_coop (edict_t *ent); -void SP_info_player_intermission (edict_t *ent); +void SP_func_plat(edict_t *ent); +void SP_func_rotating(edict_t *ent); +void SP_func_button(edict_t *ent); +void SP_func_door(edict_t *ent); +void SP_func_door_secret(edict_t *ent); +void SP_func_door_rotating(edict_t *ent); +void SP_func_water(edict_t *ent); +void SP_func_train(edict_t *ent); +void SP_func_conveyor(edict_t *self); +void SP_func_wall(edict_t *self); +void SP_func_object(edict_t *self); +void SP_func_explosive(edict_t *self); +void SP_func_timer(edict_t *self); +void SP_func_areaportal(edict_t *ent); +void SP_func_clock(edict_t *ent); +void SP_func_killbox(edict_t *ent); -void SP_func_plat (edict_t *ent); -void SP_func_rotating (edict_t *ent); -void SP_func_button (edict_t *ent); -void SP_func_door (edict_t *ent); -void SP_func_door_secret (edict_t *ent); -void SP_func_door_rotating (edict_t *ent); -void SP_func_water (edict_t *ent); -void SP_func_train (edict_t *ent); -void SP_func_conveyor (edict_t *self); -void SP_func_wall (edict_t *self); -void SP_func_object (edict_t *self); -void SP_func_explosive (edict_t *self); -void SP_func_timer (edict_t *self); -void SP_func_areaportal (edict_t *ent); -void SP_func_clock (edict_t *ent); -void SP_func_killbox (edict_t *ent); +void SP_trigger_always(edict_t *ent); +void SP_trigger_once(edict_t *ent); +void SP_trigger_multiple(edict_t *ent); +void SP_trigger_relay(edict_t *ent); +void SP_trigger_push(edict_t *ent); +void SP_trigger_hurt(edict_t *ent); +void SP_trigger_key(edict_t *ent); +void SP_trigger_counter(edict_t *ent); +void SP_trigger_elevator(edict_t *ent); +void SP_trigger_gravity(edict_t *ent); +void SP_trigger_monsterjump(edict_t *ent); -void SP_trigger_always (edict_t *ent); -void SP_trigger_once (edict_t *ent); -void SP_trigger_multiple (edict_t *ent); -void SP_trigger_relay (edict_t *ent); -void SP_trigger_push (edict_t *ent); -void SP_trigger_hurt (edict_t *ent); -void SP_trigger_key (edict_t *ent); -void SP_trigger_counter (edict_t *ent); -void SP_trigger_elevator (edict_t *ent); -void SP_trigger_gravity (edict_t *ent); -void SP_trigger_monsterjump (edict_t *ent); +void SP_target_temp_entity(edict_t *ent); +void SP_target_speaker(edict_t *ent); +void SP_target_explosion(edict_t *ent); +void SP_target_changelevel(edict_t *ent); +void SP_target_secret(edict_t *ent); +void SP_target_goal(edict_t *ent); +void SP_target_splash(edict_t *ent); +void SP_target_spawner(edict_t *ent); +void SP_target_blaster(edict_t *ent); +void SP_target_crosslevel_trigger(edict_t *ent); +void SP_target_crosslevel_target(edict_t *ent); +void SP_target_laser(edict_t *self); +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_character(edict_t *ent); +void SP_target_string(edict_t *ent); -void SP_target_temp_entity (edict_t *ent); -void SP_target_speaker (edict_t *ent); -void SP_target_explosion (edict_t *ent); -void SP_target_changelevel (edict_t *ent); -void SP_target_secret (edict_t *ent); -void SP_target_goal (edict_t *ent); -void SP_target_splash (edict_t *ent); -void SP_target_spawner (edict_t *ent); -void SP_target_blaster (edict_t *ent); -void SP_target_crosslevel_trigger (edict_t *ent); -void SP_target_crosslevel_target (edict_t *ent); -void SP_target_laser (edict_t *self); -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_character (edict_t *ent); -void SP_target_string (edict_t *ent); +void SP_worldspawn(edict_t *ent); +void SP_viewthing(edict_t *ent); -void SP_worldspawn (edict_t *ent); -void SP_viewthing (edict_t *ent); +void SP_light(edict_t *self); +void SP_light_mine1(edict_t *ent); +void SP_light_mine2(edict_t *ent); +void SP_info_null(edict_t *self); +void SP_info_notnull(edict_t *self); +void SP_path_corner(edict_t *self); +void SP_point_combat(edict_t *self); -void SP_light (edict_t *self); -void SP_light_mine1 (edict_t *ent); -void SP_light_mine2 (edict_t *ent); -void SP_info_null (edict_t *self); -void SP_info_notnull (edict_t *self); -void SP_path_corner (edict_t *self); -void SP_point_combat (edict_t *self); +void SP_misc_explobox(edict_t *self); +void SP_misc_banner(edict_t *self); +void SP_misc_satellite_dish(edict_t *self); +void SP_misc_actor(edict_t *self); +void SP_misc_gib_arm(edict_t *self); +void SP_misc_gib_leg(edict_t *self); +void SP_misc_gib_head(edict_t *self); +void SP_misc_insane(edict_t *self); +void SP_misc_deadsoldier(edict_t *self); +void SP_misc_viper(edict_t *self); +void SP_misc_viper_bomb(edict_t *self); +void SP_misc_bigviper(edict_t *self); +void SP_misc_strogg_ship(edict_t *self); +void SP_misc_teleporter(edict_t *self); +void SP_misc_teleporter_dest(edict_t *self); +void SP_misc_blackhole(edict_t *self); +void SP_misc_eastertank(edict_t *self); +void SP_misc_easterchick(edict_t *self); +void SP_misc_easterchick2(edict_t *self); -void SP_misc_explobox (edict_t *self); -void SP_misc_banner (edict_t *self); -void SP_misc_satellite_dish (edict_t *self); -void SP_misc_actor (edict_t *self); -void SP_misc_gib_arm (edict_t *self); -void SP_misc_gib_leg (edict_t *self); -void SP_misc_gib_head (edict_t *self); -void SP_misc_insane (edict_t *self); -void SP_misc_deadsoldier (edict_t *self); -void SP_misc_viper (edict_t *self); -void SP_misc_viper_bomb (edict_t *self); -void SP_misc_bigviper (edict_t *self); -void SP_misc_strogg_ship (edict_t *self); -void SP_misc_teleporter (edict_t *self); -void SP_misc_teleporter_dest (edict_t *self); -void SP_misc_blackhole (edict_t *self); -void SP_misc_eastertank (edict_t *self); -void SP_misc_easterchick (edict_t *self); -void SP_misc_easterchick2 (edict_t *self); +void SP_monster_berserk(edict_t *self); +void SP_monster_gladiator(edict_t *self); +void SP_monster_gunner(edict_t *self); +void SP_monster_infantry(edict_t *self); +void SP_monster_soldier_light(edict_t *self); +void SP_monster_soldier(edict_t *self); +void SP_monster_soldier_ss(edict_t *self); +void SP_monster_tank(edict_t *self); +void SP_monster_medic(edict_t *self); +void SP_monster_flipper(edict_t *self); +void SP_monster_chick(edict_t *self); +void SP_monster_parasite(edict_t *self); +void SP_monster_flyer(edict_t *self); +void SP_monster_brain(edict_t *self); +void SP_monster_floater(edict_t *self); +void SP_monster_hover(edict_t *self); +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_boss3_stand(edict_t *self); -void SP_monster_berserk (edict_t *self); -void SP_monster_gladiator (edict_t *self); -void SP_monster_gunner (edict_t *self); -void SP_monster_infantry (edict_t *self); -void SP_monster_soldier_light (edict_t *self); -void SP_monster_soldier (edict_t *self); -void SP_monster_soldier_ss (edict_t *self); -void SP_monster_tank (edict_t *self); -void SP_monster_medic (edict_t *self); -void SP_monster_flipper (edict_t *self); -void SP_monster_chick (edict_t *self); -void SP_monster_parasite (edict_t *self); -void SP_monster_flyer (edict_t *self); -void SP_monster_brain (edict_t *self); -void SP_monster_floater (edict_t *self); -void SP_monster_hover (edict_t *self); -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_boss3_stand (edict_t *self); +void SP_monster_commander_body(edict_t *self); -void SP_monster_commander_body (edict_t *self); +void SP_turret_breach(edict_t *self); +void SP_turret_base(edict_t *self); +void SP_turret_driver(edict_t *self); -void SP_turret_breach (edict_t *self); -void SP_turret_base (edict_t *self); -void SP_turret_driver (edict_t *self); - - -spawn_t spawns[] = { +spawn_t spawns[] = { {"item_health", SP_item_health}, {"item_health_small", SP_item_health_small}, {"item_health_large", SP_item_health_large}, @@ -155,10 +153,10 @@ spawn_t spawns[] = { {"info_player_deathmatch", SP_info_player_deathmatch}, {"info_player_coop", SP_info_player_coop}, {"info_player_intermission", SP_info_player_intermission}, - //ZOID + /* ZOID */ {"info_player_team1", SP_info_player_team1}, {"info_player_team2", SP_info_player_team2}, - //ZOID + /* ZOID */ {"func_plat", SP_func_plat}, {"func_button", SP_func_button}, @@ -221,10 +219,10 @@ spawn_t spawns[] = { {"misc_explobox", SP_misc_explobox}, {"misc_banner", SP_misc_banner}, - //ZOID + /* ZOID */ {"misc_ctf_banner", SP_misc_ctf_banner}, {"misc_ctf_small_banner", SP_misc_ctf_small_banner}, - //ZOID + /* ZOID */ {"misc_satellite_dish", SP_misc_satellite_dish}, {"misc_gib_arm", SP_misc_gib_arm}, {"misc_gib_leg", SP_misc_gib_leg}, @@ -235,10 +233,10 @@ spawn_t spawns[] = { {"misc_strogg_ship", SP_misc_strogg_ship}, {"misc_teleporter", SP_misc_teleporter}, {"misc_teleporter_dest", SP_misc_teleporter_dest}, - //ZOID + /* ZOID */ {"trigger_teleport", SP_trigger_teleport}, {"info_teleport_destination", SP_info_teleport_destination}, - //ZOID + /* ZOID */ {"misc_blackhole", SP_misc_blackhole}, {"misc_eastertank", SP_misc_eastertank}, {"misc_easterchick", SP_misc_easterchick}, @@ -248,234 +246,287 @@ spawn_t spawns[] = { }; /* -=============== -ED_CallSpawn - -Finds the spawn function for the entity and calls it -=============== -*/ -void ED_CallSpawn (edict_t *ent) + * =============== + * ED_CallSpawn + * + * Finds the spawn function for the entity and calls it + * =============== + */ +void +ED_CallSpawn(edict_t *ent) { - spawn_t *s; - gitem_t *item; - int i; + spawn_t *s; + gitem_t *item; + int i; if (!ent->classname) { - gi.dprintf ("ED_CallSpawn: NULL classname\n"); + gi.dprintf("ED_CallSpawn: NULL classname\n"); return; } - // check item spawn functions - for (i=0,item=itemlist ; iclassname) + { continue; + } + if (!strcmp(item->classname, ent->classname)) - { // found it - SpawnItem (ent, item); + { /* found it */ + SpawnItem(ent, item); return; } } - // check normal spawn functions - for (s=spawns ; s->name ; s++) + /* check normal spawn functions */ + for (s = spawns; s->name; s++) { if (!strcmp(s->name, ent->classname)) - { // found it - s->spawn (ent); + { /* found it */ + s->spawn(ent); return; } } - gi.dprintf ("%s doesn't have a spawn function\n", ent->classname); + + gi.dprintf("%s doesn't have a spawn function\n", ent->classname); } /* -============= -ED_NewString -============= -*/ -char *ED_NewString (char *string) + * ============= + * ED_NewString + * ============= + */ +char * +ED_NewString(char *string) { - char *newb, *new_p; - int i,l; - + char *newb, *new_p; + int i, l; + l = strlen(string) + 1; - newb = gi.TagMalloc (l, TAG_LEVEL); + newb = gi.TagMalloc(l, TAG_LEVEL); new_p = newb; - for (i=0 ; i< l ; i++) + for (i = 0; i < l; i++) { - if (string[i] == '\\' && i < l-1) + if ((string[i] == '\\') && (i < l - 1)) { i++; + if (string[i] == 'n') + { *new_p++ = '\n'; + } else + { *new_p++ = '\\'; + } } else + { *new_p++ = string[i]; + } } - + return newb; } - - - /* -=============== -ED_ParseField - -Takes a key/value pair and sets the binary values -in an edict -=============== -*/ -void ED_ParseField (char *key, char *value, edict_t *ent) + * =============== + * ED_ParseField + * + * Takes a key/value pair and sets the binary values + * in an edict + * =============== + */ +void +ED_ParseField(char *key, char *value, edict_t *ent) { - field_t *f; - byte *b; - float v; - vec3_t vec; + field_t *f; + byte *b; + float v; + vec3_t vec; - for (f=fields ; f->name ; f++) + for (f = fields; f->name; f++) { if (!Q_stricmp(f->name, key)) - { // found it + { /* found it */ if (f->flags & FFL_SPAWNTEMP) + { b = (byte *)&st; + } else + { b = (byte *)ent; + } switch (f->type) { - case F_LSTRING: - *(char **)(b+f->ofs) = ED_NewString (value); - break; - case F_VECTOR: - sscanf (value, "%f %f %f", &vec[0], &vec[1], &vec[2]); - ((float *)(b+f->ofs))[0] = vec[0]; - ((float *)(b+f->ofs))[1] = vec[1]; - ((float *)(b+f->ofs))[2] = vec[2]; - break; - case F_INT: - *(int *)(b+f->ofs) = atoi(value); - break; - case F_FLOAT: - *(float *)(b+f->ofs) = atof(value); - break; - case F_ANGLEHACK: - v = atof(value); - ((float *)(b+f->ofs))[0] = 0; - ((float *)(b+f->ofs))[1] = v; - ((float *)(b+f->ofs))[2] = 0; - break; - case F_IGNORE: - break; - default: - break; + case F_LSTRING: + *(char **)(b + f->ofs) = ED_NewString(value); + break; + case F_VECTOR: + sscanf(value, "%f %f %f", &vec[0], &vec[1], &vec[2]); + ((float *)(b + f->ofs))[0] = vec[0]; + ((float *)(b + f->ofs))[1] = vec[1]; + ((float *)(b + f->ofs))[2] = vec[2]; + break; + case F_INT: + *(int *)(b + f->ofs) = atoi(value); + break; + case F_FLOAT: + *(float *)(b + f->ofs) = atof(value); + break; + case F_ANGLEHACK: + v = atof(value); + ((float *)(b + f->ofs))[0] = 0; + ((float *)(b + f->ofs))[1] = v; + ((float *)(b + f->ofs))[2] = 0; + break; + case F_IGNORE: + break; + default: + break; } + return; } } - gi.dprintf ("%s is not a field\n", key); + + gi.dprintf("%s is not a field\n", key); } /* -==================== -ED_ParseEdict - -Parses an edict out of the given string, returning the new position -ed should be a properly initialized empty edict. -==================== -*/ -char *ED_ParseEdict (char *data, edict_t *ent) + * ==================== + * ED_ParseEdict + * + * Parses an edict out of the given string, returning the new position + * ed should be a properly initialized empty edict. + * ==================== + */ +char * +ED_ParseEdict(char *data, edict_t *ent) { - qboolean init; - char keyname[256]; - char *com_token; + qboolean init; + char keyname[256]; + char *com_token; init = false; - memset (&st, 0, sizeof(st)); + memset(&st, 0, sizeof(st)); - // go through all the dictionary pairs + /* go through all the dictionary pairs */ while (1) - { - // parse key - com_token = COM_Parse (&data); + { + /* parse key */ + com_token = COM_Parse(&data); + if (com_token[0] == '}') + { break; - if (!data) - gi.error ("ED_ParseEntity: EOF without closing brace"); + } - strncpy (keyname, com_token, sizeof(keyname)-1); - - // parse value - com_token = COM_Parse (&data); if (!data) - gi.error ("ED_ParseEntity: EOF without closing brace"); + { + gi.error("ED_ParseEntity: EOF without closing brace"); + } + + strncpy(keyname, com_token, sizeof(keyname) - 1); + + /* parse value */ + com_token = COM_Parse(&data); + + if (!data) + { + gi.error("ED_ParseEntity: EOF without closing brace"); + } if (com_token[0] == '}') - gi.error ("ED_ParseEntity: closing brace without data"); + { + gi.error("ED_ParseEntity: closing brace without data"); + } - init = true; + init = true; - // keynames with a leading underscore are used for utility comments, - // and are immediately discarded by quake + /* keynames with a leading underscore are used for utility comments, */ + /* and are immediately discarded by quake */ if (keyname[0] == '_') + { continue; + } - ED_ParseField (keyname, com_token, ent); + ED_ParseField(keyname, com_token, ent); } if (!init) - memset (ent, 0, sizeof(*ent)); + { + memset(ent, 0, sizeof(*ent)); + } return data; } - /* -================ -G_FindTeams - -Chain together all entities with a matching team field. - -All but the first will have the FL_TEAMSLAVE flag set. -All but the last will have the teamchain field set to the next one -================ -*/ -void G_FindTeams (void) + * ================ + * G_FindTeams + * + * Chain together all entities with a matching team field. + * + * All but the first will have the FL_TEAMSLAVE flag set. + * All but the last will have the teamchain field set to the next one + * ================ + */ +void +G_FindTeams(void) { - edict_t *e, *e2, *chain; - int i, j; - int c, c2; + edict_t *e, *e2, *chain; + int i, j; + int c, c2; c = 0; c2 = 0; - for (i=1, e=g_edicts+i ; i < globals.num_edicts ; i++,e++) + + for (i = 1, e = g_edicts + i; i < globals.num_edicts; i++, e++) { if (!e->inuse) + { continue; + } + if (!e->team) + { continue; + } + if (e->flags & FL_TEAMSLAVE) + { continue; + } + chain = e; e->teammaster = e; c++; c2++; - for (j=i+1, e2=e+1 ; j < globals.num_edicts ; j++,e2++) + + for (j = i + 1, e2 = e + 1; j < globals.num_edicts; j++, e2++) { if (!e2->inuse) + { continue; + } + if (!e2->team) + { continue; + } + if (e2->flags & FL_TEAMSLAVE) + { continue; + } + if (!strcmp(e->team, e2->team)) { c2++; @@ -487,78 +538,106 @@ void G_FindTeams (void) } } - gi.dprintf ("%i teams with %i entities.\n", c, c2); + gi.dprintf("%i teams with %i entities.\n", c, c2); } /* -============== -SpawnEntities - -Creates a server's entity / program execution context by -parsing textual entity definitions out of an ent file. -============== -*/ -void SpawnEntities (char *mapname, char *entities, char *spawnpoint) + * ============== + * SpawnEntities + * + * Creates a server's entity / program execution context by + * parsing textual entity definitions out of an ent file. + * ============== + */ +void +SpawnEntities(char *mapname, char *entities, char *spawnpoint) { - edict_t *ent; - int inhibit; - char *com_token; - int i; - float skill_level; + edict_t *ent; + int inhibit; + char *com_token; + int i; + float skill_level; + + skill_level = floor(skill->value); - skill_level = floor (skill->value); if (skill_level < 0) + { skill_level = 0; + } + if (skill_level > 3) + { skill_level = 3; + } + if (skill->value != skill_level) + { gi.cvar_forceset("skill", va("%f", skill_level)); + } - SaveClientData (); + SaveClientData(); - gi.FreeTags (TAG_LEVEL); + gi.FreeTags(TAG_LEVEL); - memset (&level, 0, sizeof(level)); - memset (g_edicts, 0, game.maxentities * sizeof (g_edicts[0])); + memset(&level, 0, sizeof(level)); + memset(g_edicts, 0, game.maxentities * sizeof(g_edicts[0])); - strncpy (level.mapname, mapname, sizeof(level.mapname)-1); - strncpy (game.spawnpoint, spawnpoint, sizeof(game.spawnpoint)-1); + strncpy(level.mapname, mapname, sizeof(level.mapname) - 1); + strncpy(game.spawnpoint, spawnpoint, sizeof(game.spawnpoint) - 1); - // set client fields on player ents - for (i=0 ; iclassname, "trigger_once") && !Q_stricmp(ent->model, "*27")) - ent->spawnflags &= ~SPAWNFLAG_NOT_HARD; + { + ent = G_Spawn(); + } - // remove things (except the world) from different skill levels or deathmatch + entities = ED_ParseEdict(entities, ent); + + /* yet another map hack */ + if (!Q_stricmp(level.mapname, + "command") && + !Q_stricmp(ent->classname, + "trigger_once") && !Q_stricmp(ent->model, "*27")) + { + ent->spawnflags &= ~SPAWNFLAG_NOT_HARD; + } + + /* remove things (except the world) from different skill levels or deathmatch */ if (ent != g_edicts) { if (deathmatch->value) { - if ( ent->spawnflags & SPAWNFLAG_NOT_DEATHMATCH ) + if (ent->spawnflags & SPAWNFLAG_NOT_DEATHMATCH) { - G_FreeEdict (ent); + G_FreeEdict(ent); inhibit++; continue; } @@ -566,362 +645,388 @@ void SpawnEntities (char *mapname, char *entities, char *spawnpoint) else { if ( /* ((coop->value) && (ent->spawnflags & SPAWNFLAG_NOT_COOP)) || */ - ((skill->value == 0) && (ent->spawnflags & SPAWNFLAG_NOT_EASY)) || - ((skill->value == 1) && (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM)) || - (((skill->value == 2) || (skill->value == 3)) && (ent->spawnflags & SPAWNFLAG_NOT_HARD)) + ((skill->value == 0) && + (ent->spawnflags & SPAWNFLAG_NOT_EASY)) || + ((skill->value == 1) && + (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM)) || + (((skill->value == 2) || + (skill->value == 3)) && + (ent->spawnflags & SPAWNFLAG_NOT_HARD)) ) - { - G_FreeEdict (ent); - inhibit++; - continue; - } + { + G_FreeEdict(ent); + inhibit++; + continue; + } } - ent->spawnflags &= ~(SPAWNFLAG_NOT_EASY|SPAWNFLAG_NOT_MEDIUM|SPAWNFLAG_NOT_HARD|SPAWNFLAG_NOT_COOP|SPAWNFLAG_NOT_DEATHMATCH); + ent->spawnflags &= + ~(SPAWNFLAG_NOT_EASY | SPAWNFLAG_NOT_MEDIUM | + SPAWNFLAG_NOT_HARD | + SPAWNFLAG_NOT_COOP | SPAWNFLAG_NOT_DEATHMATCH); } - ED_CallSpawn (ent); - } + ED_CallSpawn(ent); + } - gi.dprintf ("%i entities inhibited.\n", inhibit); + gi.dprintf("%i entities inhibited.\n", inhibit); - G_FindTeams (); + G_FindTeams(); - PlayerTrail_Init (); + PlayerTrail_Init(); - //ZOID + /* ZOID */ CTFSpawn(); - //ZOID + /* ZOID */ } +/* =================================================================== */ -//=================================================================== +char *single_statusbar = + "yb -24 " -char *single_statusbar = -"yb -24 " +/* health */ + "xv 0 " + "hnum " + "xv 50 " + "pic 0 " -// health -"xv 0 " -"hnum " -"xv 50 " -"pic 0 " +/* ammo */ + "if 2 " + " xv 100 " + " anum " + " xv 150 " + " pic 2 " + "endif " -// ammo -"if 2 " -" xv 100 " -" anum " -" xv 150 " -" pic 2 " -"endif " +/* armor */ + "if 4 " + " xv 200 " + " rnum " + " xv 250 " + " pic 4 " + "endif " -// armor -"if 4 " -" xv 200 " -" rnum " -" xv 250 " -" pic 4 " -"endif " +/* selected item */ + "if 6 " + " xv 296 " + " pic 6 " + "endif " -// selected item -"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 " -// picked up item -"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 " -// timer -"if 9 " -" xv 262 " -" num 2 10 " -" xv 296 " -" pic 9 " -"endif " - -// help / weapon icon -"if 11 " -" xv 148 " -" pic 11 " -"endif " +/* help / weapon icon */ + "if 11 " + " xv 148 " + " pic 11 " + "endif " ; char *dm_statusbar = -"yb -24 " + "yb -24 " -// health -"xv 0 " -"hnum " -"xv 50 " -"pic 0 " +/* health */ + "xv 0 " + "hnum " + "xv 50 " + "pic 0 " -// ammo -"if 2 " -" xv 100 " -" anum " -" xv 150 " -" pic 2 " -"endif " +/* ammo */ + "if 2 " + " xv 100 " + " anum " + " xv 150 " + " pic 2 " + "endif " -// armor -"if 4 " -" xv 200 " -" rnum " -" xv 250 " -" pic 4 " -"endif " +/* armor */ + "if 4 " + " xv 200 " + " rnum " + " xv 250 " + " pic 4 " + "endif " -// selected item -"if 6 " -" xv 296 " -" pic 6 " -"endif " +/* selected item */ + "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 " +/* picked up item */ + "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 " +/* timer */ + "if 9 " + " xv 246 " + " num 2 10 " + " xv 296 " + " pic 9 " + "endif " -// help / weapon icon -"if 11 " -" xv 148 " -" pic 11 " -"endif " +/* help / weapon icon */ + "if 11 " + " xv 148 " + " pic 11 " + "endif " -// frags -"xr -50 " -"yt 2 " -"num 3 14" +/* frags */ + "xr -50 " + "yt 2 " + "num 3 14" ; - /*QUAKED worldspawn (0 0 0) ? - -Only used for the world. -"sky" environment map name -"skyaxis" vector axis for rotating sky -"skyrotate" speed of rotation in degrees/second -"sounds" music cd track number -"gravity" 800 is default gravity -"message" text to print at user logon -*/ -void SP_worldspawn (edict_t *ent) + * + * Only used for the world. + * "sky" environment map name + * "skyaxis" vector axis for rotating sky + * "skyrotate" speed of rotation in degrees/second + * "sounds" music cd track number + * "gravity" 800 is default gravity + * "message" text to print at user logon + */ +void +SP_worldspawn(edict_t *ent) { ent->movetype = MOVETYPE_PUSH; ent->solid = SOLID_BSP; - ent->inuse = true; // since the world doesn't use G_Spawn() - ent->s.modelindex = 1; // world model is always index 1 + ent->inuse = true; /* since the world doesn't use G_Spawn() */ + ent->s.modelindex = 1; /* world model is always index 1 */ - //--------------- + /* --------------- */ - // reserve some spots for dead player bodies for coop / deathmatch - InitBodyQue (); + /* reserve some spots for dead player bodies for coop / deathmatch */ + InitBodyQue(); - // set configstrings for items - SetItemNames (); + /* set configstrings for items */ + SetItemNames(); if (st.nextmap) - strcpy (level.nextmap, st.nextmap); + { + strcpy(level.nextmap, st.nextmap); + } - // make some data visible to the server + /* make some data visible to the server */ if (ent->message && ent->message[0]) { - gi.configstring (CS_NAME, ent->message); - strncpy (level.level_name, ent->message, sizeof(level.level_name)); + gi.configstring(CS_NAME, ent->message); + strncpy(level.level_name, ent->message, sizeof(level.level_name)); } else - strncpy (level.level_name, level.mapname, sizeof(level.level_name)); + { + strncpy(level.level_name, level.mapname, sizeof(level.level_name)); + } if (st.sky && st.sky[0]) - gi.configstring (CS_SKY, st.sky); + { + gi.configstring(CS_SKY, st.sky); + } else - gi.configstring (CS_SKY, "unit1_"); + { + gi.configstring(CS_SKY, "unit1_"); + } - gi.configstring (CS_SKYROTATE, va("%f", st.skyrotate) ); + gi.configstring(CS_SKYROTATE, va("%f", st.skyrotate)); - gi.configstring (CS_SKYAXIS, va("%f %f %f", - st.skyaxis[0], st.skyaxis[1], st.skyaxis[2]) ); + gi.configstring(CS_SKYAXIS, va("%f %f %f", + st.skyaxis[0], st.skyaxis[1], st.skyaxis[2])); - gi.configstring (CS_CDTRACK, va("%i", ent->sounds) ); + gi.configstring(CS_CDTRACK, va("%i", ent->sounds)); - gi.configstring (CS_MAXCLIENTS, va("%i", (int)(maxclients->value) ) ); + gi.configstring(CS_MAXCLIENTS, va("%i", (int)(maxclients->value))); - // status bar program + /* status bar program */ if (deathmatch->value) - //ZOID - if (ctf->value) { - gi.configstring (CS_STATUSBAR, ctf_statusbar); + { + /* ZOID */ + if (ctf->value) + { + gi.configstring(CS_STATUSBAR, ctf_statusbar); CTFPrecache(); - } else - //ZOID - gi.configstring (CS_STATUSBAR, dm_statusbar); + } + else + { + /* ZOID */ + gi.configstring(CS_STATUSBAR, dm_statusbar); + } + } else - gi.configstring (CS_STATUSBAR, single_statusbar); + { + gi.configstring(CS_STATUSBAR, single_statusbar); + } - //--------------- + /* --------------- */ - - // help icon for statusbar - gi.imageindex ("i_help"); - level.pic_health = gi.imageindex ("i_health"); - gi.imageindex ("help"); - gi.imageindex ("field_3"); + /* help icon for statusbar */ + gi.imageindex("i_help"); + level.pic_health = gi.imageindex("i_health"); + gi.imageindex("help"); + gi.imageindex("field_3"); if (!st.gravity) + { gi.cvar_set("sv_gravity", "800"); + } else + { gi.cvar_set("sv_gravity", st.gravity); + } - snd_fry = gi.soundindex ("player/fry.wav"); // standing in lava / slime + snd_fry = gi.soundindex("player/fry.wav"); /* standing in lava / slime */ - PrecacheItem (FindItem ("Blaster")); + PrecacheItem(FindItem("Blaster")); - gi.soundindex ("player/lava1.wav"); - gi.soundindex ("player/lava2.wav"); + gi.soundindex("player/lava1.wav"); + gi.soundindex("player/lava2.wav"); - gi.soundindex ("misc/pc_up.wav"); - gi.soundindex ("misc/talk1.wav"); + gi.soundindex("misc/pc_up.wav"); + gi.soundindex("misc/talk1.wav"); - gi.soundindex ("misc/udeath.wav"); + gi.soundindex("misc/udeath.wav"); - // gibs - gi.soundindex ("items/respawn1.wav"); + /* gibs */ + gi.soundindex("items/respawn1.wav"); - // sexed sounds - gi.soundindex ("*death1.wav"); - gi.soundindex ("*death2.wav"); - gi.soundindex ("*death3.wav"); - gi.soundindex ("*death4.wav"); - gi.soundindex ("*fall1.wav"); - gi.soundindex ("*fall2.wav"); - gi.soundindex ("*gurp1.wav"); // drowning damage - gi.soundindex ("*gurp2.wav"); - gi.soundindex ("*jump1.wav"); // player jump - gi.soundindex ("*pain25_1.wav"); - gi.soundindex ("*pain25_2.wav"); - gi.soundindex ("*pain50_1.wav"); - gi.soundindex ("*pain50_2.wav"); - gi.soundindex ("*pain75_1.wav"); - gi.soundindex ("*pain75_2.wav"); - gi.soundindex ("*pain100_1.wav"); - gi.soundindex ("*pain100_2.wav"); + /* sexed sounds */ + gi.soundindex("*death1.wav"); + gi.soundindex("*death2.wav"); + gi.soundindex("*death3.wav"); + gi.soundindex("*death4.wav"); + gi.soundindex("*fall1.wav"); + gi.soundindex("*fall2.wav"); + gi.soundindex("*gurp1.wav"); /* drowning damage */ + gi.soundindex("*gurp2.wav"); + gi.soundindex("*jump1.wav"); /* player jump */ + gi.soundindex("*pain25_1.wav"); + gi.soundindex("*pain25_2.wav"); + gi.soundindex("*pain50_1.wav"); + gi.soundindex("*pain50_2.wav"); + gi.soundindex("*pain75_1.wav"); + gi.soundindex("*pain75_2.wav"); + gi.soundindex("*pain100_1.wav"); + gi.soundindex("*pain100_2.wav"); - // sexed models - // THIS ORDER MUST MATCH THE DEFINES IN g_local.h - // you can add more, max 15 - gi.modelindex ("#w_blaster.md2"); - gi.modelindex ("#w_shotgun.md2"); - gi.modelindex ("#w_sshotgun.md2"); - gi.modelindex ("#w_machinegun.md2"); - gi.modelindex ("#w_chaingun.md2"); - gi.modelindex ("#a_grenades.md2"); - gi.modelindex ("#w_glauncher.md2"); - gi.modelindex ("#w_rlauncher.md2"); - gi.modelindex ("#w_hyperblaster.md2"); - gi.modelindex ("#w_railgun.md2"); - gi.modelindex ("#w_bfg.md2"); - gi.modelindex ("#w_grapple.md2"); + /* sexed models */ + /* THIS ORDER MUST MATCH THE DEFINES IN g_local.h */ + /* you can add more, max 15 */ + gi.modelindex("#w_blaster.md2"); + gi.modelindex("#w_shotgun.md2"); + gi.modelindex("#w_sshotgun.md2"); + gi.modelindex("#w_machinegun.md2"); + gi.modelindex("#w_chaingun.md2"); + gi.modelindex("#a_grenades.md2"); + gi.modelindex("#w_glauncher.md2"); + gi.modelindex("#w_rlauncher.md2"); + gi.modelindex("#w_hyperblaster.md2"); + gi.modelindex("#w_railgun.md2"); + gi.modelindex("#w_bfg.md2"); + gi.modelindex("#w_grapple.md2"); - //------------------- + /* ------------------- */ - gi.soundindex ("player/gasp1.wav"); // gasping for air - gi.soundindex ("player/gasp2.wav"); // head breaking surface, not gasping + gi.soundindex("player/gasp1.wav"); /* gasping for air */ + gi.soundindex("player/gasp2.wav"); /* head breaking surface, not gasping */ - gi.soundindex ("player/watr_in.wav"); // feet hitting water - gi.soundindex ("player/watr_out.wav"); // feet leaving water + gi.soundindex("player/watr_in.wav"); /* feet hitting water */ + gi.soundindex("player/watr_out.wav"); /* feet leaving water */ - gi.soundindex ("player/watr_un.wav"); // head going underwater - - gi.soundindex ("player/u_breath1.wav"); - gi.soundindex ("player/u_breath2.wav"); + gi.soundindex("player/watr_un.wav"); /* head going underwater */ - gi.soundindex ("items/pkup.wav"); // bonus item pickup - gi.soundindex ("world/land.wav"); // landing thud - gi.soundindex ("misc/h2ohit1.wav"); // landing splash + gi.soundindex("player/u_breath1.wav"); + gi.soundindex("player/u_breath2.wav"); - gi.soundindex ("items/damage.wav"); - gi.soundindex ("items/protect.wav"); - gi.soundindex ("items/protect4.wav"); - gi.soundindex ("weapons/noammo.wav"); + gi.soundindex("items/pkup.wav"); /* bonus item pickup */ + gi.soundindex("world/land.wav"); /* landing thud */ + gi.soundindex("misc/h2ohit1.wav"); /* landing splash */ - gi.soundindex ("infantry/inflies1.wav"); + gi.soundindex("items/damage.wav"); + gi.soundindex("items/protect.wav"); + gi.soundindex("items/protect4.wav"); + gi.soundindex("weapons/noammo.wav"); - sm_meat_index = gi.modelindex ("models/objects/gibs/sm_meat/tris.md2"); - gi.modelindex ("models/objects/gibs/arm/tris.md2"); - gi.modelindex ("models/objects/gibs/bone/tris.md2"); - gi.modelindex ("models/objects/gibs/bone2/tris.md2"); - gi.modelindex ("models/objects/gibs/chest/tris.md2"); - gi.modelindex ("models/objects/gibs/skull/tris.md2"); - gi.modelindex ("models/objects/gibs/head2/tris.md2"); + gi.soundindex("infantry/inflies1.wav"); - // - // Setup light animation tables. 'a' is total darkness, 'z' is doublebright. - // + sm_meat_index = gi.modelindex("models/objects/gibs/sm_meat/tris.md2"); + gi.modelindex("models/objects/gibs/arm/tris.md2"); + gi.modelindex("models/objects/gibs/bone/tris.md2"); + gi.modelindex("models/objects/gibs/bone2/tris.md2"); + gi.modelindex("models/objects/gibs/chest/tris.md2"); + gi.modelindex("models/objects/gibs/skull/tris.md2"); + gi.modelindex("models/objects/gibs/head2/tris.md2"); - // 0 normal - gi.configstring(CS_LIGHTS+0, "m"); - - // 1 FLICKER (first variety) - gi.configstring(CS_LIGHTS+1, "mmnmmommommnonmmonqnmmo"); - - // 2 SLOW STRONG PULSE - gi.configstring(CS_LIGHTS+2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba"); - - // 3 CANDLE (first variety) - gi.configstring(CS_LIGHTS+3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg"); - - // 4 FAST STROBE - gi.configstring(CS_LIGHTS+4, "mamamamamama"); - - // 5 GENTLE PULSE 1 - gi.configstring(CS_LIGHTS+5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj"); - - // 6 FLICKER (second variety) - gi.configstring(CS_LIGHTS+6, "nmonqnmomnmomomno"); - - // 7 CANDLE (second variety) - gi.configstring(CS_LIGHTS+7, "mmmaaaabcdefgmmmmaaaammmaamm"); - - // 8 CANDLE (third variety) - gi.configstring(CS_LIGHTS+8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa"); - - // 9 SLOW STROBE (fourth variety) - gi.configstring(CS_LIGHTS+9, "aaaaaaaazzzzzzzz"); - - // 10 FLUORESCENT FLICKER - gi.configstring(CS_LIGHTS+10, "mmamammmmammamamaaamammma"); + /* */ + /* Setup light animation tables. 'a' is total darkness, 'z' is doublebright. */ + /* */ - // 11 SLOW PULSE NOT FADE TO BLACK - gi.configstring(CS_LIGHTS+11, "abcdefghijklmnopqrrqponmlkjihgfedcba"); - - // styles 32-62 are assigned by the light program for switchable lights + /* 0 normal */ + gi.configstring(CS_LIGHTS + 0, "m"); - // 63 testing - gi.configstring(CS_LIGHTS+63, "a"); + /* 1 FLICKER (first variety) */ + gi.configstring(CS_LIGHTS + 1, "mmnmmommommnonmmonqnmmo"); + + /* 2 SLOW STRONG PULSE */ + gi.configstring(CS_LIGHTS + 2, + "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba"); + + /* 3 CANDLE (first variety) */ + gi.configstring(CS_LIGHTS + 3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg"); + + /* 4 FAST STROBE */ + gi.configstring(CS_LIGHTS + 4, "mamamamamama"); + + /* 5 GENTLE PULSE 1 */ + gi.configstring(CS_LIGHTS + 5, "jklmnopqrstuvwxyzyxwvutsrqponmlkj"); + + /* 6 FLICKER (second variety) */ + gi.configstring(CS_LIGHTS + 6, "nmonqnmomnmomomno"); + + /* 7 CANDLE (second variety) */ + gi.configstring(CS_LIGHTS + 7, "mmmaaaabcdefgmmmmaaaammmaamm"); + + /* 8 CANDLE (third variety) */ + gi.configstring(CS_LIGHTS + 8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa"); + + /* 9 SLOW STROBE (fourth variety) */ + gi.configstring(CS_LIGHTS + 9, "aaaaaaaazzzzzzzz"); + + /* 10 FLUORESCENT FLICKER */ + gi.configstring(CS_LIGHTS + 10, "mmamammmmammamamaaamammma"); + + /* 11 SLOW PULSE NOT FADE TO BLACK */ + gi.configstring(CS_LIGHTS + 11, "abcdefghijklmnopqrrqponmlkjihgfedcba"); + + /* styles 32-62 are assigned by the light program for switchable lights */ + + /* 63 testing */ + gi.configstring(CS_LIGHTS + 63, "a"); } diff --git a/src/game/ctf/g_svcmds.c b/src/game/ctf/g_svcmds.c index 68686333..a9acae65 100644 --- a/src/game/ctf/g_svcmds.c +++ b/src/game/ctf/g_svcmds.c @@ -1,300 +1,369 @@ /* -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. - -*/ + * 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. + * + */ #include "g_local.h" - -void Svcmd_Test_f (void) +void +Svcmd_Test_f(void) { - gi.cprintf (NULL, PRINT_HIGH, "Svcmd_Test_f()\n"); + gi.cprintf(NULL, PRINT_HIGH, "Svcmd_Test_f()\n"); } /* -============================================================================== - -PACKET FILTERING - - -You can add or remove addresses from the filter list with: - -addip -removeip - -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 " 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. - - -============================================================================== -*/ + * ============================================================================== + * + * PACKET FILTERING + * + * + * You can add or remove addresses from the filter list with: + * + * addip + * removeip + * + * 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 " 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; + unsigned mask; + unsigned compare; } ipfilter_t; -#define MAX_IPFILTERS 1024 +#define MAX_IPFILTERS 1024 -ipfilter_t ipfilters[MAX_IPFILTERS]; -int numipfilters; +ipfilter_t ipfilters[MAX_IPFILTERS]; +int numipfilters; /* -================= -StringToFilter -================= -*/ -static qboolean StringToFilter (char *s, ipfilter_t *f) + * ================= + * StringToFilter + * ================= + */ +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++) + 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++) + + for (i = 0; i < 4; i++) { - if (*s < '0' || *s > '9') + 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; } /* -================= -SV_FilterPacket -================= -*/ -qboolean SV_FilterPacket (char *from) + * ================= + * SV_FilterPacket + * ================= + */ +qboolean +SV_FilterPacket(char *from) { - int i; - unsigned in; + int i; + unsigned in; byte m[4]; char *p; i = 0; p = from; - while (*p && i < 4) { + + while (*p && i < 4) + { m[i] = 0; - while (*p >= '0' && *p <= '9') { - m[i] = m[i]*10 + (*p - '0'); + + while (*p >= '0' && *p <= '9') + { + m[i] = m[i] * 10 + (*p - '0'); p++; } - if (!*p || *p == ':') + + if (!*p || (*p == ':')) + { break; + } + i++, p++; } - + in = *(unsigned *)m; - for (i=0 ; ivalue; + } + } return (int)!filterban->value; } - /* -================= -SV_AddIP_f -================= -*/ -void SVCmd_AddIP_f (void) + * ================= + * SV_AddIP_f + * ================= + */ +void +SVCmd_AddIP_f(void) { - int i; - - if (gi.argc() < 3) { + int i; + + if (gi.argc() < 3) + { gi.cprintf(NULL, PRINT_HIGH, "Usage: addip \n"); return; } - for (i=0 ; i\n"); return; } - if (!StringToFilter (gi.argv(2), &f)) + if (!StringToFilter(gi.argv(2), &f)) + { return; + } - for (i=0 ; istring) - sprintf (name, "%s/listip.cfg", GAMEVERSION); + { + sprintf(name, "%s/listip.cfg", GAMEVERSION); + } else - sprintf (name, "%s/listip.cfg", game->string); + { + sprintf(name, "%s/listip.cfg", game->string); + } - gi.cprintf (NULL, PRINT_HIGH, "Writing %s.\n", name); + gi.cprintf(NULL, PRINT_HIGH, "Writing %s.\n", name); + + f = fopen(name, "wb"); - f = fopen (name, "wb"); if (!f) { - gi.cprintf (NULL, PRINT_HIGH, "Couldn't open %s\n", name); + gi.cprintf(NULL, PRINT_HIGH, "Couldn't open %s\n", name); return; } - + fprintf(f, "set filterban %d\n", (int)filterban->value); - for (i=0 ; istyle); - gi.WritePosition (ent->s.origin); - gi.multicast (ent->s.origin, MULTICAST_PVS); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(ent->style); + gi.WritePosition(ent->s.origin); + gi.multicast(ent->s.origin, MULTICAST_PVS); } -void SP_target_temp_entity (edict_t *ent) +void +SP_target_temp_entity(edict_t *ent) { ent->use = Use_Target_Tent; } +/* ========================================================== */ -//========================================================== - -//========================================================== +/* ========================================================== */ /*QUAKED target_speaker (1 0 0) (-8 -8 -8) (8 8 8) looped-on looped-off reliable -"noise" wav file to play -"attenuation" --1 = none, send to whole level -1 = normal fighting sounds -2 = idle sound level -3 = ambient sound level -"volume" 0.0 to 1.0 - -Normal sounds play each time the target is used. The reliable flag can be set for crucial voiceovers. - -Looped sounds are allways atten 3 / vol 1, and the use function toggles it on/off. -Multiple identical looping sounds will just increase volume without any speed cost. -*/ -void Use_Target_Speaker (edict_t *ent, edict_t *other, edict_t *activator) + * "noise" wav file to play + * "attenuation" + * -1 = none, send to whole level + * 1 = normal fighting sounds + * 2 = idle sound level + * 3 = ambient sound level + * "volume" 0.0 to 1.0 + * + * Normal sounds play each time the target is used. The reliable flag can be set for crucial voiceovers. + * + * Looped sounds are allways atten 3 / vol 1, and the use function toggles it on/off. + * Multiple identical looping sounds will just increase volume without any speed cost. + */ +void +Use_Target_Speaker(edict_t *ent, edict_t *other, edict_t *activator) { - int chan; + int chan; if (ent->spawnflags & 3) - { // looping sound toggles + { /* looping sound toggles */ if (ent->s.sound) - ent->s.sound = 0; // turn it off + { + ent->s.sound = 0; /* turn it off */ + } else - ent->s.sound = ent->noise_index; // start it + { + ent->s.sound = ent->noise_index; /* start it */ + } } else - { // normal sound + { + /* normal sound */ if (ent->spawnflags & 4) - chan = CHAN_VOICE|CHAN_RELIABLE; + { + chan = CHAN_VOICE | CHAN_RELIABLE; + } else + { chan = CHAN_VOICE; - // use a positioned_sound, because this entity won't normally be - // sent to any clients because it is invisible - gi.positioned_sound (ent->s.origin, ent, chan, ent->noise_index, ent->volume, ent->attenuation, 0); + } + + /* use a positioned_sound, because this entity won't normally be */ + /* sent to any clients because it is invisible */ + gi.positioned_sound(ent->s.origin, + ent, + chan, + ent->noise_index, + ent->volume, + ent->attenuation, + 0); } } -void SP_target_speaker (edict_t *ent) +void +SP_target_speaker(edict_t *ent) { - char buffer[MAX_QPATH]; + char buffer[MAX_QPATH]; - if(!st.noise) + if (!st.noise) { - gi.dprintf("target_speaker with no noise set at %s\n", vtos(ent->s.origin)); + gi.dprintf("target_speaker with no noise set at %s\n", + vtos(ent->s.origin)); return; } - if (!strstr (st.noise, ".wav")) - Com_sprintf (buffer, sizeof(buffer), "%s.wav", st.noise); + + if (!strstr(st.noise, ".wav")) + { + Com_sprintf(buffer, sizeof(buffer), "%s.wav", st.noise); + } else - strncpy (buffer, st.noise, sizeof(buffer)); - ent->noise_index = gi.soundindex (buffer); + { + strncpy(buffer, st.noise, sizeof(buffer)); + } + + ent->noise_index = gi.soundindex(buffer); if (!ent->volume) + { ent->volume = 1.0; + } if (!ent->attenuation) + { ent->attenuation = 1.0; - else if (ent->attenuation == -1) // use -1 so 0 defaults to 1 + } + else if (ent->attenuation == -1) /* use -1 so 0 defaults to 1 */ + { ent->attenuation = 0; + } - // check for prestarted looping sound + /* check for prestarted looping sound */ if (ent->spawnflags & 1) + { ent->s.sound = ent->noise_index; + } ent->use = Use_Target_Speaker; - // must link the entity so we get areas and clusters so - // the server can determine who to send updates to - gi.linkentity (ent); + /* must link the entity so we get areas and clusters so */ + /* the server can determine who to send updates to */ + gi.linkentity(ent); } +/* ========================================================== */ -//========================================================== - -void Use_Target_Help (edict_t *ent, edict_t *other, edict_t *activator) +void +Use_Target_Help(edict_t *ent, edict_t *other, edict_t *activator) { if (ent->spawnflags & 1) - strncpy (game.helpmessage1, ent->message, sizeof(game.helpmessage2)-1); + { + strncpy(game.helpmessage1, ent->message, sizeof(game.helpmessage2) - 1); + } else - strncpy (game.helpmessage2, ent->message, sizeof(game.helpmessage1)-1); + { + strncpy(game.helpmessage2, ent->message, sizeof(game.helpmessage1) - 1); + } game.helpchanged++; } /*QUAKED target_help (1 0 1) (-16 -16 -24) (16 16 24) help1 -When fired, the "message" key becomes the current personal computer string, and the message light will be set on all clients status bars. -*/ -void SP_target_help(edict_t *ent) + * When fired, the "message" key becomes the current personal computer string, and the message light will be set on all clients status bars. + */ +void +SP_target_help(edict_t *ent) { if (deathmatch->value) - { // auto-remove for deathmatch - G_FreeEdict (ent); + { /* auto-remove for deathmatch */ + G_FreeEdict(ent); return; } if (!ent->message) { - gi.dprintf ("%s with no message at %s\n", ent->classname, vtos(ent->s.origin)); - G_FreeEdict (ent); + gi.dprintf("%s with no message at %s\n", ent->classname, + vtos(ent->s.origin)); + G_FreeEdict(ent); return; } + ent->use = Use_Target_Help; } -//========================================================== +/* ========================================================== */ /*QUAKED target_secret (1 0 1) (-8 -8 -8) (8 8 8) -Counts a secret found. -These are single use targets. -*/ -void use_target_secret (edict_t *ent, edict_t *other, edict_t *activator) + * Counts a secret found. + * These are single use targets. + */ +void +use_target_secret(edict_t *ent, edict_t *other, edict_t *activator) { - gi.sound (ent, CHAN_VOICE, ent->noise_index, 1, ATTN_NORM, 0); + gi.sound(ent, CHAN_VOICE, ent->noise_index, 1, ATTN_NORM, 0); level.found_secrets++; - G_UseTargets (ent, activator); - G_FreeEdict (ent); + G_UseTargets(ent, activator); + G_FreeEdict(ent); } -void SP_target_secret (edict_t *ent) +void +SP_target_secret(edict_t *ent) { if (deathmatch->value) - { // auto-remove for deathmatch - G_FreeEdict (ent); + { /* auto-remove for deathmatch */ + G_FreeEdict(ent); return; } ent->use = use_target_secret; + if (!st.noise) + { st.noise = "misc/secret.wav"; - ent->noise_index = gi.soundindex (st.noise); + } + + ent->noise_index = gi.soundindex(st.noise); ent->svflags = SVF_NOCLIENT; level.total_secrets++; - // map bug hack - if (!Q_stricmp(level.mapname, "mine3") && ent->s.origin[0] == 280 && ent->s.origin[1] == -2048 && ent->s.origin[2] == -624) + + /* map bug hack */ + if (!Q_stricmp(level.mapname, + "mine3") && (ent->s.origin[0] == 280) && + (ent->s.origin[1] == -2048) && + (ent->s.origin[2] == -624)) + { ent->message = "You have found a secret area."; + } } -//========================================================== +/* ========================================================== */ /*QUAKED target_goal (1 0 1) (-8 -8 -8) (8 8 8) -Counts a goal completed. -These are single use targets. -*/ -void use_target_goal (edict_t *ent, edict_t *other, edict_t *activator) + * Counts a goal completed. + * These are single use targets. + */ +void +use_target_goal(edict_t *ent, edict_t *other, edict_t *activator) { - gi.sound (ent, CHAN_VOICE, ent->noise_index, 1, ATTN_NORM, 0); + gi.sound(ent, CHAN_VOICE, ent->noise_index, 1, ATTN_NORM, 0); level.found_goals++; if (level.found_goals == level.total_goals) - gi.configstring (CS_CDTRACK, "0"); + { + gi.configstring(CS_CDTRACK, "0"); + } - G_UseTargets (ent, activator); - G_FreeEdict (ent); + G_UseTargets(ent, activator); + G_FreeEdict(ent); } -void SP_target_goal (edict_t *ent) +void +SP_target_goal(edict_t *ent) { if (deathmatch->value) - { // auto-remove for deathmatch - G_FreeEdict (ent); + { /* auto-remove for deathmatch */ + G_FreeEdict(ent); return; } ent->use = use_target_goal; + if (!st.noise) + { st.noise = "misc/secret.wav"; - ent->noise_index = gi.soundindex (st.noise); + } + + ent->noise_index = gi.soundindex(st.noise); ent->svflags = SVF_NOCLIENT; level.total_goals++; } -//========================================================== - +/* ========================================================== */ /*QUAKED target_explosion (1 0 0) (-8 -8 -8) (8 8 8) -Spawns an explosion temporary entity when used. - -"delay" wait this long before going off -"dmg" how much radius damage should be done, defaults to 0 -*/ -void target_explosion_explode (edict_t *self) + * Spawns an explosion temporary entity when used. + * + * "delay" wait this long before going off + * "dmg" how much radius damage should be done, defaults to 0 + */ +void +target_explosion_explode(edict_t *self) { - float save; + float save; - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_EXPLOSION1); - gi.WritePosition (self->s.origin); - gi.multicast (self->s.origin, MULTICAST_PHS); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_EXPLOSION1); + gi.WritePosition(self->s.origin); + gi.multicast(self->s.origin, MULTICAST_PHS); - T_RadiusDamage (self, self->activator, self->dmg, NULL, self->dmg+40, MOD_EXPLOSIVE); + T_RadiusDamage(self, + self->activator, + self->dmg, + NULL, + self->dmg + 40, + MOD_EXPLOSIVE); save = self->delay; self->delay = 0; - G_UseTargets (self, self->activator); + G_UseTargets(self, self->activator); self->delay = save; } -void use_target_explosion (edict_t *self, edict_t *other, edict_t *activator) +void +use_target_explosion(edict_t *self, edict_t *other, edict_t *activator) { self->activator = activator; if (!self->delay) { - target_explosion_explode (self); + target_explosion_explode(self); return; } @@ -255,411 +322,550 @@ void use_target_explosion (edict_t *self, edict_t *other, edict_t *activator) self->nextthink = level.time + self->delay; } -void SP_target_explosion (edict_t *ent) +void +SP_target_explosion(edict_t *ent) { ent->use = use_target_explosion; ent->svflags = SVF_NOCLIENT; } - -//========================================================== +/* ========================================================== */ /*QUAKED target_changelevel (1 0 0) (-8 -8 -8) (8 8 8) -Changes level to "map" when fired -*/ -void use_target_changelevel (edict_t *self, edict_t *other, edict_t *activator) + * Changes level to "map" when fired + */ +void +use_target_changelevel(edict_t *self, edict_t *other, edict_t *activator) { if (level.intermissiontime) - return; // allready activated + { + return; /* allready activated */ + } if (!deathmatch->value && !coop->value) { if (g_edicts[1].health <= 0) + { return; + } } - // if noexit, do a ton of damage to other - if (deathmatch->value && !( (int)dmflags->value & DF_ALLOW_EXIT) && other != world) + /* if noexit, do a ton of damage to other */ + if (deathmatch->value && !((int)dmflags->value & DF_ALLOW_EXIT) && + (other != world)) { - T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 10 * other->max_health, 1000, 0, MOD_EXIT); + T_Damage(other, + self, + self, + vec3_origin, + other->s.origin, + vec3_origin, + 10 * other->max_health, + 1000, + 0, + MOD_EXIT); return; } - // if multiplayer, let everyone know who hit the exit + /* if multiplayer, let everyone know who hit the exit */ if (deathmatch->value) { if (activator && activator->client) - gi.bprintf (PRINT_HIGH, "%s exited the level.\n", activator->client->pers.netname); + { + gi.bprintf(PRINT_HIGH, + "%s exited the level.\n", + activator->client->pers.netname); + } } - // if going to a new unit, clear cross triggers - if (strstr(self->map, "*")) + /* if going to a new unit, clear cross triggers */ + if (strstr(self->map, "*")) + { game.serverflags &= ~(SFL_CROSS_TRIGGER_MASK); + } - BeginIntermission (self); + BeginIntermission(self); } -void SP_target_changelevel (edict_t *ent) +void +SP_target_changelevel(edict_t *ent) { if (!ent->map) { gi.dprintf("target_changelevel with no map at %s\n", vtos(ent->s.origin)); - G_FreeEdict (ent); + G_FreeEdict(ent); return; } - // ugly hack because *SOMEBODY* screwed up their map - if((Q_stricmp(level.mapname, "fact1") == 0) && (Q_stricmp(ent->map, "fact3") == 0)) - ent->map = "fact3$secret1"; + /* ugly hack because *SOMEBODY* screwed up their map */ + if ((Q_stricmp(level.mapname, + "fact1") == 0) && (Q_stricmp(ent->map, "fact3") == 0)) + { + ent->map = "fact3$secret1"; + } ent->use = use_target_changelevel; ent->svflags = SVF_NOCLIENT; } - -//========================================================== +/* ========================================================== */ /*QUAKED target_splash (1 0 0) (-8 -8 -8) (8 8 8) -Creates a particle splash effect when used. + * Creates a particle splash effect when used. + * + * Set "sounds" to one of the following: + * 1) sparks + * 2) blue water + * 3) brown water + * 4) slime + * 5) lava + * 6) blood + * + * "count" how many pixels in the splash + * "dmg" if set, does a radius damage at this location when it splashes + * useful for lava/sparks + */ -Set "sounds" to one of the following: - 1) sparks - 2) blue water - 3) brown water - 4) slime - 5) lava - 6) blood - -"count" how many pixels in the splash -"dmg" if set, does a radius damage at this location when it splashes - useful for lava/sparks -*/ - -void use_target_splash (edict_t *self, edict_t *other, edict_t *activator) +void +use_target_splash(edict_t *self, edict_t *other, edict_t *activator) { - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_SPLASH); - gi.WriteByte (self->count); - gi.WritePosition (self->s.origin); - gi.WriteDir (self->movedir); - gi.WriteByte (self->sounds); - gi.multicast (self->s.origin, MULTICAST_PVS); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_SPLASH); + gi.WriteByte(self->count); + gi.WritePosition(self->s.origin); + gi.WriteDir(self->movedir); + gi.WriteByte(self->sounds); + gi.multicast(self->s.origin, MULTICAST_PVS); if (self->dmg) - T_RadiusDamage (self, activator, self->dmg, NULL, self->dmg+40, MOD_SPLASH); -} - -void SP_target_splash (edict_t *self) -{ - self->use = use_target_splash; - G_SetMovedir (self->s.angles, self->movedir); - - if (!self->count) - self->count = 32; - - self->svflags = SVF_NOCLIENT; -} - - -//========================================================== - -/*QUAKED target_spawner (1 0 0) (-8 -8 -8) (8 8 8) -Set target to the type of entity you want spawned. -Useful for spawning monsters and gibs in the factory levels. - -For monsters: - Set direction to the facing you want it to have. - -For gibs: - Set direction if you want it moving and - speed how fast it should be moving otherwise it - will just be dropped -*/ -void ED_CallSpawn (edict_t *ent); - -void use_target_spawner (edict_t *self, edict_t *other, edict_t *activator) -{ - edict_t *ent; - - ent = G_Spawn(); - ent->classname = self->target; - VectorCopy (self->s.origin, ent->s.origin); - VectorCopy (self->s.angles, ent->s.angles); - ED_CallSpawn (ent); - gi.unlinkentity (ent); - KillBox (ent); - gi.linkentity (ent); - if (self->speed) - VectorCopy (self->movedir, ent->velocity); -} - -void SP_target_spawner (edict_t *self) -{ - self->use = use_target_spawner; - self->svflags = SVF_NOCLIENT; - if (self->speed) { - G_SetMovedir (self->s.angles, self->movedir); - VectorScale (self->movedir, self->speed, self->movedir); + T_RadiusDamage(self, + activator, + self->dmg, + NULL, + self->dmg + 40, + MOD_SPLASH); } } -//========================================================== +void +SP_target_splash(edict_t *self) +{ + self->use = use_target_splash; + G_SetMovedir(self->s.angles, self->movedir); + + if (!self->count) + { + self->count = 32; + } + + self->svflags = SVF_NOCLIENT; +} + +/* ========================================================== */ + +/*QUAKED target_spawner (1 0 0) (-8 -8 -8) (8 8 8) + * Set target to the type of entity you want spawned. + * Useful for spawning monsters and gibs in the factory levels. + * + * For monsters: + * Set direction to the facing you want it to have. + * + * For gibs: + * Set direction if you want it moving and + * speed how fast it should be moving otherwise it + * will just be dropped + */ +void ED_CallSpawn(edict_t *ent); + +void +use_target_spawner(edict_t *self, edict_t *other, edict_t *activator) +{ + edict_t *ent; + + ent = G_Spawn(); + ent->classname = self->target; + VectorCopy(self->s.origin, ent->s.origin); + VectorCopy(self->s.angles, ent->s.angles); + ED_CallSpawn(ent); + gi.unlinkentity(ent); + KillBox(ent); + gi.linkentity(ent); + + if (self->speed) + { + VectorCopy(self->movedir, ent->velocity); + } +} + +void +SP_target_spawner(edict_t *self) +{ + self->use = use_target_spawner; + self->svflags = SVF_NOCLIENT; + + if (self->speed) + { + G_SetMovedir(self->s.angles, self->movedir); + VectorScale(self->movedir, self->speed, self->movedir); + } +} + +/* ========================================================== */ /*QUAKED target_blaster (1 0 0) (-8 -8 -8) (8 8 8) NOTRAIL NOEFFECTS -Fires a blaster bolt in the set direction when triggered. + * Fires a blaster bolt in the set direction when triggered. + * + * dmg default is 15 + * speed default is 1000 + */ -dmg default is 15 -speed default is 1000 -*/ - -void use_target_blaster (edict_t *self, edict_t *other, edict_t *activator) +void +use_target_blaster(edict_t *self, edict_t *other, edict_t *activator) { int effect; if (self->spawnflags & 2) + { effect = 0; + } else if (self->spawnflags & 1) + { effect = EF_HYPERBLASTER; + } else + { effect = EF_BLASTER; + } - fire_blaster (self, self->s.origin, self->movedir, self->dmg, self->speed, EF_BLASTER, MOD_TARGET_BLASTER); - gi.sound (self, CHAN_VOICE, self->noise_index, 1, ATTN_NORM, 0); + fire_blaster(self, + self->s.origin, + self->movedir, + self->dmg, + self->speed, + EF_BLASTER, + MOD_TARGET_BLASTER); + gi.sound(self, CHAN_VOICE, self->noise_index, 1, ATTN_NORM, 0); } -void SP_target_blaster (edict_t *self) +void +SP_target_blaster(edict_t *self) { self->use = use_target_blaster; - G_SetMovedir (self->s.angles, self->movedir); - self->noise_index = gi.soundindex ("weapons/laser2.wav"); + G_SetMovedir(self->s.angles, self->movedir); + self->noise_index = gi.soundindex("weapons/laser2.wav"); if (!self->dmg) + { self->dmg = 15; + } + if (!self->speed) + { self->speed = 1000; + } self->svflags = SVF_NOCLIENT; } - -//========================================================== +/* ========================================================== */ /*QUAKED target_crosslevel_trigger (.5 .5 .5) (-8 -8 -8) (8 8 8) trigger1 trigger2 trigger3 trigger4 trigger5 trigger6 trigger7 trigger8 -Once this trigger is touched/used, any trigger_crosslevel_target with the same trigger number is automatically used when a level is started within the same unit. It is OK to check multiple triggers. Message, delay, target, and killtarget also work. -*/ -void trigger_crosslevel_trigger_use (edict_t *self, edict_t *other, edict_t *activator) + * Once this trigger is touched/used, any trigger_crosslevel_target with the same trigger number is automatically used when a level is started within the same unit. It is OK to check multiple triggers. Message, delay, target, and killtarget also work. + */ +void +trigger_crosslevel_trigger_use(edict_t *self, + edict_t *other, + edict_t *activator) { game.serverflags |= self->spawnflags; - G_FreeEdict (self); + G_FreeEdict(self); } -void SP_target_crosslevel_trigger (edict_t *self) +void +SP_target_crosslevel_trigger(edict_t *self) { self->svflags = SVF_NOCLIENT; self->use = trigger_crosslevel_trigger_use; } /*QUAKED target_crosslevel_target (.5 .5 .5) (-8 -8 -8) (8 8 8) trigger1 trigger2 trigger3 trigger4 trigger5 trigger6 trigger7 trigger8 -Triggered by a trigger_crosslevel elsewhere within a unit. If multiple triggers are checked, all must be true. Delay, target and -killtarget also work. - -"delay" delay before using targets if the trigger has been activated (default 1) -*/ -void target_crosslevel_target_think (edict_t *self) + * Triggered by a trigger_crosslevel elsewhere within a unit. If multiple triggers are checked, all must be true. Delay, target and + * killtarget also work. + * + * "delay" delay before using targets if the trigger has been activated (default 1) + */ +void +target_crosslevel_target_think(edict_t *self) { - if (self->spawnflags == (game.serverflags & SFL_CROSS_TRIGGER_MASK & self->spawnflags)) + if (self->spawnflags == + (game.serverflags & SFL_CROSS_TRIGGER_MASK & self->spawnflags)) { - G_UseTargets (self, self); - G_FreeEdict (self); + G_UseTargets(self, self); + G_FreeEdict(self); } } -void SP_target_crosslevel_target (edict_t *self) +void +SP_target_crosslevel_target(edict_t *self) { - if (! self->delay) + if (!self->delay) + { self->delay = 1; + } + self->svflags = SVF_NOCLIENT; self->think = target_crosslevel_target_think; self->nextthink = level.time + self->delay; } -//========================================================== +/* ========================================================== */ /*QUAKED target_laser (0 .5 .8) (-8 -8 -8) (8 8 8) START_ON RED GREEN BLUE YELLOW ORANGE FAT -When triggered, fires a laser. You can either set a target -or a direction. -*/ + * When triggered, fires a laser. You can either set a target + * or a direction. + */ -void target_laser_think (edict_t *self) +void +target_laser_think(edict_t *self) { - edict_t *ignore; - vec3_t start; - vec3_t end; - trace_t tr; - vec3_t point; - vec3_t last_movedir; - int count; + edict_t *ignore; + vec3_t start; + vec3_t end; + trace_t tr; + vec3_t point; + vec3_t last_movedir; + int count; if (self->spawnflags & 0x80000000) + { count = 8; + } else + { count = 4; + } if (self->enemy) { - VectorCopy (self->movedir, last_movedir); - VectorMA (self->enemy->absmin, 0.5, self->enemy->size, point); - VectorSubtract (point, self->s.origin, self->movedir); - VectorNormalize (self->movedir); + VectorCopy(self->movedir, last_movedir); + VectorMA(self->enemy->absmin, 0.5, self->enemy->size, point); + VectorSubtract(point, self->s.origin, self->movedir); + VectorNormalize(self->movedir); + if (!VectorCompare(self->movedir, last_movedir)) + { self->spawnflags |= 0x80000000; + } } ignore = self; - VectorCopy (self->s.origin, start); - VectorMA (start, 2048, self->movedir, end); - while(1) + VectorCopy(self->s.origin, start); + VectorMA(start, 2048, self->movedir, end); + + while (1) { - tr = gi.trace (start, NULL, NULL, end, ignore, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_DEADMONSTER); + tr = gi.trace(start, + NULL, + NULL, + end, + ignore, + CONTENTS_SOLID | CONTENTS_MONSTER | CONTENTS_DEADMONSTER); if (!tr.ent) + { break; + } - // hurt it if we can + /* hurt it if we can */ if ((tr.ent->takedamage) && !(tr.ent->flags & FL_IMMUNE_LASER)) - T_Damage (tr.ent, self, self->activator, self->movedir, tr.endpos, vec3_origin, self->dmg, 1, DAMAGE_ENERGY, MOD_TARGET_LASER); + { + T_Damage(tr.ent, + self, + self->activator, + self->movedir, + tr.endpos, + vec3_origin, + self->dmg, + 1, + DAMAGE_ENERGY, + MOD_TARGET_LASER); + } - // if we hit something that's not a monster or player or is immune to lasers, we're done + /* if we hit something that's not a monster or player or is immune to lasers, we're done */ if (!(tr.ent->svflags & SVF_MONSTER) && (!tr.ent->client)) { if (self->spawnflags & 0x80000000) { self->spawnflags &= ~0x80000000; - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_LASER_SPARKS); - gi.WriteByte (count); - gi.WritePosition (tr.endpos); - gi.WriteDir (tr.plane.normal); - gi.WriteByte (self->s.skinnum); - gi.multicast (tr.endpos, MULTICAST_PVS); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_LASER_SPARKS); + gi.WriteByte(count); + gi.WritePosition(tr.endpos); + gi.WriteDir(tr.plane.normal); + gi.WriteByte(self->s.skinnum); + gi.multicast(tr.endpos, MULTICAST_PVS); } + break; } ignore = tr.ent; - VectorCopy (tr.endpos, start); + VectorCopy(tr.endpos, start); } - VectorCopy (tr.endpos, self->s.old_origin); + VectorCopy(tr.endpos, self->s.old_origin); self->nextthink = level.time + FRAMETIME; } -void target_laser_on (edict_t *self) +void +target_laser_on(edict_t *self) { if (!self->activator) + { self->activator = self; + } + self->spawnflags |= 0x80000001; self->svflags &= ~SVF_NOCLIENT; - target_laser_think (self); + target_laser_think(self); } -void target_laser_off (edict_t *self) +void +target_laser_off(edict_t *self) { self->spawnflags &= ~1; self->svflags |= SVF_NOCLIENT; self->nextthink = 0; } -void target_laser_use (edict_t *self, edict_t *other, edict_t *activator) +void +target_laser_use(edict_t *self, edict_t *other, edict_t *activator) { self->activator = activator; + if (self->spawnflags & 1) - target_laser_off (self); + { + target_laser_off(self); + } else - target_laser_on (self); + { + target_laser_on(self); + } } -void target_laser_start (edict_t *self) +void +target_laser_start(edict_t *self) { edict_t *ent; self->movetype = MOVETYPE_NONE; self->solid = SOLID_NOT; - self->s.renderfx |= RF_BEAM|RF_TRANSLUCENT; - self->s.modelindex = 1; // must be non-zero + self->s.renderfx |= RF_BEAM | RF_TRANSLUCENT; + self->s.modelindex = 1; /* must be non-zero */ - // set the beam diameter + /* set the beam diameter */ if (self->spawnflags & 64) + { self->s.frame = 16; + } else + { self->s.frame = 4; + } - // set the color + /* set the color */ if (self->spawnflags & 2) + { self->s.skinnum = 0xf2f2f0f0; + } else if (self->spawnflags & 4) + { self->s.skinnum = 0xd0d1d2d3; + } else if (self->spawnflags & 8) + { self->s.skinnum = 0xf3f3f1f1; + } else if (self->spawnflags & 16) + { self->s.skinnum = 0xdcdddedf; + } else if (self->spawnflags & 32) + { self->s.skinnum = 0xe0e1e2e3; + } if (!self->enemy) { if (self->target) { - ent = G_Find (NULL, FOFS(targetname), self->target); + ent = G_Find(NULL, FOFS(targetname), self->target); + if (!ent) - gi.dprintf ("%s at %s: %s is a bad target\n", self->classname, vtos(self->s.origin), self->target); + { + gi.dprintf("%s at %s: %s is a bad target\n", + self->classname, + vtos(self->s.origin), + self->target); + } + self->enemy = ent; } else { - G_SetMovedir (self->s.angles, self->movedir); + G_SetMovedir(self->s.angles, self->movedir); } } + self->use = target_laser_use; self->think = target_laser_think; if (!self->dmg) + { self->dmg = 1; + } - VectorSet (self->mins, -8, -8, -8); - VectorSet (self->maxs, 8, 8, 8); - gi.linkentity (self); + VectorSet(self->mins, -8, -8, -8); + VectorSet(self->maxs, 8, 8, 8); + gi.linkentity(self); if (self->spawnflags & 1) - target_laser_on (self); + { + target_laser_on(self); + } else - target_laser_off (self); + { + target_laser_off(self); + } } -void SP_target_laser (edict_t *self) +void +SP_target_laser(edict_t *self) { - // let everything else get spawned before we start firing + /* let everything else get spawned before we start firing */ self->think = target_laser_start; self->nextthink = level.time + 1; } -//========================================================== +/* ========================================================== */ /*QUAKED target_lightramp (0 .5 .8) (-8 -8 -8) (8 8 8) TOGGLE -speed How many seconds the ramping will take -message two letters; starting lightlevel and ending lightlevel -*/ + * speed How many seconds the ramping will take + * message two letters; starting lightlevel and ending lightlevel + */ -void target_lightramp_think (edict_t *self) +void +target_lightramp_think(edict_t *self) { - char style[2]; + char style[2]; - style[0] = 'a' + self->movedir[0] + (level.time - self->timestamp) / FRAMETIME * self->movedir[2]; + style[0] = 'a' + self->movedir[0] + + (level.time - self->timestamp) / FRAMETIME * self->movedir[2]; style[1] = 0; - gi.configstring (CS_LIGHTS+self->enemy->style, style); + gi.configstring(CS_LIGHTS + self->enemy->style, style); if ((level.time - self->timestamp) < self->speed) { @@ -667,7 +873,7 @@ void target_lightramp_think (edict_t *self) } else if (self->spawnflags & 1) { - char temp; + char temp; temp = self->movedir[0]; self->movedir[0] = self->movedir[1]; @@ -676,23 +882,32 @@ void target_lightramp_think (edict_t *self) } } -void target_lightramp_use (edict_t *self, edict_t *other, edict_t *activator) +void +target_lightramp_use(edict_t *self, edict_t *other, edict_t *activator) { if (!self->enemy) { - edict_t *e; + edict_t *e; - // check all the targets + /* check all the targets */ e = NULL; + while (1) { - e = G_Find (e, FOFS(targetname), self->target); + e = G_Find(e, FOFS(targetname), self->target); + if (!e) + { break; + } + if (strcmp(e->classname, "light") != 0) { gi.dprintf("%s at %s ", self->classname, vtos(self->s.origin)); - gi.dprintf("target %s (%s at %s) is not a light\n", self->target, e->classname, vtos(e->s.origin)); + gi.dprintf("target %s (%s at %s) is not a light\n", + self->target, + e->classname, + vtos(e->s.origin)); } else { @@ -702,35 +917,45 @@ void target_lightramp_use (edict_t *self, edict_t *other, edict_t *activator) if (!self->enemy) { - gi.dprintf("%s target %s not found at %s\n", self->classname, self->target, vtos(self->s.origin)); - G_FreeEdict (self); + gi.dprintf("%s target %s not found at %s\n", + self->classname, + self->target, + vtos(self->s.origin)); + G_FreeEdict(self); return; } } self->timestamp = level.time; - target_lightramp_think (self); + target_lightramp_think(self); } -void SP_target_lightramp (edict_t *self) +void +SP_target_lightramp(edict_t *self) { - if (!self->message || strlen(self->message) != 2 || self->message[0] < 'a' || self->message[0] > 'z' || self->message[1] < 'a' || self->message[1] > 'z' || self->message[0] == self->message[1]) + if (!self->message || (strlen(self->message) != 2) || + (self->message[0] < 'a') || (self->message[0] > 'z') || + (self->message[1] < 'a') || (self->message[1] > 'z') || + (self->message[0] == self->message[1])) { - gi.dprintf("target_lightramp has bad ramp (%s) at %s\n", self->message, vtos(self->s.origin)); - G_FreeEdict (self); + gi.dprintf("target_lightramp has bad ramp (%s) at %s\n", + self->message, + vtos(self->s.origin)); + G_FreeEdict(self); return; } if (deathmatch->value) { - G_FreeEdict (self); + G_FreeEdict(self); return; } if (!self->target) { - gi.dprintf("%s with no target at %s\n", self->classname, vtos(self->s.origin)); - G_FreeEdict (self); + gi.dprintf("%s with no target at %s\n", self->classname, + vtos(self->s.origin)); + G_FreeEdict(self); return; } @@ -740,49 +965,68 @@ void SP_target_lightramp (edict_t *self) self->movedir[0] = self->message[0] - 'a'; self->movedir[1] = self->message[1] - 'a'; - self->movedir[2] = (self->movedir[1] - self->movedir[0]) / (self->speed / FRAMETIME); + self->movedir[2] = + (self->movedir[1] - self->movedir[0]) / (self->speed / FRAMETIME); } -//========================================================== +/* ========================================================== */ /*QUAKED target_earthquake (1 0 0) (-8 -8 -8) (8 8 8) -When triggered, this initiates a level-wide earthquake. -All players and monsters are affected. -"speed" severity of the quake (default:200) -"count" duration of the quake (default:5) -*/ + * When triggered, this initiates a level-wide earthquake. + * All players and monsters are affected. + * "speed" severity of the quake (default:200) + * "count" duration of the quake (default:5) + */ -void target_earthquake_think (edict_t *self) +void +target_earthquake_think(edict_t *self) { - int i; - edict_t *e; + int i; + edict_t *e; if (self->last_move_time < level.time) { - gi.positioned_sound (self->s.origin, self, CHAN_AUTO, self->noise_index, 1.0, ATTN_NONE, 0); + gi.positioned_sound(self->s.origin, + self, + CHAN_AUTO, + self->noise_index, + 1.0, + ATTN_NONE, + 0); self->last_move_time = level.time + 0.5; } - for (i=1, e=g_edicts+i; i < globals.num_edicts; i++,e++) + for (i = 1, e = g_edicts + i; i < globals.num_edicts; i++, e++) { if (!e->inuse) + { continue; + } + if (!e->client) + { continue; + } + if (!e->groundentity) + { continue; + } e->groundentity = NULL; - e->velocity[0] += crandom()* 150; - e->velocity[1] += crandom()* 150; + e->velocity[0] += crandom() * 150; + e->velocity[1] += crandom() * 150; e->velocity[2] = self->speed * (100.0 / e->mass); } if (level.time < self->timestamp) + { self->nextthink = level.time + FRAMETIME; + } } -void target_earthquake_use (edict_t *self, edict_t *other, edict_t *activator) +void +target_earthquake_use(edict_t *self, edict_t *other, edict_t *activator) { self->timestamp = level.time + self->count; self->nextthink = level.time + FRAMETIME; @@ -790,21 +1034,29 @@ void target_earthquake_use (edict_t *self, edict_t *other, edict_t *activator) self->last_move_time = 0; } -void SP_target_earthquake (edict_t *self) +void +SP_target_earthquake(edict_t *self) { if (!self->targetname) - gi.dprintf("untargeted %s at %s\n", self->classname, vtos(self->s.origin)); + { + gi.dprintf("untargeted %s at %s\n", self->classname, + vtos(self->s.origin)); + } if (!self->count) + { self->count = 5; + } if (!self->speed) + { self->speed = 200; + } self->svflags |= SVF_NOCLIENT; self->think = target_earthquake_think; self->use = target_earthquake_use; - self->noise_index = gi.soundindex ("world/quake.wav"); + self->noise_index = gi.soundindex("world/quake.wav"); } diff --git a/src/game/ctf/g_trigger.c b/src/game/ctf/g_trigger.c index a04ef12b..ba0b513c 100644 --- a/src/game/ctf/g_trigger.c +++ b/src/game/ctf/g_trigger.c @@ -1,136 +1,162 @@ /* -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. - -*/ + * 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. + * + */ #include "g_local.h" - -void InitTrigger (edict_t *self) +void +InitTrigger(edict_t *self) { - if (!VectorCompare (self->s.angles, vec3_origin)) - G_SetMovedir (self->s.angles, self->movedir); + 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); + 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) +/* the wait time has passed, so set back up for another activation */ +void +multi_wait(edict_t *ent) { ent->nextthink = 0; } - -// the trigger was just activated -// ent->activator should be set to the activator so it can be held through a delay -// so wait for the delay time before firing -void multi_trigger (edict_t *ent) +/* the trigger was just activated */ +/* ent->activator should be set to the activator so it can be held through a delay */ +/* so wait for the delay time before firing */ +void +multi_trigger(edict_t *ent) { if (ent->nextthink) - return; // already been triggered + { + return; /* already been triggered */ + } - G_UseTargets (ent, ent->activator); + G_UseTargets(ent, ent->activator); - if (ent->wait > 0) + 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... + { + /* 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) +void +Use_Multi(edict_t *ent, edict_t *other, edict_t *activator) { ent->activator = activator; - multi_trigger (ent); + multi_trigger(ent); } -void Touch_Multi (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +void +Touch_Multi(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { - if(other->client) + 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; + vec3_t forward; AngleVectors(other->s.angles, forward, NULL, NULL); + if (_DotProduct(forward, self->movedir) < 0) + { return; + } } self->activator = other; - multi_trigger (self); + 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) + * 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); + gi.linkentity(self); } -void SP_trigger_multiple (edict_t *ent) +void +SP_trigger_multiple(edict_t *ent) { if (ent->sounds == 1) - ent->noise_index = gi.soundindex ("misc/secret.wav"); + { + ent->noise_index = gi.soundindex("misc/secret.wav"); + } else if (ent->sounds == 2) - ent->noise_index = gi.soundindex ("misc/talk.wav"); + { + ent->noise_index = gi.soundindex("misc/talk.wav"); + } else if (ent->sounds == 3) - ent->noise_index = gi.soundindex ("misc/trigger1.wav"); - + { + 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; @@ -143,112 +169,140 @@ void SP_trigger_multiple (edict_t *ent) } if (!VectorCompare(ent->s.angles, vec3_origin)) - G_SetMovedir (ent->s.angles, ent->movedir); + { + G_SetMovedir(ent->s.angles, ent->movedir); + } - gi.setmodel (ent, ent->model); - gi.linkentity (ent); + 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". + * 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 + */ -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) +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 + /* 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; + vec3_t v; - VectorMA (ent->mins, 0.5, ent->size, 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); + 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) + * 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); + G_UseTargets(self, activator); } -void SP_trigger_relay (edict_t *self) +void +SP_trigger_relay(edict_t *self) { self->use = trigger_relay_use; } - /* -============================================================================== - -trigger_key - -============================================================================== -*/ + * ============================================================================== + * + * 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) + * 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; + 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 (!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; + int player; + edict_t *ent; if (strcmp(self->item->classname, "key_power_cube") == 0) { - int cube; + 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]--; @@ -261,10 +315,17 @@ void trigger_key_use (edict_t *self, edict_t *other, edict_t *activator) 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; } } @@ -274,324 +335,420 @@ void trigger_key_use (edict_t *self, edict_t *other, edict_t *activator) activator->client->pers.inventory[index]--; } - G_UseTargets (self, activator); + G_UseTargets(self, activator); self->use = NULL; } -void SP_trigger_key (edict_t *self) +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); + + 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)); + 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)); + 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"); + gi.soundindex("misc/keytry.wav"); + gi.soundindex("misc/keyuse.wav"); self->use = trigger_key_use; } - /* -============================================================================== - -trigger_counter - -============================================================================== -*/ + * ============================================================================== + * + * trigger_counter + * + * ============================================================================== + */ /*QUAKED trigger_counter (.5 .5 .5) ? nomessage -Acts as an intermediary for an action that takes multiple inputs. + * 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. + */ -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) +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)) + 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); + gi.sound(activator, CHAN_AUTO, gi.soundindex( + "misc/talk1.wav"), 1, ATTN_NORM, 0); } + return; } - - if (! (self->spawnflags & 1)) + + if (!(self->spawnflags & 1)) { gi.centerprintf(activator, "Sequence completed!"); - 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); } + self->activator = activator; - multi_trigger (self); + multi_trigger(self); } -void SP_trigger_counter (edict_t *self) +void +SP_trigger_counter(edict_t *self) { self->wait = -1; + if (!self->count) + { self->count = 2; + } self->use = trigger_counter_use; } - /* -============================================================================== - -trigger_always - -============================================================================== -*/ + * ============================================================================== + * + * 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) + * 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 + /* 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 + * + * ============================================================================== + */ -trigger_push - -============================================================================== -*/ - -#define PUSH_ONCE 1 +#define PUSH_ONCE 1 static int windsound; -void trigger_push_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +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); + VectorScale(self->movedir, self->speed * 10, other->velocity); } else if (other->health > 0) { - VectorScale (self->movedir, self->speed * 10, other->velocity); + 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); + /* 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); + gi.sound(other, CHAN_AUTO, windsound, 1, ATTN_NORM, 0); } } } - if (self->spawnflags & PUSH_ONCE) - G_FreeEdict (self); -} + 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) + * Pushes the player + * "speed" defaults to 1000 + */ +void +SP_trigger_push(edict_t *self) { - InitTrigger (self); - windsound = gi.soundindex ("misc/windfly.wav"); + InitTrigger(self); + windsound = gi.soundindex("misc/windfly.wav"); self->touch = trigger_push_touch; - if (!self->speed) - self->speed = 1000; - gi.linkentity (self); -} + if (!self->speed) + { + self->speed = 1000; + } + + gi.linkentity(self); +} /* -============================================================================== - -trigger_hurt - -============================================================================== -*/ + * ============================================================================== + * + * 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) + * 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); + } + + 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) +void +hurt_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { - int dflags; + 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); + { + 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); + } + + 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) +void +SP_trigger_hurt(edict_t *self) { - InitTrigger (self); + InitTrigger(self); - self->noise_index = gi.soundindex ("world/electro.wav"); + 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); + gi.linkentity(self); } - /* -============================================================================== - -trigger_gravity - -============================================================================== -*/ + * ============================================================================== + * + * 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. -*/ + * 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) +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) +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); + gi.dprintf("trigger_gravity without gravity set at %s\n", + vtos(self->s.origin)); + G_FreeEdict(self); return; } - InitTrigger (self); + InitTrigger(self); self->gravity = atoi(st.gravity); self->touch = trigger_gravity_touch; } - /* -============================================================================== - -trigger_monsterjump - -============================================================================== -*/ + * ============================================================================== + * + * 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 -*/ + * 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) +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)) + if (other->flags & (FL_FLY | FL_SWIM)) + { return; + } - // set XY even if not on ground, so the jump will clear lips + 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) +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); + } + + InitTrigger(self); self->touch = trigger_monsterjump_touch; self->movedir[2] = st.height; } diff --git a/src/game/ctf/g_utils.c b/src/game/ctf/g_utils.c index e446abad..ebbb2f39 100644 --- a/src/game/ctf/g_utils.c +++ b/src/game/ctf/g_utils.c @@ -1,125 +1,162 @@ /* -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. - -*/ -// g_utils.c -- misc utility functions for game module + * 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. + * + */ +/* g_utils.c -- misc utility functions for game module */ #include "g_local.h" - -void G_ProjectSource (vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result) +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]; } - /* -============= -G_Find - -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. - -============= -*/ -edict_t *G_Find (edict_t *from, int fieldofs, char *match) + * ============= + * G_Find + * + * 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. + * + * ============= + */ +edict_t * +G_Find(edict_t *from, int fieldofs, char *match) { - char *s; + char *s; if (!from) + { from = g_edicts; + } else + { from++; + } - for ( ; from < &g_edicts[globals.num_edicts] ; from++) + for ( ; from < &g_edicts[globals.num_edicts]; from++) { if (!from->inuse) + { continue; - s = *(char **) ((byte *)from + fieldofs); + } + + s = *(char **)((byte *)from + fieldofs); + if (!s) + { continue; - if (!Q_stricmp (s, match)) + } + + if (!Q_stricmp(s, match)) + { return from; + } } return NULL; } - /* -================= -findradius - -Returns entities that have origins within a spherical area - -findradius (origin, radius) -================= -*/ -edict_t *findradius (edict_t *from, vec3_t org, float rad) + * ================= + * findradius + * + * Returns entities that have origins within a spherical area + * + * findradius (origin, radius) + * ================= + */ +edict_t * +findradius(edict_t *from, vec3_t org, float rad) { - vec3_t eorg; - int j; + 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; - for (j=0 ; j<3 ; j++) - eorg[j] = org[j] - (from->s.origin[j] + (from->mins[j] + from->maxs[j])*0.5); + } + + 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; } - /* -============= -G_PickTarget + * ============= + * G_PickTarget + * + * 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. + * + * ============= + */ +#define MAXCHOICES 8 -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. - -============= -*/ -#define MAXCHOICES 8 - -edict_t *G_PickTarget (char *targetname) +edict_t * +G_PickTarget(char *targetname) { - edict_t *ent = NULL; - int num_choices = 0; - edict_t *choice[MAXCHOICES]; + edict_t *ent = NULL; + int num_choices = 0; + edict_t *choice[MAXCHOICES]; if (!targetname) { @@ -127,14 +164,21 @@ edict_t *G_PickTarget (char *targetname) return NULL; } - while(1) + while (1) { - ent = G_Find (ent, FOFS(targetname), targetname); + ent = G_Find(ent, FOFS(targetname), targetname); + if (!ent) + { break; + } + choice[num_choices++] = ent; + if (num_choices == MAXCHOICES) + { break; + } } if (!num_choices) @@ -146,75 +190,86 @@ edict_t *G_PickTarget (char *targetname) return choice[rand() % num_choices]; } - - -void Think_Delay (edict_t *ent) +void +Think_Delay(edict_t *ent) { - G_UseTargets (ent, ent->activator); - G_FreeEdict (ent); + G_UseTargets(ent, ent->activator); + G_FreeEdict(ent); } /* -============================== -G_UseTargets - -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. - -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) + * ============================== + * G_UseTargets + * + * 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. + * + * 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) { - edict_t *t; + edict_t *t; - // - // check for a delay - // + /* */ + /* check for a delay */ + /* */ if (ent->delay) { - // create a temp object to fire at a later time + /* create a temp object to fire at a later time */ t = G_Spawn(); t->classname = "DelayedUse"; t->nextthink = level.time + ent->delay; t->think = Think_Delay; t->activator = activator; + if (!activator) - gi.dprintf ("Think_Delay with no activator\n"); + { + gi.dprintf("Think_Delay with no activator\n"); + } + t->message = ent->message; t->target = ent->target; t->killtarget = ent->killtarget; return; } - - - // - // print the message - // + + /* */ + /* print the message */ + /* */ if ((ent->message) && !(activator->svflags & SVF_MONSTER)) { - gi.centerprintf (activator, "%s", ent->message); + gi.centerprintf(activator, "%s", ent->message); + if (ent->noise_index) - gi.sound (activator, CHAN_AUTO, ent->noise_index, 1, ATTN_NORM, 0); + { + gi.sound(activator, CHAN_AUTO, ent->noise_index, 1, ATTN_NORM, 0); + } 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); + } } - // - // kill killtargets - // + /* */ + /* kill killtargets */ + /* */ if (ent->killtarget) { t = NULL; - while ((t = G_Find (t, FOFS(targetname), ent->killtarget))) + + while ((t = G_Find(t, FOFS(targetname), ent->killtarget))) { - G_FreeEdict (t); + G_FreeEdict(t); + if (!ent->inuse) { gi.dprintf("entity was removed while using killtargets\n"); @@ -223,28 +278,36 @@ void G_UseTargets (edict_t *ent, edict_t *activator) } } - // - // fire targets - // + /* */ + /* fire targets */ + /* */ if (ent->target) { t = NULL; - while ((t = G_Find (t, FOFS(targetname), ent->target))) + + while ((t = G_Find(t, FOFS(targetname), ent->target))) { - // doors fire area portals in a specific way + /* doors fire area portals in a specific way */ if (!Q_stricmp(t->classname, "func_areaportal") && - (!Q_stricmp(ent->classname, "func_door") || !Q_stricmp(ent->classname, "func_door_rotating"))) + (!Q_stricmp(ent->classname, + "func_door") || + !Q_stricmp(ent->classname, "func_door_rotating"))) + { continue; + } if (t == ent) { - gi.dprintf ("WARNING: Entity used itself.\n"); + gi.dprintf("WARNING: Entity used itself.\n"); } else { if (t->use) - t->use (t, ent, activator); + { + t->use(t, ent, activator); + } } + if (!ent->inuse) { gi.dprintf("entity was removed while using targets\n"); @@ -254,25 +317,25 @@ void G_UseTargets (edict_t *ent, edict_t *activator) } } - /* -============= -TempVector - -This is just a convenience function -for making temporary vectors for function calls -============= -*/ -float *tv (float x, float y, float z) + * ============= + * TempVector + * + * This is just a convenience function + * for making temporary vectors for function calls + * ============= + */ +float * +tv(float x, float y, float z) { - static int index; - static vec3_t vecs[8]; - float *v; + static int index; + 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; + index = (index + 1) & 7; v[0] = x; v[1] = y; @@ -281,106 +344,131 @@ float *tv (float x, float y, float z) return v; } - /* -============= -VectorToString - -This is just a convenience function -for printing vectors -============= -*/ -char *vtos (vec3_t v) + * ============= + * VectorToString + * + * This is just a convenience function + * for printing vectors + * ============= + */ +char * +vtos(vec3_t v) { - static int index; - static char str[8][32]; - char *s; + static int index; + static char str[8][32]; + char *s; - // use an array so that multiple vtos won't collide + /* use an array so that multiple vtos won't collide */ s = str[index]; - index = (index + 1)&7; + index = (index + 1) & 7; - Com_sprintf (s, 32, "(%i %i %i)", (int)v[0], (int)v[1], (int)v[2]); + Com_sprintf(s, 32, "(%i %i %i)", (int)v[0], (int)v[1], (int)v[2]); return s; } +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}; -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) +void +G_SetMovedir(vec3_t angles, vec3_t movedir) { - if (VectorCompare (angles, VEC_UP)) + if (VectorCompare(angles, VEC_UP)) { - VectorCopy (MOVEDIR_UP, movedir); + VectorCopy(MOVEDIR_UP, movedir); } - else if (VectorCompare (angles, VEC_DOWN)) + else if (VectorCompare(angles, VEC_DOWN)) { - VectorCopy (MOVEDIR_DOWN, movedir); + VectorCopy(MOVEDIR_DOWN, movedir); } else { - AngleVectors (angles, movedir, NULL, NULL); + AngleVectors(angles, movedir, NULL, NULL); } - VectorClear (angles); + VectorClear(angles); } - -float vectoyaw (vec3_t vec) +float +vectoyaw(vec3_t vec) { - float yaw; - - if (/* vec[YAW] == 0 && */ vec[PITCH] == 0) + float yaw; + + if (/* vec[YAW] == 0 && */ vec[PITCH] == 0) { yaw = 0; + if (vec[YAW] > 0) + { yaw = 90; + } else if (vec[YAW] < 0) + { yaw = -90; + } } else { - yaw = (int) (atan2(vec[YAW], vec[PITCH]) * 180 / M_PI); + yaw = (int)(atan2(vec[YAW], vec[PITCH]) * 180 / M_PI); + if (yaw < 0) + { yaw += 360; + } } return yaw; } - -void vectoangles (vec3_t value1, vec3_t angles) +void +vectoangles(vec3_t value1, vec3_t angles) { - float forward; - float yaw, pitch; - - if (value1[1] == 0 && value1[0] == 0) + 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 = (int) (atan2(value1[1], value1[0]) * 180 / M_PI); + { + yaw = (int)(atan2(value1[1], value1[0]) * 180 / M_PI); + } else if (value1[1] > 0) + { yaw = 90; + } else + { yaw = -90; - if (yaw < 0) - yaw += 360; + } + + if (yaw < 0) + { + yaw += 360; + } + + forward = sqrt(value1[0] * value1[0] + value1[1] * value1[1]); + pitch = (int)(atan2(value1[2], forward) * 180 / M_PI); - forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]); - pitch = (int) (atan2(value1[2], forward) * 180 / M_PI); if (pitch < 0) + { pitch += 360; + } } angles[PITCH] = -pitch; @@ -388,17 +476,18 @@ void vectoangles (vec3_t value1, vec3_t angles) angles[ROLL] = 0; } -char *G_CopyString (char *in) +char * +G_CopyString(char *in) { - char *out; - - out = gi.TagMalloc (strlen(in)+1, TAG_LEVEL); - strcpy (out, in); + char *out; + + out = gi.TagMalloc(strlen(in) + 1, TAG_LEVEL); + strcpy(out, in); return out; } - -void G_InitEdict (edict_t *e) +void +G_InitEdict(edict_t *e) { e->inuse = true; e->classname = "noclass"; @@ -407,162 +496,203 @@ void G_InitEdict (edict_t *e) } /* -================= -G_Spawn - -Either finds a free edict, or allocates a new one. -Try to avoid reusing an entity that was recently freed, because it -can cause the client to think the entity morphed into something else -instead of being removed and recreated, which can cause interpolated -angles and bad trails. -================= -*/ -edict_t *G_Spawn (void) + * ================= + * G_Spawn + * + * Either finds a free edict, or allocates a new one. + * Try to avoid reusing an entity that was recently freed, because it + * can cause the client to think the entity morphed into something else + * instead of being removed and recreated, which can cause interpolated + * angles and bad trails. + * ================= + */ +edict_t * +G_Spawn(void) { - int i; - edict_t *e; + int i; + edict_t *e; - e = &g_edicts[(int)maxclients->value+1]; - for ( i=maxclients->value+1 ; ivalue + 1]; + + for (i = maxclients->value + 1; i < globals.num_edicts; i++, e++) { - // the first couple seconds of server time can involve a lot of - // freeing and allocating, so relax the replacement policy - if (!e->inuse && ( e->freetime < 2 || level.time - e->freetime > 0.5 ) ) + /* the first couple seconds of server time can involve a lot of */ + /* freeing and allocating, so relax the replacement policy */ + if (!e->inuse && ((e->freetime < 2) || (level.time - e->freetime > 0.5))) { - G_InitEdict (e); + G_InitEdict(e); return e; } } - + if (i == game.maxentities) - gi.error ("ED_Alloc: no free edicts"); - + { + gi.error("ED_Alloc: no free edicts"); + } + globals.num_edicts++; - G_InitEdict (e); + G_InitEdict(e); return e; } /* -================= -G_FreeEdict - -Marks the edict as free -================= -*/ -void G_FreeEdict (edict_t *ed) + * ================= + * G_FreeEdict + * + * Marks the edict as free + * ================= + */ +void +G_FreeEdict(edict_t *ed) { - gi.unlinkentity (ed); // unlink from world + gi.unlinkentity(ed); /* unlink from world */ if ((ed - g_edicts) <= (maxclients->value + BODY_QUEUE_SIZE)) { return; } - memset (ed, 0, sizeof(*ed)); + memset(ed, 0, sizeof(*ed)); ed->classname = "freed"; ed->freetime = level.time; ed->inuse = false; } - /* -============ -G_TouchTriggers - -============ -*/ -void G_TouchTriggers (edict_t *ent) + * ============ + * G_TouchTriggers + * + * ============ + */ +void +G_TouchTriggers(edict_t *ent) { - int i, num; - edict_t *touch[MAX_EDICTS], *hit; + int i, num; + edict_t *touch[MAX_EDICTS], *hit; - // dead things don't activate triggers! + /* dead things don't activate triggers! */ if ((ent->client || (ent->svflags & SVF_MONSTER)) && (ent->health <= 0)) + { return; + } - num = gi.BoxEdicts (ent->absmin, ent->absmax, touch - , MAX_EDICTS, AREA_TRIGGERS); + num = gi.BoxEdicts(ent->absmin, ent->absmax, touch, + MAX_EDICTS, AREA_TRIGGERS); - // be careful, it is possible to have an entity in this - // list removed before we get to it (killtriggered) - for (i=0 ; iinuse) + { continue; + } + if (!hit->touch) + { continue; - hit->touch (hit, ent, NULL, NULL); + } + + hit->touch(hit, ent, NULL, NULL); } } /* -============ -G_TouchSolids - -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) + * ============ + * G_TouchSolids + * + * 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) { - int i, num; - edict_t *touch[MAX_EDICTS], *hit; + int i, num; + edict_t *touch[MAX_EDICTS], *hit; - 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) - for (i=0 ; iinuse) + { continue; + } + if (ent->touch) - ent->touch (hit, ent, NULL, NULL); + { + ent->touch(hit, ent, NULL, NULL); + } + if (!ent->inuse) + { break; + } } } - - +/* + * ============================================================================== + * + * Kill box + * + * ============================================================================== + */ /* -============================================================================== - -Kill box - -============================================================================== -*/ - -/* -================= -KillBox - -Kills all entities that would touch the proposed new positioning -of ent. Ent should be unlinked before calling this! -================= -*/ -qboolean KillBox (edict_t *ent) + * ================= + * KillBox + * + * Kills all entities that would touch the proposed new positioning + * of ent. Ent should be unlinked before calling this! + * ================= + */ +qboolean +KillBox(edict_t *ent) { - trace_t tr; + trace_t tr; 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) + { break; + } - // nail it - T_Damage (tr.ent, ent, ent, vec3_origin, ent->s.origin, vec3_origin, 100000, 0, DAMAGE_NO_PROTECTION, MOD_TELEFRAG); + /* nail it */ + T_Damage(tr.ent, + ent, + ent, + vec3_origin, + ent->s.origin, + vec3_origin, + 100000, + 0, + DAMAGE_NO_PROTECTION, + MOD_TELEFRAG); - // if we didn't kill it, fail + /* if we didn't kill it, fail */ if (tr.ent->solid) + { return false; + } } - return true; // all clear + return true; /* all clear */ } diff --git a/src/game/ctf/g_weapon.c b/src/game/ctf/g_weapon.c index 5394a9f6..28dd8e66 100644 --- a/src/game/ctf/g_weapon.c +++ b/src/game/ctf/g_weapon.c @@ -1,460 +1,628 @@ /* -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. - -*/ + * 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. + * + */ #include "g_local.h" - /* -================= -check_dodge - -This is a support routine used when a client is firing -a non-instant attack weapon. It checks to see if a -monster's dodge function should be called. -================= -*/ -static void check_dodge (edict_t *self, vec3_t start, vec3_t dir, int speed) + * ================= + * check_dodge + * + * This is a support routine used when a client is firing + * a non-instant attack weapon. It checks to see if a + * monster's dodge function should be called. + * ================= + */ +static void +check_dodge(edict_t *self, vec3_t start, vec3_t dir, int speed) { - vec3_t end; - vec3_t v; - trace_t tr; - float eta; + vec3_t end; + vec3_t v; + trace_t tr; + float eta; - // easy mode only ducks one quarter the time + /* easy mode only ducks one quarter the time */ if (skill->value == 0) { if (random() > 0.25) + { return; + } } - VectorMA (start, 8192, dir, end); - tr = gi.trace (start, NULL, NULL, end, self, MASK_SHOT); - if ((tr.ent) && (tr.ent->svflags & SVF_MONSTER) && (tr.ent->health > 0) && (tr.ent->monsterinfo.dodge) && infront(tr.ent, self)) + + VectorMA(start, 8192, dir, end); + tr = gi.trace(start, NULL, NULL, end, self, MASK_SHOT); + + if ((tr.ent) && (tr.ent->svflags & SVF_MONSTER) && (tr.ent->health > 0) && + (tr.ent->monsterinfo.dodge) && infront(tr.ent, self)) { - VectorSubtract (tr.endpos, start, v); + 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); } } - /* -================= -fire_hit - -Used for all impact (hit/punch/slash) attacks -================= -*/ -qboolean fire_hit (edict_t *self, vec3_t aim, int damage, int kick) + * ================= + * fire_hit + * + * Used for all impact (hit/punch/slash) attacks + * ================= + */ +qboolean +fire_hit(edict_t *self, vec3_t aim, int damage, int kick) { - trace_t tr; - vec3_t forward, right, up; - vec3_t v; - vec3_t point; - float range; - vec3_t dir; + trace_t tr; + vec3_t forward, right, up; + vec3_t v; + vec3_t point; + float range; + vec3_t dir; - //see if enemy is in range - VectorSubtract (self->enemy->s.origin, self->s.origin, dir); + /* see if enemy is in range */ + VectorSubtract(self->enemy->s.origin, self->s.origin, dir); range = VectorLength(dir); - if (range > aim[0]) - return false; - if (aim[1] > self->mins[0] && aim[1] < self->maxs[0]) + if (range > aim[0]) { - // the hit is straight on so back the range up to the edge of their bbox + return false; + } + + 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 */ 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]; + } else + { aim[1] = self->enemy->maxs[0]; + } } - VectorMA (self->s.origin, range, dir, point); + VectorMA(self->s.origin, range, dir, point); + + tr = gi.trace(self->s.origin, NULL, NULL, point, self, MASK_SHOT); - tr = gi.trace (self->s.origin, NULL, NULL, point, self, MASK_SHOT); if (tr.fraction < 1) { if (!tr.ent->takedamage) + { 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; + } } AngleVectors(self->s.angles, forward, right, up); - VectorMA (self->s.origin, range, forward, point); - VectorMA (point, aim[1], right, point); - VectorMA (point, aim[2], up, point); - VectorSubtract (point, self->enemy->s.origin, dir); + VectorMA(self->s.origin, range, forward, point); + VectorMA(point, aim[1], right, point); + VectorMA(point, aim[2], up, point); + 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); + /* do the damage */ + 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)) + { return false; + } + + /* do our special form of knockback here */ + VectorMA(self->enemy->absmin, 0.5, self->enemy->size, v); + VectorSubtract(v, point, v); + VectorNormalize(v); + VectorMA(self->enemy->velocity, kick, v, self->enemy->velocity); - // do our special form of knockback here - VectorMA (self->enemy->absmin, 0.5, self->enemy->size, v); - VectorSubtract (v, point, v); - VectorNormalize (v); - VectorMA (self->enemy->velocity, kick, v, self->enemy->velocity); if (self->enemy->velocity[2] > 0) + { self->enemy->groundentity = NULL; + } + return true; } - /* -================= -fire_lead - -This is an internal support routine used for bullet/pellet based weapons. -================= -*/ -static void fire_lead (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int te_impact, int hspread, int vspread, int mod) + * ================= + * fire_lead + * + * This is an internal support routine used for bullet/pellet based weapons. + * ================= + */ +static void +fire_lead(edict_t *self, + vec3_t start, + vec3_t aimdir, + int damage, + int kick, + int te_impact, + int hspread, + int vspread, + int mod) { - trace_t tr; - vec3_t dir; - vec3_t forward, right, up; - vec3_t end; - float r; - float u; - vec3_t water_start; - qboolean water = false; - int content_mask = MASK_SHOT | MASK_WATER; + trace_t tr; + vec3_t dir; + vec3_t forward, right, up; + vec3_t end; + float r; + float u; + vec3_t water_start; + qboolean water = false; + int content_mask = MASK_SHOT | MASK_WATER; + + tr = gi.trace(self->s.origin, NULL, NULL, start, self, MASK_SHOT); - tr = gi.trace (self->s.origin, NULL, NULL, start, self, MASK_SHOT); if (!(tr.fraction < 1.0)) { - vectoangles (aimdir, dir); - AngleVectors (dir, forward, right, up); + vectoangles(aimdir, dir); + AngleVectors(dir, forward, right, up); - r = crandom()*hspread; - u = crandom()*vspread; - VectorMA (start, 8192, forward, end); - VectorMA (end, r, right, end); - VectorMA (end, u, up, end); + r = crandom() * hspread; + u = crandom() * vspread; + VectorMA(start, 8192, forward, end); + VectorMA(end, r, right, end); + VectorMA(end, u, up, end); - if (gi.pointcontents (start) & MASK_WATER) + if (gi.pointcontents(start) & MASK_WATER) { water = true; - VectorCopy (start, water_start); + VectorCopy(start, water_start); content_mask &= ~MASK_WATER; } - tr = gi.trace (start, NULL, NULL, end, self, content_mask); + tr = gi.trace(start, NULL, NULL, end, self, content_mask); - // see if we hit water + /* see if we hit water */ if (tr.contents & MASK_WATER) { - int color; + int color; water = true; - VectorCopy (tr.endpos, water_start); + VectorCopy(tr.endpos, water_start); - if (!VectorCompare (start, tr.endpos)) + if (!VectorCompare(start, tr.endpos)) { if (tr.contents & CONTENTS_WATER) { if (strcmp(tr.surface->name, "*brwater") == 0) + { color = SPLASH_BROWN_WATER; + } else + { color = SPLASH_BLUE_WATER; + } } else if (tr.contents & CONTENTS_SLIME) + { color = SPLASH_SLIME; + } else if (tr.contents & CONTENTS_LAVA) + { color = SPLASH_LAVA; + } else + { color = SPLASH_UNKNOWN; + } if (color != SPLASH_UNKNOWN) { - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_SPLASH); - gi.WriteByte (8); - gi.WritePosition (tr.endpos); - gi.WriteDir (tr.plane.normal); - gi.WriteByte (color); - gi.multicast (tr.endpos, MULTICAST_PVS); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_SPLASH); + gi.WriteByte(8); + gi.WritePosition(tr.endpos); + gi.WriteDir(tr.plane.normal); + gi.WriteByte(color); + gi.multicast(tr.endpos, MULTICAST_PVS); } - // change bullet's course when it enters water - VectorSubtract (end, start, dir); - vectoangles (dir, dir); - AngleVectors (dir, forward, right, up); - r = crandom()*hspread*2; - u = crandom()*vspread*2; - VectorMA (water_start, 8192, forward, end); - VectorMA (end, r, right, end); - VectorMA (end, u, up, end); + /* change bullet's course when it enters water */ + VectorSubtract(end, start, dir); + vectoangles(dir, dir); + AngleVectors(dir, forward, right, up); + r = crandom() * hspread * 2; + u = crandom() * vspread * 2; + VectorMA(water_start, 8192, forward, end); + VectorMA(end, r, right, end); + VectorMA(end, u, up, end); } - // re-trace ignoring water this time - tr = gi.trace (water_start, NULL, NULL, end, self, MASK_SHOT); + /* re-trace ignoring water this time */ + tr = gi.trace(water_start, NULL, NULL, end, self, MASK_SHOT); } } - // send gun puff / flash + /* send gun puff / flash */ if (!((tr.surface) && (tr.surface->flags & SURF_SKY))) { if (tr.fraction < 1.0) { if (tr.ent->takedamage) { - T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, kick, DAMAGE_BULLET, mod); + T_Damage(tr.ent, + self, + self, + aimdir, + tr.endpos, + tr.plane.normal, + damage, + kick, + DAMAGE_BULLET, + mod); } else { - if (strncmp (tr.surface->name, "sky", 3) != 0) + if (strncmp(tr.surface->name, "sky", 3) != 0) { - gi.WriteByte (svc_temp_entity); - gi.WriteByte (te_impact); - gi.WritePosition (tr.endpos); - gi.WriteDir (tr.plane.normal); - gi.multicast (tr.endpos, MULTICAST_PVS); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(te_impact); + gi.WritePosition(tr.endpos); + gi.WriteDir(tr.plane.normal); + gi.multicast(tr.endpos, MULTICAST_PVS); if (self->client) + { PlayerNoise(self, tr.endpos, PNOISE_IMPACT); + } } } } } - // 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; + vec3_t pos; - VectorSubtract (tr.endpos, water_start, dir); - VectorNormalize (dir); - VectorMA (tr.endpos, -2, dir, pos); - if (gi.pointcontents (pos) & MASK_WATER) - VectorCopy (pos, tr.endpos); + VectorSubtract(tr.endpos, water_start, dir); + VectorNormalize(dir); + VectorMA(tr.endpos, -2, dir, pos); + + if (gi.pointcontents(pos) & MASK_WATER) + { + VectorCopy(pos, tr.endpos); + } else - tr = gi.trace (pos, NULL, NULL, water_start, tr.ent, MASK_WATER); + { + tr = gi.trace(pos, NULL, NULL, water_start, tr.ent, MASK_WATER); + } - VectorAdd (water_start, tr.endpos, pos); - VectorScale (pos, 0.5, pos); + VectorAdd(water_start, tr.endpos, pos); + VectorScale(pos, 0.5, pos); - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_BUBBLETRAIL); - gi.WritePosition (water_start); - gi.WritePosition (tr.endpos); - gi.multicast (pos, MULTICAST_PVS); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_BUBBLETRAIL); + gi.WritePosition(water_start); + gi.WritePosition(tr.endpos); + gi.multicast(pos, MULTICAST_PVS); } } - /* -================= -fire_bullet - -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, int kick, int hspread, int vspread, int mod) + * ================= + * fire_bullet + * + * 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, + int kick, + int hspread, + int vspread, + int mod) { - fire_lead (self, start, aimdir, damage, kick, TE_GUNSHOT, hspread, vspread, mod); + fire_lead(self, + start, + aimdir, + damage, + kick, + TE_GUNSHOT, + hspread, + vspread, + mod); } - /* -================= -fire_shotgun - -Shoots shotgun pellets. Used by shotgun and super shotgun. -================= -*/ -void fire_shotgun (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int count, int mod) + * ================= + * fire_shotgun + * + * Shoots shotgun pellets. Used by shotgun and super shotgun. + * ================= + */ +void +fire_shotgun(edict_t *self, + vec3_t start, + vec3_t aimdir, + int damage, + int kick, + int hspread, + int vspread, + int count, + int mod) { - int i; + int i; 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); + } } - /* -================= -fire_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) + * ================= + * fire_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) { - int mod; + int mod; if (other == self->owner) + { return; + } if (surf && (surf->flags & SURF_SKY)) { - G_FreeEdict (self); + G_FreeEdict(self); return; } if (self->owner->client) + { PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT); + } if (other->takedamage) { if (self->spawnflags & 1) + { mod = MOD_HYPERBLASTER; + } else + { mod = MOD_BLASTER; - T_Damage (other, self, self->owner, self->velocity, self->s.origin, plane->normal, self->dmg, 1, DAMAGE_ENERGY, mod); + } + + T_Damage(other, + self, + self->owner, + self->velocity, + self->s.origin, + plane->normal, + self->dmg, + 1, + DAMAGE_ENERGY, + mod); } else { - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_BLASTER); - gi.WritePosition (self->s.origin); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_BLASTER); + gi.WritePosition(self->s.origin); + if (!plane) - gi.WriteDir (vec3_origin); + { + gi.WriteDir(vec3_origin); + } else - gi.WriteDir (plane->normal); - gi.multicast (self->s.origin, MULTICAST_PVS); + { + gi.WriteDir(plane->normal); + } + + gi.multicast(self->s.origin, MULTICAST_PVS); } - G_FreeEdict (self); + G_FreeEdict(self); } -void fire_blaster (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int effect, qboolean hyper) +void +fire_blaster(edict_t *self, + vec3_t start, + vec3_t dir, + int damage, + int speed, + int effect, + qboolean hyper) { - edict_t *bolt; - trace_t tr; + edict_t *bolt; + trace_t tr; - VectorNormalize (dir); + VectorNormalize(dir); bolt = G_Spawn(); - bolt->svflags = SVF_PROJECTILE; // special net code is used for projectiles - VectorCopy (start, bolt->s.origin); - VectorCopy (start, bolt->s.old_origin); - vectoangles (dir, bolt->s.angles); - VectorScale (dir, speed, bolt->velocity); + bolt->svflags = SVF_PROJECTILE; /* special net code is used for projectiles */ + 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/laser/tris.md2"); - bolt->s.sound = gi.soundindex ("misc/lasfly.wav"); + VectorClear(bolt->mins); + VectorClear(bolt->maxs); + bolt->s.modelindex = gi.modelindex("models/objects/laser/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"; + if (hyper) + { bolt->spawnflags = 1; - gi.linkentity (bolt); + } + + gi.linkentity(bolt); if (self->client) - check_dodge (self, bolt->s.origin, dir, speed); + { + check_dodge(self, bolt->s.origin, dir, speed); + } + + tr = gi.trace(self->s.origin, NULL, NULL, bolt->s.origin, bolt, MASK_SHOT); - 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); + VectorMA(bolt->s.origin, -10, dir, bolt->s.origin); + bolt->touch(bolt, tr.ent, NULL, NULL); } -} - +} /* -================= -fire_grenade -================= -*/ -static void Grenade_Explode (edict_t *ent) + * ================= + * fire_grenade + * ================= + */ +static void +Grenade_Explode(edict_t *ent) { - vec3_t origin; - int mod; + vec3_t origin; + int mod; if (ent->owner->client) + { PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT); + } - //FIXME: if we are onground then raise our Z just a bit since we are a point? + /* FIXME: if we are onground then raise our Z just a bit since we are a point? */ if (ent->enemy) { - float points; - vec3_t v; - vec3_t dir; + float points; + vec3_t v; + vec3_t dir; + + VectorAdd(ent->enemy->mins, ent->enemy->maxs, v); + VectorMA(ent->enemy->s.origin, 0.5, v, v); + VectorSubtract(ent->s.origin, v, v); + points = ent->dmg - 0.5 * VectorLength(v); + VectorSubtract(ent->enemy->s.origin, ent->s.origin, dir); - VectorAdd (ent->enemy->mins, ent->enemy->maxs, v); - VectorMA (ent->enemy->s.origin, 0.5, v, v); - VectorSubtract (ent->s.origin, v, v); - points = ent->dmg - 0.5 * VectorLength (v); - VectorSubtract (ent->enemy->s.origin, ent->s.origin, dir); if (ent->spawnflags & 1) + { mod = MOD_HANDGRENADE; + } else + { mod = MOD_GRENADE; - T_Damage (ent->enemy, ent, ent->owner, dir, ent->s.origin, vec3_origin, (int)points, (int)points, DAMAGE_RADIUS, mod); + } + + T_Damage(ent->enemy, ent, ent->owner, dir, ent->s.origin, vec3_origin, + (int)points, (int)points, DAMAGE_RADIUS, mod); } if (ent->spawnflags & 2) + { mod = MOD_HELD_GRENADE; + } else if (ent->spawnflags & 1) + { mod = MOD_HG_SPLASH; + } else + { mod = MOD_G_SPLASH; + } + T_RadiusDamage(ent, ent->owner, ent->dmg, ent->enemy, ent->dmg_radius, mod); - VectorMA (ent->s.origin, -0.02, ent->velocity, origin); - gi.WriteByte (svc_temp_entity); + VectorMA(ent->s.origin, -0.02, ent->velocity, origin); + gi.WriteByte(svc_temp_entity); + if (ent->waterlevel) { if (ent->groundentity) - gi.WriteByte (TE_GRENADE_EXPLOSION_WATER); + { + gi.WriteByte(TE_GRENADE_EXPLOSION_WATER); + } else - gi.WriteByte (TE_ROCKET_EXPLOSION_WATER); + { + gi.WriteByte(TE_ROCKET_EXPLOSION_WATER); + } } else { if (ent->groundentity) - gi.WriteByte (TE_GRENADE_EXPLOSION); + { + gi.WriteByte(TE_GRENADE_EXPLOSION); + } else - gi.WriteByte (TE_ROCKET_EXPLOSION); + { + gi.WriteByte(TE_ROCKET_EXPLOSION); + } } - gi.WritePosition (origin); - gi.multicast (ent->s.origin, MULTICAST_PHS); - G_FreeEdict (ent); + gi.WritePosition(origin); + gi.multicast(ent->s.origin, MULTICAST_PHS); + + G_FreeEdict(ent); } -static void Grenade_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) +static void +Grenade_Touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { if (other == ent->owner) + { return; + } if (surf && (surf->flags & SURF_SKY)) { - G_FreeEdict (ent); + G_FreeEdict(ent); return; } @@ -463,43 +631,58 @@ static void Grenade_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurfa if (ent->spawnflags & 1) { 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; } ent->enemy = other; - Grenade_Explode (ent); + Grenade_Explode(ent); } -void fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius) +void +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; - vec3_t forward, right, up; + edict_t *grenade; + vec3_t dir; + vec3_t forward, right, up; - vectoangles (aimdir, dir); - AngleVectors (dir, forward, right, up); + vectoangles(aimdir, dir); + AngleVectors(dir, forward, right, up); grenade = G_Spawn(); - VectorCopy (start, grenade->s.origin); - VectorScale (aimdir, speed, grenade->velocity); - VectorMA (grenade->velocity, 200 + crandom() * 10.0, up, grenade->velocity); - VectorMA (grenade->velocity, crandom() * 10.0, right, grenade->velocity); - VectorSet (grenade->avelocity, 300, 300, 300); + VectorCopy(start, grenade->s.origin); + VectorScale(aimdir, speed, grenade->velocity); + VectorMA(grenade->velocity, 200 + crandom() * 10.0, up, grenade->velocity); + VectorMA(grenade->velocity, crandom() * 10.0, right, grenade->velocity); + VectorSet(grenade->avelocity, 300, 300, 300); grenade->movetype = MOVETYPE_BOUNCE; grenade->clipmask = MASK_SHOT; grenade->solid = SOLID_BBOX; grenade->s.effects |= EF_GRENADE; - VectorClear (grenade->mins); - VectorClear (grenade->maxs); - grenade->s.modelindex = gi.modelindex ("models/objects/grenade/tris.md2"); + VectorClear(grenade->mins); + VectorClear(grenade->maxs); + grenade->s.modelindex = gi.modelindex("models/objects/grenade/tris.md2"); grenade->owner = self; grenade->touch = Grenade_Touch; grenade->nextthink = level.time + timer; @@ -508,31 +691,39 @@ void fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int s grenade->dmg_radius = damage_radius; grenade->classname = "grenade"; - gi.linkentity (grenade); + gi.linkentity(grenade); } -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_grenade2(edict_t *self, + vec3_t start, + vec3_t aimdir, + int damage, + int speed, + float timer, + float damage_radius, + qboolean held) { - edict_t *grenade; - vec3_t dir; - vec3_t forward, right, up; + edict_t *grenade; + vec3_t dir; + vec3_t forward, right, up; - vectoangles (aimdir, dir); - AngleVectors (dir, forward, right, up); + vectoangles(aimdir, dir); + AngleVectors(dir, forward, right, up); grenade = G_Spawn(); - VectorCopy (start, grenade->s.origin); - VectorScale (aimdir, speed, grenade->velocity); - VectorMA (grenade->velocity, 200 + crandom() * 10.0, up, grenade->velocity); - VectorMA (grenade->velocity, crandom() * 10.0, right, grenade->velocity); - VectorSet (grenade->avelocity, 300, 300, 300); + VectorCopy(start, grenade->s.origin); + VectorScale(aimdir, speed, grenade->velocity); + VectorMA(grenade->velocity, 200 + crandom() * 10.0, up, grenade->velocity); + VectorMA(grenade->velocity, crandom() * 10.0, right, grenade->velocity); + VectorSet(grenade->avelocity, 300, 300, 300); grenade->movetype = MOVETYPE_BOUNCE; grenade->clipmask = MASK_SHOT; grenade->solid = SOLID_BBOX; grenade->s.effects |= EF_GRENADE; - VectorClear (grenade->mins); - VectorClear (grenade->maxs); - grenade->s.modelindex = gi.modelindex ("models/objects/grenade2/tris.md2"); + VectorClear(grenade->mins); + VectorClear(grenade->maxs); + grenade->s.modelindex = gi.modelindex("models/objects/grenade2/tris.md2"); grenade->owner = self; grenade->touch = Grenade_Touch; grenade->nextthink = level.time + timer; @@ -540,249 +731,364 @@ void fire_grenade2 (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int grenade->dmg = damage; grenade->dmg_radius = damage_radius; grenade->classname = "hgrenade"; + if (held) + { grenade->spawnflags = 3; + } else + { grenade->spawnflags = 1; + } + grenade->s.sound = gi.soundindex("weapons/hgrenc1b.wav"); if (timer <= 0.0) - Grenade_Explode (grenade); + { + Grenade_Explode(grenade); + } else { - gi.sound (self, CHAN_WEAPON, gi.soundindex ("weapons/hgrent1a.wav"), 1, ATTN_NORM, 0); - gi.linkentity (grenade); + gi.sound(self, CHAN_WEAPON, gi.soundindex( + "weapons/hgrent1a.wav"), 1, ATTN_NORM, 0); + gi.linkentity(grenade); } } - /* -================= -fire_rocket -================= -*/ -void rocket_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) + * ================= + * fire_rocket + * ================= + */ +void +rocket_touch(edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { - vec3_t origin; - int n; + vec3_t origin; + int n; if (other == ent->owner) + { return; + } if (surf && (surf->flags & SURF_SKY)) { - G_FreeEdict (ent); + 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); + /* calculate position for the explosion entity */ + VectorMA(ent->s.origin, -0.02, ent->velocity, origin); if (other->takedamage) { - T_Damage (other, ent, ent->owner, ent->velocity, ent->s.origin, plane->normal, ent->dmg, 0, 0, MOD_ROCKET); + T_Damage(other, + ent, + ent->owner, + ent->velocity, + ent->s.origin, + plane->normal, + ent->dmg, + 0, + 0, + MOD_ROCKET); } else { - // don't throw any debris in net games + /* don't throw any debris in net games */ if (!deathmatch->value && !coop->value) { - if ((surf) && !(surf->flags & (SURF_WARP|SURF_TRANS33|SURF_TRANS66|SURF_FLOWING))) + if ((surf) && + !(surf->flags & + (SURF_WARP | SURF_TRANS33 | SURF_TRANS66 | SURF_FLOWING))) { n = rand() % 5; - while(n--) - ThrowDebris (ent, "models/objects/debris2/tris.md2", 2, ent->s.origin); + + while (n--) + { + ThrowDebris(ent, + "models/objects/debris2/tris.md2", + 2, + ent->s.origin); + } } } } - 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); - gi.WriteByte (svc_temp_entity); if (ent->waterlevel) - gi.WriteByte (TE_ROCKET_EXPLOSION_WATER); + { + gi.WriteByte(TE_ROCKET_EXPLOSION_WATER); + } else - gi.WriteByte (TE_ROCKET_EXPLOSION); - gi.WritePosition (origin); - gi.multicast (ent->s.origin, MULTICAST_PHS); + { + gi.WriteByte(TE_ROCKET_EXPLOSION); + } - G_FreeEdict (ent); + gi.WritePosition(origin); + gi.multicast(ent->s.origin, MULTICAST_PHS); + + G_FreeEdict(ent); } -void fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage) +void +fire_rocket(edict_t *self, + vec3_t start, + vec3_t dir, + int damage, + int speed, + float damage_radius, + int radius_damage) { - edict_t *rocket; + edict_t *rocket; rocket = G_Spawn(); - VectorCopy (start, rocket->s.origin); - VectorCopy (dir, rocket->movedir); - vectoangles (dir, rocket->s.angles); - VectorScale (dir, speed, rocket->velocity); + VectorCopy(start, rocket->s.origin); + VectorCopy(dir, rocket->movedir); + vectoangles(dir, rocket->s.angles); + VectorScale(dir, speed, rocket->velocity); rocket->movetype = MOVETYPE_FLYMISSILE; rocket->clipmask = MASK_SHOT; rocket->solid = SOLID_BBOX; rocket->s.effects |= EF_ROCKET; - VectorClear (rocket->mins); - VectorClear (rocket->maxs); - rocket->s.modelindex = gi.modelindex ("models/objects/rocket/tris.md2"); + VectorClear(rocket->mins); + VectorClear(rocket->maxs); + 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 / speed; rocket->think = G_FreeEdict; rocket->dmg = damage; rocket->radius_dmg = radius_damage; rocket->dmg_radius = damage_radius; - rocket->s.sound = gi.soundindex ("weapons/rockfly.wav"); + rocket->s.sound = gi.soundindex("weapons/rockfly.wav"); rocket->classname = "rocket"; if (self->client) - check_dodge (self, rocket->s.origin, dir, speed); + { + check_dodge(self, rocket->s.origin, dir, speed); + } - gi.linkentity (rocket); + gi.linkentity(rocket); } - /* -================= -fire_rail -================= -*/ -void fire_rail (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick) + * ================= + * fire_rail + * ================= + */ +void +fire_rail(edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick) { - vec3_t from; - vec3_t end; - trace_t tr; - edict_t *ignore; - int mask; - qboolean water; + vec3_t from; + vec3_t end; + trace_t tr; + edict_t *ignore; + int mask; + qboolean water; - VectorMA (start, 8192, aimdir, end); - VectorCopy (start, from); + VectorMA(start, 8192, aimdir, end); + VectorCopy(start, from); ignore = self; water = false; - mask = MASK_SHOT|CONTENTS_SLIME|CONTENTS_LAVA; + mask = MASK_SHOT | CONTENTS_SLIME | CONTENTS_LAVA; + while (ignore) { - tr = gi.trace (from, NULL, NULL, end, ignore, mask); + tr = gi.trace(from, NULL, NULL, end, ignore, mask); - if (tr.contents & (CONTENTS_SLIME|CONTENTS_LAVA)) + if (tr.contents & (CONTENTS_SLIME | CONTENTS_LAVA)) { - mask &= ~(CONTENTS_SLIME|CONTENTS_LAVA); + mask &= ~(CONTENTS_SLIME | CONTENTS_LAVA); water = true; } else { - //ZOID--added so rail goes through SOLID_BBOX entities (gibs, etc) + /* ZOID--added so rail goes through SOLID_BBOX entities (gibs, etc) */ if ((tr.ent->svflags & SVF_MONSTER) || (tr.ent->client) || (tr.ent->solid == SOLID_BBOX)) + { ignore = tr.ent; + } else + { ignore = NULL; + } if ((tr.ent != self) && (tr.ent->takedamage)) - T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, kick, 0, MOD_RAILGUN); + { + T_Damage(tr.ent, + self, + self, + aimdir, + tr.endpos, + tr.plane.normal, + damage, + kick, + 0, + MOD_RAILGUN); + } } - VectorCopy (tr.endpos, from); + VectorCopy(tr.endpos, from); } - // send gun puff / flash - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_RAILTRAIL); - gi.WritePosition (start); - gi.WritePosition (tr.endpos); - gi.multicast (self->s.origin, MULTICAST_PHS); + /* send gun puff / flash */ + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_RAILTRAIL); + gi.WritePosition(start); + gi.WritePosition(tr.endpos); + gi.multicast(self->s.origin, MULTICAST_PHS); + if (water) { - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_RAILTRAIL); - gi.WritePosition (start); - gi.WritePosition (tr.endpos); - gi.multicast (tr.endpos, MULTICAST_PHS); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_RAILTRAIL); + gi.WritePosition(start); + gi.WritePosition(tr.endpos); + gi.multicast(tr.endpos, MULTICAST_PHS); } if (self->client) + { PlayerNoise(self, tr.endpos, PNOISE_IMPACT); + } } - /* -================= -fire_bfg -================= -*/ -void bfg_explode (edict_t *self) + * ================= + * fire_bfg + * ================= + */ +void +bfg_explode(edict_t *self) { - edict_t *ent; - float points; - vec3_t v; - float dist; + edict_t *ent; + float points; + vec3_t v; + float dist; if (self->s.frame == 0) { - // the BFG effect + /* the BFG effect */ ent = NULL; - while ((ent = findradius(ent, self->s.origin, self->dmg_radius)) != NULL) + + while ((ent = + findradius(ent, self->s.origin, self->dmg_radius)) != NULL) { if (!ent->takedamage) + { continue; - if (ent == self->owner) - continue; - if (!CanDamage (ent, self)) - continue; - if (!CanDamage (ent, self->owner)) - continue; + } - VectorAdd (ent->mins, ent->maxs, v); - VectorMA (ent->s.origin, 0.5, v, v); - VectorSubtract (self->s.origin, v, v); + if (ent == self->owner) + { + continue; + } + + if (!CanDamage(ent, self)) + { + continue; + } + + if (!CanDamage(ent, self->owner)) + { + continue; + } + + VectorAdd(ent->mins, ent->maxs, v); + VectorMA(ent->s.origin, 0.5, v, v); + VectorSubtract(self->s.origin, v, v); dist = VectorLength(v); - points = self->radius_dmg * (1.0 - sqrt(dist/self->dmg_radius)); - if (ent == self->owner) - points = points * 0.5; + points = self->radius_dmg * (1.0 - sqrt(dist / self->dmg_radius)); - gi.WriteByte (svc_temp_entity); - 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); + if (ent == self->owner) + { + points = points * 0.5; + } + + gi.WriteByte(svc_temp_entity); + 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); } } self->nextthink = level.time + FRAMETIME; self->s.frame++; + if (self->s.frame == 5) + { self->think = G_FreeEdict; + } } -void bfg_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) +void +bfg_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { if (other == self->owner) + { return; + } if (surf && (surf->flags & SURF_SKY)) { - G_FreeEdict (self); + G_FreeEdict(self); return; } if (self->owner->client) + { PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT); + } - // core explosion - prevents firing it into the wall/floor + /* core explosion - prevents firing it into the wall/floor */ if (other->takedamage) - T_Damage (other, self, self->owner, self->velocity, self->s.origin, plane->normal, 200, 0, 0, MOD_BFG_BLAST); + { + T_Damage(other, + self, + self->owner, + self->velocity, + self->s.origin, + plane->normal, + 200, + 0, + 0, + MOD_BFG_BLAST); + } + 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); - VectorClear (self->velocity); - self->s.modelindex = gi.modelindex ("sprites/s_bfg3.sp2"); + VectorMA(self->s.origin, -1 * FRAMETIME, 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; self->s.effects &= ~EF_ANIM_ALLFAST; @@ -790,123 +1096,165 @@ void bfg_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf self->nextthink = level.time + FRAMETIME; self->enemy = other; - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_BFG_BIGEXPLOSION); - gi.WritePosition (self->s.origin); - gi.multicast (self->s.origin, MULTICAST_PVS); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_BFG_BIGEXPLOSION); + gi.WritePosition(self->s.origin); + gi.multicast(self->s.origin, MULTICAST_PVS); } - -void bfg_think (edict_t *self) +void +bfg_think(edict_t *self) { - edict_t *ent; - edict_t *ignore; - vec3_t point; - vec3_t dir; - vec3_t start; - vec3_t end; - int dmg; - trace_t tr; + edict_t *ent; + edict_t *ignore; + vec3_t point; + vec3_t dir; + vec3_t start; + vec3_t end; + int dmg; + trace_t tr; if (deathmatch->value) + { dmg = 5; + } else + { dmg = 10; + } ent = NULL; + while ((ent = findradius(ent, self->s.origin, 256)) != NULL) { if (ent == self) + { continue; + } if (ent == self->owner) + { continue; + } if (!ent->takedamage) + { continue; + } - if (!(ent->svflags & SVF_MONSTER) && (!ent->client) && (strcmp(ent->classname, "misc_explobox") != 0)) + if (!(ent->svflags & SVF_MONSTER) && (!ent->client) && + (strcmp(ent->classname, "misc_explobox") != 0)) + { continue; + } - //ZOID - //don't target players in CTF + /* ZOID */ + /* don't target players in CTF */ if (ctf->value && ent->client && - self->owner->client && - ent->client->resp.ctf_team == self->owner->client->resp.ctf_team) + self->owner->client && + (ent->client->resp.ctf_team == self->owner->client->resp.ctf_team)) + { continue; - //ZOID + } - VectorMA (ent->absmin, 0.5, ent->size, point); + /* ZOID */ - VectorSubtract (point, self->s.origin, dir); - VectorNormalize (dir); + VectorMA(ent->absmin, 0.5, ent->size, point); + + VectorSubtract(point, self->s.origin, dir); + VectorNormalize(dir); ignore = self; - VectorCopy (self->s.origin, start); - VectorMA (start, 2048, dir, end); - while(1) + VectorCopy(self->s.origin, start); + VectorMA(start, 2048, dir, end); + + while (1) { - tr = gi.trace (start, NULL, NULL, end, ignore, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_DEADMONSTER); + tr = gi.trace(start, + NULL, + NULL, + end, + ignore, + CONTENTS_SOLID | CONTENTS_MONSTER | CONTENTS_DEADMONSTER); if (!tr.ent) + { break; + } - // hurt it if we can - 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); + /* hurt it if we can */ + 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); + } - // if we hit something that's not a monster or player we're done + /* if we hit something that's not a monster or player we're done */ if (!(tr.ent->svflags & SVF_MONSTER) && (!tr.ent->client)) { - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_LASER_SPARKS); - gi.WriteByte (4); - gi.WritePosition (tr.endpos); - gi.WriteDir (tr.plane.normal); - gi.WriteByte (self->s.skinnum); - gi.multicast (tr.endpos, MULTICAST_PVS); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_LASER_SPARKS); + gi.WriteByte(4); + gi.WritePosition(tr.endpos); + gi.WriteDir(tr.plane.normal); + gi.WriteByte(self->s.skinnum); + gi.multicast(tr.endpos, MULTICAST_PVS); break; } ignore = tr.ent; - VectorCopy (tr.endpos, start); + VectorCopy(tr.endpos, start); } - gi.WriteByte (svc_temp_entity); - gi.WriteByte (TE_BFG_LASER); - gi.WritePosition (self->s.origin); - gi.WritePosition (tr.endpos); - gi.multicast (self->s.origin, MULTICAST_PHS); + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_BFG_LASER); + gi.WritePosition(self->s.origin); + gi.WritePosition(tr.endpos); + gi.multicast(self->s.origin, MULTICAST_PHS); } self->nextthink = level.time + FRAMETIME; } - -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) { - edict_t *bfg; + edict_t *bfg; bfg = G_Spawn(); - VectorCopy (start, bfg->s.origin); - VectorCopy (dir, bfg->movedir); - vectoangles (dir, bfg->s.angles); - VectorScale (dir, speed, bfg->velocity); + VectorCopy(start, bfg->s.origin); + VectorCopy(dir, bfg->movedir); + vectoangles(dir, bfg->s.angles); + VectorScale(dir, speed, bfg->velocity); bfg->movetype = MOVETYPE_FLYMISSILE; bfg->clipmask = MASK_SHOT; bfg->solid = SOLID_BBOX; bfg->s.effects |= EF_BFG | EF_ANIM_ALLFAST; - VectorClear (bfg->mins); - VectorClear (bfg->maxs); - bfg->s.modelindex = gi.modelindex ("sprites/s_bfg1.sp2"); + VectorClear(bfg->mins); + VectorClear(bfg->maxs); + 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 / speed; bfg->think = G_FreeEdict; bfg->radius_dmg = damage; bfg->dmg_radius = damage_radius; bfg->classname = "bfg blast"; - bfg->s.sound = gi.soundindex ("weapons/bfg__l1a.wav"); + bfg->s.sound = gi.soundindex("weapons/bfg__l1a.wav"); bfg->think = bfg_think; bfg->nextthink = level.time + FRAMETIME; @@ -914,8 +1262,10 @@ void fire_bfg (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, f bfg->teamchain = NULL; if (self->client) - check_dodge (self, bfg->s.origin, dir, speed); + { + check_dodge(self, bfg->s.origin, dir, speed); + } - gi.linkentity (bfg); + gi.linkentity(bfg); }