diff options
Diffstat (limited to 'src/jake2/game/GameMisc.java')
-rw-r--r-- | src/jake2/game/GameMisc.java | 320 |
1 files changed, 290 insertions, 30 deletions
diff --git a/src/jake2/game/GameMisc.java b/src/jake2/game/GameMisc.java index dba1e26..acb996a 100644 --- a/src/jake2/game/GameMisc.java +++ b/src/jake2/game/GameMisc.java @@ -19,7 +19,7 @@ */ // Created on 27.12.2003 by RST. -// $Id: GameMisc.java,v 1.4 2004-09-22 19:22:03 salomo Exp $ +// $Id: GameMisc.java,v 1.5 2005-11-16 22:24:53 salomo Exp $ package jake2.game; import java.util.Calendar; @@ -508,7 +508,7 @@ public class GameMisc { ent.solid = Defines.SOLID_NOT; ent.s.effects |= Defines.EF_GIB; ent.takedamage = Defines.DAMAGE_YES; - ent.die = GameAI.gib_die; + ent.die = gib_die; ent.movetype = Defines.MOVETYPE_TOSS; ent.svflags |= Defines.SVF_MONSTER; ent.deadflag = Defines.DEAD_DEAD; @@ -529,7 +529,7 @@ public class GameMisc { ent.solid = Defines.SOLID_NOT; ent.s.effects |= Defines.EF_GIB; ent.takedamage = Defines.DAMAGE_YES; - ent.die = GameAI.gib_die; + ent.die = gib_die; ent.movetype = Defines.MOVETYPE_TOSS; ent.svflags |= Defines.SVF_MONSTER; ent.deadflag = Defines.DEAD_DEAD; @@ -550,7 +550,7 @@ public class GameMisc { ent.solid = Defines.SOLID_NOT; ent.s.effects |= Defines.EF_GIB; ent.takedamage = Defines.DAMAGE_YES; - ent.die = GameAI.gib_die; + ent.die = gib_die; ent.movetype = Defines.MOVETYPE_TOSS; ent.svflags |= Defines.SVF_MONSTER; ent.deadflag = Defines.DEAD_DEAD; @@ -701,6 +701,207 @@ public class GameMisc { * editor convenience. */ + public static void VelocityForDamage(int damage, float[] v) { + v[0] = 100.0f * Lib.crandom(); + v[1] = 100.0f * Lib.crandom(); + v[2] = 200.0f + 100.0f * Lib.random(); + + if (damage < 50) + Math3D.VectorScale(v, 0.7f, v); + else + Math3D.VectorScale(v, 1.2f, v); + } + + public static void BecomeExplosion1(edict_t self) { + GameBase.gi.WriteByte(Defines.svc_temp_entity); + GameBase.gi.WriteByte(Defines.TE_EXPLOSION1); + GameBase.gi.WritePosition(self.s.origin); + GameBase.gi.multicast(self.s.origin, Defines.MULTICAST_PVS); + + GameUtil.G_FreeEdict(self); + } + + public static void BecomeExplosion2(edict_t self) { + GameBase.gi.WriteByte(Defines.svc_temp_entity); + GameBase.gi.WriteByte(Defines.TE_EXPLOSION2); + GameBase.gi.WritePosition(self.s.origin); + GameBase.gi.multicast(self.s.origin, Defines.MULTICAST_PVS); + + GameUtil.G_FreeEdict(self); + } + + public static void ThrowGib(edict_t self, String gibname, int damage, + int type) { + edict_t gib; + + float[] vd = { 0, 0, 0 }; + float[] origin = { 0, 0, 0 }; + float[] size = { 0, 0, 0 }; + float vscale; + + gib = GameUtil.G_Spawn(); + + Math3D.VectorScale(self.size, 0.5f, size); + Math3D.VectorAdd(self.absmin, size, origin); + gib.s.origin[0] = origin[0] + Lib.crandom() * size[0]; + gib.s.origin[1] = origin[1] + Lib.crandom() * size[1]; + gib.s.origin[2] = origin[2] + Lib.crandom() * size[2]; + + GameBase.gi.setmodel(gib, gibname); + gib.solid = Defines.SOLID_NOT; + gib.s.effects |= Defines.EF_GIB; + gib.flags |= Defines.FL_NO_KNOCKBACK; + gib.takedamage = Defines.DAMAGE_YES; + gib.die = gib_die; + + if (type == Defines.GIB_ORGANIC) { + gib.movetype = Defines.MOVETYPE_TOSS; + gib.touch = gib_touch; + vscale = 0.5f; + } else { + gib.movetype = Defines.MOVETYPE_BOUNCE; + vscale = 1.0f; + } + + VelocityForDamage(damage, vd); + Math3D.VectorMA(self.velocity, vscale, vd, gib.velocity); + ClipGibVelocity(gib); + gib.avelocity[0] = Lib.random() * 600; + gib.avelocity[1] = Lib.random() * 600; + gib.avelocity[2] = Lib.random() * 600; + + gib.think = GameUtil.G_FreeEdictA; + gib.nextthink = GameBase.level.time + 10 + Lib.random() * 10; + + GameBase.gi.linkentity(gib); + } + + public static void ThrowHead(edict_t self, String gibname, int damage, + int type) { + float vd[] = { 0, 0, 0 }; + + float vscale; + + self.s.skinnum = 0; + self.s.frame = 0; + Math3D.VectorClear(self.mins); + Math3D.VectorClear(self.maxs); + + self.s.modelindex2 = 0; + GameBase.gi.setmodel(self, gibname); + self.solid = Defines.SOLID_NOT; + self.s.effects |= Defines.EF_GIB; + self.s.effects &= ~Defines.EF_FLIES; + self.s.sound = 0; + self.flags |= Defines.FL_NO_KNOCKBACK; + self.svflags &= ~Defines.SVF_MONSTER; + self.takedamage = Defines.DAMAGE_YES; + self.die = gib_die; + + if (type == Defines.GIB_ORGANIC) { + self.movetype = Defines.MOVETYPE_TOSS; + self.touch = gib_touch; + vscale = 0.5f; + } else { + self.movetype = Defines.MOVETYPE_BOUNCE; + vscale = 1.0f; + } + + VelocityForDamage(damage, vd); + Math3D.VectorMA(self.velocity, vscale, vd, self.velocity); + ClipGibVelocity(self); + + self.avelocity[Defines.YAW] = Lib.crandom() * 600f; + + self.think = GameUtil.G_FreeEdictA; + self.nextthink = GameBase.level.time + 10 + Lib.random() * 10; + + GameBase.gi.linkentity(self); + } + + public static void ThrowClientHead(edict_t self, int damage) { + float vd[] = { 0, 0, 0 }; + String gibname; + + if ((Lib.rand() & 1) != 0) { + gibname = "models/objects/gibs/head2/tris.md2"; + self.s.skinnum = 1; // second skin is player + } else { + gibname = "models/objects/gibs/skull/tris.md2"; + self.s.skinnum = 0; + } + + self.s.origin[2] += 32; + self.s.frame = 0; + GameBase.gi.setmodel(self, gibname); + Math3D.VectorSet(self.mins, -16, -16, 0); + Math3D.VectorSet(self.maxs, 16, 16, 16); + + self.takedamage = Defines.DAMAGE_NO; + self.solid = Defines.SOLID_NOT; + self.s.effects = Defines.EF_GIB; + self.s.sound = 0; + self.flags |= Defines.FL_NO_KNOCKBACK; + + self.movetype = Defines.MOVETYPE_BOUNCE; + VelocityForDamage(damage, vd); + Math3D.VectorAdd(self.velocity, vd, self.velocity); + + if (self.client != null) + // bodies in the queue don't have a client anymore + { + self.client.anim_priority = Defines.ANIM_DEATH; + self.client.anim_end = self.s.frame; + } else { + self.think = null; + self.nextthink = 0; + } + + GameBase.gi.linkentity(self); + } + + public static void ThrowDebris(edict_t self, String modelname, float speed, + float[] origin) { + edict_t chunk; + float[] v = { 0, 0, 0 }; + + chunk = GameUtil.G_Spawn(); + Math3D.VectorCopy(origin, chunk.s.origin); + GameBase.gi.setmodel(chunk, modelname); + v[0] = 100 * Lib.crandom(); + v[1] = 100 * Lib.crandom(); + v[2] = 100 + 100 * Lib.crandom(); + Math3D.VectorMA(self.velocity, speed, v, chunk.velocity); + chunk.movetype = Defines.MOVETYPE_BOUNCE; + chunk.solid = Defines.SOLID_NOT; + chunk.avelocity[0] = Lib.random() * 600; + chunk.avelocity[1] = Lib.random() * 600; + chunk.avelocity[2] = Lib.random() * 600; + chunk.think = GameUtil.G_FreeEdictA; + chunk.nextthink = GameBase.level.time + 5 + Lib.random() * 5; + chunk.s.frame = 0; + chunk.flags = 0; + chunk.classname = "debris"; + chunk.takedamage = Defines.DAMAGE_YES; + chunk.die = debris_die; + GameBase.gi.linkentity(chunk); + } + + public static 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 + else if (ent.velocity[2] > 500) + ent.velocity[2] = 500; + } + //===================================================== public static EntUseAdapter Use_Areaportal = new EntUseAdapter() { public void use(edict_t ent, edict_t other, edict_t activator) { @@ -923,7 +1124,7 @@ public class GameMisc { return; if (other.takedamage == Defines.DAMAGE_NO) return; - GameUtil.T_Damage(other, self, self, Globals.vec3_origin, + GameCombat.T_Damage(other, self, self, Globals.vec3_origin, self.s.origin, Globals.vec3_origin, self.dmg, 1, 0, Defines.MOD_CRUSH); } @@ -979,7 +1180,7 @@ public class GameMisc { self.takedamage = Defines.DAMAGE_NO; if (self.dmg != 0) - GameUtil.T_RadiusDamage(self, attacker, self.dmg, null, + GameCombat.T_RadiusDamage(self, attacker, self.dmg, null, self.dmg + 40, Defines.MOD_EXPLOSIVE); Math3D.VectorSubtract(self.s.origin, inflictor.s.origin, @@ -1003,7 +1204,7 @@ public class GameMisc { chunkorigin[0] = origin[0] + Lib.crandom() * size[0]; chunkorigin[1] = origin[1] + Lib.crandom() * size[1]; chunkorigin[2] = origin[2] + Lib.crandom() * size[2]; - GameAI.ThrowDebris(self, "models/objects/debris1/tris.md2", + ThrowDebris(self, "models/objects/debris1/tris.md2", 1, chunkorigin); } } @@ -1016,14 +1217,14 @@ public class GameMisc { chunkorigin[0] = origin[0] + Lib.crandom() * size[0]; chunkorigin[1] = origin[1] + Lib.crandom() * size[1]; chunkorigin[2] = origin[2] + Lib.crandom() * size[2]; - GameAI.ThrowDebris(self, "models/objects/debris2/tris.md2", 2, + ThrowDebris(self, "models/objects/debris2/tris.md2", 2, chunkorigin); } GameUtil.G_UseTargets(self, attacker); if (self.dmg != 0) - GameAI.BecomeExplosion1(self); + BecomeExplosion1(self); else GameUtil.G_FreeEdict(self); } @@ -1076,7 +1277,7 @@ public class GameMisc { float spd; float[] save = { 0, 0, 0 }; - GameUtil.T_RadiusDamage(self, self.activator, self.dmg, null, + GameCombat.T_RadiusDamage(self, self.activator, self.dmg, null, self.dmg + 40, Defines.MOD_BARREL); Math3D.VectorCopy(self.s.origin, save); @@ -1087,31 +1288,31 @@ public class GameMisc { org[0] = self.s.origin[0] + Lib.crandom() * self.size[0]; org[1] = self.s.origin[1] + Lib.crandom() * self.size[1]; org[2] = self.s.origin[2] + Lib.crandom() * self.size[2]; - GameAI.ThrowDebris(self, "models/objects/debris1/tris.md2", spd, + ThrowDebris(self, "models/objects/debris1/tris.md2", spd, org); org[0] = self.s.origin[0] + Lib.crandom() * self.size[0]; org[1] = self.s.origin[1] + Lib.crandom() * self.size[1]; org[2] = self.s.origin[2] + Lib.crandom() * self.size[2]; - GameAI.ThrowDebris(self, "models/objects/debris1/tris.md2", spd, + ThrowDebris(self, "models/objects/debris1/tris.md2", spd, org); // bottom corners spd = 1.75f * (float) self.dmg / 200.0f; Math3D.VectorCopy(self.absmin, org); - GameAI.ThrowDebris(self, "models/objects/debris3/tris.md2", spd, + ThrowDebris(self, "models/objects/debris3/tris.md2", spd, org); Math3D.VectorCopy(self.absmin, org); org[0] += self.size[0]; - GameAI.ThrowDebris(self, "models/objects/debris3/tris.md2", spd, + ThrowDebris(self, "models/objects/debris3/tris.md2", spd, org); Math3D.VectorCopy(self.absmin, org); org[1] += self.size[1]; - GameAI.ThrowDebris(self, "models/objects/debris3/tris.md2", spd, + ThrowDebris(self, "models/objects/debris3/tris.md2", spd, org); Math3D.VectorCopy(self.absmin, org); org[0] += self.size[0]; org[1] += self.size[1]; - GameAI.ThrowDebris(self, "models/objects/debris3/tris.md2", spd, + ThrowDebris(self, "models/objects/debris3/tris.md2", spd, org); // a bunch of little chunks @@ -1119,49 +1320,49 @@ public class GameMisc { org[0] = self.s.origin[0] + Lib.crandom() * self.size[0]; org[1] = self.s.origin[1] + Lib.crandom() * self.size[1]; org[2] = self.s.origin[2] + Lib.crandom() * self.size[2]; - GameAI.ThrowDebris(self, "models/objects/debris2/tris.md2", spd, + ThrowDebris(self, "models/objects/debris2/tris.md2", spd, org); org[0] = self.s.origin[0] + Lib.crandom() * self.size[0]; org[1] = self.s.origin[1] + Lib.crandom() * self.size[1]; org[2] = self.s.origin[2] + Lib.crandom() * self.size[2]; - GameAI.ThrowDebris(self, "models/objects/debris2/tris.md2", spd, + ThrowDebris(self, "models/objects/debris2/tris.md2", spd, org); org[0] = self.s.origin[0] + Lib.crandom() * self.size[0]; org[1] = self.s.origin[1] + Lib.crandom() * self.size[1]; org[2] = self.s.origin[2] + Lib.crandom() * self.size[2]; - GameAI.ThrowDebris(self, "models/objects/debris2/tris.md2", spd, + ThrowDebris(self, "models/objects/debris2/tris.md2", spd, org); org[0] = self.s.origin[0] + Lib.crandom() * self.size[0]; org[1] = self.s.origin[1] + Lib.crandom() * self.size[1]; org[2] = self.s.origin[2] + Lib.crandom() * self.size[2]; - GameAI.ThrowDebris(self, "models/objects/debris2/tris.md2", spd, + ThrowDebris(self, "models/objects/debris2/tris.md2", spd, org); org[0] = self.s.origin[0] + Lib.crandom() * self.size[0]; org[1] = self.s.origin[1] + Lib.crandom() * self.size[1]; org[2] = self.s.origin[2] + Lib.crandom() * self.size[2]; - GameAI.ThrowDebris(self, "models/objects/debris2/tris.md2", spd, + ThrowDebris(self, "models/objects/debris2/tris.md2", spd, org); org[0] = self.s.origin[0] + Lib.crandom() * self.size[0]; org[1] = self.s.origin[1] + Lib.crandom() * self.size[1]; org[2] = self.s.origin[2] + Lib.crandom() * self.size[2]; - GameAI.ThrowDebris(self, "models/objects/debris2/tris.md2", spd, + ThrowDebris(self, "models/objects/debris2/tris.md2", spd, org); org[0] = self.s.origin[0] + Lib.crandom() * self.size[0]; org[1] = self.s.origin[1] + Lib.crandom() * self.size[1]; org[2] = self.s.origin[2] + Lib.crandom() * self.size[2]; - GameAI.ThrowDebris(self, "models/objects/debris2/tris.md2", spd, + ThrowDebris(self, "models/objects/debris2/tris.md2", spd, org); org[0] = self.s.origin[0] + Lib.crandom() * self.size[0]; org[1] = self.s.origin[1] + Lib.crandom() * self.size[1]; org[2] = self.s.origin[2] + Lib.crandom() * self.size[2]; - GameAI.ThrowDebris(self, "models/objects/debris2/tris.md2", spd, + ThrowDebris(self, "models/objects/debris2/tris.md2", spd, org); Math3D.VectorCopy(save, self.s.origin); if (self.groundentity != null) - GameAI.BecomeExplosion2(self); + BecomeExplosion2(self); else - GameAI.BecomeExplosion1(self); + BecomeExplosion1(self); return true; } @@ -1324,9 +1525,9 @@ public class GameMisc { GameBase.gi.sound(self, Defines.CHAN_BODY, GameBase.gi .soundindex("misc/udeath.wav"), 1, Defines.ATTN_NORM, 0); for (n = 0; n < 4; n++) - GameAI.ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", + ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, Defines.GIB_ORGANIC); - GameAI.ThrowHead(self, "models/objects/gibs/head2/tris.md2", + ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, Defines.GIB_ORGANIC); } }; @@ -1359,9 +1560,9 @@ public class GameMisc { GameUtil.G_UseTargets(self, self.activator); self.s.origin[2] = self.absmin[2] + 1; - GameUtil.T_RadiusDamage(self, self, self.dmg, null, self.dmg + 40, + GameCombat.T_RadiusDamage(self, self, self.dmg, null, self.dmg + 40, Defines.MOD_BOMB); - GameAI.BecomeExplosion2(self); + BecomeExplosion2(self); } }; @@ -1650,4 +1851,63 @@ public class GameMisc { return true; } }; + + public static EntThinkAdapter gib_think = new EntThinkAdapter() { + public boolean think(edict_t self) { + self.s.frame++; + self.nextthink = GameBase.level.time + Defines.FRAMETIME; + + if (self.s.frame == 10) { + self.think = GameUtil.G_FreeEdictA; + self.nextthink = GameBase.level.time + 8 + + Globals.rnd.nextFloat() * 10; + } + return true; + } + }; + + public static EntTouchAdapter gib_touch = new EntTouchAdapter() { + public void touch(edict_t self, edict_t other, cplane_t plane, + csurface_t surf) { + float[] normal_angles = { 0, 0, 0 }, right = { 0, 0, 0 }; + + if (null == self.groundentity) + return; + + self.touch = null; + + if (plane != null) { + GameBase.gi.sound(self, Defines.CHAN_VOICE, GameBase.gi + .soundindex("misc/fhit3.wav"), 1, Defines.ATTN_NORM, 0); + + Math3D.vectoangles(plane.normal, normal_angles); + Math3D.AngleVectors(normal_angles, null, right, null); + Math3D.vectoangles(right, self.s.angles); + + if (self.s.modelindex == GameBase.sm_meat_index) { + self.s.frame++; + self.think = gib_think; + self.nextthink = GameBase.level.time + Defines.FRAMETIME; + } + } + } + }; + + public static EntDieAdapter gib_die = new EntDieAdapter() { + public void die(edict_t self, edict_t inflictor, edict_t attacker, + int damage, float[] point) { + GameUtil.G_FreeEdict(self); + } + }; + + /* + * ================= debris ================= + */ + public static EntDieAdapter debris_die = new EntDieAdapter() { + + public void die(edict_t self, edict_t inflictor, edict_t attacker, + int damage, float[] point) { + GameUtil.G_FreeEdict(self); + } + }; }
\ No newline at end of file |