📄 gamefunc.java
字号:
ent.moveinfo.sound_end = GameBase.gi .soundindex("doors/dr1_end.wav"); } GameBase.G_SetMovedir(ent.s.angles, ent.movedir); ent.movetype = Defines.MOVETYPE_PUSH; ent.solid = Defines.SOLID_BSP; GameBase.gi.setmodel(ent, ent.model); ent.blocked = door_blocked; ent.use = door_use; if (0 == ent.speed) ent.speed = 100; if (GameBase.deathmatch.value != 0) ent.speed *= 2; if (0 == ent.accel) ent.accel = ent.speed; if (0 == ent.decel) ent.decel = ent.speed; if (0 == ent.wait) ent.wait = 3; if (0 == GameBase.st.lip) GameBase.st.lip = 8; if (0 == ent.dmg) ent.dmg = 2; // calculate second position Math3D.VectorCopy(ent.s.origin, ent.pos1); abs_movedir[0] = Math.abs(ent.movedir[0]); abs_movedir[1] = Math.abs(ent.movedir[1]); abs_movedir[2] = Math.abs(ent.movedir[2]); ent.moveinfo.distance = abs_movedir[0] * ent.size[0] + abs_movedir[1] * ent.size[1] + abs_movedir[2] * ent.size[2] - GameBase.st.lip; Math3D.VectorMA(ent.pos1, ent.moveinfo.distance, ent.movedir, ent.pos2); // if it starts open, switch the positions if ((ent.spawnflags & DOOR_START_OPEN) != 0) { Math3D.VectorCopy(ent.pos2, ent.s.origin); Math3D.VectorCopy(ent.pos1, ent.pos2); Math3D.VectorCopy(ent.s.origin, ent.pos1); } ent.moveinfo.state = STATE_BOTTOM; if (ent.health != 0) { ent.takedamage = Defines.DAMAGE_YES; ent.die = door_killed; ent.max_health = ent.health; } else if (ent.targetname != null && ent.message != null) { GameBase.gi.soundindex("misc/talk.wav"); ent.touch = door_touch; } ent.moveinfo.speed = ent.speed; ent.moveinfo.accel = ent.accel; ent.moveinfo.decel = ent.decel; ent.moveinfo.wait = ent.wait; Math3D.VectorCopy(ent.pos1, ent.moveinfo.start_origin); Math3D.VectorCopy(ent.s.angles, ent.moveinfo.start_angles); Math3D.VectorCopy(ent.pos2, ent.moveinfo.end_origin); Math3D.VectorCopy(ent.s.angles, ent.moveinfo.end_angles); if ((ent.spawnflags & 16) != 0) ent.s.effects |= Defines.EF_ANIM_ALL; if ((ent.spawnflags & 64) != 0) ent.s.effects |= Defines.EF_ANIM_ALLFAST; // to simplify logic elsewhere, make non-teamed doors into a team of // one if (null == ent.team) ent.teammaster = ent; GameBase.gi.linkentity(ent); ent.nextthink = GameBase.level.time + Defines.FRAMETIME; if (ent.health != 0 || ent.targetname != null) ent.think = Think_CalcMoveSpeed; else ent.think = Think_SpawnDoorTrigger; return true; } }; /* * QUAKED func_door_rotating (0 .5 .8) ? START_OPEN REVERSE CRUSHER * NOMONSTER ANIMATED TOGGLE X_AXIS Y_AXIS TOGGLE causes the door to wait in * both the start and end states for a trigger event. * * START_OPEN the door to moves to its destination when spawned, and operate * in reverse. It is used to temporarily or permanently close off an area * when triggered (not useful for touch or takedamage doors). NOMONSTER * monsters will not trigger this door * * You need to have an origin brush as part of this entity. The center of * that brush will be the point around which it is rotated. It will rotate * around the Z axis by default. You can check either the X_AXIS or Y_AXIS * box to change that. * * "distance" is how many degrees the door will be rotated. "speed" * determines how fast the door moves; default value is 100. * * REVERSE will cause the door to rotate in the opposite direction. * * "message" is printed when the door is touched if it is a trigger door and * it hasn't been fired yet "angle" determines the opening direction * "targetname" if set, no touch field will be spawned and a remote button * or trigger field activates the door. "health" if set, door must be shot * open "speed" movement speed (100 default) "wait" wait before returning (3 * default, -1 = never return) "dmg" damage to inflict when blocked (2 * default) "sounds" 1) silent 2) light 3) medium 4) heavy */ static EntThinkAdapter SP_func_door_rotating = new EntThinkAdapter() { public String getID() { return "sp_func_door_rotating";} public boolean think(edict_t ent) { Math3D.VectorClear(ent.s.angles); // set the axis of rotation Math3D.VectorClear(ent.movedir); if ((ent.spawnflags & DOOR_X_AXIS) != 0) ent.movedir[2] = 1.0f; else if ((ent.spawnflags & DOOR_Y_AXIS) != 0) ent.movedir[0] = 1.0f; else // Z_AXIS ent.movedir[1] = 1.0f; // check for reverse rotation if ((ent.spawnflags & DOOR_REVERSE) != 0) Math3D.VectorNegate(ent.movedir, ent.movedir); if (0 == GameBase.st.distance) { GameBase.gi.dprintf(ent.classname + " at " + Lib.vtos(ent.s.origin) + " with no distance set\n"); GameBase.st.distance = 90; } Math3D.VectorCopy(ent.s.angles, ent.pos1); Math3D.VectorMA(ent.s.angles, GameBase.st.distance, ent.movedir, ent.pos2); ent.moveinfo.distance = GameBase.st.distance; ent.movetype = Defines.MOVETYPE_PUSH; ent.solid = Defines.SOLID_BSP; GameBase.gi.setmodel(ent, ent.model); ent.blocked = door_blocked; ent.use = door_use; if (0 == ent.speed) ent.speed = 100; if (0 == ent.accel) ent.accel = ent.speed; if (0 == ent.decel) ent.decel = ent.speed; if (0 == ent.wait) ent.wait = 3; if (0 == ent.dmg) ent.dmg = 2; if (ent.sounds != 1) { ent.moveinfo.sound_start = GameBase.gi .soundindex("doors/dr1_strt.wav"); ent.moveinfo.sound_middle = GameBase.gi .soundindex("doors/dr1_mid.wav"); ent.moveinfo.sound_end = GameBase.gi .soundindex("doors/dr1_end.wav"); } // if it starts open, switch the positions if ((ent.spawnflags & DOOR_START_OPEN) != 0) { Math3D.VectorCopy(ent.pos2, ent.s.angles); Math3D.VectorCopy(ent.pos1, ent.pos2); Math3D.VectorCopy(ent.s.angles, ent.pos1); Math3D.VectorNegate(ent.movedir, ent.movedir); } if (ent.health != 0) { ent.takedamage = Defines.DAMAGE_YES; ent.die = door_killed; ent.max_health = ent.health; } if (ent.targetname != null && ent.message != null) { GameBase.gi.soundindex("misc/talk.wav"); ent.touch = door_touch; } ent.moveinfo.state = STATE_BOTTOM; ent.moveinfo.speed = ent.speed; ent.moveinfo.accel = ent.accel; ent.moveinfo.decel = ent.decel; ent.moveinfo.wait = ent.wait; Math3D.VectorCopy(ent.s.origin, ent.moveinfo.start_origin); Math3D.VectorCopy(ent.pos1, ent.moveinfo.start_angles); Math3D.VectorCopy(ent.s.origin, ent.moveinfo.end_origin); Math3D.VectorCopy(ent.pos2, ent.moveinfo.end_angles); if ((ent.spawnflags & 16) != 0) ent.s.effects |= Defines.EF_ANIM_ALL; // to simplify logic elsewhere, make non-teamed doors into a team of // one if (ent.team == null) ent.teammaster = ent; GameBase.gi.linkentity(ent); ent.nextthink = GameBase.level.time + Defines.FRAMETIME; if (ent.health != 0 || ent.targetname != null) ent.think = Think_CalcMoveSpeed; else ent.think = Think_SpawnDoorTrigger; return true; } }; public final static int TRAIN_START_ON = 1; public final static int TRAIN_TOGGLE = 2; public final static int TRAIN_BLOCK_STOPS = 4; /* * QUAKED func_train (0 .5 .8) ? START_ON TOGGLE BLOCK_STOPS Trains are * moving platforms that players can ride. The targets origin specifies the * min point of the train at each corner. The train spawns at the first * target it is pointing at. If the train is the target of a button or * trigger, it will not begin moving until activated. speed default 100 dmg * default 2 noise looping sound to play when the train is in motion * */ static EntBlockedAdapter train_blocked = new EntBlockedAdapter() { public String getID() { return "train_blocked";} public void blocked(edict_t self, edict_t other) { if (0 == (other.svflags & Defines.SVF_MONSTER) && (null == other.client)) { // give it a chance to go away on it's own terms (like gibs) GameCombat.T_Damage(other, self, self, Globals.vec3_origin, other.s.origin, Globals.vec3_origin, 100000, 1, 0, Defines.MOD_CRUSH); // if it's still there, nuke it if (other != null) GameMisc.BecomeExplosion1(other); return; } if (GameBase.level.time < self.touch_debounce_time) return; if (self.dmg == 0) return; self.touch_debounce_time = GameBase.level.time + 0.5f; GameCombat.T_Damage(other, self, self, Globals.vec3_origin, other.s.origin, Globals.vec3_origin, self.dmg, 1, 0, Defines.MOD_CRUSH); } }; static EntThinkAdapter train_wait = new EntThinkAdapter() { public String getID() { return "train_wait";} public boolean think(edict_t self) { if (self.target_ent.pathtarget != null) { String savetarget; edict_t ent; ent = self.target_ent; savetarget = ent.target; ent.target = ent.pathtarget; GameUtil.G_UseTargets(ent, self.activator); ent.target = savetarget; // make sure we didn't get killed by a killtarget if (!self.inuse) return true; } if (self.moveinfo.wait != 0) { if (self.moveinfo.wait > 0) { self.nextthink = GameBase.level.time + self.moveinfo.wait; self.think = train_next; } else if (0 != (self.spawnflags & TRAIN_TOGGLE)) // && wait < 0 { train_next.think(self); self.spawnflags &= ~TRAIN_START_ON; Math3D.VectorClear(self.velocity); self.nextthink = 0; } if (0 == (self.flags & Defines.FL_TEAMSLAVE)) { if (self.moveinfo.sound_end != 0) GameBase.gi.sound(self, Defines.CHAN_NO_PHS_ADD + Defines.CHAN_VOICE, self.moveinfo.sound_end, 1, Defines.ATTN_STATIC, 0); self.s.sound = 0; } } else { train_next.think(self); } return true; } }; static EntThinkAdapter train_next = new EntThinkAdapter() { public String getID() { return "train_next";} public boolean think(edict_t self) { edict_t ent = null; float[] dest = { 0, 0, 0 }; boolean first; first = true; boolean dogoto = true; while (dogoto) { if (null == self.target) { // gi.dprintf ("train_next: no next target\n"); return true; } ent = GameBase.G_PickTarget(self.target); if (null == ent) { GameBase.gi.dprintf("train_next: bad target " + self.target + "\n"); return true; } self.target = ent.target; dogoto = false; // check for a teleport path_corner if ((ent.spawnflags & 1) != 0) { if (!first) { GameBase.gi .dprintf("connected teleport path_corners, see " + ent.classname + " at " + Lib.vtos(ent.s.origin) + "\n"); return true; } first = false; Math3D.VectorSub
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -