📄 gamemisc.java
字号:
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 String getID() { return "use_areaportal";} public void use(edict_t ent, edict_t other, edict_t activator) { ent.count ^= 1; // toggle state // gi.dprintf ("portalstate: %i = %i\n", ent.style, ent.count); GameBase.gi.SetAreaPortalState(ent.style, ent.count != 0); } }; /** * 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. */ static EntThinkAdapter SP_func_areaportal = new EntThinkAdapter() { public String getID() { return "sp_func_areaportal";} public boolean think(edict_t ent) { ent.use = Use_Areaportal; ent.count = 0; // always start closed; return true; } }; /** * 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 */ public static EntTouchAdapter path_corner_touch = new EntTouchAdapter() { public String getID() { return "path_corner_touch";} public void touch(edict_t self, edict_t other, cplane_t plane, csurface_t surf) { float[] v = { 0, 0, 0 }; edict_t next; if (other.movetarget != self) return; if (other.enemy != null) return; if (self.pathtarget != null) { String savetarget; savetarget = self.target; self.target = self.pathtarget; GameUtil.G_UseTargets(self, other); self.target = savetarget; } if (self.target != null) next = GameBase.G_PickTarget(self.target); else next = null; if ((next != null) && (next.spawnflags & 1) != 0) { Math3D.VectorCopy(next.s.origin, v); v[2] += next.mins[2]; v[2] -= other.mins[2]; Math3D.VectorCopy(v, other.s.origin); next = GameBase.G_PickTarget(next.target); other.s.event = Defines.EV_OTHER_TELEPORT; } other.goalentity = other.movetarget = next; if (self.wait != 0) { other.monsterinfo.pausetime = GameBase.level.time + self.wait; other.monsterinfo.stand.think(other); return; } if (other.movetarget == null) { other.monsterinfo.pausetime = GameBase.level.time + 100000000; other.monsterinfo.stand.think(other); } else { Math3D.VectorSubtract(other.goalentity.s.origin, other.s.origin, v); other.ideal_yaw = Math3D.vectoyaw(v); } } }; /* * 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. */ public static EntTouchAdapter point_combat_touch = new EntTouchAdapter() { public String getID() { return "point_combat_touch";} public void touch(edict_t self, edict_t other, cplane_t plane, csurface_t surf) { edict_t activator; if (other.movetarget != self) return; if (self.target != null) { other.target = self.target; other.goalentity = other.movetarget = GameBase .G_PickTarget(other.target); if (null == other.goalentity) { GameBase.gi.dprintf(self.classname + " at " + Lib.vtos(self.s.origin) + " target " + self.target + " does not exist\n"); other.movetarget = self; } self.target = null; } else if ((self.spawnflags & 1) != 0 && 0 == (other.flags & (Defines.FL_SWIM | Defines.FL_FLY))) { other.monsterinfo.pausetime = GameBase.level.time + 100000000; other.monsterinfo.aiflags |= Defines.AI_STAND_GROUND; other.monsterinfo.stand.think(other); } if (other.movetarget == self) { other.target = null; other.movetarget = null; other.goalentity = other.enemy; other.monsterinfo.aiflags &= ~Defines.AI_COMBAT_POINT; } if (self.pathtarget != null) { String savetarget; savetarget = self.target; self.target = self.pathtarget; if (other.enemy != null && other.enemy.client != null) activator = other.enemy; else if (other.oldenemy != null && other.oldenemy.client != null) activator = other.oldenemy; else if (other.activator != null && other.activator.client != null) activator = other.activator; else activator = other; GameUtil.G_UseTargets(self, activator); self.target = savetarget; } } }; /* * QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8) Just for the debugging * level. Don't use */ public static EntThinkAdapter TH_viewthing = new EntThinkAdapter() { public String getID() { return "th_viewthing";} public boolean think(edict_t ent) { ent.s.frame = (ent.s.frame + 1) % 7; ent.nextthink = GameBase.level.time + Defines.FRAMETIME; return true; } }; /* * 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) */ public static final int START_OFF = 1; public static EntUseAdapter light_use = new EntUseAdapter() { public String getID() { return "light_use";} public void use(edict_t self, edict_t other, edict_t activator) { if ((self.spawnflags & START_OFF) != 0) { GameBase.gi.configstring(Defines.CS_LIGHTS + self.style, "m"); self.spawnflags &= ~START_OFF; } else { GameBase.gi.configstring(Defines.CS_LIGHTS + self.style, "a"); self.spawnflags |= START_OFF; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -