diff --git a/src/gs-entbase/server.src b/src/gs-entbase/server.src index b22496bd..3663b6d2 100644 --- a/src/gs-entbase/server.src +++ b/src/gs-entbase/server.src @@ -16,6 +16,8 @@ server/env_render.cpp server/env_shake.cpp server/env_message.cpp server/game_text.cpp +server/path_corner.cpp +server/path_track.cpp server/func_recharge.cpp server/func_healthcharger.cpp server/func_breakable.cpp @@ -52,8 +54,6 @@ server/env_shooter.cpp server/env_beverage.cpp server/env_global.cpp server/item_food.cpp -server/path_corner.cpp -server/path_track.cpp server/multi_manager.cpp server/monster_furniture.cpp server/monster_generic.cpp diff --git a/src/gs-entbase/server/func_train.cpp b/src/gs-entbase/server/func_train.cpp index 08efd163..862bab8a 100644 --- a/src/gs-entbase/server/func_train.cpp +++ b/src/gs-entbase/server/func_train.cpp @@ -14,131 +14,216 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/*QUAKED func_train (0 .5 .8) ? +/*QUAKED func_train (0 .5 .8) ? x x x TRAIN_NOTSOLID "targetname" Name -"target" Target when triggered. +"target" First node. "killtarget" Target to kill when triggered. +"dmg" Damage to inflict upon a person blocking the way. +"snd_move" Path to sound sample which plays when it's moving. +"snd_stop" Path to sound sample which plays when it stops moving. -Moving platform following along path_* entities. -Very unfinished. +Moving platform following along path_corner entities, aka nodes. +Most of its behaviour is controlled by the path_corner entities it passes over. +See the entity definition for path_corner to find out more. + +Upon level entry, the func_train will spawn right where its first path_corner +node is. This is so you can light the func_train somewhere else - like a lonely +box somewhere outside the playable area. */ +#define TRAIN_NOTSOLID 8 + +string g_strTrainMoveSnd[] = { + "common/null.wav", + "plats/bigmove1.wav", + "plats/bigmove2.wav", + "plats/elevmove1.wav", + "plats/elevmove2.wav", + "plats/elevmove3.wav", + "plats/freightmove1.wav", + "plats/freightmove2.wav", + "plats/heavymove1.wav", + "plats/rackmove1.wav", + "plats/railmove1.wav", + "plats/squeekmove1.wav", + "plats/talkmove1.wav", + "plats/talkmove2.wav" +}; +string g_strTrainStopSnd[] = { + "common/null.wav", + "plats/bigstop1.wav", + "plats/bigstop2.wav", + "plats/freightstop1.wav", + "plats/heavystop2.wav", + "plats/rackstop1.wav", + "plats/railstop1.wav", + "plats/squeekstop1.wav", + "plats/talkstop1.wav" +}; + class func_train:CBaseTrigger { + float m_flWait; float m_flSpeed; + float m_flDamage; + string m_strMoveSnd; + string m_strStopSnd; void() func_train; - virtual void() Find; virtual void() NextPath; virtual void() GoToTarget; virtual void() Trigger; virtual void() Respawn; + virtual void() Blocked; }; -void func_train::GoToTarget(void) +void +func_train::Blocked(void) { + Damage_Apply(other, this, m_flDamage, other.origin, TRUE); +} + +void +func_train::GoToTarget(void) +{ + entity eNode; float flTravelTime; - vector vel_to_pos; - entity f; + vector vecVelocity; + vector vecWorldPos; - f = find(world, CBaseTrigger::m_strTargetName, m_strTarget); + eNode = find(world, CBaseTrigger::m_strTargetName, m_strTarget); - if (!f) { - print("^1func_train^7: Trigger-Target not found! Removing.\n"); + if (!eNode) { return; } - vector vecWorldPos; vecWorldPos[0] = absmin[0] + (0.5 * (absmax[0] - absmin[0])); vecWorldPos[1] = absmin[1] + (0.5 * (absmax[1] - absmin[1])); vecWorldPos[2] = absmin[2] + (0.5 * (absmax[2] - absmin[2])); - vel_to_pos = (f.origin - vecWorldPos); - flTravelTime = (vlen(vel_to_pos) / m_flSpeed); + vecVelocity = (eNode.origin - vecWorldPos); + flTravelTime = (vlen(vecVelocity) / m_flSpeed); if (!flTravelTime) { NextPath(); - print(sprintf("TRAIN %s SPEED: %f\n", m_strTargetName, flTravelTime)); return; } - velocity = (vel_to_pos * (1 / flTravelTime)); + /* more stuff for the ears */ + if (m_strMoveSnd) { + sound(this, CHAN_VOICE, m_strMoveSnd, 1.0, ATTN_NORM); + } + + velocity = (vecVelocity * (1 / flTravelTime)); think = NextPath; nextthink = (ltime + flTravelTime); } -void func_train::NextPath(void) +void +func_train::NextPath(void) { - CBaseTrigger current_target; + path_corner eNode; + eNode = (path_corner)find(world, CBaseTrigger::m_strTargetName, m_strTarget); - print(sprintf("^2func_train^7: Talking to current target %s... ", m_strTarget)); - current_target = (CBaseTrigger)find(world, CBaseTrigger::m_strTargetName, m_strTarget); - - if (!current_target) { - print("^1FAILED.\n"); - } else { - print("^2SUCCESS.\n"); + if (!eNode) { + return; } - m_strTarget = current_target.m_strTarget; + /* fire the path_corners' target */ + if (eNode.m_strMessage) { + eNode.Trigger(); + } + + /* stuff for the ears */ + if (m_strStopSnd) { + sound(this, CHAN_BODY, m_strStopSnd, 1.0, ATTN_NORM); + } + /* make the loopy noise stop */ + if (m_strMoveSnd) { + sound(this, CHAN_VOICE, "common/null.wav", 0.0, ATTN_NORM); + } + + setorigin(this, eNode.origin - (mins + maxs) * 0.5); + m_flSpeed = eNode.m_flSpeed; + m_flWait = eNode.m_flWait; + m_strTarget = eNode.m_strTarget; velocity = [0,0,0]; - if (m_strTarget) { + /* warp */ + if (eNode.spawnflags & PC_TELEPORT) { + NextPath(); + return; + } + + /* stop until triggered again */ + if (eNode.spawnflags & PC_WAIT) { + return; + } + + if (m_flWait > 0) { + think = GoToTarget; + nextthink = ltime + m_flWait; + } else { GoToTarget(); } } -void func_train::Trigger(void) +void +func_train::Trigger(void) { GoToTarget(); } -void func_train::Find(void) +void +func_train::Respawn(void) { - entity f = find(world, CBaseTrigger::m_strTargetName, m_strTarget); - - if (!f) { - print(sprintf("^1func_train^7: End-Target %s not found! Removing.\n",m_strTarget)); - remove(this); - return; - } - - print("^2func_train^7: Successfully found first target.\n"); - vector vecWorldPos; - vecWorldPos[0] = absmin[0] + (0.5 * (absmax[0] - absmin[0])); - vecWorldPos[1] = absmin[1] + (0.5 * (absmax[1] - absmin[1])); - vecWorldPos[2] = absmin[2] + (0.5 * (absmax[2] - absmin[2])); - - vecWorldPos = f.origin - vecWorldPos; - setorigin(this, vecWorldPos); -} - -void func_train::Respawn(void) -{ - solid = SOLID_BSP; + solid = spawnflags & TRAIN_NOTSOLID ? SOLID_NOT : SOLID_BSP; movetype = MOVETYPE_PUSH; - //blocked = Blocked; - + blocked = Blocked; setmodel(this, m_oldModel); setorigin(this, m_oldOrigin); - /* Make sure we got some time for the paths to spawn */ - nextthink = ltime + 0.1f; - think = Find; + /* let's wait 1/4 a second to give the path_corner entities a chance to + * spawn in case they're after us in the ent lump */ + think = NextPath; + nextthink = ltime + 0.25f; } -void func_train::func_train(void) +void +func_train::func_train(void) { + int a; for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) { switch (argv(i)) { - case "speed": - m_flSpeed = stof(argv(i+1)); + case "dmg": + m_flDamage = stof(argv(i+1)); + break; + case "movesnd": + a = bound(0, stof(argv(i+1)), g_strTrainMoveSnd.length); + m_strMoveSnd = g_strTrainMoveSnd[a]; + break; + case "stopsnd": + a = bound(0, stof(argv(i+1)), g_strTrainStopSnd.length); + m_strStopSnd = g_strTrainStopSnd[a]; + break; + case "snd_move": + m_strMoveSnd = argv(i+1); + break; + case "snd_stop": + m_strStopSnd = argv(i+1); break; default: break; } } + if (m_strMoveSnd) { + precache_sound(m_strMoveSnd); + } + if (m_strStopSnd) { + precache_sound(m_strStopSnd); + } + if (!m_flSpeed) { m_flSpeed = 100; } diff --git a/src/gs-entbase/server/path_corner.cpp b/src/gs-entbase/server/path_corner.cpp index b33fa13a..9d1d2f18 100644 --- a/src/gs-entbase/server/path_corner.cpp +++ b/src/gs-entbase/server/path_corner.cpp @@ -22,17 +22,57 @@ STUB! */ +enumflags { + PC_WAIT, + PC_TELEPORT, + PC_FIREONCE +}; + class path_corner:CBaseTrigger { float m_flSpeed; + float m_flYawSpeed; float m_flWait; void() path_corner; + virtual void() Trigger; }; +void path_corner::Trigger(void) +{ + for ( entity eFind = world; ( eFind = find( eFind, CBaseTrigger::m_strTargetName, m_strMessage));) { + CBaseTrigger trigger = (CBaseTrigger) eFind; + trigger.Trigger(); + } +} + void path_corner::path_corner(void) { CBaseTrigger::CBaseTrigger(); - m_flSpeed = 100; - m_flWait = 1.0f; + + for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) { + switch ( argv( i ) ) { + case "speed": + m_flSpeed = stof(argv( i + 1 )); + break; + case "yaw_speed": + m_flYawSpeed = stof(argv(i+1)); + break; + case "wait": + m_flWait = stof(argv( i + 1 )); + break; + case "message": + m_strMessage = argv( i + 1); + break; + default: + break; + } + } + + if (!m_flSpeed) + m_flSpeed = 100; + + if (!m_flWait) + m_flWait = 1.0f; + }