diff --git a/src/gs-entbase/server/basemonster.cpp b/src/gs-entbase/server/basemonster.cpp index 53803f31..7ecb422a 100644 --- a/src/gs-entbase/server/basemonster.cpp +++ b/src/gs-entbase/server/basemonster.cpp @@ -339,17 +339,11 @@ CBaseMonster::FreeState(void) /* trigger when required */ if (m_strRouteEnded) { - CBaseTrigger trigger = 0; - trigger = (CBaseTrigger)find(trigger, ::targetname, m_strRouteEnded); - if (!trigger) { - dprint(sprintf("^1CBaseMonster::^3FreeState^7: %s doesn't exist. Won't trigger\n", m_strRouteEnded)); - } - - if (trigger.Trigger != __NULL__) { - dprint(sprintf("^2CBaseMonster::^3FreeState^7: %s triggered %f\n", m_strRouteEnded, time)); - trigger.Trigger(this, TRIG_TOGGLE); - } else { - dprint(sprintf("^1CBaseMonster::^3FreeState^7: %s not a valid trigger\n", m_strRouteEnded)); + for (entity f = world; (f = find(f, ::targetname, m_strRouteEnded));) { + CBaseTrigger trigger = (CBaseTrigger)f; + if (trigger.Trigger != __NULL__) { + trigger.Trigger(this, TRIG_TOGGLE); + } } } diff --git a/src/gs-entbase/server/basenpc.cpp b/src/gs-entbase/server/basenpc.cpp index f8befd22..6796840f 100644 --- a/src/gs-entbase/server/basenpc.cpp +++ b/src/gs-entbase/server/basenpc.cpp @@ -445,6 +445,10 @@ CBaseNPC::Physics(void) input_timelength = frametime; input_angles = v_angle; + if (m_iSequenceState != SEQUENCESTATE_NONE) { + m_eFollowing = __NULL__; + } + /* override whatever we did above with this */ if (m_iSequenceState == SEQUENCESTATE_ENDING) { input_angles = v_angle = angles = m_vecSequenceAngle; diff --git a/src/gs-entbase/server/scripted_sentence.cpp b/src/gs-entbase/server/scripted_sentence.cpp index c4f9b8f7..b4d49b83 100644 --- a/src/gs-entbase/server/scripted_sentence.cpp +++ b/src/gs-entbase/server/scripted_sentence.cpp @@ -45,16 +45,33 @@ class scripted_sentence:CBaseTrigger void scripted_sentence::Trigger(entity act, int unused) { - entity speaker = find(world, ::targetname, m_strSpeaker); + entity spe; + spe = find(world, ::targetname, m_strSpeaker); - if (!speaker) { + if (!spe) { + /* time to look for a classname instead */ + float closest = 9999999; + + for (entity c = world; (c = find(c, ::classname, m_strSpeaker));) { + float rad; + rad = vlen(origin - c.origin); + + /* pick the closest entity */ + if (rad < closest) { + spe = c; + closest = rad; + } + } + } + + if (!spe) { print(sprintf("^1scripted_sentence::^3Trigger^7: Couldn't find %s!\n", m_strSpeaker)); return; } dprint(sprintf("^2scripted_sentence::^3Trigger^7: %s on %s\n", m_strSentence, m_strSpeaker)); - CBaseNPC npc = (CBaseNPC)speaker; + CBaseNPC npc = (CBaseNPC)spe; WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); WriteByte(MSG_MULTICAST, EV_SENTENCE); WriteEntity(MSG_MULTICAST, npc); diff --git a/src/gs-entbase/server/scripted_sequence.cpp b/src/gs-entbase/server/scripted_sequence.cpp index c02dedc7..4e899e2b 100644 --- a/src/gs-entbase/server/scripted_sequence.cpp +++ b/src/gs-entbase/server/scripted_sequence.cpp @@ -93,46 +93,20 @@ class scripted_sequence:CBaseTrigger void(void) scripted_sequence; virtual void(entity, int) Trigger; + virtual void(entity) RunOnEntity; virtual void(void) InitIdle; virtual void(void) Respawn; + virtual void(void) touch; virtual void(string, string) SpawnKey; }; void -scripted_sequence::Trigger(entity act, int unused) -{ +scripted_sequence::RunOnEntity(entity targ) +{ CBaseMonster f; float duration; - if (!m_iEnabled) { - return; - } - - /* aaaaand it's gone */ - if (!(spawnflags & SSFL_REPEATABLE)) { - m_iEnabled = FALSE; - } - - dprint(sprintf("^2scripted_sequence::^3Trigger^7: with spawnflags %d\n", spawnflags)); - f = (CBaseMonster)find(world, ::targetname, m_strMonster); - - /* target doesn't exist/hasn't spawned */ - if (!f) { - /* time to look for a classname instead */ - for (entity c = world; (c = find(c, ::classname, m_strMonster));) { - /* within radius */ - if (vlen(origin - c.origin) < m_flSearchRadius) { - f = (CBaseMonster)c; - break; - } - } - - /* cancel out. this trigger is broken. */ - if (!f) { - dprint(sprintf("^1scripted_sequence::^3Trigger^7: Unknown target %s\n", m_strMonster)); - return; - } - } + f = (CBaseMonster)targ; dprint(sprintf("\tName: %s\n", targetname)); dprint(sprintf("\tTarget: %s\n", m_strMonster)); @@ -211,6 +185,40 @@ scripted_sequence::Trigger(entity act, int unused) dprint(sprintf("\tEnding: %f\n", f.nextthink)); } +void +scripted_sequence::Trigger(entity act, int unused) +{ + CBaseMonster f; + + if (!m_iEnabled) + return; + + dprint(sprintf("^2scripted_sequence::^3Trigger^7: with spawnflags %d\n", spawnflags)); + f = (CBaseMonster)find(world, ::targetname, m_strMonster); + + /* target doesn't exist/hasn't spawned */ + if (!f) { + for (entity c = world; (c = find(c, ::classname, m_strMonster));) { + /* within radius */ + if (vlen(origin - c.origin) < m_flSearchRadius) { + f = (CBaseMonster)c; + break; + } + } + + /* cancel out. this trigger is not yet ready. */ + if (!f) { + return; + } + } + + /* aaaaand it's gone */ + if (!(spawnflags & SSFL_REPEATABLE)) + m_iEnabled = FALSE; + + RunOnEntity((entity)f); +} + void scripted_sequence::InitIdle(void) { @@ -243,11 +251,36 @@ scripted_sequence::InitIdle(void) f.m_vecSequenceAngle = angles; } +void +scripted_sequence::touch(void) +{ + if (other.classname != m_strMonster) + return; + + if (!m_iEnabled) + return; + + /* aaaaand it's gone */ + if (!(spawnflags & SSFL_REPEATABLE)) + m_iEnabled = FALSE; + + RunOnEntity(other); +} + void scripted_sequence::Respawn(void) { m_iEnabled = TRUE; target = m_oldstrTarget; + + if (m_flSearchRadius) { + SetSolid(SOLID_TRIGGER); + mins[0] = mins[1] = mins[2] = -(m_flSearchRadius/2); + maxs[0] = maxs[1] = maxs[2] = (m_flSearchRadius/2); + setsize(this, mins, maxs); + } else { + SetSolid(SOLID_NOT); + } if (m_strIdleAnim) { think = InitIdle; @@ -259,9 +292,6 @@ void scripted_sequence::SpawnKey(string strKey, string strValue) { switch (strKey) { - case "target": - target = strValue; - break; case "m_iszEntity": m_strMonster = strValue; break; @@ -288,7 +318,6 @@ void scripted_sequence::scripted_sequence(void) { CBaseTrigger::CBaseTrigger(); - m_oldstrTarget = target; } CLASSEXPORT(aiscripted_sequence, scripted_sequence) diff --git a/src/gs-entbase/server/trigger_multiple.cpp b/src/gs-entbase/server/trigger_multiple.cpp index 950848af..6208dedb 100644 --- a/src/gs-entbase/server/trigger_multiple.cpp +++ b/src/gs-entbase/server/trigger_multiple.cpp @@ -50,6 +50,11 @@ trigger_multiple::touch(void) if (GetMaster() == FALSE) return; + if (spawnflags & TM_NOCLIENTS && other.flags & FL_CLIENT) + return; + if (!(spawnflags & TM_MONSTERS) && other.flags & FL_MONSTER) + return; + if (Rules_IsTeamPlay() == TRUE) { if (m_iTeam > 0 && eActivator.team != m_iTeam + 1) { return; diff --git a/src/shared/valve/pmove.c b/src/shared/valve/pmove.c index d99256ad..7550fcc0 100644 --- a/src/shared/valve/pmove.c +++ b/src/shared/valve/pmove.c @@ -32,13 +32,13 @@ void GamePMove_Fall(player target, float impactspeed) #ifdef SERVER float fFallDamage = (impactspeed - 580) * (100 / (1024 - 580)); Damage_Apply(target, world, fFallDamage, 0, DMG_FALL); - Sound_Play(target, CHAN_AUTO, "player.fall"); + Sound_Play(target, CHAN_VOICE, "player.fall"); #endif target.punchangle += [15,0,(input_sequence & 1) ? 15 : -15]; } else if (impactspeed > 400) { target.punchangle += [15,0,0]; #ifdef SERVER - Sound_Play(target, CHAN_AUTO, "player.lightfall"); + Sound_Play(target, CHAN_VOICE, "player.lightfall"); #endif } }