📄 gametrigger.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 27.12.2003 by RST.// $Id: GameTrigger.java,v 1.8 2006/01/21 21:53:32 salomo Exp $package jake2.game;import jake2.*;import jake2.client.*;import jake2.qcommon.*;import jake2.render.*;import jake2.server.*;import jake2.util.Lib;import jake2.util.Math3D;public class GameTrigger { public static void InitTrigger(edict_t self) { if (!Math3D.VectorEquals(self.s.angles, Globals.vec3_origin)) GameBase.G_SetMovedir(self.s.angles, self.movedir); self.solid = Defines.SOLID_TRIGGER; self.movetype = Defines.MOVETYPE_NONE; GameBase.gi.setmodel(self, self.model); self.svflags = Defines.SVF_NOCLIENT; } // 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 public static void multi_trigger(edict_t ent) { if (ent.nextthink != 0) return; // already been triggered GameUtil.G_UseTargets(ent, ent.activator); 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 // function // called while looping through area links... ent.touch = null; ent.nextthink = GameBase.level.time + Defines.FRAMETIME; ent.think = GameUtil.G_FreeEdictA; } } public static void SP_trigger_multiple(edict_t ent) { if (ent.sounds == 1) ent.noise_index = GameBase.gi.soundindex("misc/secret.wav"); else if (ent.sounds == 2) ent.noise_index = GameBase.gi.soundindex("misc/talk.wav"); else if (ent.sounds == 3) ent.noise_index = GameBase.gi.soundindex("misc/trigger1.wav"); if (ent.wait == 0) ent.wait = 0.2f; ent.touch = Touch_Multi; ent.movetype = Defines.MOVETYPE_NONE; ent.svflags |= Defines.SVF_NOCLIENT; if ((ent.spawnflags & 4) != 0) { ent.solid = Defines.SOLID_NOT; ent.use = trigger_enable; } else { ent.solid = Defines.SOLID_TRIGGER; ent.use = Use_Multi; } if (!Math3D.VectorEquals(ent.s.angles, Globals.vec3_origin)) GameBase.G_SetMovedir(ent.s.angles, ent.movedir); GameBase.gi.setmodel(ent, ent.model); GameBase.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". * * 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 */ public static 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 if ((ent.spawnflags & 1) != 0) { float[] v = { 0, 0, 0 }; Math3D.VectorMA(ent.mins, 0.5f, ent.size, v); ent.spawnflags &= ~1; ent.spawnflags |= 4; GameBase.gi.dprintf("fixed TRIGGERED flag on " + ent.classname + " at " + Lib.vtos(v) + "\n"); } ent.wait = -1; SP_trigger_multiple(ent); } public static void SP_trigger_relay(edict_t self) { self.use = trigger_relay_use; } public static void SP_trigger_key(edict_t self) { if (GameBase.st.item == null) { GameBase.gi.dprintf("no key item for trigger_key at " + Lib.vtos(self.s.origin) + "\n"); return; } self.item = GameItems.FindItemByClassname(GameBase.st.item); if (null == self.item) { GameBase.gi.dprintf("item " + GameBase.st.item + " not found for trigger_key at " + Lib.vtos(self.s.origin) + "\n"); return; } if (self.target == null) { GameBase.gi.dprintf(self.classname + " at " + Lib.vtos(self.s.origin) + " has no target\n"); return; } GameBase.gi.soundindex("misc/keytry.wav"); GameBase.gi.soundindex("misc/keyuse.wav"); self.use = trigger_key_use; } public static void SP_trigger_counter(edict_t self) { self.wait = -1; if (0 == self.count) self.count = 2; self.use = trigger_counter_use; } /* * ============================================================================== * * 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. */ public static void SP_trigger_always(edict_t ent) { // we must have some delay to make sure our use targets are present if (ent.delay < 0.2f) ent.delay = 0.2f; GameUtil.G_UseTargets(ent, ent); } /* * QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE Pushes the player "speed" * defaults to 1000 */ 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; GameBase.gi.linkentity(self); } public static void SP_trigger_hurt(edict_t self) { InitTrigger(self); self.noise_index = GameBase.gi.soundindex("world/electro.wav"); self.touch = hurt_touch; if (0 == self.dmg) self.dmg = 5; if ((self.spawnflags & 1) != 0) self.solid = Defines.SOLID_NOT; else self.solid = Defines.SOLID_TRIGGER; if ((self.spawnflags & 2) != 0) self.use = hurt_use; GameBase.gi.linkentity(self); } public static void SP_trigger_gravity(edict_t self) { if (GameBase.st.gravity == null) { GameBase.gi.dprintf("trigger_gravity without gravity set at " + Lib.vtos(self.s.origin) + "\n"); GameUtil.G_FreeEdict(self); return; } InitTrigger(self); self.gravity = Lib.atoi(GameBase.st.gravity); self.touch = trigger_gravity_touch; } public static void SP_trigger_monsterjump(edict_t self) { if (0 == self.speed) self.speed = 200; if (0 == GameBase.st.height) GameBase.st.height = 200; if (self.s.angles[Defines.YAW] == 0) self.s.angles[Defines.YAW] = 360; InitTrigger(self); self.touch = trigger_monsterjump_touch; self.movedir[2] = GameBase.st.height; } // the wait time has passed, so set back up for another activation public static EntThinkAdapter multi_wait = new EntThinkAdapter() { public String getID(){ return "multi_wait"; } public boolean think(edict_t ent) { ent.nextthink = 0; return true; } }; static EntUseAdapter Use_Multi = new EntUseAdapter() { public String getID(){ return "Use_Multi"; } public void use(edict_t ent, edict_t other, edict_t activator) { ent.activator = activator; multi_trigger(ent); } }; static EntTouchAdapter Touch_Multi = new EntTouchAdapter() { public String getID(){ return "Touch_Multi"; } public void touch(edict_t self, edict_t other, cplane_t plane, csurface_t surf) { if (other.client != null) { if ((self.spawnflags & 2) != 0) return; } else if ((other.svflags & Defines.SVF_MONSTER) != 0) { if (0 == (self.spawnflags & 1)) return; } else return; if (!Math3D.VectorEquals(self.movedir, Globals.vec3_origin)) { float[] forward = { 0, 0, 0 }; Math3D.AngleVectors(other.s.angles, forward, null, null); if (Math3D.DotProduct(forward, self.movedir) < 0) return; } self.activator = other; 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 */ static EntUseAdapter trigger_enable = new EntUseAdapter() { public String getID(){ return "trigger_enable"; } public void use(edict_t self, edict_t other, edict_t activator) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -