aboutsummaryrefslogtreecommitdiffstats
path: root/src/jake2/game/GameMisc.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jake2/game/GameMisc.java')
-rw-r--r--src/jake2/game/GameMisc.java320
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