📄 gamefunc.java
字号:
if (Lib.Q_stricmp(t.classname, "func_areaportal") == 0) { GameBase.gi.SetAreaPortalState(t.style, open); } } } static void door_go_up(edict_t self, edict_t activator) { if (self.moveinfo.state == STATE_UP) return; // already going up if (self.moveinfo.state == STATE_TOP) { // reset top wait time if (self.moveinfo.wait >= 0) self.nextthink = GameBase.level.time + self.moveinfo.wait; return; } if (0 == (self.flags & Defines.FL_TEAMSLAVE)) { if (self.moveinfo.sound_start != 0) GameBase.gi.sound(self, Defines.CHAN_NO_PHS_ADD + Defines.CHAN_VOICE, self.moveinfo.sound_start, 1, Defines.ATTN_STATIC, 0); self.s.sound = self.moveinfo.sound_middle; } self.moveinfo.state = STATE_UP; if (Lib.strcmp(self.classname, "func_door") == 0) Move_Calc(self, self.moveinfo.end_origin, door_hit_top); else if (Lib.strcmp(self.classname, "func_door_rotating") == 0) AngleMove_Calc(self, door_hit_top); GameUtil.G_UseTargets(self, activator); door_use_areaportals(self, true); } /** * QUAKED func_water (0 .5 .8) ? START_OPEN func_water is a moveable water * brush. It must be targeted to operate. Use a non-water texture at your * own risk. * * START_OPEN causes the water to move to its destination when spawned and * operate in reverse. * * "angle" determines the opening direction (up or down only) "speed" * movement speed (25 default) "wait" wait before returning (-1 default, -1 = * TOGGLE) "lip" lip remaining at end of move (0 default) "sounds" (yes, * these need to be changed) 0) no sound 1) water 2) lava */ static void SP_func_water(edict_t self) { float[] abs_movedir = { 0, 0, 0 }; GameBase.G_SetMovedir(self.s.angles, self.movedir); self.movetype = Defines.MOVETYPE_PUSH; self.solid = Defines.SOLID_BSP; GameBase.gi.setmodel(self, self.model); switch (self.sounds) { default: break; case 1: // water self.moveinfo.sound_start = GameBase.gi .soundindex("world/mov_watr.wav"); self.moveinfo.sound_end = GameBase.gi .soundindex("world/stp_watr.wav"); break; case 2: // lava self.moveinfo.sound_start = GameBase.gi .soundindex("world/mov_watr.wav"); self.moveinfo.sound_end = GameBase.gi .soundindex("world/stp_watr.wav"); break; } // calculate second position Math3D.VectorCopy(self.s.origin, self.pos1); abs_movedir[0] = Math.abs(self.movedir[0]); abs_movedir[1] = Math.abs(self.movedir[1]); abs_movedir[2] = Math.abs(self.movedir[2]); self.moveinfo.distance = abs_movedir[0] * self.size[0] + abs_movedir[1] * self.size[1] + abs_movedir[2] * self.size[2] - GameBase.st.lip; Math3D.VectorMA(self.pos1, self.moveinfo.distance, self.movedir, self.pos2); // if it starts open, switch the positions if ((self.spawnflags & DOOR_START_OPEN) != 0) { Math3D.VectorCopy(self.pos2, self.s.origin); Math3D.VectorCopy(self.pos1, self.pos2); Math3D.VectorCopy(self.s.origin, self.pos1); } Math3D.VectorCopy(self.pos1, self.moveinfo.start_origin); Math3D.VectorCopy(self.s.angles, self.moveinfo.start_angles); Math3D.VectorCopy(self.pos2, self.moveinfo.end_origin); Math3D.VectorCopy(self.s.angles, self.moveinfo.end_angles); self.moveinfo.state = STATE_BOTTOM; if (0 == self.speed) self.speed = 25; self.moveinfo.accel = self.moveinfo.decel = self.moveinfo.speed = self.speed; if (0 == self.wait) self.wait = -1; self.moveinfo.wait = self.wait; self.use = door_use; if (self.wait == -1) self.spawnflags |= DOOR_TOGGLE; self.classname = "func_door"; GameBase.gi.linkentity(self); } static void train_resume(edict_t self) { edict_t ent; float[] dest = { 0, 0, 0 }; ent = self.target_ent; Math3D.VectorSubtract(ent.s.origin, self.mins, dest); self.moveinfo.state = STATE_TOP; Math3D.VectorCopy(self.s.origin, self.moveinfo.start_origin); Math3D.VectorCopy(dest, self.moveinfo.end_origin); Move_Calc(self, dest, train_wait); self.spawnflags |= TRAIN_START_ON; } static void SP_func_train(edict_t self) { self.movetype = Defines.MOVETYPE_PUSH; Math3D.VectorClear(self.s.angles); self.blocked = train_blocked; if ((self.spawnflags & TRAIN_BLOCK_STOPS) != 0) self.dmg = 0; else { if (0 == self.dmg) self.dmg = 100; } self.solid = Defines.SOLID_BSP; GameBase.gi.setmodel(self, self.model); if (GameBase.st.noise != null) self.moveinfo.sound_middle = GameBase.gi .soundindex(GameBase.st.noise); if (0 == self.speed) self.speed = 100; self.moveinfo.speed = self.speed; self.moveinfo.accel = self.moveinfo.decel = self.moveinfo.speed; self.use = train_use; GameBase.gi.linkentity(self); if (self.target != null) { // start trains on the second frame, to make sure their targets have // had // a chance to spawn self.nextthink = GameBase.level.time + Defines.FRAMETIME; self.think = func_train_find; } else { GameBase.gi.dprintf("func_train without a target at " + Lib.vtos(self.absmin) + "\n"); } } static void SP_func_timer(edict_t self) { if (0 == self.wait) self.wait = 1.0f; self.use = func_timer_use; self.think = func_timer_think; if (self.random >= self.wait) { self.random = self.wait - Defines.FRAMETIME; GameBase.gi.dprintf("func_timer at " + Lib.vtos(self.s.origin) + " has random >= wait\n"); } if ((self.spawnflags & 1) != 0) { self.nextthink = GameBase.level.time + 1.0f + GameBase.st.pausetime + self.delay + self.wait + Lib.crandom() * self.random; self.activator = self; } self.svflags = Defines.SVF_NOCLIENT; } /** * PLATS * * movement options: * * linear smooth start, hard stop smooth start, smooth stop * * start end acceleration speed deceleration begin sound end sound target * fired when reaching end wait at end * * object characteristics that use move segments * --------------------------------------------- movetype_push, or * movetype_stop action when touched action when blocked action when used * disabled? auto trigger spawning * */ public final static int PLAT_LOW_TRIGGER = 1; public final static int STATE_TOP = 0; public final static int STATE_BOTTOM = 1; public final static int STATE_UP = 2; public final static int STATE_DOWN = 3; public final static int DOOR_START_OPEN = 1; public final static int DOOR_REVERSE = 2; public final static int DOOR_CRUSHER = 4; public final static int DOOR_NOMONSTER = 8; public final static int DOOR_TOGGLE = 32; public final static int DOOR_X_AXIS = 64; public final static int DOOR_Y_AXIS = 128; // // Support routines for movement (changes in origin using velocity) // static EntThinkAdapter Move_Done = new EntThinkAdapter() { public String getID() { return "move_done";} public boolean think(edict_t ent) { Math3D.VectorClear(ent.velocity); ent.moveinfo.endfunc.think(ent); return true; } }; static EntThinkAdapter Move_Final = new EntThinkAdapter() { public String getID() { return "move_final";} public boolean think(edict_t ent) { if (ent.moveinfo.remaining_distance == 0) { Move_Done.think(ent); return true; } Math3D.VectorScale(ent.moveinfo.dir, ent.moveinfo.remaining_distance / Defines.FRAMETIME, ent.velocity); ent.think = Move_Done; ent.nextthink = GameBase.level.time + Defines.FRAMETIME; return true; } }; static EntThinkAdapter Move_Begin = new EntThinkAdapter() { public String getID() { return "move_begin";} public boolean think(edict_t ent) { float frames; if ((ent.moveinfo.speed * Defines.FRAMETIME) >= ent.moveinfo.remaining_distance) { Move_Final.think(ent); return true; } Math3D.VectorScale(ent.moveinfo.dir, ent.moveinfo.speed, ent.velocity); frames = (float) Math .floor((ent.moveinfo.remaining_distance / ent.moveinfo.speed) / Defines.FRAMETIME); ent.moveinfo.remaining_distance -= frames * ent.moveinfo.speed * Defines.FRAMETIME; ent.nextthink = GameBase.level.time + (frames * Defines.FRAMETIME); ent.think = Move_Final; return true; } }; // // Support routines for angular movement (changes in angle using avelocity) // static EntThinkAdapter AngleMove_Done = new EntThinkAdapter() { public String getID() { return "agnle_move_done";} public boolean think(edict_t ent) { Math3D.VectorClear(ent.avelocity); ent.moveinfo.endfunc.think(ent); return true; } }; static EntThinkAdapter AngleMove_Final = new EntThinkAdapter() { public String getID() { return "angle_move_final";} public boolean think(edict_t ent) { float[] move = { 0, 0, 0 }; if (ent.moveinfo.state == STATE_UP) Math3D.VectorSubtract(ent.moveinfo.end_angles, ent.s.angles, move); else Math3D.VectorSubtract(ent.moveinfo.start_angles, ent.s.angles, move); if (Math3D.VectorEquals(move, Globals.vec3_origin)) { AngleMove_Done.think(ent); return true; } Math3D.VectorScale(move, 1.0f / Defines.FRAMETIME, ent.avelocity); ent.think = AngleMove_Done; ent.nextthink = GameBase.level.time + Defines.FRAMETIME; return true; } }; static EntThinkAdapter AngleMove_Begin = new EntThinkAdapter() { public String getID() { return "angle_move_begin";} public boolean think(edict_t ent) { float[] destdelta = { 0, 0, 0 }; float len; float traveltime; float frames; // set destdelta to the vector needed to move if (ent.moveinfo.state == STATE_UP) Math3D.VectorSubtract(ent.moveinfo.end_angles, ent.s.angles, destdelta); else Math3D.VectorSubtract(ent.moveinfo.start_angles, ent.s.angles, destdelta); // calculate length of vector len = Math3D.VectorLength(destdelta); // divide by speed to get time to reach dest traveltime = len / ent.moveinfo.speed; if (traveltime < Defines.FRAMETIME) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -