Update of /cvsroot/jake2/jake2/src/jake2/game In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13343/src/jake2/game Modified Files: GameWeapon.java GameFunc.java GameUtil.java PlayerView.java GameTrigger.java GameSave.java GameTarget.java PlayerClient.java GameBase.java PlayerHud.java Cmd.java GameSpawn.java GameMisc.java Monster.java GameAI.java GameTurret.java Added Files: GameChase.java PlayerWeapon.java GameItems.java GameCombat.java Removed Files: Fire.java PlayerClientAdapters.java GamePWeapon.java Log Message: sorted the methods according to their original locations in the c files. Index: GameTrigger.java =================================================================== RCS file: /cvsroot/jake2/jake2/src/jake2/game/GameTrigger.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** GameTrigger.java 20 Feb 2005 21:49:46 -0000 1.4 --- GameTrigger.java 16 Nov 2005 22:24:52 -0000 1.5 *************** *** 20,24 **** --- 20,26 ---- // Created on 27.12.2003 by RST. + // $Id$ + package jake2.game; *************** *** 54,58 **** if (ent.wait > 0) { ! ent.think = GameTrigger.multi_wait; ent.nextthink = GameBase.level.time + ent.wait; } else { // we can't just remove (self) here, because this is a touch --- 56,60 ---- if (ent.wait > 0) { ! ent.think = multi_wait; ent.nextthink = GameBase.level.time + ent.wait; } else { // we can't just remove (self) here, because this is a touch *************** *** 76,80 **** ent.wait = 0.2f; ! ent.touch = GameTrigger.Touch_Multi; ent.movetype = Defines.MOVETYPE_NONE; ent.svflags |= Defines.SVF_NOCLIENT; --- 78,82 ---- ent.wait = 0.2f; ! ent.touch = Touch_Multi; ent.movetype = Defines.MOVETYPE_NONE; ent.svflags |= Defines.SVF_NOCLIENT; *************** *** 82,89 **** if ((ent.spawnflags & 4) != 0) { ent.solid = Defines.SOLID_NOT; ! ent.use = GameTrigger.trigger_enable; } else { ent.solid = Defines.SOLID_TRIGGER; ! ent.use = GameTrigger.Use_Multi; } --- 84,91 ---- if ((ent.spawnflags & 4) != 0) { ent.solid = Defines.SOLID_NOT; ! ent.use = trigger_enable; } else { ent.solid = Defines.SOLID_TRIGGER; ! ent.use = Use_Multi; } *************** *** 125,129 **** public static void SP_trigger_relay(edict_t self) { ! self.use = GameTrigger.trigger_relay_use; } --- 127,131 ---- public static void SP_trigger_relay(edict_t self) { ! self.use = trigger_relay_use; } *************** *** 134,138 **** return; } ! self.item = GameUtil.FindItemByClassname(GameBase.st.item); if (null == self.item) { --- 136,140 ---- return; } ! self.item = GameItems.FindItemByClassname(GameBase.st.item); if (null == self.item) { *************** *** 152,156 **** GameBase.gi.soundindex("misc/keyuse.wav"); ! self.use = GameTrigger.trigger_key_use; } --- 154,158 ---- GameBase.gi.soundindex("misc/keyuse.wav"); ! self.use = trigger_key_use; } *************** *** 160,164 **** self.count = 2; ! self.use = GameTrigger.trigger_counter_use; } --- 162,166 ---- self.count = 2; ! self.use = trigger_counter_use; } *************** *** 188,193 **** public static void SP_trigger_push(edict_t self) { InitTrigger(self); ! GameTrigger.windsound = GameBase.gi.soundindex("misc/windfly.wav"); ! self.touch = GameTrigger.trigger_push_touch; if (0 == self.speed) self.speed = 1000; --- 190,195 ---- public static void SP_trigger_push(edict_t self) { InitTrigger(self); ! windsound = GameBase.gi.soundindex("misc/windfly.wav"); ! self.touch = trigger_push_touch; if (0 == self.speed) self.speed = 1000; *************** *** 199,203 **** self.noise_index = GameBase.gi.soundindex("world/electro.wav"); ! self.touch = GameTrigger.hurt_touch; if (0 == self.dmg) --- 201,205 ---- self.noise_index = GameBase.gi.soundindex("world/electro.wav"); ! self.touch = hurt_touch; if (0 == self.dmg) *************** *** 210,214 **** if ((self.spawnflags & 2) != 0) ! self.use = GameTrigger.hurt_use; GameBase.gi.linkentity(self); --- 212,216 ---- if ((self.spawnflags & 2) != 0) ! self.use = hurt_use; GameBase.gi.linkentity(self); *************** *** 225,229 **** InitTrigger(self); self.gravity = Lib.atoi(GameBase.st.gravity); ! self.touch = GameTrigger.trigger_gravity_touch; } --- 227,231 ---- InitTrigger(self); self.gravity = Lib.atoi(GameBase.st.gravity); ! self.touch = trigger_gravity_touch; } *************** *** 236,240 **** self.s.angles[Defines.YAW] = 360; InitTrigger(self); ! self.touch = GameTrigger.trigger_monsterjump_touch; self.movedir[2] = GameBase.st.height; } --- 238,242 ---- self.s.angles[Defines.YAW] = 360; InitTrigger(self); ! self.touch = trigger_monsterjump_touch; self.movedir[2] = GameBase.st.height; } *************** *** 252,256 **** public void use(edict_t ent, edict_t other, edict_t activator) { ent.activator = activator; ! GameTrigger.multi_trigger(ent); } }; --- 254,258 ---- public void use(edict_t ent, edict_t other, edict_t activator) { ent.activator = activator; ! multi_trigger(ent); } }; *************** *** 277,281 **** self.activator = other; ! GameTrigger.multi_trigger(self); } }; --- 279,283 ---- self.activator = other; ! multi_trigger(self); } }; *************** *** 329,333 **** return; ! index = GameUtil.ITEM_INDEX(self.item); if (activator.client.pers.inventory[index] == 0) { if (GameBase.level.time < self.touch_debounce_time) --- 331,335 ---- return; ! index = GameItems.ITEM_INDEX(self.item); if (activator.client.pers.inventory[index] == 0) { if (GameBase.level.time < self.touch_debounce_time) *************** *** 429,433 **** } self.activator = activator; ! GameTrigger.multi_trigger(self); } }; --- 431,435 ---- } self.activator = activator; ! multi_trigger(self); } }; *************** *** 530,534 **** else dflags = 0; ! GameUtil.T_Damage(other, self, self, Globals.vec3_origin, other.s.origin, Globals.vec3_origin, self.dmg, self.dmg, dflags, Defines.MOD_TRIGGER_HURT); --- 532,536 ---- else dflags = 0; ! GameCombat.T_Damage(other, self, self, Globals.vec3_origin, other.s.origin, Globals.vec3_origin, self.dmg, self.dmg, dflags, Defines.MOD_TRIGGER_HURT); Index: GameAI.java =================================================================== RCS file: /cvsroot/jake2/jake2/src/jake2/game/GameAI.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** GameAI.java 20 Feb 2005 16:38:36 -0000 1.7 --- GameAI.java 16 Nov 2005 22:24:53 -0000 1.8 *************** *** 20,24 **** --- 20,26 ---- // Created on 02.11.2003 by RST. + // $Id$ + package jake2.game; *************** *** 26,304 **** [...2957 lines suppressed...] ! if (anum1 < bnum1) ! return -1; ! if (anum1 > bnum1) ! return 1; ! return 0; ! } ! }; } --- 819,828 ---- }; ! static boolean enemy_vis; ! static boolean enemy_infront; ! static int enemy_range; ! static float enemy_yaw; } Index: PlayerView.java =================================================================== RCS file: /cvsroot/jake2/jake2/src/jake2/game/PlayerView.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** PlayerView.java 6 Feb 2005 19:13:56 -0000 1.3 --- PlayerView.java 16 Nov 2005 22:24:52 -0000 1.4 *************** *** 42,46 **** /* ! * =============== SV_CalcRoll * * =============== --- 42,47 ---- /* ! * =============== ! * SV_CalcRoll * * =============== *************** *** 66,72 **** /* ! * =============== P_DamageFeedback * ! * Handles color blends and view kicks =============== */ --- 67,75 ---- /* ! * =============== ! * P_DamageFeedback * ! * Handles color blends and view kicks ! * =============== */ *************** *** 159,162 **** --- 162,167 ---- // the color of the blend will vary based on how much was absorbed // by different armors + // + Math3D.VectorClear(v); if (client.damage_parmor != 0) *************** *** 209,213 **** /* ! * =============== SV_CalcViewOffset * * Auto pitching on slopes? --- 214,219 ---- /* ! * =============== ! * SV_CalcViewOffset * * Auto pitching on slopes? *************** *** 336,340 **** /* ! * ============== SV_CalcGunOffset ============== */ public static void SV_CalcGunOffset(edict_t ent) { --- 342,348 ---- /* ! * ============== ! * SV_CalcGunOffset ! * ============== */ public static void SV_CalcGunOffset(edict_t ent) { *************** *** 381,385 **** /* ! * ============= SV_AddBlend ============= */ public static void SV_AddBlend(float r, float g, float b, float a, --- 389,395 ---- /* ! * ============= ! * SV_AddBlend ! * ============= */ public static void SV_AddBlend(float r, float g, float b, float a, *************** *** 399,403 **** /* ! * ============= SV_CalcBlend ============= */ public static void SV_CalcBlend(edict_t ent) { --- 409,415 ---- /* ! * ============= ! * SV_CalcBlend ! * ============= */ public static void SV_CalcBlend(edict_t ent) { *************** *** 483,487 **** /* ! * ================= P_FallingDamage ================= */ public static void P_FallingDamage(edict_t ent) { --- 495,501 ---- /* ! * ================= ! * P_FallingDamage ! * ================= */ public static void P_FallingDamage(edict_t ent) { *************** *** 544,548 **** if (GameBase.deathmatch.value == 0 || 0 == ((int) GameBase.dmflags.value & Defines.DF_NO_FALLING)) ! GameUtil.T_Damage(ent, GameBase.g_edicts[0], GameBase.g_edicts[0], dir, ent.s.origin, Globals.vec3_origin, damage, 0, 0, Defines.MOD_FALLING); --- 558,562 ---- if (GameBase.deathmatch.value == 0 || 0 == ((int) GameBase.dmflags.value & Defines.DF_NO_FALLING)) ! GameCombat.T_Damage(ent, GameBase.g_edicts[0], GameBase.g_edicts[0], dir, ent.s.origin, Globals.vec3_origin, damage, 0, 0, Defines.MOD_FALLING); *************** *** 554,558 **** /* ! * ============= P_WorldEffects ============= */ public static void P_WorldEffects() { --- 568,574 ---- /* ! * ============= ! * P_WorldEffects ! * ============= */ public static void P_WorldEffects() { *************** *** 578,582 **** // if (old_waterlevel == 0 && waterlevel != 0) { ! GameWeapon.PlayerNoise(current_player, current_player.s.origin, Defines.PNOISE_SELF); if ((current_player.watertype & Defines.CONTENTS_LAVA) != 0) --- 594,598 ---- // if (old_waterlevel == 0 && waterlevel != 0) { ! PlayerWeapon.PlayerNoise(current_player, current_player.s.origin, Defines.PNOISE_SELF); if ((current_player.watertype & Defines.CONTENTS_LAVA) != 0) *************** *** 602,606 **** // if (old_waterlevel != 0 && waterlevel == 0) { ! GameWeapon.PlayerNoise(current_player, current_player.s.origin, Defines.PNOISE_SELF); GameBase.gi --- 618,622 ---- // if (old_waterlevel != 0 && waterlevel == 0) { ! PlayerWeapon.PlayerNoise(current_player, current_player.s.origin, Defines.PNOISE_SELF); GameBase.gi *************** *** 628,632 **** GameBase.gi.soundindex("player/gasp1.wav"), 1, Defines.ATTN_NORM, 0); ! GameWeapon.PlayerNoise(current_player, current_player.s.origin, Defines.PNOISE_SELF); } else if (current_player.air_finished < GameBase.level.time + 11) { // just --- 644,648 ---- GameBase.gi.soundindex("player/gasp1.wav"), 1, Defines.ATTN_NORM, 0); ! PlayerWeapon.PlayerNoise(current_player, current_player.s.origin, Defines.PNOISE_SELF); } else if (current_player.air_finished < GameBase.level.time + 11) { // just *************** *** 657,661 **** 1, Defines.ATTN_NORM, 0); current_client.breather_sound ^= 1; ! GameWeapon.PlayerNoise(current_player, current_player.s.origin, Defines.PNOISE_SELF); //FIXME: release a bubble? --- 673,677 ---- 1, Defines.ATTN_NORM, 0); current_client.breather_sound ^= 1; ! PlayerWeapon.PlayerNoise(current_player, current_player.s.origin, Defines.PNOISE_SELF); //FIXME: release a bubble? *************** *** 690,694 **** current_player.pain_debounce_time = GameBase.level.time; ! GameUtil.T_Damage(current_player, GameBase.g_edicts[0], GameBase.g_edicts[0], Globals.vec3_origin, current_player.s.origin, Globals.vec3_origin, --- 706,710 ---- current_player.pain_debounce_time = GameBase.level.time; ! GameCombat.T_Damage(current_player, GameBase.g_edicts[0], GameBase.g_edicts[0], Globals.vec3_origin, current_player.s.origin, Globals.vec3_origin, *************** *** 723,732 **** if (envirosuit) // take 1/3 damage with envirosuit ! GameUtil.T_Damage(current_player, GameBase.g_edicts[0], GameBase.g_edicts[0], Globals.vec3_origin, current_player.s.origin, Globals.vec3_origin, 1 * waterlevel, 0, 0, Defines.MOD_LAVA); else ! GameUtil.T_Damage(current_player, GameBase.g_edicts[0], GameBase.g_edicts[0], Globals.vec3_origin, current_player.s.origin, Globals.vec3_origin, --- 739,748 ---- if (envirosuit) // take 1/3 damage with envirosuit ! GameCombat.T_Damage(current_player, GameBase.g_edicts[0], GameBase.g_edicts[0], Globals.vec3_origin, current_player.s.origin, Globals.vec3_origin, 1 * waterlevel, 0, 0, Defines.MOD_LAVA); else ! GameCombat.T_Damage(current_player, GameBase.g_edicts[0], GameBase.g_edicts[0], Globals.vec3_origin, current_player.s.origin, Globals.vec3_origin, *************** *** 736,740 **** if ((current_player.watertype & Defines.CONTENTS_SLIME) != 0) { if (!envirosuit) { // no damage from slime with envirosuit ! GameUtil.T_Damage(current_player, GameBase.g_edicts[0], GameBase.g_edicts[0], Globals.vec3_origin, current_player.s.origin, Globals.vec3_origin, --- 752,756 ---- if ((current_player.watertype & Defines.CONTENTS_SLIME) != 0) { if (!envirosuit) { // no damage from slime with envirosuit ! GameCombat.T_Damage(current_player, GameBase.g_edicts[0], GameBase.g_edicts[0], Globals.vec3_origin, current_player.s.origin, Globals.vec3_origin, *************** *** 746,750 **** /* ! * =============== G_SetClientEffects =============== */ public static void G_SetClientEffects(edict_t ent) { --- 762,768 ---- /* ! * =============== ! * G_SetClientEffects ! * =============== */ public static void G_SetClientEffects(edict_t ent) { *************** *** 759,763 **** if (ent.powerarmor_time > GameBase.level.time) { ! pa_type = GameUtil.PowerArmorType(ent); if (pa_type == Defines.POWER_ARMOR_SCREEN) { ent.s.effects |= Defines.EF_POWERSCREEN; --- 777,781 ---- if (ent.powerarmor_time > GameBase.level.time) { ! pa_type = GameItems.PowerArmorType(ent); if (pa_type == Defines.POWER_ARMOR_SCREEN) { ent.s.effects |= Defines.EF_POWERSCREEN; *************** *** 790,794 **** /* ! * =============== G_SetClientEvent =============== */ public static void G_SetClientEvent(edict_t ent) { --- 808,814 ---- /* ! * =============== ! * G_SetClientEvent ! * =============== */ public static void G_SetClientEvent(edict_t ent) { *************** *** 803,807 **** /* ! * =============== G_SetClientSound =============== */ public static void G_SetClientSound(edict_t ent) { --- 823,829 ---- /* ! * =============== ! * G_SetClientSound ! * =============== */ public static void G_SetClientSound(edict_t ent) { *************** *** 841,845 **** /* ! * =============== G_SetClientFrame =============== */ public static void G_SetClientFrame(edict_t ent) { --- 863,869 ---- /* ! * =============== ! * G_SetClientFrame ! * =============== */ public static void G_SetClientFrame(edict_t ent) { *************** *** 928,935 **** /* ! * ================= ClientEndServerFrame * * Called for each player at the end of the server frame and right after ! * spawning ================= */ public static void ClientEndServerFrame(edict_t ent) { --- 952,961 ---- /* ! * ================= ! * ClientEndServerFrame * * Called for each player at the end of the server frame and right after ! * spawning ! * ================= */ public static void ClientEndServerFrame(edict_t ent) { --- NEW FILE: GameCombat.java --- /* 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. */ // Created on 16.11.2005 by RST. // $Id: GameCombat.java,v 1.1 2005/11/16 22:24:53 salomo Exp $ package jake2.game; import jake2.Defines; import jake2.Globals; import jake2.qcommon.Com; import jake2.util.Math3D; public class GameCombat { /* * ============ CanDamage * * Returns true if the inflictor can directly damage the target. Used for * explosions and melee attacks. ============ */ static boolean CanDamage(edict_t targ, edict_t inflictor) { float[] dest = { 0, 0, 0 }; trace_t trace; // bmodels need special checking because their origin is 0,0,0 if (targ.movetype == Defines.MOVETYPE_PUSH) { Math3D.VectorAdd(targ.absmin, targ.absmax, dest); Math3D.VectorScale(dest, 0.5f, dest); trace = GameBase.gi.trace(inflictor.s.origin, Globals.vec3_origin, Globals.vec3_origin, dest, inflictor, Defines.MASK_SOLID); if (trace.fraction == 1.0f) return true; if (trace.ent == targ) return true; return false; } trace = GameBase.gi.trace(inflictor.s.origin, Globals.vec3_origin, Globals.vec3_origin, targ.s.origin, inflictor, Defines.MASK_SOLID); if (trace.fraction == 1.0) return true; Math3D.VectorCopy(targ.s.origin, dest); dest[0] += 15.0; dest[1] += 15.0; trace = GameBase.gi.trace(inflictor.s.origin, Globals.vec3_origin, Globals.vec3_origin, dest, inflictor, Defines.MASK_SOLID); if (trace.fraction == 1.0) return true; Math3D.VectorCopy(targ.s.origin, dest); dest[0] += 15.0; dest[1] -= 15.0; trace = GameBase.gi.trace(inflictor.s.origin, Globals.vec3_origin, Globals.vec3_origin, dest, inflictor, Defines.MASK_SOLID); if (trace.fraction == 1.0) return true; Math3D.VectorCopy(targ.s.origin, dest); dest[0] -= 15.0; dest[1] += 15.0; trace = GameBase.gi.trace(inflictor.s.origin, Globals.vec3_origin, Globals.vec3_origin, dest, inflictor, Defines.MASK_SOLID); if (trace.fraction == 1.0) return true; Math3D.VectorCopy(targ.s.origin, dest); dest[0] -= 15.0; dest[1] -= 15.0; trace = GameBase.gi.trace(inflictor.s.origin, Globals.vec3_origin, Globals.vec3_origin, dest, inflictor, Defines.MASK_SOLID); if (trace.fraction == 1.0) return true; return false; } /* * ============ Killed ============ */ public static void Killed(edict_t targ, edict_t inflictor, edict_t attacker, int damage, float[] point) { Com.DPrintf("Killing a " + targ.classname + "\n"); if (targ.health < -999) targ.health = -999; //Com.Println("Killed:" + targ.classname); targ.enemy = attacker; if ((targ.svflags & Defines.SVF_MONSTER) != 0 && (targ.deadflag != Defines.DEAD_DEAD)) { // targ.svflags |= SVF_DEADMONSTER; // now treat as a different // content type if (0 == (targ.monsterinfo.aiflags & Defines.AI_GOOD_GUY)) { GameBase.level.killed_monsters++; if (GameBase.coop.value != 0 && attacker.client != null) attacker.client.resp.score++; // medics won't heal monsters that they kill themselves if (attacker.classname.equals("monster_medic")) targ.owner = attacker; } } if (targ.movetype == Defines.MOVETYPE_PUSH || targ.movetype == Defines.MOVETYPE_STOP || targ.movetype == Defines.MOVETYPE_NONE) { // doors, triggers, // etc targ.die.die(targ, inflictor, attacker, damage, point); return; } if ((targ.svflags & Defines.SVF_MONSTER) != 0 && (targ.deadflag != Defines.DEAD_DEAD)) { targ.touch = null; Monster.monster_death_use(targ); } targ.die.die(targ, inflictor, attacker, damage, point); } /* * ================ SpawnDamage ================ */ static void SpawnDamage(int type, float[] origin, float[] normal, int damage) { if (damage > 255) damage = 255; GameBase.gi.WriteByte(Defines.svc_temp_entity); GameBase.gi.WriteByte(type); // gi.WriteByte (damage); GameBase.gi.WritePosition(origin); GameBase.gi.WriteDir(normal); GameBase.gi.multicast(origin, Defines.MULTICAST_PVS); } static int CheckPowerArmor(edict_t ent, float[] point, float[] 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; if (damage == 0) return 0; client = ent.client; if ((dflags & Defines.DAMAGE_NO_ARMOR) != 0) return 0; if (client != null) { power_armor_type = GameItems.PowerArmorType(ent); if (power_armor_type != Defines.POWER_ARMOR_NONE) { index = GameItems.ITEM_INDEX(GameItems.FindItem("Cells")); power = client.pers.inventory[index]; } } else if ((ent.svflags & Defines.SVF_MONSTER) != 0) { power_armor_type = ent.monsterinfo.power_armor_type; power = ent.monsterinfo.power_armor_power; } else return 0; if (power_armor_type == Defines.POWER_ARMOR_NONE) return 0; if (power == 0) return 0; if (power_armor_type == Defines.POWER_ARMOR_SCREEN) { float[] vec = { 0, 0, 0 }; float dot; float[] forward = { 0, 0, 0 }; // only works if damage point is in front Math3D.AngleVectors(ent.s.angles, forward, null, null); Math3D.VectorSubtract(point, ent.s.origin, vec); Math3D.VectorNormalize(vec); dot = Math3D.DotProduct(vec, forward); if (dot <= 0.3) return 0; damagePerCell = 1; pa_te_type = Defines.TE_SCREEN_SPARKS; damage = damage / 3; } else { damagePerCell = 2; pa_te_type = Defines.TE_SHIELD_SPARKS; damage = (2 * damage) / 3; } save = power * damagePerCell; if (save == 0) return 0; if (save > damage) save = damage; SpawnDamage(pa_te_type, point, normal, save); ent.powerarmor_time = GameBase.level.time + 0.2f; power_used = save / damagePerCell; if (client != null) client.pers.inventory[index] -= power_used; else ent.monsterinfo.power_armor_power -= power_used; return save; } static int CheckArmor(edict_t ent, float[] point, float[] normal, int damage, int te_sparks, int dflags) { gclient_t client; int save; int index; gitem_t armor; if (damage == 0) return 0; client = ent.client; if (client != null) return 0; if ((dflags & Defines.DAMAGE_NO_ARMOR) != 0) return 0; index = GameItems.ArmorIndex(ent); if (index == 0) return 0; armor = GameItems.GetItemByIndex(index); gitem_armor_t garmor = (gitem_armor_t) armor.info; if (0 != (dflags & Defines.DAMAGE_ENERGY)) save = (int) Math.ceil(garmor.energy_protection * damage); else save = (int) Math.ceil(garmor.normal_protection * damage); if (save >= client.pers.inventory[index]) save = client.pers.inventory[index]; if (save == 0) return 0; client.pers.inventory[index] -= save; SpawnDamage(te_sparks, point, normal, save); return save; } public static void M_ReactToDamage(edict_t targ, edict_t attacker) { if ((null != attacker.client) && 0 != (attacker.svflags & Defines.SVF_MONSTER)) return; 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 (0 != (targ.monsterinfo.aiflags & Defines.AI_GOOD_GUY)) { if (attacker.client != null || (attacker.monsterinfo.aiflags & Defines.AI_GOOD_GUY) != 0) return; } // 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.client != null) { targ.monsterinfo.aiflags &= ~Defines.AI_SOUND_TARGET; // 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 != null && targ.enemy.client != null) { if (GameUtil.visible(targ, targ.enemy)) { targ.oldenemy = attacker; return; } targ.oldenemy = targ.enemy; } targ.enemy = attacker; if (0 == (targ.monsterinfo.aiflags & Defines.AI_DUCKED)) GameUtil.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 & (Defines.FL_FLY | Defines.FL_SWIM)) == (attacker.flags & (Defines.FL_FLY | Defines.FL_SWIM))) && (!(targ.classname.equals(attacker.classname))) && (!(attacker.classname.equals("monster_tank"))) && (!(attacker.classname.equals("monster_supertank"))) && (!(attacker.classname.equals("monster_makron"))) && (!(attacker.classname.equals("monster_jorg")))) { if (targ.enemy != null && targ.enemy.client != null) targ.oldenemy = targ.enemy; targ.enemy = attacker; if (0 == (targ.monsterinfo.aiflags & Defines.AI_DUCKED)) GameUtil.FoundTarget(targ); } // if they *meant* to shoot us, then shoot back else if (attacker.enemy == targ) { if (targ.enemy != null && targ.enemy.client != null) targ.oldenemy = targ.enemy; targ.enemy = attacker; if (0 == (targ.monsterinfo.aiflags & Defines.AI_DUCKED)) GameUtil.FoundTarget(targ); } // otherwise get mad at whoever they are mad at (help our buddy) unless // it is us! else if (attacker.enemy != null && attacker.enemy != targ) { if (targ.enemy != null && targ.enemy.client != null) targ.oldenemy = targ.enemy; targ.enemy = attacker.enemy; if (0 == (targ.monsterinfo.aiflags & Defines.AI_DUCKED)) GameUtil.FoundTarget(targ); } } static boolean CheckTeamDamage(edict_t targ, edict_t attacker) { //FIXME make the next line real and uncomment this block // if ((ability to damage a teammate == OFF) && (targ's team == // attacker's team)) return false; } /* * ============ T_RadiusDamage ============ */ static void T_RadiusDamage(edict_t inflictor, edict_t attacker, float damage, edict_t ignore, float radius, int mod) { float points; EdictIterator edictit = null; float[] v = { 0, 0, 0 }; float[] dir = { 0, 0, 0 }; while ((edictit = GameBase.findradius(edictit, inflictor.s.origin, radius)) != null) { edict_t ent = edictit.o; if (ent == ignore) continue; if (ent.takedamage == 0) continue; Math3D.VectorAdd(ent.mins, ent.maxs, v); Math3D.VectorMA(ent.s.origin, 0.5f, v, v); Math3D.VectorSubtract(inflictor.s.origin, v, v); points = damage - 0.5f * Math3D.VectorLength(v); if (ent == attacker) points = points * 0.5f; if (points > 0) { if (CanDamage(ent, inflictor)) { Math3D.VectorSubtract(ent.s.origin, inflictor.s.origin, dir); T_Damage(ent, inflictor, attacker, dir, inflictor.s.origin, Globals.vec3_origin, (int) points, (int) points, Defines.DAMAGE_RADIUS, mod); } } } } public static void T_Damage(edict_t targ, edict_t inflictor, edict_t attacker, float[] dir, float[] point, float[] normal, int damage, int knockback, int dflags, int mod) { gclient_t client; int take; int save; int asave; int psave; int te_sparks; if (targ.takedamage == 0) return; // friendly fire avoidance // if enabled you can't hurt teammates (but you can hurt yourself) // knockback still occurs if ((targ != attacker) && ((GameBase.deathmatch.value != 0 && 0 != ((int) (GameBase.dmflags.value) & (Defines.DF_MODELTEAMS | Defines.DF_SKINTEAMS))) || GameBase.coop.value != 0)) { if (GameUtil.OnSameTeam(targ, attacker)) { if (((int) (GameBase.dmflags.value) & Defines.DF_NO_FRIENDLY_FIRE) != 0) damage = 0; else mod |= Defines.MOD_FRIENDLY_FIRE; } } GameBase.meansOfDeath = mod; // easy mode takes half damage if (GameBase.skill.value == 0 && GameBase.deathmatch.value == 0 && targ.client != null) { damage *= 0.5; if (damage == 0) damage = 1; } client = targ.client; if ((dflags & Defines.DAMAGE_BULLET) != 0) te_sparks = Defines.TE_BULLET_SPARKS; else te_sparks = Defines.TE_SPARKS; Math3D.VectorNormalize(dir); // bonus damage for suprising a monster if (0 == (dflags & Defines.DAMAGE_RADIUS) && (targ.svflags & Defines.SVF_MONSTER) != 0 && (attacker.client != null) && (targ.enemy == null) && (targ.health > 0)) damage *= 2; if ((targ.flags & Defines.FL_NO_KNOCKBACK) != 0) knockback = 0; // figure momentum add if (0 == (dflags & Defines.DAMAGE_NO_KNOCKBACK)) { if ((knockback != 0) && (targ.movetype != Defines.MOVETYPE_NONE) && (targ.movetype != Defines.MOVETYPE_BOUNCE) && (targ.movetype != Defines.MOVETYPE_PUSH) && (targ.movetype != Defines.MOVETYPE_STOP)) { float[] kvel = { 0, 0, 0 }; float mass; if (targ.mass < 50) mass = 50; else mass = targ.mass; if (targ.client != null && attacker == targ) Math3D.VectorScale(dir, 1600.0f * (float) knockback / mass, kvel); // the rocket jump hack... else Math3D.VectorScale(dir, 500.0f * (float) knockback / mass, kvel); Math3D.VectorAdd(targ.velocity, kvel, targ.velocity); } } take = damage; save = 0; // check for godmode if ((targ.flags & Defines.FL_GODMODE) != 0 && 0 == (dflags & Defines.DAMAGE_NO_PROTECTION)) { take = 0; save = damage; SpawnDamage(te_sparks, point, normal, save); } // check for invincibility if ((client != null && client.invincible_framenum > GameBase.level.framenum) && 0 == (dflags & Defines.DAMAGE_NO_PROTECTION)) { if (targ.pain_debounce_time < GameBase.level.time) { GameBase.gi.sound(targ, Defines.CHAN_ITEM, GameBase.gi .soundindex("items/protect4.wav"), 1, Defines.ATTN_NORM, 0); targ.pain_debounce_time = GameBase.level.time + 2; } take = 0; save = damage; } psave = CheckPowerArmor(targ, point, normal, take, dflags); take -= psave; asave = CheckArmor(targ, point, normal, take, te_sparks, dflags); take -= asave; // treat cheat/powerup savings the same as armor asave += save; // team damage avoidance if (0 == (dflags & Defines.DAMAGE_NO_PROTECTION) && CheckTeamDamage(targ, attacker)) return; // do the damage if (take != 0) { if (0 != (targ.svflags & Defines.SVF_MONSTER) || (client != null)) SpawnDamage(Defines.TE_BLOOD, point, normal, take); else SpawnDamage(te_sparks, point, normal, take); targ.health = targ.health - take; if (targ.health <= 0) { if ((targ.svflags & Defines.SVF_MONSTER) != 0 || (client != null)) targ.flags |= Defines.FL_NO_KNOCKBACK; Killed(targ, inflictor, attacker, take, point); return; } } if ((targ.svflags & Defines.SVF_MONSTER) != 0) { M_ReactToDamage(targ, attacker); if (0 == (targ.monsterinfo.aiflags & Defines.AI_DUCKED) && (take != 0)) { targ.pain.pain(targ, attacker, knockback, take); // nightmare mode monsters don't go into pain frames often if (GameBase.skill.value == 3) targ.pain_debounce_time = GameBase.level.time + 5; } } else if (client != null) { if (((targ.flags & Defines.FL_GODMODE) == 0) && (take != 0)) targ.pain.pain(targ, attacker, knockback, take); } else if (take != 0) { if (targ.pain != null) targ.pain.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 if (client != null) { client.damage_parmor += psave; client.damage_armor += asave; client.damage_blood += take; client.damage_knockback += knockback; Math3D.VectorCopy(point, client.damage_from); } } } --- NEW FILE: GameItems.java --- /* 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. */ [...2016 lines suppressed...] } if (0 == (ent.spawnflags & Defines.ITEM_TARGETS_USED)) { GameUtil.G_UseTargets(ent, other); ent.spawnflags |= Defines.ITEM_TARGETS_USED; } if (!taken) return; if (!((GameBase.coop.value != 0) && (ent.item.flags & Defines.IT_STAY_COOP) != 0) || 0 != (ent.spawnflags & (Defines.DROPPED_ITEM | Defines.DROPPED_PLAYER_ITEM))) { if ((ent.flags & Defines.FL_RESPAWN) != 0) ent.flags &= ~Defines.FL_RESPAWN; else GameUtil.G_FreeEdict(ent); } } } Index: PlayerClient.java =================================================================== RCS file: /cvsroot/jake2/jake2/src/jake2/game/PlayerClient.java,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** PlayerClient.java 19 Feb 2005 21:20:10 -0000 1.9 --- PlayerClient.java 16 Nov 2005 22:24:52 -0000 1.10 *************** *** 20,27 **** --- 20,31 ---- // Created on 28.12.2003 by RST. + // $Id$ + package jake2.game; import jake2.Defines; + import jake2.game.monsters.M_Player; + import jake2.game.pmove_t.TraceAdapter; import jake2.util.Lib; import jake2.util.Math3D; *************** *** 29,32 **** --- 33,249 ---- public class PlayerClient { + public static int player_die_i = 0; + /* + * ================== + * player_die + * ================== + */ + static EntDieAdapter player_die = new EntDieAdapter() { + public void die(edict_t self, edict_t inflictor, edict_t attacker, + int damage, float[] point) { + int n; + + Math3D.VectorClear(self.avelocity); + + self.takedamage = Defines.DAMAGE_YES; + self.movetype = Defines.MOVETYPE_TOSS; + + self.s.modelindex2 = 0; // remove linked weapon model + + self.s.angles[0] = 0; + self.s.angles[2] = 0; + + self.s.sound = 0; + self.client.weapon_sound = 0; + + self.maxs[2] = -8; + + // self.solid = SOLID_NOT; + self.svflags |= Defines.SVF_DEADMONSTER; + + if (self.deadflag == 0) { + self.client.respawn_time = GameBase.level.time + 1.0f; + PlayerClient.LookAtKiller(self, inflictor, attacker); + self.client.ps.pmove.pm_type = Defines.PM_DEAD; + ClientObituary(self, inflictor, attacker); + PlayerClient.TossClientWeapon(self); + if (GameBase.deathmatch.value != 0) + Cmd.Help_f(self); // show scores + + // clear inventory + // this is kind of ugly, but it's how we want to handle keys in + // coop + for (n = 0; n < GameBase.game.num_items; n++) { + if (GameBase.coop.value != 0 + && (GameItems.itemlist[n].flags & Defines.IT_KEY) != 0) + self.client.resp.coop_respawn.inventory[n] = self.client.pers.inventory[n]; + self.client.pers.inventory[n] = 0; + } + } + + // remove powerups + self.client.quad_framenum = 0; + self.client.invincible_framenum = 0; + self.client.breather_framenum = 0; + self.client.enviro_framenum = 0; + self.flags &= ~Defines.FL_POWER_ARMOR; + + if (self.health < -40) { // gib + GameBase.gi + .sound(self, Defines.CHAN_BODY, GameBase.gi + .soundindex("misc/udeath.wav"), 1, + Defines.ATTN_NORM, 0); + for (n = 0; n < 4; n++) + GameMisc.ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", + damage, Defines.GIB_ORGANIC); + GameMisc.ThrowClientHead(self, damage); + + self.takedamage = Defines.DAMAGE_NO; + } else { // normal death + if (self.deadflag == 0) { + + player_die_i = (player_die_i + 1) % 3; + // start a death animation + self.client.anim_priority = Defines.ANIM_DEATH; + if ((self.client.ps.pmove.pm_flags & pmove_t.PMF_DUCKED) != 0) { + self.s.frame = M_Player.FRAME_crdeath1 - 1; + self.client.anim_end = M_Player.FRAME_crdeath5; + } else + switch (player_die_i) { + case 0: + self.s.frame = M_Player.FRAME_death101 - 1; + self.client.anim_end = M_Player.FRAME_death106; + break; + case 1: + self.s.frame = M_Player.FRAME_death201 - 1; + self.client.anim_end = M_Player.FRAME_death206; + break; + case 2: + self.s.frame = M_Player.FRAME_death301 - 1; + self.client.anim_end = M_Player.FRAME_death308; + break; + } + + GameBase.gi.sound(self, Defines.CHAN_VOICE, GameBase.gi + .soundindex("*death" + ((Lib.rand() % 4) + 1) + + ".wav"), 1, Defines.ATTN_NORM, 0); + } + } + + self.deadflag = Defines.DEAD_DEAD; + + GameBase.gi.linkentity(self); + } + }; + static EntThinkAdapter SP_FixCoopSpots = new EntThinkAdapter() { + public boolean think(edict_t self) { + + edict_t spot; + float[] d = { 0, 0, 0 }; + + spot = null; + EdictIterator es = null; + + while (true) { + es = GameBase.G_Find(es, GameBase.findByClass, + "info_player_start"); + + if (es == null) + return true; + + spot = es.o; + + if (spot.targetname == null) + continue; + Math3D.VectorSubtract(self.s.origin, spot.s.origin, d); + if (Math3D.VectorLength(d) < 384) { + if ((self.targetname == null) + || Lib.Q_stricmp(self.targetname, spot.targetname) != 0) { + // gi.dprintf("FixCoopSpots changed %s at %s targetname + // from %s to %s\n", self.classname, + // vtos(self.s.origin), self.targetname, + // spot.targetname); + self.targetname = spot.targetname; + } + return true; + } + } + } + }; + static EntThinkAdapter SP_CreateCoopSpots = new EntThinkAdapter() { + public boolean think(edict_t self) { + + edict_t spot; + + if (Lib.Q_stricmp(GameBase.level.mapname, "security") == 0) { + spot = GameUtil.G_Spawn(); + spot.classname = "info_player_coop"; + spot.s.origin[0] = 188 - 64; + spot.s.origin[1] = -164; + spot.s.origin[2] = 80; + spot.targetname = "jail3"; + spot.s.angles[1] = 90; + + spot = GameUtil.G_Spawn(); + spot.classname = "info_player_coop"; + spot.s.origin[0] = 188 + 64; + spot.s.origin[1] = -164; + spot.s.origin[2] = 80; + spot.targetname = "jail3"; + spot.s.angles[1] = 90; + + spot = GameUtil.G_Spawn(); + spot.classname = "info_player_coop"; + spot.s.origin[0] = 188 + 128; + spot.s.origin[1] = -164; + spot.s.origin[2] = 80; + spot.targetname = "jail3"; + spot.s.angles[1] = 90; + } + return true; + } + }; + // player pain is handled at the end of the frame in P_DamageFeedback + static EntPainAdapter player_pain = new EntPainAdapter() { + public void pain(edict_t self, edict_t other, float kick, int damage) { + } + }; + static EntDieAdapter body_die = new EntDieAdapter() { + public void die(edict_t self, edict_t inflictor, edict_t attacker, + int damage, float[] point) { + + int n; + + if (self.health < -40) { + GameBase.gi + .sound(self, Defines.CHAN_BODY, GameBase.gi + .soundindex("misc/udeath.wav"), 1, + Defines.ATTN_NORM, 0); + for (n = 0; n < 4; n++) + GameMisc.ThrowGib(self, + "models/objects/gibs/sm_meat/tris.md2", damage, + Defines.GIB_ORGANIC); + self.s.origin[2] -= 48; + GameMisc.ThrowClientHead(self, damage); + self.takedamage = Defines.DAMAGE_NO; + } + } + }; + static edict_t pm_passent; + // pmove doesn't need to know about passent and contentmask + public static pmove_t.TraceAdapter PM_trace = new pmove_t.TraceAdapter() { + + public trace_t trace(float[] start, float[] mins, float[] maxs, + float[] end) { + if (pm_passent.health > 0) + return GameBase.gi.trace(start, mins, maxs, end, pm_passent, + Defines.MASK_PLAYERSOLID); + else + return GameBase.gi.trace(start, mins, maxs, end, pm_passent, + Defines.MASK_DEADSOLID); + } + + }; + /* * QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 32) The normal *************** *** 38,42 **** if (Lib.Q_stricmp(GameBase.level.mapname, "security") == 0) { // invoke one of our gross, ugly, disgusting hacks ! self.think = PlayerClientAdapters.SP_CreateCoopSpots; self.nextthink = GameBase.level.time + Defines.FRAMETIME; } --- 255,259 ---- if (Lib.Q_stricmp(GameBase.level.mapname, "security") == 0) { // invoke one of our gross, ugly, disgusting hacks ! self.think = PlayerClient.SP_CreateCoopSpots; self.nextthink = GameBase.level.time + Defines.FRAMETIME; } *************** *** 81,85 **** || (Lib.Q_stricmp(GameBase.level.mapname, "strike") == 0)) { // invoke one of our gross, ugly, disgusting hacks ! self.think = PlayerClientAdapters.SP_FixCoopSpots; self.nextthink = GameBase.level.time + Defines.FRAMETIME; } --- 298,302 ---- || (Lib.Q_stricmp(GameBase.level.mapname, "strike") == 0)) { // invoke one of our gross, ugly, disgusting hacks ! self.think = PlayerClient.SP_FixCoopSpots; self.nextthink = GameBase.level.time + Defines.FRAMETIME; } *************** *** 156,162 **** case Defines.MOD_HG_SPLASH: case Defines.MOD_G_SPLASH: ! if (GameAI.IsNeutral(self)) message = "tripped on its own grenade"; ! else if (GameAI.IsFemale(self)) message = "tripped on her own grenade"; else --- 373,379 ---- case Defines.MOD_HG_SPLASH: case Defines.MOD_G_SPLASH: ! if (PlayerClient.IsNeutral(self)) message = "tripped on its own grenade"; ! else if (PlayerClient.IsFemale(self)) message = "tripped on her own grenade"; else *************** *** 164,170 **** break; case Defines.MOD_R_SPLASH: ! if (GameAI.IsNeutral(self)) message = "blew itself up"; ! else if (GameAI.IsFemale(self)) message = "blew herself up"; else --- 381,387 ---- break; case Defines.MOD_R_SPLASH: ! if (PlayerClient.IsNeutral(self)) message = "blew itself up"; ! else if (PlayerClient.IsFemale(self)) message = "blew herself up"; else *************** *** 175,181 **** break; default: ! if (GameAI.IsNeutral(self)) message = "killed itself"; ! else if (GameAI.IsFemale(self)) message = "killed herself"; else --- 392,398 ---- break; default: ! if (PlayerClient.IsNeutral(self)) message = "killed itself"; ! else if (PlayerClient.IsFemale(self)) message = "killed herself"; else *************** *** 287,300 **** } - /* - * ================== player_die ================== - */ - //======================================================================= /* ! * ============== InitClientPersistant * * This is only called when the game first initializes in single player, but ! * is called after each death and level change in deathmatch ============== */ public static void InitClientPersistant(gclient_t client) { --- 504,515 ---- } //======================================================================= /* ! * ============== ! * InitClientPersistant * * This is only called when the game first initializes in single player, but ! * is called after each death and level change in deathmatch ! * ============== */ public static void InitClientPersistant(gclient_t client) { *************** *** 303,308 **** client.pers = new client_persistant_t(); ! item = GameUtil.FindItem("Blaster"); ! client.pers.selected_item = GameUtil.ITEM_INDEX(item); client.pers.inventory[client.pers.selected_item] = 1; --- 518,523 ---- client.pers = new client_persistant_t(); ! item = GameItems.FindItem("Blaster"); ! client.pers.selected_item = GameItems.ITEM_INDEX(item); client.pers.inventory[client.pers.selected_item] = 1; *************** *** 336,344 **** /* ! * ================== SaveClientData * * Some information that should be persistant, like health, is still stored * in the edict structure, so it needs to be mirrored out to the client ! * structure before all the edicts are wiped. ================== */ public static void SaveClientData() { --- 551,561 ---- /* ! * ================== ! * SaveClientData * * Some information that should be persistant, like health, is still stored * in the edict structure, so it needs to be mirrored out to the client ! * structure before all the edicts are wiped. ! * ================== */ public static void SaveClientData() { *************** *** 370,374 **** /* ! * ================ PlayersRangeFromSpot * * Returns the distance to the nearest player from the given spot --- 587,592 ---- /* ! * ================ ! * PlayersRangeFromSpot * * Returns the distance to the nearest player from the given spot *************** *** 404,408 **** /* ! * ================ SelectRandomDeathmatchSpawnPoint * * go to a random point, but NOT the two points closest to other players --- 622,627 ---- /* ! * ================ ! * SelectRandomDeathmatchSpawnPoint * * go to a random point, but NOT the two points closest to other players *************** *** 463,467 **** /* ! * ================ SelectFarthestDeathmatchSpawnPoint * * ================ --- 682,687 ---- /* ! * ================ ! * SelectFarthestDeathmatchSpawnPoint * * ================ *************** *** 553,559 **** /* ! * =========== SelectSpawnPoint * ! * Chooses a player start, deathmatch start, coop start, etc ============ */ public static void SelectSpawnPoint(edict_t ent, float[] origin, --- 773,781 ---- /* ! * =========== ! * SelectSpawnPoint * ! * Chooses a player start, deathmatch start, coop start, etc ! * ============ */ public static void SelectSpawnPoint(edict_t ent, float[] origin, *************** *** 651,655 **** body.movetype = ent.movetype; ! body.die = PlayerClientAdapters.body_die; body.takedamage = Defines.DAMAGE_YES; --- 873,877 ---- body.movetype = ent.movetype; ! body.die = PlayerClient.body_die; body.takedamage = Defines.DAMAGE_YES; *************** *** 851,856 **** ent.clipmask = Defines.MASK_PLAYERSOLID; ent.model = "players/male/tris.md2"; ! ent.pain = PlayerClientAdapters.player_pain; ! ent.die = GameAI.player_die; ent.waterlevel = 0; ent.watertype = 0; --- 1073,1078 ---- ent.clipmask = Defines.MASK_PLAYERSOLID; ent.model = "players/male/tris.md2"; ! ent.pain = PlayerClient.player_pain; ! ent.die = PlayerClient.player_die; ent.waterlevel = 0; ent.watertype = 0; *************** *** 931,942 **** // force the current weapon up client.newweapon = client.pers.weapon; ! GamePWeapon.ChangeWeapon(ent); } /* ! * ===================== ClientBeginDeathmatch * * A client has just connected to the server in deathmatch mode, so clear ! * everything out before starting them. ===================== */ public static void ClientBeginDeathmatch(edict_t ent) { --- 1153,1166 ---- // force the current weapon up client.newweapon = client.pers.weapon; ! PlayerWeapon.ChangeWeapon(ent); } /* ! * ===================== ! * ClientBeginDeathmatch * * A client has just connected to the server in deathmatch mode, so clear ! * everything out before starting them. ! * ===================== */ public static void ClientBeginDeathmatch(edict_t ent) { *************** *** 967,974 **** /* ! * =========== ClientBegin * * called when a client has finished connecting, and is ready to be placed ! * into the game. This will happen every level load. ============ */ public static void ClientBegin(edict_t ent) { --- 1191,1200 ---- /* ! * =========== ! * ClientBegin * * called when a client has finished connecting, and is ready to be placed !... [truncated message content] |