diff --git a/src/botlib/defs.h b/src/botlib/defs.h index 413e892e..c7443b1c 100644 --- a/src/botlib/defs.h +++ b/src/botlib/defs.h @@ -16,6 +16,7 @@ #include "bot.h" #include "botinfo.h" -#include "route.h" #include "cvar.h" -#include "way.h" + + +vector Route_SelectDestination( bot target ); diff --git a/src/gs-entbase/shared/NSMonster.h b/src/gs-entbase/shared/NSMonster.h index d3fed560..d29e12b4 100644 --- a/src/gs-entbase/shared/NSMonster.h +++ b/src/gs-entbase/shared/NSMonster.h @@ -218,7 +218,8 @@ class NSMonster:NSSurfacePropEntity virtual void(float) Save; virtual void(string,string) Restore; - virtual void(void) touch; + virtual bool(void) CanCrouch; + virtual void(entity) Touch; virtual void(void) Hide; virtual void(void) Respawn; virtual void(void) Pain; diff --git a/src/gs-entbase/shared/NSMonster.qc b/src/gs-entbase/shared/NSMonster.qc index a6cfe644..ea3929c2 100644 --- a/src/gs-entbase/shared/NSMonster.qc +++ b/src/gs-entbase/shared/NSMonster.qc @@ -432,6 +432,31 @@ NSMonster::CheckRoute(void) } } + /* crouch attempt */ + if (CanCrouch()) { + vector src; + bool shouldcrouch = false; + + /* test up */ + src = origin + [0,0,24]; + makevectors(angles); + traceline(src, src + v_forward * 128, MOVE_NORMAL, this); + + /* we hit something */ + if (trace_fraction < 1.0) { + src = origin + [0,0, -8]; + traceline(src, src + v_forward * 128, MOVE_NORMAL, this); + + /* we can crouch here, so let's do it */ + if (trace_fraction >= 1.0) + shouldcrouch = true; + } + + /* entire way-link needs to be crouched. that's the law of the land */ + if (shouldcrouch || Route_GetNodeFlags(&m_pRoute[m_iCurNode]) & LF_CROUCH) + input_buttons |= INPUT_BUTTON8; + } + /*if (flDist == m_flLastDist) { m_flNodeGiveup += frametime; } else { @@ -545,7 +570,7 @@ NSMonster::NewRoute(vector destination) const int CONTENTBITS_MONSTER = CONTENTBIT_SOLID|CONTENTBIT_BODY|CONTENTBIT_MONSTERCLIP|CONTENTBIT_BOTCLIP; void PMoveCustom_RunPlayerPhysics(entity target); - +void PMoveCustom_RunCrouchPhysics(entity target); void NSMonster::Physics(void) { @@ -569,9 +594,13 @@ NSMonster::Physics(void) WalkRoute(); hitcontentsmaski = CONTENTBITS_MONSTER; - PMoveCustom_RunPlayerPhysics(this); + if (CanCrouch()) + PMoveCustom_RunCrouchPhysics(this); + else + PMoveCustom_RunPlayerPhysics(this); SetOrigin(origin); IdleNoise(); + button8 = input_buttons & INPUT_BUTTON8; // duck if (style != MONSTER_DEAD) { if (m_flAnimTime > time) { @@ -611,15 +640,21 @@ NSMonster::Physics(void) frame1time += frametime; } +bool +NSMonster::CanCrouch(void) +{ + return false; +} + void -NSMonster::touch(void) +NSMonster::Touch(entity eToucher) { if (movetype != MOVETYPE_WALK) return; - if (other.movetype == MOVETYPE_WALK) { - if (other.absmin[2] < origin[2]) - velocity = normalize(other.origin - origin) * -128; + if (eToucher.movetype == MOVETYPE_WALK) { + if (eToucher.absmin[2] < origin[2]) + velocity = normalize(eToucher.origin - origin) * -128; } } diff --git a/src/gs-entbase/shared/NSTalkMonster.qc b/src/gs-entbase/shared/NSTalkMonster.qc index 43eb7d36..4d75bde4 100644 --- a/src/gs-entbase/shared/NSTalkMonster.qc +++ b/src/gs-entbase/shared/NSTalkMonster.qc @@ -511,7 +511,12 @@ NSTalkMonster::Physics(void) CheckRoute(); WalkRoute(); hitcontentsmaski = CONTENTBITS_MONSTER; - PMoveCustom_RunPlayerPhysics(this); + + if (CanCrouch()) + PMoveCustom_RunCrouchPhysics(this); + else + PMoveCustom_RunPlayerPhysics(this); + SetOrigin(origin); } diff --git a/src/server/defs.h b/src/server/defs.h index b80d8080..1db1ff51 100644 --- a/src/server/defs.h +++ b/src/server/defs.h @@ -25,6 +25,9 @@ #include "traceattack.h" #include "footsteps.h" +#include "route.h" +#include "way.h" + #define AREAPORTAL_CLOSED 0 #define AREAPORTAL_OPEN 1 diff --git a/src/botlib/route.h b/src/server/route.h similarity index 93% rename from src/botlib/route.h rename to src/server/route.h index 81cdfdef..e9d57539 100644 --- a/src/botlib/route.h +++ b/src/server/route.h @@ -15,7 +15,6 @@ */ int Route_RoundDistance( float flDist ); -vector Route_SelectDestination( bot target ); void Bot_RouteCB( entity ent, vector dest, int numnodes, nodeslist_t *nodelist ); int Route_GetNodeFlags(nodeslist_t *node); diff --git a/src/botlib/way.h b/src/server/way.h similarity index 100% rename from src/botlib/way.h rename to src/server/way.h diff --git a/src/shared/pmove_custom.qc b/src/shared/pmove_custom.qc index 695624b9..6b4fc825 100644 --- a/src/shared/pmove_custom.qc +++ b/src/shared/pmove_custom.qc @@ -594,4 +594,41 @@ PMoveCustom_RunPlayerPhysics(entity target) touchtriggers(); self = oldself; } + +void +PMoveCustom_RunCrouchPhysics(entity target) +{ + int iFixCrouch = FALSE; + if (input_buttons & INPUT_BUTTON8) { + target.flags |= FL_CROUCHING; + } else { + // If we aren't holding down duck anymore and 'attempt' to stand up, prevent it + if (target.flags & FL_CROUCHING) { + if (PMove_IsStuck(target, [0,0,36], PHY_HULL_MIN, PHY_HULL_MAX) == FALSE) { + target.flags &= ~FL_CROUCHING; + iFixCrouch = TRUE; + } + } else { + target.flags &= ~FL_CROUCHING; + } + } + + if (target.flags & FL_CROUCHING) { + setsize(target, PHY_HULL_CROUCHED_MIN, PHY_HULL_CROUCHED_MAX); + target.view_ofs = PHY_VIEWPOS_CROUCHED; + } else { + setsize(target, PHY_HULL_MIN, PHY_HULL_MAX); + if (iFixCrouch && PMove_IsStuck(target, [0,0,0], PHY_HULL_MIN, PHY_HULL_MAX)) { + for (int i = 0; i < 36; i++) { + target.origin[2] += 1; + if (PMove_IsStuck(target, [0,0,0], target.mins, target.maxs) == FALSE) { + break; + } + } + } + setorigin(target, target.origin); + target.view_ofs = PHY_VIEWPOS; + } + PMoveCustom_RunPlayerPhysics(target); +} #endif diff --git a/src/shared/sound.qc b/src/shared/sound.qc index fd805c8c..7bf28311 100644 --- a/src/shared/sound.qc +++ b/src/shared/sound.qc @@ -14,6 +14,8 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +void(vector origin, string sample, float volume, float attenuation, float pitch) pointsound_proper = #483; + #ifndef SOUNDSHADER_DYNAMIC #ifndef SOUNDSHADER_MAX #define SOUNDSHADER_MAX 512 @@ -395,6 +397,63 @@ Sound_Distance(entity target, string shader) ); } +void +Sound_DistancePos(vector pos, string shader) +{ + int r; + float volume; + float radius; + float pitch; + int flag; + int sample; + + flag = 0; + sample = (int)hash_get(g_hashsounds, shader, -1); + + if (sample < 0) { +#ifdef SERVER + print(sprintf("^1Sound_DistancePos: shader %s is not precached (SERVER)\n", shader)); +#else + print(sprintf("^1Sound_DistancePos: shader %s is not precached (CLIENT)\n", shader)); +#endif + } + + /* pick a sample */ + r = floor(random(0, g_sounds[sample].sample_count)); + tokenizebyseparator(g_sounds[sample].samples, "\n"); + + /* set pitch */ + pitch = random(g_sounds[sample].pitch_min, g_sounds[sample].pitch_max); + radius = Sound_GetAttenuation(sample); + volume = g_sounds[sample].volume; + + /* flags */ + if (g_sounds[sample].flags & SNDFL_NOREVERB) { + flag |= SOUNDFLAG_NOREVERB; + } + if (g_sounds[sample].flags & SNDFL_LOOPING) { + flag |= SOUNDFLAG_FORCELOOP; + } + if (g_sounds[sample].flags & SNDFL_NODUPS) { + if (g_sounds[sample].playc >= g_sounds[sample].sample_count) { + g_sounds[sample].playc = 0; + } + r = g_sounds[sample].playc++; + } + +#ifdef CLIENT + if (g_sounds[sample].flags & SNDFL_OMNI) { + flag |= SOUNDFLAG_NOSPACIALISE; + } +#endif + +#ifdef DEVELOPER + print(sprintf("Sound_DistancePos: %s\n", argv(r))); +#endif + + pointsound_proper(pos, argv(r), volume, ATTN_NONE, pitch); +} + void Sound_Play(entity target, int chan, string shader) { @@ -512,7 +571,6 @@ Sound_Play(entity target, int chan, string shader) } } -void(vector origin, string sample, float volume, float attenuation, float pitch) pointsound_proper = #483; void Sound_PlayAt(vector pos, string shader) { @@ -565,6 +623,10 @@ Sound_PlayAt(vector pos, string shader) /* really? this doesn't do any more? */ pointsound_proper(pos, argv(r), g_sounds[sample].volume, Sound_GetAttenuation(sample), pitch); + + if (g_sounds[sample].distshader) { + Sound_DistancePos(pos, g_sounds[sample].distshader); + } } #ifdef CLIENT