From 63323222fe6cc673912baf205b02840f11e60aa8 Mon Sep 17 00:00:00 2001 From: Blixibon Date: Thu, 16 Jul 2020 15:43:30 +0000 Subject: [PATCH] Mapbase v4.3 - Fixed a crash with multiple trigger_look targets - Fixed an issue where some zombie submodel server ragdolls are not solid to the world - Fixed a crash with certain instance classes being loaded in a savegame before the class is registered - Added some of Tony Sergi's missing Source 2007 fixes (contributed by Kris) - Added "ClientCommand" hook for VScript to allow handling of unknown console commands - Added "PlayerRunCommand" hook for VScript to control player movement - Added new button-related script functions for players (GetButtons, DisableButtons, etc.) - Added CUserCmd accessor in VScript for the "PlayerRunCommand" hook - Added "GetWaterLevel" function for VScript - Exposed "Ignite" to VScript for controlling how a fire starts - Fixed NPCs being unable to unholster weapons - Fixed Mapbase crashing when Steam isn't running - Fixed issues with angled/updating sky_camera save/restore - Added VBSP "-skyboxcubemap" parameter to enable skybox default cubemaps + "-defaultcubemapres" to control their resolution - Added ability to disable VScript in a map (and fixed a few potential complications from disabling VScript) - Made clientside VScript only initialize after world is spawned in order to receive serverside script language in time - Added tons of VScript functions to CBaseAnimating related to bodygroups, sequences, etc. - Added VScript functions to players for getting user ID and player name, similar to logic_playerinfo - Added a few L4D2 script functions missing from the ASW SDK - Added "Localize" singleton with a single "GetTokenAsUTF8" function for getting localization strings - Disabled r_hunkalloclightmaps by the request of various users (apparently this completely removes the "Engine hunk overflow" error and allows for really high-res lightmaps) - Fixed npc_antlionguard NPC_TranslateActivity not hooking into base class (allows for VScript manipulation) - Added various unused antlion guard activities to npc_antlionguard AI, allowing for usage as registered activities - Added keyvalue to set LOS mask on combine_mine - Added +USE bounding box limiter to prop_interactable --- sp/src/game/client/c_baseanimating.cpp | 76 +++++++- sp/src/game/client/c_baseanimating.h | 11 ++ sp/src/game/client/c_basecombatweapon.cpp | 36 +++- sp/src/game/client/c_baseentity.h | 1 + sp/src/game/client/c_baseplayer.cpp | 26 ++- sp/src/game/client/c_baseplayer.h | 12 +- sp/src/game/client/c_playerlocaldata.h | 3 + sp/src/game/client/c_te_effect_dispatch.cpp | 4 + sp/src/game/client/c_te_effect_dispatch.h | 1 + sp/src/game/client/c_te_legacytempents.cpp | 5 + sp/src/game/client/c_world.cpp | 9 + sp/src/game/client/cdll_client_int.cpp | 9 +- sp/src/game/client/fx_tracer.cpp | 12 +- sp/src/game/client/hl2/c_basehlplayer.cpp | 5 + sp/src/game/client/hl2/c_basehlplayer.h | 4 +- sp/src/game/client/viewpostprocess.cpp | 38 +++- sp/src/game/client/vscript_client.cpp | 19 +- sp/src/game/client/weapon_selection.cpp | 9 +- sp/src/game/server/SkyCamera.cpp | 2 + sp/src/game/server/ai_basenpc.cpp | 10 +- sp/src/game/server/ai_basenpc.h | 2 +- sp/src/game/server/baseanimating.cpp | 58 ++++++- sp/src/game/server/baseanimating.h | 7 + sp/src/game/server/baseentity.cpp | 35 +++- sp/src/game/server/baseentity.h | 2 +- sp/src/game/server/bmodels.cpp | 4 +- sp/src/game/server/client.cpp | 30 ++++ sp/src/game/server/env_tonemap_controller.cpp | 119 +++++++++++++ sp/src/game/server/fogcontroller.cpp | 12 ++ sp/src/game/server/hl2/combine_mine.cpp | 9 +- sp/src/game/server/hl2/combine_mine.h | 5 +- sp/src/game/server/hl2/hl2_player.cpp | 5 + sp/src/game/server/hl2/hl2_player.h | 14 ++ sp/src/game/server/hl2/item_healthkit.cpp | 4 +- sp/src/game/server/hl2/npc_BaseZombie.cpp | 8 +- sp/src/game/server/hl2/npc_antlionguard.cpp | 25 +++ sp/src/game/server/hl2/prop_combine_ball.cpp | 57 +++++- sp/src/game/server/hl2/vehicle_airboat.cpp | 2 + sp/src/game/server/hl2/vehicle_jeep.cpp | 4 + sp/src/game/server/physconstraint.cpp | 17 ++ sp/src/game/server/physics_impact_damage.cpp | 48 ++++-- sp/src/game/server/player.cpp | 121 ++++++++++++- sp/src/game/server/player.h | 29 +++- sp/src/game/server/player_command.cpp | 21 ++- sp/src/game/server/playerinfomanager.cpp | 93 ++++------ sp/src/game/server/playerinfomanager.h | 6 + sp/src/game/server/playerlocaldata.cpp | 21 +++ sp/src/game/server/playerlocaldata.h | 3 + sp/src/game/server/point_template.cpp | 5 + sp/src/game/server/props.cpp | 30 ++++ sp/src/game/server/server_mapbase.vpc | 2 + sp/src/game/server/triggers.cpp | 3 + sp/src/game/server/util.h | 7 +- sp/src/game/server/vscript_server.cpp | 8 + sp/src/game/server/world.cpp | 2 +- .../Multiplayer/multiplayer_animstate.h | 9 +- sp/src/game/shared/basecombatweapon_shared.h | 4 + sp/src/game/shared/baseentity_shared.cpp | 4 + sp/src/game/shared/baseplayer_shared.cpp | 36 ++-- sp/src/game/shared/baseviewmodel_shared.cpp | 8 +- sp/src/game/shared/hl2/hl_gamemovement.cpp | 27 +++ sp/src/game/shared/hl2/hl_gamemovement.h | 2 + sp/src/game/shared/mapbase/mapbase_rpc.cpp | 22 ++- .../shared/mapbase/vscript_funcs_math.cpp | 57 +----- .../game/shared/mapbase/vscript_funcs_math.h | 66 +++++++ .../shared/mapbase/vscript_funcs_shared.cpp | 153 ++++++++++++----- .../shared/mapbase/vscript_funcs_shared.h | 162 ++++++++++++++++++ sp/src/game/shared/multiplay_gamerules.cpp | 7 +- sp/src/game/shared/playernet_vars.h | 45 +++++ sp/src/game/shared/predicted_viewmodel.cpp | 74 +++++--- sp/src/game/shared/predicted_viewmodel.h | 1 + sp/src/game/shared/shareddefs.h | 36 +++- sp/src/game/shared/vscript_shared.h | 56 ------ sp/src/public/const.h | 12 ++ sp/src/utils/vbsp/cubemap.cpp | 24 +++ sp/src/utils/vbsp/vbsp.cpp | 19 +- 76 files changed, 1575 insertions(+), 359 deletions(-) create mode 100644 sp/src/game/shared/mapbase/vscript_funcs_math.h create mode 100644 sp/src/game/shared/mapbase/vscript_funcs_shared.h diff --git a/sp/src/game/client/c_baseanimating.cpp b/sp/src/game/client/c_baseanimating.cpp index 6aa13486..051eeb2c 100644 --- a/sp/src/game/client/c_baseanimating.cpp +++ b/sp/src/game/client/c_baseanimating.cpp @@ -287,6 +287,23 @@ BEGIN_ENT_SCRIPTDESC( C_BaseAnimating, C_BaseEntity, "Animating models client-si #endif DEFINE_SCRIPTFUNC_NAMED( ScriptSetPoseParameter, "SetPoseParameter", "Set the specified pose parameter to the specified value" ) DEFINE_SCRIPTFUNC( IsSequenceFinished, "Ask whether the main sequence is done playing" ) +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC( SetBodygroup, "Sets a bodygroup") + DEFINE_SCRIPTFUNC( GetBodygroup, "Gets a bodygroup" ) + DEFINE_SCRIPTFUNC( GetBodygroupName, "Gets a bodygroup name" ) + DEFINE_SCRIPTFUNC( FindBodygroupByName, "Finds a bodygroup by name" ) + DEFINE_SCRIPTFUNC( GetBodygroupCount, "Gets the number of models in a bodygroup" ) + DEFINE_SCRIPTFUNC( GetNumBodyGroups, "Gets the number of bodygroups" ) + + DEFINE_SCRIPTFUNC( GetSequence, "Gets the current sequence" ) + DEFINE_SCRIPTFUNC( SetSequence, "Sets the current sequence" ) + DEFINE_SCRIPTFUNC( SequenceLoops, "Loops the current sequence" ) + DEFINE_SCRIPTFUNC( LookupSequence, "Gets the index of the specified sequence name" ) + DEFINE_SCRIPTFUNC( LookupActivity, "Gets the ID of the specified activity name" ) + DEFINE_SCRIPTFUNC( GetSequenceName, "Gets the name of the specified sequence index" ) + DEFINE_SCRIPTFUNC( GetSequenceActivityName, "Gets the activity name of the specified sequence index" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetSequenceActivity, "GetSequenceActivity", "Gets the activity ID of the specified sequence index" ) +#endif END_SCRIPTDESC(); C_ClientRagdoll::C_ClientRagdoll( bool bRestoring ) @@ -3868,18 +3885,33 @@ void C_BaseAnimating::FireEvent( const Vector& origin, const QAngle& angles, int // Eject brass case CL_EVENT_EJECTBRASS1: - if ( m_Attachments.Count() > 0 ) { - if ( MainViewOrigin().DistToSqr( GetAbsOrigin() ) < (256 * 256) ) + // Check if we're a weapon, if we belong to the local player, and if the local player is in third person - if all are true, don't do a muzzleflash in this instance, because + // we're using the view models dispatch for smoothness. + if ( dynamic_cast< C_BaseCombatWeapon *>(this) != NULL ) { - Vector attachOrigin; - QAngle attachAngles; - - if( GetAttachment( 2, attachOrigin, attachAngles ) ) + C_BaseCombatWeapon *pWeapon = dynamic_cast< C_BaseCombatWeapon *>(this); + if ( pWeapon && pWeapon->GetOwner() == C_BasePlayer::GetLocalPlayer() && ::input->CAM_IsThirdPerson() ) + break; + } + + if ( ( prediction->InPrediction() && !prediction->IsFirstTimePredicted() ) ) + break; + + if ( m_Attachments.Count() > 0 ) + { + if ( MainViewOrigin().DistToSqr( GetAbsOrigin() ) < (256 * 256) ) { - tempents->EjectBrass( attachOrigin, attachAngles, GetAbsAngles(), atoi( options ) ); + Vector attachOrigin; + QAngle attachAngles; + + if( GetAttachment( 2, attachOrigin, attachAngles ) ) + { + tempents->EjectBrass( attachOrigin, attachAngles, GetAbsAngles(), atoi( options ) ); + } } } + break; } break; @@ -3893,6 +3925,36 @@ void C_BaseAnimating::FireEvent( const Vector& origin, const QAngle& angles, int case AE_NPC_MUZZLEFLASH: { // Send out the effect for an NPC +#if defined ( HL2MP ) || defined ( SDK_DLL ) // works for the modified CSS weapons included in the new template sdk. + // HL2MP - Make third person muzzleflashes as reliable as the first person ones + // while in third person the view model dispatches the muzzleflash event - note: the weapon models dispatch them too, but not frequently. + if ( IsViewModel() ) + { + C_BasePlayer *pPlayer = ToBasePlayer( dynamic_cast(this)->GetOwner() ); + if ( pPlayer && pPlayer == C_BasePlayer::GetLocalPlayer()) + { + if ( ::input->CAM_IsThirdPerson() ) + { + // Dispatch on the weapon - the player model doesn't have the attachments in hl2mp. + C_BaseCombatWeapon *pWeapon = pPlayer->GetActiveWeapon(); + if ( !pWeapon ) + break; + pWeapon->DispatchMuzzleEffect( options, false ); + break; + } + } + } + + // Check if we're a weapon, if we belong to the local player, and if the local player is in third person - if all are true, don't do a muzzleflash in this instance, because + // we're using the view models dispatch for smoothness. + if ( dynamic_cast< C_BaseCombatWeapon *>(this) != NULL ) + { + C_BaseCombatWeapon *pWeapon = dynamic_cast< C_BaseCombatWeapon *>(this); + if ( pWeapon && pWeapon->GetOwner() == C_BasePlayer::GetLocalPlayer() && ::input->CAM_IsThirdPerson() ) + break; + } + +#endif DispatchMuzzleEffect( options, false ); break; } diff --git a/sp/src/game/client/c_baseanimating.h b/sp/src/game/client/c_baseanimating.h index 87c6b372..e1426b71 100644 --- a/sp/src/game/client/c_baseanimating.h +++ b/sp/src/game/client/c_baseanimating.h @@ -164,6 +164,13 @@ public: virtual void FireObsoleteEvent( const Vector& origin, const QAngle& angles, int event, const char *options ); virtual const char* ModifyEventParticles( const char* token ) { return token; } +#if defined ( SDK_DLL ) || defined ( HL2MP ) + virtual void ResetEventsParity() { m_nPrevResetEventsParity = -1; } // used to force animation events to function on players so the muzzleflashes and other events occur + // so new functions don't have to be made to parse the models like CSS does in ProcessMuzzleFlashEvent + // allows the multiplayer world weapon models to declare the muzzleflashes, and other effects like sp + // without the need to script it and add extra parsing code. +#endif + // Parses and distributes muzzle flash events virtual bool DispatchMuzzleEffect( const char *options, bool isFirstPerson ); @@ -468,6 +475,10 @@ protected: virtual bool CalcAttachments(); +#ifdef MAPBASE_VSCRIPT + int ScriptGetSequenceActivity( int iSequence ) { return GetSequenceActivity( iSequence ); } +#endif + private: // This method should return true if the bones have changed + SetupBones needs to be called virtual float LastBoneChangedTime() { return FLT_MAX; } diff --git a/sp/src/game/client/c_basecombatweapon.cpp b/sp/src/game/client/c_basecombatweapon.cpp index 87a11180..2d2fc3d2 100644 --- a/sp/src/game/client/c_basecombatweapon.cpp +++ b/sp/src/game/client/c_basecombatweapon.cpp @@ -181,11 +181,8 @@ void C_BaseCombatWeapon::OnDataChanged( DataUpdateType_t updateType ) } else // weapon carried by other player or not at all { - int overrideModelIndex = CalcOverrideModelIndex(); - if( overrideModelIndex != -1 && overrideModelIndex != GetModelIndex() ) - { - SetModelIndex( overrideModelIndex ); - } + // See comment below + EnsureCorrectRenderingModel(); } UpdateVisibility(); @@ -555,6 +552,35 @@ int C_BaseCombatWeapon::CalcOverrideModelIndex() } } +//----------------------------------------------------------------------------- +// If the local player is visible (thirdperson mode, tf2 taunts, etc., then make sure that we are using the +// w_ (world) model not the v_ (view) model or else the model can flicker, etc. +// Otherwise, if we're not the local player, always use the world model +//----------------------------------------------------------------------------- +void C_BaseCombatWeapon::EnsureCorrectRenderingModel() +{ + C_BasePlayer *localplayer = C_BasePlayer::GetLocalPlayer(); + if ( localplayer && + localplayer == GetOwner() && + !ShouldDrawUsingViewModel() ) + { + return; + } + + // BRJ 10/14/02 + // FIXME: Remove when Yahn's client-side prediction is done + // It's a hacky workaround for the model indices fighting + // (GetRenderBounds uses the model index, which is for the view model) + SetModelIndex( GetWorldModelIndex() ); + + // Validate our current sequence just in case ( in theory the view and weapon models should have the same sequences for sequences that overlap at least ) + CStudioHdr *pStudioHdr = GetModelPtr(); + if ( pStudioHdr && + GetSequence() >= pStudioHdr->GetNumSeq() ) + { + SetSequence( 0 ); + } +} //----------------------------------------------------------------------------- // tool recording diff --git a/sp/src/game/client/c_baseentity.h b/sp/src/game/client/c_baseentity.h index cb8eae7a..515ba21f 100644 --- a/sp/src/game/client/c_baseentity.h +++ b/sp/src/game/client/c_baseentity.h @@ -1010,6 +1010,7 @@ public: ///////////////// virtual bool IsPlayer( void ) const { return false; }; + virtual bool IsBot( void ) const { return ((GetFlags() & FL_FAKECLIENT) == FL_FAKECLIENT) ? true : false; } virtual bool IsBaseCombatCharacter( void ) { return false; }; virtual C_BaseCombatCharacter *MyCombatCharacterPointer( void ) { return NULL; } virtual bool IsNPC( void ) { return false; } diff --git a/sp/src/game/client/c_baseplayer.cpp b/sp/src/game/client/c_baseplayer.cpp index 09f12a03..b7382f4e 100644 --- a/sp/src/game/client/c_baseplayer.cpp +++ b/sp/src/game/client/c_baseplayer.cpp @@ -225,6 +225,14 @@ BEGIN_RECV_TABLE_NOBASE( CPlayerLocalData, DT_Local ) RecvPropInt( RECVINFO( m_audio.soundscapeIndex ) ), RecvPropInt( RECVINFO( m_audio.localBits ) ), RecvPropEHandle( RECVINFO( m_audio.ent ) ), + + //Tony; tonemap stuff! -- TODO! Optimize this with bit sizes from env_tonemap_controller. + RecvPropFloat ( RECVINFO( m_TonemapParams.m_flTonemapScale ) ), + RecvPropFloat ( RECVINFO( m_TonemapParams.m_flTonemapRate ) ), + RecvPropFloat ( RECVINFO( m_TonemapParams.m_flBloomScale ) ), + + RecvPropFloat ( RECVINFO( m_TonemapParams.m_flAutoExposureMin ) ), + RecvPropFloat ( RECVINFO( m_TonemapParams.m_flAutoExposureMax ) ), END_RECV_TABLE() // -------------------------------------------------------------------------------- // @@ -426,7 +434,10 @@ BEGIN_PREDICTION_DATA( C_BasePlayer ) END_PREDICTION_DATA() +// link this in each derived player class, like the server!! +#if 0 LINK_ENTITY_TO_CLASS( player, C_BasePlayer ); +#endif // -------------------------------------------------------------------------------- // // Functions. @@ -1609,7 +1620,14 @@ void C_BasePlayer::CalcChaseCamView(Vector& eyeOrigin, QAngle& eyeAngles, float& } } - if ( target && !target->IsPlayer() && target->IsNextBot() ) + // SDK TODO + if ( target && target->IsBaseTrain() ) + { + // if this is a train, we want to be back a little further so we can see more of it + flMaxDistance *= 2.5f; + m_flObserverChaseDistance = flMaxDistance; + } + else if ( target && !target->IsPlayer() && target->IsNextBot() ) { // if this is a boss, we want to be back a little further so we can see more of it flMaxDistance *= 2.5f; @@ -1942,6 +1960,12 @@ void C_BasePlayer::ThirdPersonSwitch( bool bThirdperson ) } } } + else + { + CBaseCombatWeapon *pWeapon = GetActiveWeapon(); + if ( pWeapon ) + pWeapon->ThirdPersonSwitch( bThirdperson ); + } } diff --git a/sp/src/game/client/c_baseplayer.h b/sp/src/game/client/c_baseplayer.h index 5faec479..3e746311 100644 --- a/sp/src/game/client/c_baseplayer.h +++ b/sp/src/game/client/c_baseplayer.h @@ -183,7 +183,7 @@ public: // Flashlight void Flashlight( void ); - void UpdateFlashlight( void ); + virtual void UpdateFlashlight( void ); // Weapon selection code virtual bool IsAllowedToSwitchWeapons( void ) { return !IsObserver(); } @@ -458,18 +458,18 @@ public: protected: - void CalcPlayerView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov ); - void CalcVehicleView(IClientVehicle *pVehicle, Vector& eyeOrigin, QAngle& eyeAngles, - float& zNear, float& zFar, float& fov ); + //Tony; made all of these virtual so mods can override. + virtual void CalcPlayerView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov ); + virtual void CalcVehicleView(IClientVehicle *pVehicle, Vector& eyeOrigin, QAngle& eyeAngles, float& zNear, float& zFar, float& fov ); virtual void CalcObserverView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov ); virtual Vector GetChaseCamViewOffset( CBaseEntity *target ); - void CalcChaseCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov ); + virtual void CalcChaseCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov ); virtual void CalcInEyeCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov ); virtual float GetDeathCamInterpolationTime(); virtual void CalcDeathCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov ); - void CalcRoamingView(Vector& eyeOrigin, QAngle& eyeAngles, float& fov); + virtual void CalcRoamingView(Vector& eyeOrigin, QAngle& eyeAngles, float& fov); virtual void CalcFreezeCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov ); // Check to see if we're in vgui input mode... diff --git a/sp/src/game/client/c_playerlocaldata.h b/sp/src/game/client/c_playerlocaldata.h index 95b6d48d..1efb8021 100644 --- a/sp/src/game/client/c_playerlocaldata.h +++ b/sp/src/game/client/c_playerlocaldata.h @@ -75,6 +75,9 @@ public: bool m_bSlowMovement; + //Tony; added so tonemap controller can work in multiplayer with inputs. + tonemap_params_t m_TonemapParams; + }; #endif // C_PLAYERLOCALDATA_H diff --git a/sp/src/game/client/c_te_effect_dispatch.cpp b/sp/src/game/client/c_te_effect_dispatch.cpp index 160e11b7..e0688a2d 100644 --- a/sp/src/game/client/c_te_effect_dispatch.cpp +++ b/sp/src/game/client/c_te_effect_dispatch.cpp @@ -179,6 +179,10 @@ void DispatchEffect( const char *pName, const CEffectData &data ) te->DispatchEffect( filter, 0.0, data.m_vOrigin, pName, data ); } +void DispatchEffect( const char *pName, const CEffectData &data, IRecipientFilter &filter ) +{ + te->DispatchEffect( filter, 0.0, data.m_vOrigin, pName, data ); +} //----------------------------------------------------------------------------- // Playback diff --git a/sp/src/game/client/c_te_effect_dispatch.h b/sp/src/game/client/c_te_effect_dispatch.h index 63fa6173..8abaaeab 100644 --- a/sp/src/game/client/c_te_effect_dispatch.h +++ b/sp/src/game/client/c_te_effect_dispatch.h @@ -42,5 +42,6 @@ public: void DispatchEffectToCallback( const char *pEffectName, const CEffectData &m_EffectData ); void DispatchEffect( const char *pName, const CEffectData &data ); +void DispatchEffect( const char *pName, const CEffectData &data, IRecipientFilter &filter ); #endif // C_TE_EFFECT_DISPATCH_H diff --git a/sp/src/game/client/c_te_legacytempents.cpp b/sp/src/game/client/c_te_legacytempents.cpp index 8cec8730..8c7a8551 100644 --- a/sp/src/game/client/c_te_legacytempents.cpp +++ b/sp/src/game/client/c_te_legacytempents.cpp @@ -1833,6 +1833,9 @@ void CTempEnts::MuzzleFlash( const Vector& pos1, const QAngle& angles, int type, // UNDONE: These need their own effects/sprites. For now use the pistol // SMG1 +#if defined ( HL2MP ) // HACK for hl2mp, make the default muzzleflash the smg muzzleflash for weapons like the RPG that are using 'type 0' + default: +#endif // HL2MP case MUZZLEFLASH_SMG1: if ( firstPerson ) { @@ -1870,10 +1873,12 @@ void CTempEnts::MuzzleFlash( const Vector& pos1, const QAngle& angles, int type, } break; +#if !defined ( HL2MP ) // HACK for hl2mp, make the default muzzleflash the smg muzzleflash for weapons like the RPG that are using 'type 0' default: // There's no supported muzzle flash for the type specified! Assert(0); break; +#endif // HL2MP } #endif diff --git a/sp/src/game/client/c_world.cpp b/sp/src/game/client/c_world.cpp index 238f4cb3..dcec1f09 100644 --- a/sp/src/game/client/c_world.cpp +++ b/sp/src/game/client/c_world.cpp @@ -67,6 +67,10 @@ BEGIN_RECV_TABLE( C_World, DT_World ) #endif END_RECV_TABLE() +#ifdef MAPBASE_VSCRIPT +extern bool VScriptClientInit(); +#endif + C_World::C_World( void ) { @@ -125,6 +129,11 @@ void C_World::OnDataChanged( DataUpdateType_t updateType ) engine->SetOcclusionParameters( params ); modelinfo->SetLevelScreenFadeRange( m_flMinPropScreenSpaceWidth, m_flMaxPropScreenSpaceWidth ); + +#ifdef MAPBASE_VSCRIPT + // This is now here so that C_World has time to receive the selected script language + VScriptClientInit(); +#endif } } diff --git a/sp/src/game/client/cdll_client_int.cpp b/sp/src/game/client/cdll_client_int.cpp index 6fa98d68..275655f0 100644 --- a/sp/src/game/client/cdll_client_int.cpp +++ b/sp/src/game/client/cdll_client_int.cpp @@ -147,11 +147,6 @@ #include "fbxsystem/fbxsystem.h" #endif -#ifdef DISCORD_RPC -#include "discord_rpc.h" -#include -#endif - extern vgui::IInputInternal *g_InputInternal; //============================================================================= @@ -1126,6 +1121,10 @@ int CHLClient::Init( CreateInterfaceFn appSystemFactory, CreateInterfaceFn physi MapbaseRPC_Init(); #endif +#ifdef MAPBASE + CommandLine()->AppendParm( "+r_hunkalloclightmaps", "0" ); +#endif + return true; } diff --git a/sp/src/game/client/fx_tracer.cpp b/sp/src/game/client/fx_tracer.cpp index f0ca0e13..8ce6de18 100644 --- a/sp/src/game/client/fx_tracer.cpp +++ b/sp/src/game/client/fx_tracer.cpp @@ -37,11 +37,13 @@ Vector GetTracerOrigin( const CEffectData &data ) C_BaseEntity *pEnt = data.GetEntity(); -// This check should probably be for all multiplayer games, investigate later -#if defined( HL2MP ) || defined( TF_CLIENT_DLL ) - if ( pEnt && pEnt->IsDormant() ) - return vecStart; -#endif + // This check should probably be for all multiplayer games, investigate later + // 10/09/2008: It should. + if ( gpGlobals->maxClients > 1 ) + { + if ( pEnt && pEnt->IsDormant() ) + return vecStart; + } C_BaseCombatWeapon *pWpn = dynamic_cast( pEnt ); if ( pWpn && pWpn->ShouldDrawUsingViewModel() ) diff --git a/sp/src/game/client/hl2/c_basehlplayer.cpp b/sp/src/game/client/hl2/c_basehlplayer.cpp index 1bfe8891..17b3cf53 100644 --- a/sp/src/game/client/hl2/c_basehlplayer.cpp +++ b/sp/src/game/client/hl2/c_basehlplayer.cpp @@ -38,6 +38,11 @@ BEGIN_PREDICTION_DATA( C_BaseHLPlayer ) DEFINE_PRED_FIELD( m_fIsSprinting, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), END_PREDICTION_DATA() +// link to the correct class. +#if !defined ( HL2MP ) && !defined ( PORTAL ) +LINK_ENTITY_TO_CLASS( player, C_BaseHLPlayer ); +#endif + //----------------------------------------------------------------------------- // Purpose: Drops player's primary weapon //----------------------------------------------------------------------------- diff --git a/sp/src/game/client/hl2/c_basehlplayer.h b/sp/src/game/client/hl2/c_basehlplayer.h index c6507e95..1a9f7836 100644 --- a/sp/src/game/client/hl2/c_basehlplayer.h +++ b/sp/src/game/client/hl2/c_basehlplayer.h @@ -5,7 +5,6 @@ // $Workfile: $ // $NoKeywords: $ //=============================================================================// - #if !defined( C_BASEHLPLAYER_H ) #define C_BASEHLPLAYER_H #ifdef _WIN32 @@ -34,7 +33,8 @@ public: float GetZoom( void ); bool IsZoomed( void ) { return m_HL2Local.m_bZooming; } - bool IsSprinting( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_SPRINT; } + //Tony; minor cosmetic really, fix confusion by simply renaming this one; everything calls IsSprinting(), and this isn't really even used. + bool IsSprintActive( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_SPRINT; } bool IsFlashlightActive( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_FLASHLIGHT; } bool IsBreatherActive( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_BREATHER; } diff --git a/sp/src/game/client/viewpostprocess.cpp b/sp/src/game/client/viewpostprocess.cpp index 39c2237e..2ad1b0d9 100644 --- a/sp/src/game/client/viewpostprocess.cpp +++ b/sp/src/game/client/viewpostprocess.cpp @@ -15,6 +15,10 @@ #include "colorcorrectionmgr.h" #include "view_scene.h" #include "c_world.h" + +//Tony; new +#include "c_baseplayer.h" + #include "bitmap/tgawriter.h" #include "filesystem.h" #include "tier0/vprof.h" @@ -765,7 +769,19 @@ static float GetCurrentBloomScale( void ) { // Use the appropriate bloom scale settings. Mapmakers's overrides the convar settings. float flCurrentBloomScale = 1.0f; - if ( g_bUseCustomBloomScale ) + + //Tony; get the local player first.. + C_BasePlayer *pLocalPlayer = NULL; + + if ( ( gpGlobals->maxClients > 1 ) ) + pLocalPlayer = (C_BasePlayer*)C_BasePlayer::GetLocalPlayer(); + + //Tony; in multiplayer, get the local player etc. + if ( (pLocalPlayer != NULL && pLocalPlayer->m_Local.m_TonemapParams.m_flAutoExposureMin > 0.0f) ) + { + flCurrentBloomScale = pLocalPlayer->m_Local.m_TonemapParams.m_flAutoExposureMin; + } + else if ( g_bUseCustomBloomScale ) { flCurrentBloomScale = g_flCustomBloomScale; } @@ -778,8 +794,19 @@ static float GetCurrentBloomScale( void ) static void GetExposureRange( float *flAutoExposureMin, float *flAutoExposureMax ) { + //Tony; get the local player first.. + C_BasePlayer *pLocalPlayer = NULL; + + if ( ( gpGlobals->maxClients > 1 ) ) + pLocalPlayer = (C_BasePlayer*)C_BasePlayer::GetLocalPlayer(); + + //Tony; in multiplayer, get the local player etc. + if ( (pLocalPlayer != NULL && pLocalPlayer->m_Local.m_TonemapParams.m_flAutoExposureMin > 0.0f) ) + { + *flAutoExposureMin = pLocalPlayer->m_Local.m_TonemapParams.m_flAutoExposureMin; + } // Get min - if ( ( g_bUseCustomAutoExposureMin ) && ( g_flCustomAutoExposureMin > 0.0f ) ) + else if ( ( g_bUseCustomAutoExposureMin ) && ( g_flCustomAutoExposureMin > 0.0f ) ) { *flAutoExposureMin = g_flCustomAutoExposureMin; } @@ -788,8 +815,13 @@ static void GetExposureRange( float *flAutoExposureMin, float *flAutoExposureMax *flAutoExposureMin = mat_autoexposure_min.GetFloat(); } + //Tony; in multiplayer, get the value from the local player, if it's set. + if ( (pLocalPlayer != NULL && pLocalPlayer->m_Local.m_TonemapParams.m_flAutoExposureMax > 0.0f) ) + { + *flAutoExposureMax = pLocalPlayer->m_Local.m_TonemapParams.m_flAutoExposureMax; + } // Get max - if ( ( g_bUseCustomAutoExposureMax ) && ( g_flCustomAutoExposureMax > 0.0f ) ) + else if ( ( g_bUseCustomAutoExposureMax ) && ( g_flCustomAutoExposureMax > 0.0f ) ) { *flAutoExposureMax = g_flCustomAutoExposureMax; } diff --git a/sp/src/game/client/vscript_client.cpp b/sp/src/game/client/vscript_client.cpp index 29b998f8..234466be 100644 --- a/sp/src/game/client/vscript_client.cpp +++ b/sp/src/game/client/vscript_client.cpp @@ -445,6 +445,10 @@ bool VScriptClientInit() { // Allow world entity to override script language scriptLanguage = GetClientWorldEntity()->GetScriptLanguage(); + + // Less than SL_NONE means the script language should literally be none + if (scriptLanguage < SL_NONE) + scriptLanguage = SL_NONE; } else #endif @@ -476,7 +480,11 @@ bool VScriptClientInit() if( g_pScriptVM ) { +#ifdef MAPBASE_VSCRIPT + Log( "VSCRIPT CLIENT: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() ); +#else Log( "VSCRIPT: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() ); +#endif ScriptRegisterFunction( g_pScriptVM, GetMapName, "Get the name of the map."); ScriptRegisterFunction( g_pScriptVM, Time, "Get the current server time" ); ScriptRegisterFunction( g_pScriptVM, DoIncludeScript, "Execute a script (internal)" ); @@ -553,17 +561,22 @@ public: virtual void LevelInitPreEntity( void ) { m_bAllowEntityCreationInScripts = true; +#ifndef MAPBASE_VSCRIPT // Now initted in C_World VScriptClientInit(); +#endif } virtual void LevelInitPostEntity( void ) { m_bAllowEntityCreationInScripts = false; #ifdef MAPBASE_VSCRIPT - C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); - if (pPlayer) + if (g_pScriptVM) { - g_pScriptVM->SetValue( "player", pPlayer->GetScriptInstance() ); + C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); + if (pPlayer) + { + g_pScriptVM->SetValue( "player", pPlayer->GetScriptInstance() ); + } } #endif } diff --git a/sp/src/game/client/weapon_selection.cpp b/sp/src/game/client/weapon_selection.cpp index 66666b59..5568c532 100644 --- a/sp/src/game/client/weapon_selection.cpp +++ b/sp/src/game/client/weapon_selection.cpp @@ -249,9 +249,14 @@ int CBaseHudWeaponSelection::KeyInput( int down, ButtonCode_t keynum, const char return 0; } - if ( down >= 1 && keynum >= KEY_1 && keynum <= KEY_9 ) + //Tony; check 0 as well, otherwise you have to have 0 bound to slot10 no matter what. + if ( down >= 1 && keynum >= KEY_0 && keynum <= KEY_9 ) { - if ( HandleHudMenuInput( keynum - KEY_0 ) ) + //Tony; 0 is actually '10' (slot10) + if (keynum == KEY_0) + keynum = KEY_A; //Dealing with button codes, so just use KEY_A, which is equal to 11 anyway. + + if ( HandleHudMenuInput( keynum - 1 ) ) return 0; } diff --git a/sp/src/game/server/SkyCamera.cpp b/sp/src/game/server/SkyCamera.cpp index c7e277cf..5ef2f900 100644 --- a/sp/src/game/server/SkyCamera.cpp +++ b/sp/src/game/server/SkyCamera.cpp @@ -50,6 +50,8 @@ BEGIN_DATADESC( CSkyCamera ) DEFINE_FIELD( m_skyboxData.origin, FIELD_VECTOR ), DEFINE_FIELD( m_skyboxData.area, FIELD_INTEGER ), #ifdef MAPBASE + DEFINE_FIELD( m_skyboxData.angles, FIELD_VECTOR ), + DEFINE_FIELD( m_skyboxData.skycamera, FIELD_EHANDLE ), DEFINE_KEYFIELD( m_skyboxData.skycolor, FIELD_COLOR32, "skycolor" ), DEFINE_KEYFIELD( m_bUseAnglesForSky, FIELD_BOOLEAN, "use_angles_for_sky" ), #endif diff --git a/sp/src/game/server/ai_basenpc.cpp b/sp/src/game/server/ai_basenpc.cpp index bcc7db74..cd0e236b 100644 --- a/sp/src/game/server/ai_basenpc.cpp +++ b/sp/src/game/server/ai_basenpc.cpp @@ -1191,7 +1191,8 @@ void CAI_BaseNPC::NotifyFriendsOfDamage( CBaseEntity *pAttackerEntity ) { if ( (originNpc.AsVector2D() - origin.AsVector2D()).LengthSqr() < NEAR_XY_SQ ) { - if ( pNpc->GetSquad() == GetSquad() || IRelationType( pNpc ) == D_LI ) + //Tony; add a check to make sure this doesn't get called if the npc isn't in a squad + if ( ( pNpc->GetSquad() == GetSquad() && !( pNpc->GetSquad() == NULL || GetSquad() == NULL ) ) || IRelationType( pNpc ) == D_LI ) pNpc->OnFriendDamaged( this, pAttacker ); } } @@ -5189,16 +5190,17 @@ void CAI_BaseNPC::PrescheduleThink( void ) // Please excuse the readability here. if (CapabilitiesGet() & bits_CAP_USE_WEAPONS) { - // If we should have our gun out, fetch it - if ( ShouldUnholsterWeapon() ) + if ( CanUnholsterWeapon() ) { - if ( m_iDesiredWeaponState == DESIREDWEAPONSTATE_IGNORE ) + // If we should have our gun out, fetch it + if ( ShouldUnholsterWeapon() && m_iDesiredWeaponState == DESIREDWEAPONSTATE_IGNORE ) { SetDesiredWeaponState( DESIREDWEAPONSTATE_UNHOLSTERED ); } } else if (m_iDesiredWeaponState == DESIREDWEAPONSTATE_UNHOLSTERED) { + // If we cannot have our gun out, refuse to fetch it SetDesiredWeaponState( DESIREDWEAPONSTATE_IGNORE ); } diff --git a/sp/src/game/server/ai_basenpc.h b/sp/src/game/server/ai_basenpc.h index 2b86cca5..7604404e 100644 --- a/sp/src/game/server/ai_basenpc.h +++ b/sp/src/game/server/ai_basenpc.h @@ -1715,7 +1715,7 @@ public: virtual bool DoHolster(void); virtual bool DoUnholster(void); - virtual bool ShouldUnholsterWeapon() { return GetState() == NPC_STATE_COMBAT && CanUnholsterWeapon(); } + virtual bool ShouldUnholsterWeapon() { return GetState() == NPC_STATE_COMBAT; } virtual bool CanUnholsterWeapon() { return IsWeaponHolstered(); } void InputGiveWeaponHolstered( inputdata_t &inputdata ); diff --git a/sp/src/game/server/baseanimating.cpp b/sp/src/game/server/baseanimating.cpp index 0b1b5cc7..a71d344b 100644 --- a/sp/src/game/server/baseanimating.cpp +++ b/sp/src/game/server/baseanimating.cpp @@ -32,6 +32,9 @@ #include "gib.h" #include "CRagdollMagnet.h" #endif +#ifdef MAPBASE_VSCRIPT +#include "mapbase/vscript_funcs_math.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -293,11 +296,36 @@ BEGIN_ENT_SCRIPTDESC( CBaseAnimating, CBaseEntity, "Animating models" ) DEFINE_SCRIPTFUNC_NAMED( ScriptSetPoseParameter, "SetPoseParameter", "Set the specified pose parameter to the specified value" ) DEFINE_SCRIPTFUNC( LookupBone, "Get the named bone id" ) DEFINE_SCRIPTFUNC_NAMED( ScriptGetBoneTransform, "GetBoneTransform", "Get the transform for the specified bone" ) - DEFINE_SCRIPTFUNC( Dissolve, "" ) - DEFINE_SCRIPTFUNC( Scorch, "Makes the entity darker from scorching" ) + DEFINE_SCRIPTFUNC( GetPhysicsBone, "Get physics bone from bone index" ) + DEFINE_SCRIPTFUNC( GetNumBones, "Get the number of bones" ) + DEFINE_SCRIPTFUNC( GetSequence, "Gets the current sequence" ) + DEFINE_SCRIPTFUNC( SetSequence, "Sets the current sequence" ) + DEFINE_SCRIPTFUNC( SequenceLoops, "Loops the current sequence" ) + DEFINE_SCRIPTFUNC( LookupSequence, "Gets the index of the specified sequence name" ) + DEFINE_SCRIPTFUNC( LookupActivity, "Gets the ID of the specified activity name" ) + DEFINE_SCRIPTFUNC_NAMED( HasMovement, "SequenceHasMovement", "Checks if the specified sequence has movement" ) + DEFINE_SCRIPTFUNC( GetSequenceMoveYaw, "Gets the move yaw of the specified sequence" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetSequenceMoveDist, "GetSequenceMoveDist", "Gets the move distance of the specified sequence" ) + DEFINE_SCRIPTFUNC( GetSequenceName, "Gets the name of the specified sequence index" ) + DEFINE_SCRIPTFUNC( GetSequenceActivityName, "Gets the activity name of the specified sequence index" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetSequenceActivity, "GetSequenceActivity", "Gets the activity ID of the specified sequence index" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSelectWeightedSequence, "SelectWeightedSequence", "Selects a sequence for the specified activity ID" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptSelectHeaviestSequence, "SelectHeaviestSequence", "Selects the sequence with the heaviest weight for the specified activity ID" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetSequenceKeyValues, "GetSequenceKeyValues", "Get a KeyValue class instance on the specified sequence. WARNING: This uses the same KeyValue pointer as GetModelKeyValues!" ) #endif DEFINE_SCRIPTFUNC( IsSequenceFinished, "Ask whether the main sequence is done playing" ) DEFINE_SCRIPTFUNC( SetBodygroup, "Sets a bodygroup") +#ifdef MAPBASE_VSCRIPT + DEFINE_SCRIPTFUNC( GetBodygroup, "Gets a bodygroup" ) + DEFINE_SCRIPTFUNC( GetBodygroupName, "Gets a bodygroup name" ) + DEFINE_SCRIPTFUNC( FindBodygroupByName, "Finds a bodygroup by name" ) + DEFINE_SCRIPTFUNC( GetBodygroupCount, "Gets the number of models in a bodygroup" ) + DEFINE_SCRIPTFUNC( GetNumBodyGroups, "Gets the number of bodygroups" ) + + DEFINE_SCRIPTFUNC( Dissolve, "" ) + DEFINE_SCRIPTFUNC( Ignite, "" ) + DEFINE_SCRIPTFUNC( Scorch, "Makes the entity darker from scorching" ) +#endif END_SCRIPTDESC(); CBaseAnimating::CBaseAnimating() @@ -2193,8 +2221,6 @@ void CBaseAnimating::ScriptSetPoseParameter( const char* szName, float fValue ) SetPoseParameter( pHdr, iPoseParam, fValue ); } -extern matrix3x4_t *ToMatrix3x4( HSCRIPT hMat ); - void CBaseAnimating::ScriptGetBoneTransform( int iBone, HSCRIPT hTransform ) { if (hTransform == NULL) @@ -2202,6 +2228,30 @@ void CBaseAnimating::ScriptGetBoneTransform( int iBone, HSCRIPT hTransform ) GetBoneTransform( iBone, *ToMatrix3x4( hTransform ) ); } + +//----------------------------------------------------------------------------- +// VScript access to sequence's key values +// for iteration and value access, use: +// ScriptFindKey, ScriptGetFirstSubKey, ScriptGetString, +// ScriptGetInt, ScriptGetFloat, ScriptGetNextKey +// NOTE: This is recycled from ScriptGetModelKeyValues() and uses its pointer!!! +//----------------------------------------------------------------------------- +HSCRIPT CBaseAnimating::ScriptGetSequenceKeyValues( int iSequence ) +{ + KeyValues *pSeqKeyValues = GetSequenceKeyValues( iSequence ); + HSCRIPT hScript = NULL; + if ( pSeqKeyValues ) + { + // UNDONE: how does destructor get called on this + m_pScriptModelKeyValues = new CScriptKeyValues( pSeqKeyValues ); + + // UNDONE: who calls ReleaseInstance on this??? Does name need to be unique??? + + hScript = g_pScriptVM->RegisterInstance( m_pScriptModelKeyValues ); + } + + return hScript; +} #endif //----------------------------------------------------------------------------- diff --git a/sp/src/game/server/baseanimating.h b/sp/src/game/server/baseanimating.h index 80dfafed..da43ef40 100644 --- a/sp/src/game/server/baseanimating.h +++ b/sp/src/game/server/baseanimating.h @@ -195,6 +195,13 @@ public: void ScriptSetPoseParameter(const char* szName, float fValue); void ScriptGetBoneTransform( int iBone, HSCRIPT hTransform ); + + int ScriptGetSequenceActivity( int iSequence ) { return GetSequenceActivity( iSequence ); } + float ScriptGetSequenceMoveDist( int iSequence ) { return GetSequenceMoveDist( GetModelPtr(), iSequence ); } + int ScriptSelectHeaviestSequence( int activity ) { return SelectHeaviestSequence( (Activity)activity ); } + int ScriptSelectWeightedSequence( int activity, int curSequence ) { return SelectWeightedSequence( (Activity)activity, curSequence ); } + + HSCRIPT ScriptGetSequenceKeyValues( int iSequence ); #endif // These return the attachment in the space of the entity diff --git a/sp/src/game/server/baseentity.cpp b/sp/src/game/server/baseentity.cpp index 4230e44b..ac299bfd 100644 --- a/sp/src/game/server/baseentity.cpp +++ b/sp/src/game/server/baseentity.cpp @@ -66,6 +66,9 @@ #include "mapbase/matchers.h" #include "mapbase/datadesc_mod.h" #endif +#ifdef MAPBASE_VSCRIPT +#include "mapbase/vscript_funcs_math.h" +#endif #if defined( TF_DLL ) #include "tf_gamerules.h" @@ -1635,7 +1638,27 @@ int CBaseEntity::VPhysicsTakeDamage( const CTakeDamageInfo &info ) if ( gameFlags & FVPHYSICS_PLAYER_HELD ) { // if the player is holding the object, use it's real mass (player holding reduced the mass) - CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + CBasePlayer *pPlayer = NULL; + + if ( AI_IsSinglePlayer() ) + { + pPlayer = UTIL_GetLocalPlayer(); + } + else + { + // See which MP player is holding the physics object and then use that player to get the real mass of the object. + // This is ugly but better than having linkage between an object and its "holding" player. + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) + { + CBasePlayer *tempPlayer = UTIL_PlayerByIndex( i ); + if ( tempPlayer && (tempPlayer->GetHeldObject() == this ) ) + { + pPlayer = tempPlayer; + break; + } + } + } + if ( pPlayer ) { float mass = pPlayer->GetHeldObjectMass( VPhysicsGetObject() ); @@ -2221,6 +2244,8 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities" DEFINE_SCRIPTFUNC( TakeHealth, "Give this entity health" ) DEFINE_SCRIPTFUNC( IsAlive, "Return true if this entity is alive" ) + DEFINE_SCRIPTFUNC( GetWaterLevel, "Get current level of water submergence" ) + DEFINE_SCRIPTFUNC_NAMED( ScriptGetContext, "GetContext", "Get a response context value" ) DEFINE_SCRIPTFUNC_NAMED( ScriptAddContext, "AddContext", "Add a response context value" ) @@ -9651,6 +9676,14 @@ void CBaseEntity::ScriptSetColorVector( const Vector& vecColor ) { SetRenderColor( vecColor.x, vecColor.y, vecColor.z ); } + +//----------------------------------------------------------------------------- +// Vscript: Gets the entity matrix transform +//----------------------------------------------------------------------------- +HSCRIPT CBaseEntity::ScriptEntityToWorldTransform( void ) +{ + return ScriptCreateMatrixInstance( EntityToWorldTransform() ); +} #endif diff --git a/sp/src/game/server/baseentity.h b/sp/src/game/server/baseentity.h index aca58d01..fa4dea17 100644 --- a/sp/src/game/server/baseentity.h +++ b/sp/src/game/server/baseentity.h @@ -1988,7 +1988,7 @@ public: const Vector& ScriptGetUp(void) { static Vector vecUp; GetVectors(NULL, NULL, &vecUp); return vecUp; } #ifdef MAPBASE_VSCRIPT - HSCRIPT ScriptEntityToWorldTransform(void) { return ScriptCreateMatrixInstance( EntityToWorldTransform() ); } + HSCRIPT ScriptEntityToWorldTransform( void ); #endif const char* ScriptGetModelName(void) const; diff --git a/sp/src/game/server/bmodels.cpp b/sp/src/game/server/bmodels.cpp index bcfbb144..8c5ca480 100644 --- a/sp/src/game/server/bmodels.cpp +++ b/sp/src/game/server/bmodels.cpp @@ -16,9 +16,7 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -#define SF_BRUSH_ACCDCC 16// brush should accelerate and decelerate when toggled -#define SF_BRUSH_HURT 32// rotating brush that inflicts pain based on rotation speed -#define SF_ROTATING_NOT_SOLID 64 // some special rotating objects are not solid. +//Tony; moved the spawnflags to util.h to prevent more mistakes in the future. // =================== FUNC_WALL ============================================== class CFuncWall : public CBaseEntity diff --git a/sp/src/game/server/client.cpp b/sp/src/game/server/client.cpp index 357f0f22..2da25686 100644 --- a/sp/src/game/server/client.cpp +++ b/sp/src/game/server/client.cpp @@ -45,6 +45,10 @@ #include "weapon_physcannon.h" #endif +#ifdef MAPBASE +#include "fmtstr.h" +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -1521,6 +1525,32 @@ void ClientCommand( CBasePlayer *pPlayer, const CCommand &args ) { if ( !g_pGameRules->ClientCommand( pPlayer, args ) ) { +#ifdef MAPBASE_VSCRIPT + // Console command hook for VScript + if ( pPlayer->m_ScriptScope.IsInitialized() ) + { + ScriptVariant_t functionReturn; + g_pScriptVM->SetValue( "command", ScriptVariant_t( pCmd ) ); + + ScriptVariant_t varTable; + g_pScriptVM->CreateTable( varTable ); + HSCRIPT hTable = varTable.m_hScript; + for ( int i = 0; i < args.ArgC(); i++ ) + { + g_pScriptVM->SetValue( hTable, CNumStr( i ), ScriptVariant_t( args[i] ) ); + } + g_pScriptVM->SetValue( "args", varTable ); + + pPlayer->CallScriptFunction( "ClientCommand", &functionReturn ); + + g_pScriptVM->ClearValue( "command" ); + g_pScriptVM->ClearValue( "args" ); + g_pScriptVM->ReleaseValue( varTable ); + + if (functionReturn.m_bool) + return; + } +#endif if ( Q_strlen( pCmd ) > 128 ) { ClientPrint( pPlayer, HUD_PRINTCONSOLE, "Console command too long.\n" ); diff --git a/sp/src/game/server/env_tonemap_controller.cpp b/sp/src/game/server/env_tonemap_controller.cpp index a45a1107..39998e4b 100644 --- a/sp/src/game/server/env_tonemap_controller.cpp +++ b/sp/src/game/server/env_tonemap_controller.cpp @@ -8,6 +8,9 @@ #include "baseentity.h" #include "entityoutput.h" #include "convar.h" + +#include "player.h" //Tony; need player.h so we can trigger inputs on the player, from our inputs! + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -122,6 +125,22 @@ int CEnvTonemapController::UpdateTransmitState() //----------------------------------------------------------------------------- void CEnvTonemapController::InputSetTonemapScale( inputdata_t &inputdata ) { + //Tony; in multiplayer, we check to see if the activator is a player, if they are, we trigger an input on them, and then get out. + //if there is no activator, or the activator is not a player; ie: LogicAuto, we set the 'global' values. + if ( ( gpGlobals->maxClients > 1 ) ) + { + if ( inputdata.pActivator != NULL && inputdata.pActivator->IsPlayer() ) + { +// DevMsg("activator is a player: InputSetTonemapScale\n"); + CBasePlayer *pPlayer = ToBasePlayer(inputdata.pActivator); + if (pPlayer) + { + pPlayer->InputSetTonemapScale( inputdata ); + return; + } + } + } + float flRemapped = inputdata.value.Float(); mat_hdr_tonemapscale.SetValue( flRemapped ); } @@ -131,6 +150,10 @@ void CEnvTonemapController::InputSetTonemapScale( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CEnvTonemapController::InputBlendTonemapScale( inputdata_t &inputdata ) { + //Tony; TODO!!! -- tonemap scale blending does _not_ work properly in multiplayer.. + if ( ( gpGlobals->maxClients > 1 ) ) + return; + char parseString[255]; Q_strncpy(parseString, inputdata.value.String(), sizeof(parseString)); @@ -181,6 +204,22 @@ void CEnvTonemapController::InputSetBloomScaleRange( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CEnvTonemapController::InputSetTonemapRate( inputdata_t &inputdata ) { + //Tony; in multiplayer, we check to see if the activator is a player, if they are, we trigger an input on them, and then get out. + //if there is no activator, or the activator is not a player; ie: LogicAuto, we set the 'global' values. + if ( ( gpGlobals->maxClients > 1 ) ) + { + if ( inputdata.pActivator != NULL && inputdata.pActivator->IsPlayer() ) + { +// DevMsg("activator is a player: InputSetTonemapRate\n"); + CBasePlayer *pPlayer = ToBasePlayer(inputdata.pActivator); + if (pPlayer) + { + pPlayer->InputSetTonemapRate( inputdata ); + return; + } + } + } + // TODO: There should be a better way to do this. ConVarRef mat_hdr_manual_tonemap_rate( "mat_hdr_manual_tonemap_rate" ); if ( mat_hdr_manual_tonemap_rate.IsValid() ) @@ -212,6 +251,22 @@ void CEnvTonemapController::UpdateTonemapScaleBlend( void ) //----------------------------------------------------------------------------- void CEnvTonemapController::InputSetAutoExposureMin( inputdata_t &inputdata ) { + //Tony; in multiplayer, we check to see if the activator is a player, if they are, we trigger an input on them, and then get out. + //if there is no activator, or the activator is not a player; ie: LogicAuto, we set the 'global' values. + if ( ( gpGlobals->maxClients > 1 ) ) + { + if ( inputdata.pActivator != NULL && inputdata.pActivator->IsPlayer() ) + { +// DevMsg("activator is a player: InputSetAutoExposureMin\n"); + CBasePlayer *pPlayer = ToBasePlayer(inputdata.pActivator); + if (pPlayer) + { + pPlayer->InputSetAutoExposureMin( inputdata ); + return; + } + } + } + m_flCustomAutoExposureMin = inputdata.value.Float(); m_bUseCustomAutoExposureMin = true; } @@ -221,6 +276,22 @@ void CEnvTonemapController::InputSetAutoExposureMin( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CEnvTonemapController::InputSetAutoExposureMax( inputdata_t &inputdata ) { + //Tony; in multiplayer, we check to see if the activator is a player, if they are, we trigger an input on them, and then get out. + //if there is no activator, or the activator is not a player; ie: LogicAuto, we set the 'global' values. + if ( ( gpGlobals->maxClients > 1 ) ) + { + if ( inputdata.pActivator != NULL && inputdata.pActivator->IsPlayer() ) + { +// DevMsg("activator is a player: InputSetAutoExposureMax\n"); + CBasePlayer *pPlayer = ToBasePlayer(inputdata.pActivator); + if (pPlayer) + { + pPlayer->InputSetAutoExposureMax( inputdata ); + return; + } + } + } + m_flCustomAutoExposureMax = inputdata.value.Float(); m_bUseCustomAutoExposureMax = true; } @@ -230,6 +301,22 @@ void CEnvTonemapController::InputSetAutoExposureMax( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CEnvTonemapController::InputUseDefaultAutoExposure( inputdata_t &inputdata ) { + //Tony; in multiplayer, we check to see if the activator is a player, if they are, we trigger an input on them, and then get out. + //if there is no activator, or the activator is not a player; ie: LogicAuto, we set the 'global' values. + if ( ( gpGlobals->maxClients > 1 ) ) + { + if ( inputdata.pActivator != NULL && inputdata.pActivator->IsPlayer() ) + { +// DevMsg("activator is a player: InputUseDefaultAutoExposure\n"); + CBasePlayer *pPlayer = ToBasePlayer(inputdata.pActivator); + if (pPlayer) + { + pPlayer->InputUseDefaultAutoExposure( inputdata ); + return; + } + } + } + m_bUseCustomAutoExposureMin = false; m_bUseCustomAutoExposureMax = false; } @@ -239,6 +326,22 @@ void CEnvTonemapController::InputUseDefaultAutoExposure( inputdata_t &inputdata //----------------------------------------------------------------------------- void CEnvTonemapController::InputSetBloomScale( inputdata_t &inputdata ) { + //Tony; in multiplayer, we check to see if the activator is a player, if they are, we trigger an input on them, and then get out. + //if there is no activator, or the activator is not a player; ie: LogicAuto, we set the 'global' values. + if ( ( gpGlobals->maxClients > 1 ) ) + { + if ( inputdata.pActivator != NULL && inputdata.pActivator->IsPlayer() ) + { +// DevMsg("activator is a player: InputSetBloomScale\n"); + CBasePlayer *pPlayer = ToBasePlayer(inputdata.pActivator); + if (pPlayer) + { + pPlayer->InputSetBloomScale( inputdata ); + return; + } + } + } + m_flCustomBloomScale = inputdata.value.Float(); m_flCustomBloomScaleMinimum = m_flCustomBloomScale; m_bUseCustomBloomScale = true; @@ -249,5 +352,21 @@ void CEnvTonemapController::InputSetBloomScale( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void CEnvTonemapController::InputUseDefaultBloomScale( inputdata_t &inputdata ) { + //Tony; in multiplayer, we check to see if the activator is a player, if they are, we trigger an input on them, and then get out. + //if there is no activator, or the activator is not a player; ie: LogicAuto, we set the 'global' values. + if ( ( gpGlobals->maxClients > 1 ) ) + { + if ( inputdata.pActivator != NULL && inputdata.pActivator->IsPlayer() ) + { +// DevMsg("activator is a player: InputUseDefaultBloomScale\n"); + CBasePlayer *pPlayer = ToBasePlayer(inputdata.pActivator); + if (pPlayer) + { + pPlayer->InputUseDefaultBloomScale( inputdata ); + return; + } + } + } + m_bUseCustomBloomScale = false; } diff --git a/sp/src/game/server/fogcontroller.cpp b/sp/src/game/server/fogcontroller.cpp index 7057982a..3ed75060 100644 --- a/sp/src/game/server/fogcontroller.cpp +++ b/sp/src/game/server/fogcontroller.cpp @@ -387,5 +387,17 @@ void CFogSystem::LevelInitPostEntity( void ) pPlayer->InitFogController(); } } + else + { + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex( i ); + + if ( pPlayer && ( pPlayer->m_Local.m_PlayerFog.m_hCtrl.Get() == NULL ) ) + { + pPlayer->InitFogController(); + } + } + } } diff --git a/sp/src/game/server/hl2/combine_mine.cpp b/sp/src/game/server/hl2/combine_mine.cpp index b0145366..104c0b0d 100644 --- a/sp/src/game/server/hl2/combine_mine.cpp +++ b/sp/src/game/server/hl2/combine_mine.cpp @@ -90,6 +90,7 @@ BEGIN_DATADESC( CBounceBomb ) #ifdef MAPBASE DEFINE_KEYFIELD( m_iInitialState, FIELD_INTEGER, "InitialState" ), DEFINE_KEYFIELD( m_bCheapWarnSound, FIELD_BOOLEAN, "CheapWarnSound" ), + DEFINE_KEYFIELD( m_iLOSMask, FIELD_INTEGER, "LOSMask" ), #endif DEFINE_KEYFIELD( m_iModification, FIELD_INTEGER, "Modification" ), @@ -962,7 +963,11 @@ float CBounceBomb::FindNearestNPC() if( flDist < flNearest ) { // Now do a visibility test. +#ifdef MAPBASE + if( FVisible( pNPC, m_iLOSMask ) ) +#else if( FVisible( pNPC, MASK_SOLID_BRUSHONLY ) ) +#endif { flNearest = flDist; SetNearestNPC( pNPC ); @@ -979,7 +984,7 @@ float CBounceBomb::FindNearestNPC() { float flDist = (pPlayer->GetAbsOrigin() - GetAbsOrigin() ).LengthSqr(); - if( flDist < flNearest && FVisible( pPlayer, MASK_SOLID_BRUSHONLY ) ) + if( flDist < flNearest && FVisible( pPlayer, m_iLOSMask ) ) { flNearest = flDist; SetNearestNPC( pPlayer ); @@ -1010,7 +1015,7 @@ float CBounceBomb::FindNearestNPC() float flDist = (pPlayer->GetAbsOrigin() - GetAbsOrigin() ).LengthSqr(); #ifdef MAPBASE - if( flDist < flNearest && FVisible( pPlayer, MASK_SOLID_BRUSHONLY ) && bPassesFilter ) + if( flDist < flNearest && FVisible( pPlayer, m_iLOSMask ) && bPassesFilter ) #else if( flDist < flNearest && FVisible( pPlayer, MASK_SOLID_BRUSHONLY ) ) #endif diff --git a/sp/src/game/server/hl2/combine_mine.h b/sp/src/game/server/hl2/combine_mine.h index 9d0d78e3..fdcd68da 100644 --- a/sp/src/game/server/hl2/combine_mine.h +++ b/sp/src/game/server/hl2/combine_mine.h @@ -34,7 +34,7 @@ class CBounceBomb : public CBaseAnimating, public CDefaultPlayerPickupVPhysics public: #ifdef MAPBASE - CBounceBomb() { m_pWarnSound = NULL; m_bPlacedByPlayer = false; m_flExplosionDelay = 0.5f; } + CBounceBomb() { m_pWarnSound = NULL; m_bPlacedByPlayer = false; m_flExplosionDelay = 0.5f; m_iLOSMask = MASK_SOLID_BRUSHONLY; } #else CBounceBomb() { m_pWarnSound = NULL; m_bPlacedByPlayer = false; } #endif @@ -122,6 +122,9 @@ private: #ifdef MAPBASE int m_iInitialState; bool m_bCheapWarnSound; + + // Allows control over the mask used in LOS + int m_iLOSMask; #endif bool m_bPlacedByPlayer; diff --git a/sp/src/game/server/hl2/hl2_player.cpp b/sp/src/game/server/hl2/hl2_player.cpp index 2a29a8a8..d04992fd 100644 --- a/sp/src/game/server/hl2/hl2_player.cpp +++ b/sp/src/game/server/hl2/hl2_player.cpp @@ -3819,6 +3819,11 @@ float CHL2_Player::GetHeldObjectMass( IPhysicsObject *pHeldObject ) return mass; } +CBaseEntity *CHL2_Player::GetHeldObject( void ) +{ + return PhysCannonGetHeldEntity( GetActiveWeapon() ); +} + //----------------------------------------------------------------------------- // Purpose: Force the player to drop any physics objects he's carrying //----------------------------------------------------------------------------- diff --git a/sp/src/game/server/hl2/hl2_player.h b/sp/src/game/server/hl2/hl2_player.h index d7ab4598..58ad64cd 100644 --- a/sp/src/game/server/hl2/hl2_player.h +++ b/sp/src/game/server/hl2/hl2_player.h @@ -15,6 +15,11 @@ #include "simtimer.h" #include "soundenvelope.h" +// In HL2MP we need to inherit from BaseMultiplayerPlayer! +#if defined ( HL2MP ) +#include "basemultiplayerplayer.h" +#endif + class CAI_Squad; class CPropCombineBall; @@ -75,10 +80,18 @@ public: //============================================================================= // >> HL2_PLAYER //============================================================================= +#if defined ( HL2MP ) +class CHL2_Player : public CBaseMultiplayerPlayer +#else class CHL2_Player : public CBasePlayer +#endif { public: +#if defined ( HL2MP ) + DECLARE_CLASS( CHL2_Player, CBaseMultiplayerPlayer ); +#else DECLARE_CLASS( CHL2_Player, CBasePlayer ); +#endif #ifdef MAPBASE_VSCRIPT DECLARE_ENT_SCRIPTDESC(); #endif @@ -280,6 +293,7 @@ public: virtual bool IsHoldingEntity( CBaseEntity *pEnt ); virtual void ForceDropOfCarriedPhysObjects( CBaseEntity *pOnlyIfHoldindThis ); virtual float GetHeldObjectMass( IPhysicsObject *pHeldObject ); + virtual CBaseEntity *CHL2_Player::GetHeldObject( void ); virtual bool IsFollowingPhysics( void ) { return (m_afPhysicsFlags & PFLAG_ONBARNACLE) > 0; } void InputForceDropPhysObjects( inputdata_t &data ); diff --git a/sp/src/game/server/hl2/item_healthkit.cpp b/sp/src/game/server/hl2/item_healthkit.cpp index 70e1a21a..628f873e 100644 --- a/sp/src/game/server/hl2/item_healthkit.cpp +++ b/sp/src/game/server/hl2/item_healthkit.cpp @@ -78,7 +78,7 @@ bool CHealthKit::MyTouch( CBasePlayer *pPlayer ) CPASAttenuationFilter filter( pPlayer, "HealthKit.Touch" ); EmitSound( filter, pPlayer->entindex(), "HealthKit.Touch" ); - if ( g_pGameRules->ItemShouldRespawn( this ) ) + if ( g_pGameRules->ItemShouldRespawn( this ) == GR_ITEM_RESPAWN_YES ) { Respawn(); } @@ -131,7 +131,7 @@ public: CPASAttenuationFilter filter( pPlayer, "HealthVial.Touch" ); EmitSound( filter, pPlayer->entindex(), "HealthVial.Touch" ); - if ( g_pGameRules->ItemShouldRespawn( this ) ) + if ( g_pGameRules->ItemShouldRespawn( this ) == GR_ITEM_RESPAWN_YES ) { Respawn(); } diff --git a/sp/src/game/server/hl2/npc_BaseZombie.cpp b/sp/src/game/server/hl2/npc_BaseZombie.cpp index c8d2865d..bbe1f9d0 100644 --- a/sp/src/game/server/hl2/npc_BaseZombie.cpp +++ b/sp/src/game/server/hl2/npc_BaseZombie.cpp @@ -1154,7 +1154,7 @@ void CNPC_BaseZombie::DieChopped( const CTakeDamageInfo &info ) if ( flFadeTime > 0.0 ) { - pLegGib->SUB_StartFadeOut( flFadeTime ); + pLegGib->SUB_StartFadeOut( flFadeTime, false ); } } else @@ -1196,7 +1196,7 @@ void CNPC_BaseZombie::DieChopped( const CTakeDamageInfo &info ) if ( flFadeTime > 0.0 ) { - pTorsoGib->SUB_StartFadeOut( flFadeTime ); + pTorsoGib->SUB_StartFadeOut( flFadeTime, false ); } } else @@ -2354,7 +2354,7 @@ void CNPC_BaseZombie::BecomeTorso( const Vector &vecTorsoForce, const Vector &ve if (flFadeTime > 0.0) { - pGib->SUB_StartFadeOut( flFadeTime ); + pGib->SUB_StartFadeOut( flFadeTime, false ); } } else @@ -2506,7 +2506,7 @@ void CNPC_BaseZombie::ReleaseHeadcrab( const Vector &vecOrigin, const Vector &ve if (ShouldIgniteZombieGib()) static_cast(pGib)->Ignite( random->RandomFloat( 8.0, 12.0 ), false ); - pGib->SUB_StartFadeOut( 15 ); + pGib->SUB_StartFadeOut( 15, false ); } else pGib = CreateRagGib( GetHeadcrabModel(), vecOrigin, GetLocalAngles(), vecVelocity, 15, ShouldIgniteZombieGib() ); diff --git a/sp/src/game/server/hl2/npc_antlionguard.cpp b/sp/src/game/server/hl2/npc_antlionguard.cpp index a571e1e2..2635f28c 100644 --- a/sp/src/game/server/hl2/npc_antlionguard.cpp +++ b/sp/src/game/server/hl2/npc_antlionguard.cpp @@ -190,6 +190,17 @@ Activity ACT_ANTLIONGUARD_CHARGE_STOP; Activity ACT_ANTLIONGUARD_CHARGE_HIT; Activity ACT_ANTLIONGUARD_CHARGE_ANTICIPATION; +#ifdef MAPBASE +// Unused activities +Activity ACT_ANTLIONGUARD_COVER_ENTER; +Activity ACT_ANTLIONGUARD_COVER_LOOP; +Activity ACT_ANTLIONGUARD_COVER_EXIT; +Activity ACT_ANTLIONGUARD_COVER_ADVANCE; +Activity ACT_ANTLIONGUARD_COVER_FLINCH; +Activity ACT_ANTLIONGUARD_SNEAK; +Activity ACT_ANTLIONGUARD_RUN_FULL; +#endif + // Anim events int AE_ANTLIONGUARD_CHARGE_HIT; int AE_ANTLIONGUARD_SHOVE_PHYSOBJECT; @@ -3374,6 +3385,11 @@ void CNPC_AntlionGuard::InputClearChargeTarget( inputdata_t &inputdata ) //----------------------------------------------------------------------------- Activity CNPC_AntlionGuard::NPC_TranslateActivity( Activity baseAct ) { +#ifdef MAPBASE + // Needed for VScript NPC_TranslateActiviy hook + baseAct = BaseClass::NPC_TranslateActivity( baseAct ); +#endif + //See which run to use if ( ( baseAct == ACT_RUN ) && IsCurSchedule( SCHED_ANTLIONGUARD_CHARGE ) ) return (Activity) ACT_ANTLIONGUARD_CHARGE_RUN; @@ -4684,6 +4700,15 @@ AI_BEGIN_CUSTOM_NPC( npc_antlionguard, CNPC_AntlionGuard ) DECLARE_ACTIVITY( ACT_ANTLIONGUARD_PHYSHIT_FL ) DECLARE_ACTIVITY( ACT_ANTLIONGUARD_PHYSHIT_RR ) DECLARE_ACTIVITY( ACT_ANTLIONGUARD_PHYSHIT_RL ) +#ifdef MAPBASE + DECLARE_ACTIVITY( ACT_ANTLIONGUARD_COVER_ENTER ) + DECLARE_ACTIVITY( ACT_ANTLIONGUARD_COVER_LOOP ) + DECLARE_ACTIVITY( ACT_ANTLIONGUARD_COVER_EXIT ) + DECLARE_ACTIVITY( ACT_ANTLIONGUARD_COVER_ADVANCE ) + DECLARE_ACTIVITY( ACT_ANTLIONGUARD_COVER_FLINCH ) + DECLARE_ACTIVITY( ACT_ANTLIONGUARD_SNEAK ) + DECLARE_ACTIVITY( ACT_ANTLIONGUARD_RUN_FULL ) +#endif //Adrian: events go here DECLARE_ANIMEVENT( AE_ANTLIONGUARD_CHARGE_HIT ) diff --git a/sp/src/game/server/hl2/prop_combine_ball.cpp b/sp/src/game/server/hl2/prop_combine_ball.cpp index e94d2bc4..7a6f287b 100644 --- a/sp/src/game/server/hl2/prop_combine_ball.cpp +++ b/sp/src/game/server/hl2/prop_combine_ball.cpp @@ -794,9 +794,63 @@ void CPropCombineBall::WhizSoundThink() pPhysicsObject->GetPosition( &vecPosition, NULL ); pPhysicsObject->GetVelocity( &vecVelocity, NULL ); - if ( gpGlobals->maxClients == 1 ) + // Multiplayer equivelent, loops through players and decides if it should go or not, like SP. + if ( gpGlobals->maxClients > 1 ) + { + CBasePlayer *pPlayer = NULL; + + for (int i = 1;i <= gpGlobals->maxClients; i++) + { + pPlayer = UTIL_PlayerByIndex( i ); + if ( pPlayer ) + { + Vector vecDelta; + VectorSubtract( pPlayer->GetAbsOrigin(), vecPosition, vecDelta ); + VectorNormalize( vecDelta ); + if ( DotProduct( vecDelta, vecVelocity ) > 0.5f ) + { + Vector vecEndPoint; + VectorMA( vecPosition, 2.0f * TICK_INTERVAL, vecVelocity, vecEndPoint ); + float flDist = CalcDistanceToLineSegment( pPlayer->GetAbsOrigin(), vecPosition, vecEndPoint ); + if ( flDist < 200.0f ) + { + // We're basically doing what CPASAttenuationFilter does, on a per-user basis, if it passes we create the filter and send off the sound + // if it doesn't, we skip the player. + float distance, maxAudible; + Vector vecRelative; + + VectorSubtract( pPlayer->EarPosition(), vecPosition, vecRelative ); + distance = VectorLength( vecRelative ); + maxAudible = ( 2 * SOUND_NORMAL_CLIP_DIST ) / ATTN_NORM; + if ( distance <= maxAudible ) + continue; + + // Set the recipient to the player it checked against so multiple sounds don't play. + CSingleUserRecipientFilter filter( pPlayer ); + + EmitSound_t ep; + ep.m_nChannel = CHAN_STATIC; + if ( hl2_episodic.GetBool() ) + { + ep.m_pSoundName = "NPC_CombineBall_Episodic.WhizFlyby"; + } + else + { + ep.m_pSoundName = "NPC_CombineBall.WhizFlyby"; + } + ep.m_flVolume = 1.0f; + ep.m_SoundLevel = SNDLVL_NORM; + + EmitSound( filter, entindex(), ep ); + } + } + } + } + } + else { CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + if ( pPlayer ) { Vector vecDelta; @@ -831,6 +885,7 @@ void CPropCombineBall::WhizSoundThink() } } } + } SetContextThink( &CPropCombineBall::WhizSoundThink, gpGlobals->curtime + 2.0f * TICK_INTERVAL, s_pWhizThinkContext ); diff --git a/sp/src/game/server/hl2/vehicle_airboat.cpp b/sp/src/game/server/hl2/vehicle_airboat.cpp index c8a49ddb..120ffcaf 100644 --- a/sp/src/game/server/hl2/vehicle_airboat.cpp +++ b/sp/src/game/server/hl2/vehicle_airboat.cpp @@ -1573,6 +1573,8 @@ void CPropAirboat::FireGun( ) Vector vecForward; GetAttachment( m_nGunBarrelAttachment, vecGunPosition, &vecForward ); + CDisablePredictionFiltering disabler; + // NOTE: For the airboat, unable to fire really means the aim is clamped Vector vecAimPoint; if ( !m_bUnableToFire ) diff --git a/sp/src/game/server/hl2/vehicle_jeep.cpp b/sp/src/game/server/hl2/vehicle_jeep.cpp index 5b10afdf..0b47f3cb 100644 --- a/sp/src/game/server/hl2/vehicle_jeep.cpp +++ b/sp/src/game/server/hl2/vehicle_jeep.cpp @@ -907,6 +907,8 @@ void CPropJeep::FireCannon( void ) if ( m_bUnableToFire ) return; + CDisablePredictionFiltering disabler; + m_flCannonTime = gpGlobals->curtime + 0.2f; m_bCannonCharging = false; @@ -945,6 +947,8 @@ void CPropJeep::FireCannon( void ) //----------------------------------------------------------------------------- void CPropJeep::FireChargedCannon( void ) { + CDisablePredictionFiltering disabler; + bool penetrated = false; m_bCannonCharging = false; diff --git a/sp/src/game/server/physconstraint.cpp b/sp/src/game/server/physconstraint.cpp index 8fa25cdd..467c7cfb 100644 --- a/sp/src/game/server/physconstraint.cpp +++ b/sp/src/game/server/physconstraint.cpp @@ -569,6 +569,8 @@ void CPhysConstraint::GetConstraintObjects( hl_constraint_info_t &info ) // Missing one object, assume the world instead if ( info.pObjects[0] == NULL && info.pObjects[1] ) { + // This brokens hanging lamps in hl2mp +#if !defined ( HL2MP ) if ( Q_strlen(STRING(m_nameAttach1)) ) { Warning("Bogus constraint %s (attaches ENTITY NOT FOUND:%s to %s)\n", GetDebugName(), STRING(m_nameAttach1), STRING(m_nameAttach2)); @@ -577,11 +579,15 @@ void CPhysConstraint::GetConstraintObjects( hl_constraint_info_t &info ) return; #endif // HL2_EPISODIC } +#endif info.pObjects[0] = g_PhysWorldObject; info.massScale[0] = info.massScale[1] = 1.0f; // no mass scale on world constraint + } else if ( info.pObjects[0] && !info.pObjects[1] ) { + // This brokens hanging lamps in hl2mp +#if !defined ( HL2MP ) if ( Q_strlen(STRING(m_nameAttach2)) ) { Warning("Bogus constraint %s (attaches %s to ENTITY NOT FOUND:%s)\n", GetDebugName(), STRING(m_nameAttach1), STRING(m_nameAttach2)); @@ -590,6 +596,7 @@ void CPhysConstraint::GetConstraintObjects( hl_constraint_info_t &info ) return; #endif // HL2_EPISODIC } +#endif info.pObjects[1] = info.pObjects[0]; info.pObjects[0] = g_PhysWorldObject; // Try to make the world object consistently object0 for ease of implementation info.massScale[0] = info.massScale[1] = 1.0f; // no mass scale on world constraint @@ -1038,6 +1045,16 @@ public: for ( int i = 0; i < 2; i++ ) { info.pObjects[i]->WorldToLocal( &ballsocket.constraintPosition[i], GetAbsOrigin() ); + // HACKHACK - the mapper forgot to put in some sane physics damping + float damping, adamping; + info.pObjects[i]->GetDamping(&damping, &adamping); + if (damping < .2f) { + damping = .2f; + } + if (adamping < .2f) { + adamping = .2f; + } + info.pObjects[i]->SetDamping(&damping, &adamping); } GetBreakParams( ballsocket.constraint, info ); ballsocket.constraint.torqueLimit = 0; diff --git a/sp/src/game/server/physics_impact_damage.cpp b/sp/src/game/server/physics_impact_damage.cpp index 164568e2..312b8a1e 100644 --- a/sp/src/game/server/physics_impact_damage.cpp +++ b/sp/src/game/server/physics_impact_damage.cpp @@ -335,15 +335,32 @@ float CalculatePhysicsImpactDamage( int index, gamevcollisionevent_t *pEvent, co if ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) { - if ( gpGlobals->maxClients == 1 ) + // if the player is holding the object, use its real mass (player holding reduced the mass) + CBasePlayer *pPlayer = NULL; + + if ( 1 == gpGlobals->maxClients ) { - // if the player is holding the object, use it's real mass (player holding reduced the mass) - CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); - if ( pPlayer ) + pPlayer = UTIL_GetLocalPlayer(); + } + else + { + // See which MP player is holding the physics object and then use that player to get the real mass of the object. + // This is ugly but better than having linkage between an object and its "holding" player. + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) { - otherMass = pPlayer->GetHeldObjectMass( pEvent->pObjects[otherIndex] ); + CBasePlayer *tempPlayer = UTIL_PlayerByIndex( i ); + if ( tempPlayer && pEvent->pEntities[index] == tempPlayer->GetHeldObject() ) + { + pPlayer = tempPlayer; + break; + } } } + + if ( pPlayer ) + { + otherMass = pPlayer->GetHeldObjectMass( pEvent->pObjects[otherIndex] ); + } } // NOTE: sum the mass of each object in this system for the purpose of damage @@ -438,16 +455,23 @@ float CalculatePhysicsImpactDamage( int index, gamevcollisionevent_t *pEvent, co } else if ( pEvent->pObjects[index]->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) { - if ( gpGlobals->maxClients == 1 ) + // if the player is holding the object, use it's real mass (player holding reduced the mass) + CBasePlayer *pPlayer = NULL; + if ( 1 == gpGlobals->maxClients ) { - // if the player is holding the object, use it's real mass (player holding reduced the mass) - CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); - if ( pPlayer ) + pPlayer = UTIL_GetLocalPlayer(); + } + else + { + // See which MP player is holding the physics object and then use that player to get the real mass of the object. + // This is ugly but better than having linkage between an object and its "holding" player. + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) { - float mass = pPlayer->GetHeldObjectMass( pEvent->pObjects[index] ); - if ( mass > 0 ) + CBasePlayer *tempPlayer = UTIL_PlayerByIndex( i ); + if ( tempPlayer && pEvent->pEntities[index] == tempPlayer->GetHeldObject() ) { - invMass = 1.0f / mass; + pPlayer = tempPlayer; + break; } } } diff --git a/sp/src/game/server/player.cpp b/sp/src/game/server/player.cpp index a89ff7db..a48650a5 100644 --- a/sp/src/game/server/player.cpp +++ b/sp/src/game/server/player.cpp @@ -86,6 +86,10 @@ #endif #endif +#ifdef MAPBASE_VSCRIPT +#include "mapbase/vscript_funcs_shared.h" +#endif + ConVar autoaim_max_dist( "autoaim_max_dist", "2160" ); // 2160 = 180 feet ConVar autoaim_max_deflect( "autoaim_max_deflect", "0.99" ); @@ -485,6 +489,10 @@ BEGIN_ENT_SCRIPTDESC( CBasePlayer, CBaseCombatCharacter, "The player entity." ) DEFINE_SCRIPTFUNC_NAMED( VScriptGetExpresser, "GetExpresser", "Gets a handle for this player's expresser." ) + DEFINE_SCRIPTFUNC( GetPlayerName, "Gets the player's name." ) + DEFINE_SCRIPTFUNC_NAMED( GetUserID, "GetPlayerUserId", "Gets the player's user ID." ) + DEFINE_SCRIPTFUNC( GetNetworkIDString, "Gets the player's network (i.e. Steam) ID." ) + DEFINE_SCRIPTFUNC( FragCount, "Gets the number of frags (kills) this player has in a multiplayer game." ) DEFINE_SCRIPTFUNC( DeathCount, "Gets the number of deaths this player has had in a multiplayer game." ) DEFINE_SCRIPTFUNC( IsConnected, "Returns true if this player is connected." ) @@ -498,6 +506,18 @@ BEGIN_ENT_SCRIPTDESC( CBasePlayer, CBaseCombatCharacter, "The player entity." ) DEFINE_SCRIPTFUNC( FlashlightTurnOn, "Turns on the flashlight." ) DEFINE_SCRIPTFUNC( FlashlightTurnOff, "Turns off the flashlight." ) + DEFINE_SCRIPTFUNC( DisableButtons, "Disables the specified button mask." ) + DEFINE_SCRIPTFUNC( EnableButtons, "Enables the specified button mask if it was disabled before." ) + DEFINE_SCRIPTFUNC( ForceButtons, "Forces the specified button mask." ) + DEFINE_SCRIPTFUNC( UnforceButtons, "Unforces the specified button mask if it was forced before." ) + + DEFINE_SCRIPTFUNC( GetButtons, "Gets the player's active buttons." ) + DEFINE_SCRIPTFUNC( GetButtonPressed, "Gets the player's currently pressed buttons." ) + DEFINE_SCRIPTFUNC( GetButtonReleased, "Gets the player's just-released buttons." ) + DEFINE_SCRIPTFUNC( GetButtonLast, "Gets the player's previously active buttons." ) + DEFINE_SCRIPTFUNC( GetButtonDisabled, "Gets the player's currently unusable buttons." ) + DEFINE_SCRIPTFUNC( GetButtonForced, "Gets the player's currently forced buttons." ) + END_SCRIPTDESC(); #else BEGIN_ENT_SCRIPTDESC( CBasePlayer, CBaseAnimating, "The player entity." ) @@ -800,9 +820,13 @@ int CBasePlayer::ShouldTransmit( const CCheckTransmitInfo *pInfo ) bool CBasePlayer::WantsLagCompensationOnEntity( const CBasePlayer *pPlayer, const CUserCmd *pCmd, const CBitVec *pEntityTransmitBits ) const { - // Team members shouldn't be adjusted unless friendly fire is on. - if ( !friendlyfire.GetInt() && pPlayer->GetTeamNumber() == GetTeamNumber() ) - return false; + //Tony; only check teams in teamplay + if ( gpGlobals->teamplay ) + { + // Team members shouldn't be adjusted unless friendly fire is on. + if ( !friendlyfire.GetInt() && pPlayer->GetTeamNumber() == GetTeamNumber() ) + return false; + } // If this entity hasn't been transmitted to us and acked, then don't bother lag compensating it. if ( pEntityTransmitBits && !pEntityTransmitBits->Get( pPlayer->entindex() ) ) @@ -1649,9 +1673,10 @@ void CBasePlayer::RemoveAllItems( bool removeSuit ) UpdateClientData(); } +//Tony; correct this for base code so that IsDead will be correct accross all games. bool CBasePlayer::IsDead() const { - return m_lifeState == LIFE_DEAD; + return m_lifeState != LIFE_ALIVE; } static float DamageForce( const Vector &size, float damage ) @@ -2952,6 +2977,10 @@ float CBasePlayer::GetHeldObjectMass( IPhysicsObject *pHeldObject ) return 0; } +CBaseEntity *CBasePlayer::GetHeldObject( void ) +{ + return NULL; +} //----------------------------------------------------------------------------- // Purpose: Server side of jumping rules. Most jumping logic is already @@ -3765,6 +3794,21 @@ void CBasePlayer::PlayerRunCommand(CUserCmd *ucmd, IMoveHelper *moveHelper) } } } + +#ifdef MAPBASE_VSCRIPT + // Movement hook for VScript + if ( m_ScriptScope.IsInitialized() ) + { + CUserCmdAccessor accessor = CUserCmdAccessor( ucmd ); + HSCRIPT hCmd = g_pScriptVM->RegisterInstance( &accessor ); + + g_pScriptVM->SetValue( "command", hCmd ); + CallScriptFunction( "PlayerRunCommand", NULL ); + g_pScriptVM->ClearValue( "command" ); + + g_pScriptVM->RemoveInstance( hCmd ); + } +#endif PlayerMove()->RunCommand(this, ucmd, moveHelper); } @@ -4976,6 +5020,55 @@ void CBasePlayer::InitialSpawn( void ) gamestats->Event_PlayerConnected( this ); } +//----------------------------------------------------------------------------- +// Purpose: clear our m_Local.m_TonemapParams to -1. +//----------------------------------------------------------------------------- +void CBasePlayer::ClearTonemapParams( void ) +{ + //Tony; clear all the variables to -1.0 + m_Local.m_TonemapParams.m_flAutoExposureMin = -1.0f; + m_Local.m_TonemapParams.m_flAutoExposureMax = -1.0f; + m_Local.m_TonemapParams.m_flTonemapScale = -1.0f; + m_Local.m_TonemapParams.m_flBloomScale = -1.0f; + m_Local.m_TonemapParams.m_flTonemapRate = -1.0f; +} +void CBasePlayer::InputSetTonemapScale( inputdata_t &inputdata ) +{ + m_Local.m_TonemapParams.m_flTonemapScale = inputdata.value.Float(); +} + +void CBasePlayer::InputSetTonemapRate( inputdata_t &inputdata ) +{ + m_Local.m_TonemapParams.m_flTonemapRate = inputdata.value.Float(); +} +void CBasePlayer::InputSetAutoExposureMin( inputdata_t &inputdata ) +{ + m_Local.m_TonemapParams.m_flAutoExposureMin = inputdata.value.Float(); +} + +void CBasePlayer::InputSetAutoExposureMax( inputdata_t &inputdata ) +{ + m_Local.m_TonemapParams.m_flAutoExposureMax = inputdata.value.Float(); +} + +void CBasePlayer::InputSetBloomScale( inputdata_t &inputdata ) +{ + m_Local.m_TonemapParams.m_flBloomScale = inputdata.value.Float(); +} + +//Tony; restore defaults (set min/max to -1.0 so nothing gets overridden) +void CBasePlayer::InputUseDefaultAutoExposure( inputdata_t &inputdata ) +{ + m_Local.m_TonemapParams.m_flAutoExposureMin = -1.0f; + m_Local.m_TonemapParams.m_flAutoExposureMax = -1.0f; + m_Local.m_TonemapParams.m_flTonemapRate = -1.0f; +} +void CBasePlayer::InputUseDefaultBloomScale( inputdata_t &inputdata ) +{ + m_Local.m_TonemapParams.m_flBloomScale = -1.0f; +} +// void InputSetBloomScaleRange( inputdata_t &inputdata ); + //----------------------------------------------------------------------------- // Purpose: Called everytime the player respawns //----------------------------------------------------------------------------- @@ -4987,6 +5080,9 @@ void CBasePlayer::Spawn( void ) Hints()->ResetHints(); } + //Tony; make sure tonemap params is cleared. + ClearTonemapParams(); + SetClassname( "player" ); // Shared spawning code.. @@ -6157,8 +6253,9 @@ static void CreateJeep( CBasePlayer *pPlayer ) // Cheat to create a jeep in front of the player Vector vecForward; AngleVectors( pPlayer->EyeAngles(), &vecForward ); -#if defined(HL2_EPISODIC) && defined(MAPBASE) - CBaseEntity *pJeep = (CBaseEntity *)CreateEntityByName( "prop_vehicle_jeep_old" ); + //Tony; in sp sdk, we have prop_vehicle_hl2buggy; because episode 2 modified the jeep code to turn it into the jalopy instead of the regular buggy +#if defined ( HL2_EPISODIC ) + CBaseEntity *pJeep = (CBaseEntity *)CreateEntityByName( "prop_vehicle_hl2buggy" ); #else CBaseEntity *pJeep = (CBaseEntity *)CreateEntityByName( "prop_vehicle_jeep" ); #endif @@ -6170,7 +6267,11 @@ static void CreateJeep( CBasePlayer *pPlayer ) pJeep->SetAbsAngles( vecAngles ); pJeep->KeyValue( "model", "models/buggy.mdl" ); pJeep->KeyValue( "solid", "6" ); +#if defined ( HL2_EPISODIC ) + pJeep->KeyValue( "targetname", "hl2buggy" ); +#else pJeep->KeyValue( "targetname", "jeep" ); +#endif pJeep->KeyValue( "vehiclescript", "scripts/vehicles/jeep_test.txt" ); DispatchSpawn( pJeep ); pJeep->Activate(); @@ -9428,6 +9529,14 @@ bool CBasePlayer::HandleVoteCommands( const CCommand &args ) //----------------------------------------------------------------------------- const char *CBasePlayer::GetNetworkIDString() { + //Tony; bots don't have network id's, and this can potentially crash, especially with plugins creating them. + if (IsBot()) + return "__BOT__"; + + //Tony; if networkidstring is null for any reason, the strncpy will crash! + if (!m_szNetworkIDString) + return "NULLID"; + const char *pStr = engine->GetPlayerNetworkIDString( edict() ); Q_strncpy( m_szNetworkIDString, pStr ? pStr : "", sizeof(m_szNetworkIDString) ); return m_szNetworkIDString; diff --git a/sp/src/game/server/player.h b/sp/src/game/server/player.h index 35b19e84..d185aa62 100644 --- a/sp/src/game/server/player.h +++ b/sp/src/game/server/player.h @@ -392,6 +392,13 @@ public: #ifdef MAPBASE_VSCRIPT HSCRIPT VScriptGetExpresser(); + + int GetButtons() { return m_nButtons; } + int GetButtonPressed() { return m_afButtonPressed; } + int GetButtonReleased() { return m_afButtonReleased; } + int GetButtonLast() { return m_afButtonLast; } + int GetButtonDisabled() { return m_afButtonDisabled; } + int GetButtonForced() { return m_afButtonForced; } #endif // View model prediction setup @@ -564,8 +571,9 @@ public: virtual void PickupObject( CBaseEntity *pObject, bool bLimitMassAndSize = true ) {} virtual void ForceDropOfCarriedPhysObjects( CBaseEntity *pOnlyIfHoldindThis = NULL ) {} virtual float GetHeldObjectMass( IPhysicsObject *pHeldObject ); + virtual CBaseEntity *GetHeldObject( void ); - void CheckSuitUpdate(); + virtual void CheckSuitUpdate(); void SetSuitUpdate(const char *name, int fgroup, int iNoRepeat); virtual void UpdateGeigerCounter( void ); void CheckTimeBasedDamage( void ); @@ -680,7 +688,7 @@ public: bool IsConnected() const { return m_iConnected != PlayerDisconnected; } bool IsDisconnecting() const { return m_iConnected == PlayerDisconnecting; } bool IsSuitEquipped() const { return m_Local.m_bWearingSuit; } - int ArmorValue() const { return m_ArmorValue; } + virtual int ArmorValue() const { return m_ArmorValue; } bool HUDNeedsRestart() const { return m_fInitHUD; } float MaxSpeed() const { return m_flMaxspeed; } Activity GetActivity( ) const { return m_Activity; } @@ -1242,6 +1250,23 @@ private: public: virtual unsigned int PlayerSolidMask( bool brushOnly = false ) const; // returns the solid mask for the given player, so bots can have a more-restrictive set +private: + // + //Tony; new tonemap controller changes, specifically for multiplayer. + // + void ClearTonemapParams(); //Tony; we need to clear our tonemap params every time we spawn to -1, if we trigger an input, the values will be set again. +public: + void InputSetTonemapScale( inputdata_t &inputdata ); //Set m_Local. +// void InputBlendTonemapScale( inputdata_t &inputdata ); //TODO; this should be calculated on the client, if we use it; perhaps an entity message would suffice? .. hmm.. + void InputSetTonemapRate( inputdata_t &inputdata ); + void InputSetAutoExposureMin( inputdata_t &inputdata ); + void InputSetAutoExposureMax( inputdata_t &inputdata ); + void InputSetBloomScale( inputdata_t &inputdata ); + + //Tony; restore defaults (set min/max to -1.0 so nothing gets overridden) + void InputUseDefaultAutoExposure( inputdata_t &inputdata ); + void InputUseDefaultBloomScale( inputdata_t &inputdata ); + }; typedef CHandle CBasePlayerHandle; diff --git a/sp/src/game/server/player_command.cpp b/sp/src/game/server/player_command.cpp index 9cdbfdcf..d5a6a1f0 100644 --- a/sp/src/game/server/player_command.cpp +++ b/sp/src/game/server/player_command.cpp @@ -59,21 +59,26 @@ void CPlayerMove::StartCommand( CBasePlayer *player, CUserCmd *cmd ) #if defined (HL2_DLL) // pull out backchannel data and move this out - int i; - for (i = 0; i < cmd->entitygroundcontact.Count(); i++) + // Let's not bother with IK Ground Contact Info in MP games -- the system needs to be re-worked, every client sends down the same info for each entity, so how would it determine which to use? + if ( 1 == gpGlobals->maxClients ) { - int entindex = cmd->entitygroundcontact[i].entindex; - CBaseEntity *pEntity = CBaseEntity::Instance( engine->PEntityOfEntIndex( entindex) ); - if (pEntity) + int i; + for (i = 0; i < cmd->entitygroundcontact.Count(); i++) { - CBaseAnimating *pAnimating = pEntity->GetBaseAnimating(); - if (pAnimating) + int entindex = cmd->entitygroundcontact[i].entindex; + CBaseEntity *pEntity = CBaseEntity::Instance( engine->PEntityOfEntIndex( entindex) ); + if (pEntity) { - pAnimating->SetIKGroundContactInfo( cmd->entitygroundcontact[i].minheight, cmd->entitygroundcontact[i].maxheight ); + CBaseAnimating *pAnimating = pEntity->GetBaseAnimating(); + if (pAnimating) + { + pAnimating->SetIKGroundContactInfo( cmd->entitygroundcontact[i].minheight, cmd->entitygroundcontact[i].maxheight ); + } } } } + #endif } diff --git a/sp/src/game/server/playerinfomanager.cpp b/sp/src/game/server/playerinfomanager.cpp index 903efb6f..69917511 100644 --- a/sp/src/game/server/playerinfomanager.cpp +++ b/sp/src/game/server/playerinfomanager.cpp @@ -9,6 +9,16 @@ #include "playerinfomanager.h" #include "edict.h" +#if defined( TF_DLL ) +#include "tf_shareddefs.h" +#elif defined( CSTRIKE_DLL ) +#include "weapon_csbase.h" +#elif defined( DOD_DLL ) +#include "weapon_dodbase.h" +#elif defined( SDK_DLL ) +#include "weapon_sdkbase.h" +#endif + extern CGlobalVars *gpGlobals; static CPlayerInfoManager s_PlayerInfoManager; static CPluginBotManager s_BotManager; @@ -19,74 +29,43 @@ namespace // // Old version support // - abstract_class IPlayerInfo_V1 - { - public: - // returns the players name (UTF-8 encoded) - virtual const char *GetName() = 0; - // returns the userid (slot number) - virtual int GetUserID() = 0; - // returns the string of their network (i.e Steam) ID - virtual const char *GetNetworkIDString() = 0; - // returns the team the player is on - virtual int GetTeamIndex() = 0; - // changes the player to a new team (if the game dll logic allows it) - virtual void ChangeTeam( int iTeamNum ) = 0; - // returns the number of kills this player has (exact meaning is mod dependent) - virtual int GetFragCount() = 0; - // returns the number of deaths this player has (exact meaning is mod dependent) - virtual int GetDeathCount() = 0; - // returns if this player slot is actually valid - virtual bool IsConnected() = 0; - // returns the armor/health of the player (exact meaning is mod dependent) - virtual int GetArmorValue() = 0; - }; - - abstract_class IPlayerInfoManager_V1 - { - public: - virtual IPlayerInfo_V1 *GetPlayerInfo( edict_t *pEdict ) = 0; - }; - - class CPlayerInfoManager_V1: public IPlayerInfoManager_V1 - { - public: - virtual IPlayerInfo_V1 *GetPlayerInfo( edict_t *pEdict ); - }; - - static CPlayerInfoManager_V1 s_PlayerInfoManager_V1; - - - IPlayerInfo_V1 *CPlayerInfoManager_V1::GetPlayerInfo( edict_t *pEdict ) - { - CBasePlayer *pPlayer = ( ( CBasePlayer * )CBaseEntity::Instance( pEdict )); - if ( pPlayer ) - { - return (IPlayerInfo_V1 *)pPlayer->GetPlayerInfo(); - } - else - { - return NULL; - } - } - - EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CPlayerInfoManager_V1, IPlayerInfoManager_V1, "PlayerInfoManager001", s_PlayerInfoManager_V1); + //Tony; pulled out version 1 and 2 support for orange box, we're starting fresh now with v3 player and v2 of the bot interface. } IPlayerInfo *CPlayerInfoManager::GetPlayerInfo( edict_t *pEdict ) { CBasePlayer *pPlayer = ( ( CBasePlayer * )CBaseEntity::Instance( pEdict )); if ( pPlayer ) - { return pPlayer->GetPlayerInfo(); - } else - { return NULL; - } +} +IPlayerInfo *CPlayerInfoManager::GetPlayerInfo( int index ) +{ + return GetPlayerInfo( engine->PEntityOfEntIndex( index ) ); } +// Games implementing advanced bot support should override this. +int CPlayerInfoManager::AliasToWeaponId(const char *weaponName) +{ + //Tony; TF doesn't support this. Should it? +#if defined ( CSTRIKE_DLL ) || defined ( DOD_DLL ) || defined ( SDK_DLL ) + return AliasToWeaponID(weaponName); +#endif + return -1; +} + +// Games implementing advanced bot support should override this. +const char *CPlayerInfoManager::WeaponIdToAlias(int weaponId) +{ +#if defined( TF_DLL ) + return WeaponIdToAlias(weaponId); +#elif defined ( CSTRIKE_DLL ) || defined ( DOD_DLL ) || defined ( SDK_DLL ) + return WeaponIDToAlias(weaponId); +#endif + return "MOD_DIDNT_IMPLEMENT_ME"; +} CGlobalVars *CPlayerInfoManager::GetGlobalVars() { return gpGlobals; @@ -121,8 +100,8 @@ edict_t *CPluginBotManager::CreateBot( const char *botname ) pPlayer->ClearFlags(); pPlayer->AddFlag( FL_CLIENT | FL_FAKECLIENT ); - pPlayer->ChangeTeam( TEAM_UNASSIGNED ); + pPlayer->AddEFlags( EFL_PLUGIN_BASED_BOT ); // Mark it as a plugin based bot pPlayer->RemoveAllItems( true ); pPlayer->Spawn(); diff --git a/sp/src/game/server/playerinfomanager.h b/sp/src/game/server/playerinfomanager.h index 33eb1fa9..2b110562 100644 --- a/sp/src/game/server/playerinfomanager.h +++ b/sp/src/game/server/playerinfomanager.h @@ -19,7 +19,13 @@ class CPlayerInfoManager: public IPlayerInfoManager { public: virtual IPlayerInfo *GetPlayerInfo( edict_t *pEdict ); + virtual IPlayerInfo *GetPlayerInfo( int index ); virtual CGlobalVars *GetGlobalVars(); + // accessor to hook into aliastoweaponid + virtual int AliasToWeaponId(const char *weaponName); + // accessor to hook into weaponidtoalias + virtual const char *WeaponIdToAlias(int weaponId); + }; class CPluginBotManager: public IBotManager diff --git a/sp/src/game/server/playerlocaldata.cpp b/sp/src/game/server/playerlocaldata.cpp index 3319b2b1..3b9aea08 100644 --- a/sp/src/game/server/playerlocaldata.cpp +++ b/sp/src/game/server/playerlocaldata.cpp @@ -91,6 +91,14 @@ BEGIN_SEND_TABLE_NOBASE( CPlayerLocalData, DT_Local ) SendPropInt( SENDINFO_STRUCTELEM( m_audio.soundscapeIndex ), 17, 0 ), SendPropInt( SENDINFO_STRUCTELEM( m_audio.localBits ), NUM_AUDIO_LOCAL_SOUNDS, SPROP_UNSIGNED ), SendPropEHandle( SENDINFO_STRUCTELEM( m_audio.ent ) ), + + //Tony; tonemap stuff! -- TODO! Optimize this with bit sizes from env_tonemap_controller. + SendPropFloat ( SENDINFO_STRUCTELEM( m_TonemapParams.m_flTonemapScale ), 0, SPROP_NOSCALE ), + SendPropFloat ( SENDINFO_STRUCTELEM( m_TonemapParams.m_flTonemapRate ), 0, SPROP_NOSCALE ), + SendPropFloat ( SENDINFO_STRUCTELEM( m_TonemapParams.m_flBloomScale ), 0, SPROP_NOSCALE ), + + SendPropFloat ( SENDINFO_STRUCTELEM( m_TonemapParams.m_flAutoExposureMin ), 0, SPROP_NOSCALE ), + SendPropFloat ( SENDINFO_STRUCTELEM( m_TonemapParams.m_flAutoExposureMax ), 0, SPROP_NOSCALE ), END_SEND_TABLE() BEGIN_SIMPLE_DATADESC( fogplayerparams_t ) @@ -146,6 +154,16 @@ BEGIN_SIMPLE_DATADESC( audioparams_t ) END_DATADESC() +//Tony; tonepam params!! +BEGIN_SIMPLE_DATADESC ( tonemap_params_t ) + DEFINE_FIELD( m_flTonemapScale, FIELD_FLOAT ), + DEFINE_FIELD( m_flTonemapRate, FIELD_FLOAT ), + DEFINE_FIELD( m_flBloomScale, FIELD_FLOAT ), + DEFINE_FIELD( m_flAutoExposureMin, FIELD_FLOAT ), + DEFINE_FIELD( m_flAutoExposureMax, FIELD_FLOAT ), +END_DATADESC() + + BEGIN_SIMPLE_DATADESC( CPlayerLocalData ) DEFINE_AUTO_ARRAY( m_chAreaBits, FIELD_CHARACTER ), DEFINE_AUTO_ARRAY( m_chAreaPortalBits, FIELD_CHARACTER ), @@ -172,6 +190,9 @@ BEGIN_SIMPLE_DATADESC( CPlayerLocalData ) DEFINE_EMBEDDED( m_PlayerFog ), DEFINE_EMBEDDED( m_fog ), DEFINE_EMBEDDED( m_audio ), + + //Tony; added + DEFINE_EMBEDDED( m_TonemapParams ), // "Why don't we save this field, grandpa?" // diff --git a/sp/src/game/server/playerlocaldata.h b/sp/src/game/server/playerlocaldata.h index 04dc3a8f..9a61d526 100644 --- a/sp/src/game/server/playerlocaldata.h +++ b/sp/src/game/server/playerlocaldata.h @@ -83,6 +83,9 @@ public: // audio environment CNetworkVarEmbedded( audioparams_t, m_audio ); + //Tony; added so tonemap controller can work in multiplayer with inputs. + CNetworkVarEmbedded( tonemap_params_t, m_TonemapParams ); + CNetworkVar( bool, m_bSlowMovement ); }; diff --git a/sp/src/game/server/point_template.cpp b/sp/src/game/server/point_template.cpp index 4f6463a4..3cb654ca 100644 --- a/sp/src/game/server/point_template.cpp +++ b/sp/src/game/server/point_template.cpp @@ -544,6 +544,11 @@ void CPointTemplate::InputForceSpawnRandomTemplate( inputdata_t &inputdata ) //----------------------------------------------------------------------------- void ScriptInstallPreSpawnHook() { +#ifdef MAPBASE_VSCRIPT + if ( !g_pScriptVM ) + return; +#endif + #ifdef IS_WINDOWS_PC if ( !g_pScriptVM->ValueExists( "__ExecutePreSpawn " ) ) { diff --git a/sp/src/game/server/props.cpp b/sp/src/game/server/props.cpp index cb483bc7..9263628b 100644 --- a/sp/src/game/server/props.cpp +++ b/sp/src/game/server/props.cpp @@ -43,6 +43,7 @@ #include "vehicle_base.h" #ifdef MAPBASE #include "mapbase/GlobalStrings.h" +#include "collisionutils.h" #endif // memdbgon must be the last include file in a .cpp file!!! @@ -2655,6 +2656,9 @@ private: string_t m_iszInSequence; string_t m_iszOutSequence; string_t m_iszLockedSequence; + + Vector m_vecUseMins; + Vector m_vecUseMaxs; }; LINK_ENTITY_TO_CLASS( prop_interactable, CInteractableProp ); @@ -2672,6 +2676,9 @@ BEGIN_DATADESC( CInteractableProp ) DEFINE_KEYFIELD( m_iszOutSequence, FIELD_STRING, "OutSequence" ), DEFINE_KEYFIELD( m_iszLockedSequence, FIELD_STRING, "LockedSequence" ), + DEFINE_KEYFIELD( m_vecUseMins, FIELD_VECTOR, "use_mins" ), + DEFINE_KEYFIELD( m_vecUseMaxs, FIELD_VECTOR, "use_maxs" ), + // Inputs DEFINE_INPUTFUNC( FIELD_VOID, "Lock", InputLock ), DEFINE_INPUTFUNC( FIELD_VOID, "Unlock", InputUnlock ), @@ -2732,6 +2739,29 @@ void CInteractableProp::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_ if (m_flCooldownTime > gpGlobals->curtime) return; + // If we're using +USE mins/maxs, make sure this is being +USE'd from the right place + if (m_vecUseMins.LengthSqr() != 0.0f && m_vecUseMaxs.LengthSqr() != 0.0f) + { + CBasePlayer *pPlayer = ToBasePlayer( pActivator ); + if (pPlayer) + { + Vector forward; + pPlayer->EyeVectors( &forward, NULL, NULL ); + + // This might be a little convoluted and/or seem needlessly expensive, but I couldn't figure out any better way to do this. + // TOOD: Can we calculate a box in local space instead of world space? + Vector vecWorldMins, vecWorldMaxs; + RotateAABB( EntityToWorldTransform(), m_vecUseMins, m_vecUseMaxs, vecWorldMins, vecWorldMaxs ); + TransformAABB( EntityToWorldTransform(), vecWorldMins, vecWorldMaxs, vecWorldMins, vecWorldMaxs ); + if (!IsBoxIntersectingRay( vecWorldMins, vecWorldMaxs, pPlayer->EyePosition(), forward * 1024 )) + { + // Reject this +USE if it's not in our box + DevMsg("Outside of +USE box\n"); + return; + } + } + } + int nSequence = -1; if (m_bLocked) diff --git a/sp/src/game/server/server_mapbase.vpc b/sp/src/game/server/server_mapbase.vpc index 7d30a511..5bfc6178 100644 --- a/sp/src/game/server/server_mapbase.vpc +++ b/sp/src/game/server/server_mapbase.vpc @@ -32,7 +32,9 @@ $Project $File "$SRCDIR\game\shared\mapbase\matchers.cpp" $File "$SRCDIR\game\shared\mapbase\matchers.h" $File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.cpp" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.h" [$MAPBASE_VSCRIPT] $File "$SRCDIR\game\shared\mapbase\vscript_funcs_math.cpp" [$MAPBASE_VSCRIPT] + $File "$SRCDIR\game\shared\mapbase\vscript_funcs_math.h" [$MAPBASE_VSCRIPT] $File "$SRCDIR\game\shared\mapbase\vscript_funcs_hl2.cpp" [$MAPBASE_VSCRIPT] $File "mapbase\ai_grenade.cpp" diff --git a/sp/src/game/server/triggers.cpp b/sp/src/game/server/triggers.cpp index 1cc438a3..abc906a3 100644 --- a/sp/src/game/server/triggers.cpp +++ b/sp/src/game/server/triggers.cpp @@ -1228,6 +1228,9 @@ void CTriggerLook::Touch(CBaseEntity *pOther) EHANDLE hLookingAtEntity = NULL; for (int i = 0; i < m_hLookTargets.Count(); i++) { + if (!m_hLookTargets[i]) + continue; + Vector vTargetDir = m_hLookTargets[i]->GetAbsOrigin() - pOther->EyePosition(); VectorNormalize(vTargetDir); diff --git a/sp/src/game/server/util.h b/sp/src/game/server/util.h index 9f356891..d7e7ae73 100644 --- a/sp/src/game/server/util.h +++ b/sp/src/game/server/util.h @@ -552,12 +552,17 @@ float UTIL_ScaleForGravity( float desiredGravity ); #define SF_BRUSH_ROTATE_BACKWARDS 2 #define SF_BRUSH_ROTATE_Z_AXIS 4 #define SF_BRUSH_ROTATE_X_AXIS 8 -#define SF_BRUSH_ROTATE_CLIENTSIDE 16 +// brought over from bmodels.cpp +#define SF_BRUSH_ACCDCC 16 // brush should accelerate and decelerate when toggled +#define SF_BRUSH_HURT 32 // rotating brush that inflicts pain based on rotation speed +#define SF_ROTATING_NOT_SOLID 64 // some special rotating objects are not solid. #define SF_BRUSH_ROTATE_SMALLRADIUS 128 #define SF_BRUSH_ROTATE_MEDIUMRADIUS 256 #define SF_BRUSH_ROTATE_LARGERADIUS 512 +// changed bit to not conflict with much older flag SF_BRUSH_ACCDCC +#define SF_BRUSH_ROTATE_CLIENTSIDE 1024 #define PUSH_BLOCK_ONLY_X 1 #define PUSH_BLOCK_ONLY_Y 2 diff --git a/sp/src/game/server/vscript_server.cpp b/sp/src/game/server/vscript_server.cpp index a0c87f93..b3f900ba 100644 --- a/sp/src/game/server/vscript_server.cpp +++ b/sp/src/game/server/vscript_server.cpp @@ -498,6 +498,10 @@ bool VScriptServerInit() { // Allow world entity to override script language scriptLanguage = GetWorldEntity()->GetScriptLanguage(); + + // Less than SL_NONE means the script language should literally be none + if (scriptLanguage < SL_NONE) + scriptLanguage = SL_NONE; } else #endif @@ -535,7 +539,11 @@ bool VScriptServerInit() if( g_pScriptVM ) { +#ifdef MAPBASE_VSCRIPT + Log( "VSCRIPT SERVER: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() ); +#else Log( "VSCRIPT: Started VScript virtual machine using script language '%s'\n", g_pScriptVM->GetLanguageName() ); +#endif ScriptRegisterFunctionNamed( g_pScriptVM, UTIL_ShowMessageAll, "ShowMessage", "Print a hud message on all clients" ); ScriptRegisterFunction( g_pScriptVM, SendToConsole, "Send a string to the console as a command" ); diff --git a/sp/src/game/server/world.cpp b/sp/src/game/server/world.cpp index 211e2bda..5f68a3d7 100644 --- a/sp/src/game/server/world.cpp +++ b/sp/src/game/server/world.cpp @@ -421,7 +421,7 @@ IMPLEMENT_SERVERCLASS_ST(CWorld, DT_WORLD) SendPropStringT (SENDINFO(m_iszChapterTitle) ), #endif #ifdef MAPBASE_VSCRIPT - SendPropInt (SENDINFO(m_iScriptLanguage), 2, SPROP_UNSIGNED ), + SendPropInt (SENDINFO(m_iScriptLanguage), 4 ), // No SPROP_UNSIGNED to allow -1 (disabled) #endif END_SEND_TABLE() diff --git a/sp/src/game/shared/Multiplayer/multiplayer_animstate.h b/sp/src/game/shared/Multiplayer/multiplayer_animstate.h index 007533a1..bbbc837d 100644 --- a/sp/src/game/shared/Multiplayer/multiplayer_animstate.h +++ b/sp/src/game/shared/Multiplayer/multiplayer_animstate.h @@ -289,7 +289,6 @@ protected: // Pose parameters. bool m_bPoseParameterInit; MultiPlayerPoseData_t m_PoseParameterData; - DebugPlayerAnimData_t m_DebugAnimData; bool m_bCurrentFeetYawInitialized; float m_flLastAnimationStateClearTime; @@ -334,6 +333,14 @@ protected: // movement playback options int m_nMovementSequence; LegAnimType_t m_LegAnimType; + + //Tony; moved debuganim data to a private block and made the 2 sdk animstates friendly. I override the base classes + //but want complete functionality. +private: + friend class CSDKPlayerAnimState; + friend class CHL2MPPlayerAnimState; + DebugPlayerAnimData_t m_DebugAnimData; + }; // If this is set, then the game code needs to make sure to send player animation events diff --git a/sp/src/game/shared/basecombatweapon_shared.h b/sp/src/game/shared/basecombatweapon_shared.h index 69ee6bcf..bd95b1f3 100644 --- a/sp/src/game/shared/basecombatweapon_shared.h +++ b/sp/src/game/shared/basecombatweapon_shared.h @@ -576,6 +576,7 @@ public: virtual int GetWorldModelIndex( void ); virtual void GetToolRecordingState( KeyValues *msg ); + void EnsureCorrectRenderingModel(); virtual void GetWeaponCrosshairScale( float &flScale ) { flScale = 1.f; } @@ -588,6 +589,9 @@ public: bool WantsToOverrideViewmodelAttachments( void ) { return false; } #endif + //Tony; notifications of any third person switches. + virtual void ThirdPersonSwitch( bool bThirdPerson ) {}; + #endif // End client-only methods virtual bool CanLower( void ) { return false; } diff --git a/sp/src/game/shared/baseentity_shared.cpp b/sp/src/game/shared/baseentity_shared.cpp index 643b650a..2778cc56 100644 --- a/sp/src/game/shared/baseentity_shared.cpp +++ b/sp/src/game/shared/baseentity_shared.cpp @@ -53,6 +53,10 @@ ConVar hl2_episodic( "hl2_episodic", "0", FCVAR_REPLICATED ); #include "tf_weaponbase.h" #endif // TF_DLL +#ifdef MAPBASE_VSCRIPT +#include "mapbase/vscript_funcs_shared.h" +#endif + #include "rumble_shared.h" // memdbgon must be the last include file in a .cpp file!!! diff --git a/sp/src/game/shared/baseplayer_shared.cpp b/sp/src/game/shared/baseplayer_shared.cpp index cba09eb7..5ad7d453 100644 --- a/sp/src/game/shared/baseplayer_shared.cpp +++ b/sp/src/game/shared/baseplayer_shared.cpp @@ -163,12 +163,30 @@ void CBasePlayer::ItemPreFrame() // Handle use events PlayerUse(); - CBaseCombatWeapon *pActive = GetActiveWeapon(); + //Tony; re-ordered this for efficiency and to make sure that certain things happen in the correct order! + if ( gpGlobals->curtime < m_flNextAttack ) + { + return; + } + if (!GetActiveWeapon()) + return; + +#if defined( CLIENT_DLL ) + // Not predicting this weapon + if ( !GetActiveWeapon()->IsPredicted() ) + return; +#endif + + GetActiveWeapon()->ItemPreFrame(); + + CBaseCombatWeapon *pWeapon; + + CBaseCombatWeapon *pActive = GetActiveWeapon(); // Allow all the holstered weapons to update for ( int i = 0; i < WeaponCount(); ++i ) { - CBaseCombatWeapon *pWeapon = GetWeapon( i ); + pWeapon = GetWeapon( i ); if ( pWeapon == NULL ) continue; @@ -178,20 +196,6 @@ void CBasePlayer::ItemPreFrame() pWeapon->ItemHolsterFrame(); } - - if ( gpGlobals->curtime < m_flNextAttack ) - return; - - if (!pActive) - return; - -#if defined( CLIENT_DLL ) - // Not predicting this weapon - if ( !pActive->IsPredicted() ) - return; -#endif - - pActive->ItemPreFrame(); } //----------------------------------------------------------------------------- diff --git a/sp/src/game/shared/baseviewmodel_shared.cpp b/sp/src/game/shared/baseviewmodel_shared.cpp index d789d3f3..b7fef9b7 100644 --- a/sp/src/game/shared/baseviewmodel_shared.cpp +++ b/sp/src/game/shared/baseviewmodel_shared.cpp @@ -407,15 +407,13 @@ void CBaseViewModel::CalcViewModelView( CBasePlayer *owner, const Vector& eyePos } // Add model-specific bob even if no weapon associated (for head bob for off hand models) AddViewModelBob( owner, vmorigin, vmangles ); -#if !defined ( CSTRIKE_DLL ) - // This was causing weapon jitter when rotating in updated CS:S; original Source had this in above InPrediction block 07/14/10 - // Add lag - CalcViewModelLag( vmorigin, vmangles, vmangoriginal ); -#endif #if defined( CLIENT_DLL ) if ( !prediction->InPrediction() ) { + // Add lag + CalcViewModelLag( vmorigin, vmangles, vmangoriginal ); + // Let the viewmodel shake at about 10% of the amplitude of the player's view vieweffects->ApplyShake( vmorigin, vmangles, 0.1 ); } diff --git a/sp/src/game/shared/hl2/hl_gamemovement.cpp b/sp/src/game/shared/hl2/hl_gamemovement.cpp index 6a3fa51a..d4fc3aef 100644 --- a/sp/src/game/shared/hl2/hl_gamemovement.cpp +++ b/sp/src/game/shared/hl2/hl_gamemovement.cpp @@ -9,6 +9,10 @@ #include "utlrbtree.h" #include "hl2_shareddefs.h" +#ifdef HL2MP +#include "hl2mp_gamerules.h" +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -1267,6 +1271,29 @@ bool CHL2GameMovement::CanAccelerate() return true; } +//----------------------------------------------------------------------------- +// Purpose: Allow bots etc to use slightly different solid masks +//----------------------------------------------------------------------------- +unsigned int CHL2GameMovement::PlayerSolidMask( bool brushOnly ) +{ + int mask = 0; +#ifdef HL2MP + if ( HL2MPRules()->IsTeamplay() ) + { + switch ( player->GetTeamNumber() ) + { + case TEAM_REBELS: + mask = CONTENTS_TEAM1; + break; + + case TEAM_COMBINE: + mask = CONTENTS_TEAM2; + break; + } + } +#endif + return ( mask | BaseClass::PlayerSolidMask( brushOnly ) ); +} #ifndef PORTAL // Portal inherits from this but needs to declare it's own global interface // Expose our interface. diff --git a/sp/src/game/shared/hl2/hl_gamemovement.h b/sp/src/game/shared/hl2/hl_gamemovement.h index 6db52350..fba5c8c1 100644 --- a/sp/src/game/shared/hl2/hl_gamemovement.h +++ b/sp/src/game/shared/hl2/hl_gamemovement.h @@ -44,6 +44,8 @@ public: virtual void SetGroundEntity( trace_t *pm ); virtual bool CanAccelerate( void ); + virtual unsigned int PlayerSolidMask( bool brushOnly = false ); + #ifdef MAPBASE // Called by mappers who need a player to be on a ladder. bool ForcePlayerOntoLadder(CFuncLadder *ladder); diff --git a/sp/src/game/shared/mapbase/mapbase_rpc.cpp b/sp/src/game/shared/mapbase/mapbase_rpc.cpp index ed3ff95a..4a318c7c 100644 --- a/sp/src/game/shared/mapbase/mapbase_rpc.cpp +++ b/sp/src/game/shared/mapbase/mapbase_rpc.cpp @@ -330,8 +330,11 @@ void MapbaseRPC_Init() pKV->deleteThis(); // Steam RPC - if (steamapicontext->SteamFriends()) - steamapicontext->SteamFriends()->ClearRichPresence(); + if (steamapicontext) + { + if (steamapicontext->SteamFriends()) + steamapicontext->SteamFriends()->ClearRichPresence(); + } // Discord RPC DiscordEventHandlers handlers; @@ -368,8 +371,11 @@ void MapbaseRPC_Shutdown() Discord_Shutdown(); // Steam RPC - if (steamapicontext->SteamFriends()) - steamapicontext->SteamFriends()->ClearRichPresence(); + if (steamapicontext) + { + if (steamapicontext->SteamFriends()) + steamapicontext->SteamFriends()->ClearRichPresence(); + } } void MapbaseRPC_Update( int iType, const char *pMapName ) @@ -380,6 +386,10 @@ void MapbaseRPC_Update( int iType, const char *pMapName ) void MapbaseRPC_Update( int iRPCMask, int iType, const char *pMapName ) { + // Only update if RPC is enabled + if (mapbase_rpc_enabled.GetInt() <= 0) + return; + if (iRPCMask & RPCFlag(RPC_STEAM)) MapbaseRPC_UpdateSteam(iType, pMapName); if (iRPCMask & RPCFlag(RPC_DISCORD)) @@ -389,6 +399,10 @@ void MapbaseRPC_Update( int iRPCMask, int iType, const char *pMapName ) #ifdef STEAM_RPC void MapbaseRPC_UpdateSteam( int iType, const char *pMapName ) { + // No Steam + if (!steamapicontext) + return; + const char *pszStatus = NULL; if (g_Metadata[RPC_STEAM] != NULL) diff --git a/sp/src/game/shared/mapbase/vscript_funcs_math.cpp b/sp/src/game/shared/mapbase/vscript_funcs_math.cpp index cc8714aa..68eb543c 100644 --- a/sp/src/game/shared/mapbase/vscript_funcs_math.cpp +++ b/sp/src/game/shared/mapbase/vscript_funcs_math.cpp @@ -7,6 +7,8 @@ #include "cbase.h" +#include "vscript_funcs_math.h" + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -15,40 +17,6 @@ // matrix3x4_t // //============================================================================= - -// -// Exposes matrix3x4_t to VScript -// -class CScriptMatrix3x4 -{ -public: - CScriptMatrix3x4() - { - matrix = new matrix3x4_t(); - m_bFree = true; - } - - ~CScriptMatrix3x4() - { - if (m_bFree == true) - delete matrix; - } - - CScriptMatrix3x4( matrix3x4_t &inmatrix ) { matrix = &inmatrix; } - - matrix3x4_t *GetMatrix() { return matrix; } - void SetMatrix( matrix3x4_t &inmatrix ) { matrix = &inmatrix; } - - void Init( const Vector& xAxis, const Vector& yAxis, const Vector& zAxis, const Vector &vecOrigin ) - { - matrix->Init( xAxis, yAxis, zAxis, vecOrigin ); - } - -private: - matrix3x4_t *matrix; - bool m_bFree = false; -}; - BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptMatrix3x4, "matrix3x4_t", "A 3x4 matrix transform." ) DEFINE_SCRIPT_CONSTRUCTOR() @@ -56,25 +24,6 @@ BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptMatrix3x4, "matrix3x4_t", "A 3x4 matrix tran END_SCRIPTDESC(); -matrix3x4_t *ToMatrix3x4( HSCRIPT hMat ) { return HScriptToClass( hMat )->GetMatrix(); } - -HSCRIPT ScriptCreateMatrixInstance( matrix3x4_t &matrix ) -{ - CScriptMatrix3x4 *smatrix = new CScriptMatrix3x4( matrix ); - - return g_pScriptVM->RegisterInstance( smatrix ); -} - -void ScriptFreeMatrixInstance( HSCRIPT hMat ) -{ - CScriptMatrix3x4 *smatrix = HScriptToClass( hMat ); - if (smatrix) - { - g_pScriptVM->RemoveInstance( hMat ); - delete smatrix; - } -} - //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -273,8 +222,6 @@ void RegisterMathScriptFunctions() // // matrix3x4_t // - g_pScriptVM->RegisterClass( GetScriptDescForClass( CScriptMatrix3x4 ) ); - ScriptRegisterFunctionNamed( g_pScriptVM, ScriptFreeMatrixInstance, "FreeMatrixInstance", "Frees an allocated matrix instance." ); ScriptRegisterFunctionNamed( g_pScriptVM, ScriptConcatTransforms, "ConcatTransforms", "Concatenates two transformation matrices into another matrix." ); diff --git a/sp/src/game/shared/mapbase/vscript_funcs_math.h b/sp/src/game/shared/mapbase/vscript_funcs_math.h new file mode 100644 index 00000000..13241980 --- /dev/null +++ b/sp/src/game/shared/mapbase/vscript_funcs_math.h @@ -0,0 +1,66 @@ +//========= Copyright Valve Corporation, All rights reserved. ================= +// +// Purpose: Shared VScript math functions. +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VSCRIPT_FUNCS_MATH +#define VSCRIPT_FUNCS_MATH +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +// Exposes matrix3x4_t to VScript +//----------------------------------------------------------------------------- +class CScriptMatrix3x4 +{ +public: + CScriptMatrix3x4() + { + matrix = new matrix3x4_t(); + m_bFree = true; + } + + ~CScriptMatrix3x4() + { + if (m_bFree == true) + delete matrix; + } + + CScriptMatrix3x4( matrix3x4_t &inmatrix ) { matrix = &inmatrix; } + + matrix3x4_t *GetMatrix() { return matrix; } + void SetMatrix( matrix3x4_t &inmatrix ) { matrix = &inmatrix; } + + void Init( const Vector& xAxis, const Vector& yAxis, const Vector& zAxis, const Vector &vecOrigin ) + { + matrix->Init( xAxis, yAxis, zAxis, vecOrigin ); + } + +private: + matrix3x4_t *matrix; + bool m_bFree = false; +}; + +inline matrix3x4_t *ToMatrix3x4( HSCRIPT hMat ) { return HScriptToClass( hMat )->GetMatrix(); } + +static HSCRIPT ScriptCreateMatrixInstance( matrix3x4_t &matrix ) +{ + CScriptMatrix3x4 *smatrix = new CScriptMatrix3x4( matrix ); + + return g_pScriptVM->RegisterInstance( smatrix ); +} + +static void ScriptFreeMatrixInstance( HSCRIPT hMat ) +{ + CScriptMatrix3x4 *smatrix = HScriptToClass( hMat ); + if (smatrix) + { + g_pScriptVM->RemoveInstance( hMat ); + delete smatrix; + } +} + +#endif diff --git a/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp b/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp index 5dc68aba..e6cbabc6 100644 --- a/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp +++ b/sp/src/game/shared/mapbase/vscript_funcs_shared.cpp @@ -13,12 +13,16 @@ #include "matchers.h" #include "takedamageinfo.h" #include "ammodef.h" +#include +#include #ifndef CLIENT_DLL #include "globalstate.h" #include "vscript_server.h" #endif +#include "vscript_funcs_shared.h" + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -354,6 +358,33 @@ BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptConvarLookup, "CConvars", SCRIPT_SINGLETON " END_SCRIPTDESC(); #ifndef CLIENT_DLL +void EmitSoundOn( const char *pszSound, HSCRIPT hEnt ) +{ + CBaseEntity *pEnt = ToEnt( hEnt ); + if (!hEnt || !pEnt) + return; + + pEnt->EmitSound( pszSound ); +} + +void EmitSoundOnClient( const char *pszSound, HSCRIPT hEnt, HSCRIPT hPlayer ) +{ + CBaseEntity *pEnt = ToEnt( hEnt ); + CBasePlayer *pPlayer = ToBasePlayer( ToEnt( hPlayer ) ); + if (!hPlayer || !pEnt || !pPlayer) + return; + + CSingleUserRecipientFilter filter( pPlayer ); + + EmitSound_t params; + params.m_pSoundName = pszSound; + params.m_flSoundTime = 0.0f; + params.m_pflSoundDuration = NULL; + params.m_bWarnOnDirectWaveReference = true; + + pEnt->EmitSound( filter, pEnt->entindex(), params ); +} + void AddThinkToEnt( HSCRIPT entity, const char *pszFuncName ) { CBaseEntity *pEntity = ToEnt( entity ); @@ -501,6 +532,33 @@ void ScriptDispatchSpawn( HSCRIPT hEntity ) } #endif +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +class CScriptLocalize +{ +public: + + const char *GetTokenAsUTF8( const char *pszToken ) + { + const char *pText = g_pVGuiLocalize->FindAsUTF8( pszToken ); + if ( pText ) + { + return pText; + } + + return NULL; + } + +private: +} g_ScriptLocalize; + +BEGIN_SCRIPTDESC_ROOT_NAMED( CScriptLocalize, "Localize", SCRIPT_SINGLETON "Accesses functions related to localization strings." ) + + DEFINE_SCRIPTFUNC( GetTokenAsUTF8, "Gets the current language's token as a UTF-8 string (not Unicode)." ) + +END_SCRIPTDESC(); + //----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- @@ -537,50 +595,6 @@ void ScriptGuessDamageForce( HSCRIPT info, const Vector &vecForceDir, const Vect //----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- -class CTraceInfoAccessor -{ -public: - - // CGrameTrace stuff - bool DidHitWorld() const { return m_tr.DidHitWorld(); } - bool DidHitNonWorldEntity() const { return m_tr.DidHitNonWorldEntity(); } - int GetEntityIndex() const { return m_tr.GetEntityIndex(); } - bool DidHit() const { return m_tr.DidHit(); } - - float FractionLeftSolid() const { return m_tr.fractionleftsolid; } - int HitGroup() const { return m_tr.hitgroup; } - int PhysicsBone() const { return m_tr.physicsbone; } - - HSCRIPT Entity() const { return ToHScript(m_tr.m_pEnt); } - - int HitBox() const { return m_tr.hitbox; } - - // CBaseTrace stuff - bool IsDispSurface() { return m_tr.IsDispSurface(); } - bool IsDispSurfaceWalkable() { return m_tr.IsDispSurfaceWalkable(); } - bool IsDispSurfaceBuildable() { return m_tr.IsDispSurfaceBuildable(); } - bool IsDispSurfaceProp1() { return m_tr.IsDispSurfaceProp1(); } - bool IsDispSurfaceProp2() { return m_tr.IsDispSurfaceProp2(); } - - Vector StartPos() const { return m_tr.startpos; } - Vector EndPos() const { return m_tr.endpos; } - - float Fraction() const { return m_tr.fraction; } - - int Contents() const { return m_tr.contents; } - int DispFlags() const { return m_tr.dispFlags; } - - bool AllSolid() const { return m_tr.allsolid; } - bool StartSolid() const { return m_tr.startsolid; } - - trace_t &GetTrace() { return m_tr; } - void Destroy() { delete this; } - -private: - trace_t m_tr; - -}; - BEGIN_SCRIPTDESC_ROOT_NAMED( CTraceInfoAccessor, "CGameTrace", "Handle for accessing trace_t info." ) DEFINE_SCRIPTFUNC( DidHitWorld, "Returns whether the trace hit the world entity or not." ) DEFINE_SCRIPTFUNC( DidHitNonWorldEntity, "Returns whether the trace hit something other than the world entity." ) @@ -750,6 +764,42 @@ FireBulletsInfo_t *GetFireBulletsInfoFromInfo( HSCRIPT hBulletsInfo ) return NULL; } +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +BEGIN_SCRIPTDESC_ROOT_NAMED( CUserCmdAccessor, "CUserCmd", "Handle for accessing CUserCmd info." ) + DEFINE_SCRIPTFUNC( GetCommandNumber, "For matching server and client commands for debugging." ) + + DEFINE_SCRIPTFUNC_NAMED( ScriptGetTickCount, "GetTickCount", "The tick the client created this command." ) + + DEFINE_SCRIPTFUNC( GetViewAngles, "Player instantaneous view angles." ) + DEFINE_SCRIPTFUNC( SetViewAngles, "Sets player instantaneous view angles." ) + + DEFINE_SCRIPTFUNC( GetForwardMove, "Forward velocity." ) + DEFINE_SCRIPTFUNC( SetForwardMove, "Sets forward velocity." ) + DEFINE_SCRIPTFUNC( GetSideMove, "Side velocity." ) + DEFINE_SCRIPTFUNC( SetSideMove, "Sets side velocity." ) + DEFINE_SCRIPTFUNC( GetUpMove, "Up velocity." ) + DEFINE_SCRIPTFUNC( SetUpMove, "Sets up velocity." ) + + DEFINE_SCRIPTFUNC( GetButtons, "Attack button states." ) + DEFINE_SCRIPTFUNC( SetButtons, "Sets attack button states." ) + DEFINE_SCRIPTFUNC( GetImpulse, "Impulse command issued." ) + DEFINE_SCRIPTFUNC( SetImpulse, "Sets impulse command issued." ) + + DEFINE_SCRIPTFUNC( GetWeaponSelect, "Current weapon id." ) + DEFINE_SCRIPTFUNC( SetWeaponSelect, "Sets current weapon id." ) + DEFINE_SCRIPTFUNC( GetWeaponSubtype, "Current weapon subtype id." ) + DEFINE_SCRIPTFUNC( SetWeaponSubtype, "Sets current weapon subtype id." ) + + DEFINE_SCRIPTFUNC( GetRandomSeed, "For shared random functions." ) + + DEFINE_SCRIPTFUNC( GetMouseX, "Mouse accum in x from create move." ) + DEFINE_SCRIPTFUNC( SetMouseX, "Sets mouse accum in x from create move." ) + DEFINE_SCRIPTFUNC( GetMouseY, "Mouse accum in y from create move." ) + DEFINE_SCRIPTFUNC( SetMouseY, "Sets mouse accum in y from create move." ) +END_SCRIPTDESC(); + //============================================================================= //============================================================================= @@ -829,18 +879,27 @@ void RegisterSharedScriptFunctions() ScriptRegisterFunctionNamed( g_pScriptVM, NDebugOverlay::BoxDirection, "DebugDrawBoxDirection", "Draw a debug forward box" ); ScriptRegisterFunctionNamed( g_pScriptVM, NDebugOverlay::Text, "DebugDrawText", "Draw a debug overlay text" ); + ScriptRegisterFunction( g_pScriptVM, EmitSoundOn, "Play named sound on an entity." ); + ScriptRegisterFunction( g_pScriptVM, EmitSoundOnClient, "Play named sound only on the client for the specified player." ); + ScriptRegisterFunction( g_pScriptVM, AddThinkToEnt, "This will put a think function onto an entity, or pass null to remove it. This is NOT chained, so be careful." ); ScriptRegisterFunction( g_pScriptVM, EntIndexToHScript, "Returns the script handle for the given entity index." ); ScriptRegisterFunction( g_pScriptVM, PrecacheEntityFromTable, "Precache an entity from KeyValues in a table." ); ScriptRegisterFunction( g_pScriptVM, SpawnEntityFromTable, "Native function for entity spawning." ); #endif - g_pScriptVM->RegisterInstance( GetAmmoDef(), "AmmoDef" ); - g_pScriptVM->RegisterInstance( &g_ScriptConvarLookup, "Convars" ); g_pScriptVM->RegisterInstance( &g_ScriptNetPropManager, "NetProps" ); - // Functions unique to Mapbase + //----------------------------------------------------------------------------- + // Functions, singletons, etc. unique to Mapbase + //----------------------------------------------------------------------------- + + g_pScriptVM->RegisterInstance( GetAmmoDef(), "AmmoDef" ); + g_pScriptVM->RegisterInstance( &g_ScriptLocalize, "Localize" ); + + //----------------------------------------------------------------------------- + ScriptRegisterFunctionNamed( g_pScriptVM, ScriptColorPrint, "printc", "Version of print() which takes a color before the message." ); ScriptRegisterFunctionNamed( g_pScriptVM, ScriptColorPrintL, "printcl", "Version of printl() which takes a color before the message." ); diff --git a/sp/src/game/shared/mapbase/vscript_funcs_shared.h b/sp/src/game/shared/mapbase/vscript_funcs_shared.h new file mode 100644 index 00000000..43928e37 --- /dev/null +++ b/sp/src/game/shared/mapbase/vscript_funcs_shared.h @@ -0,0 +1,162 @@ +//========= Copyright Valve Corporation, All rights reserved. ================= +// +// Purpose: Due to this being a custom integration of VScript based on the Alien Swarm SDK, we don't have access to +// some of the code normally available in games like L4D2 or Valve's original VScript DLL. +// Instead, that code is recreated here, shared between server and client. +// +// It also contains other functions unique to Mapbase. +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VSCRIPT_FUNCS_SHARED +#define VSCRIPT_FUNCS_SHARED +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +// Exposes trace_t to VScript +//----------------------------------------------------------------------------- +class CTraceInfoAccessor +{ +public: + + // CGrameTrace stuff + bool DidHitWorld() const { return m_tr.DidHitWorld(); } + bool DidHitNonWorldEntity() const { return m_tr.DidHitNonWorldEntity(); } + int GetEntityIndex() const { return m_tr.GetEntityIndex(); } + bool DidHit() const { return m_tr.DidHit(); } + + float FractionLeftSolid() const { return m_tr.fractionleftsolid; } + int HitGroup() const { return m_tr.hitgroup; } + int PhysicsBone() const { return m_tr.physicsbone; } + + HSCRIPT Entity() const { return ToHScript(m_tr.m_pEnt); } + + int HitBox() const { return m_tr.hitbox; } + + // CBaseTrace stuff + bool IsDispSurface() { return m_tr.IsDispSurface(); } + bool IsDispSurfaceWalkable() { return m_tr.IsDispSurfaceWalkable(); } + bool IsDispSurfaceBuildable() { return m_tr.IsDispSurfaceBuildable(); } + bool IsDispSurfaceProp1() { return m_tr.IsDispSurfaceProp1(); } + bool IsDispSurfaceProp2() { return m_tr.IsDispSurfaceProp2(); } + + Vector StartPos() const { return m_tr.startpos; } + Vector EndPos() const { return m_tr.endpos; } + + float Fraction() const { return m_tr.fraction; } + + int Contents() const { return m_tr.contents; } + int DispFlags() const { return m_tr.dispFlags; } + + bool AllSolid() const { return m_tr.allsolid; } + bool StartSolid() const { return m_tr.startsolid; } + + trace_t &GetTrace() { return m_tr; } + void Destroy() { delete this; } + +private: + trace_t m_tr; + +}; + +//----------------------------------------------------------------------------- +// Exposes FireBulletsInfo_t to VScript +//----------------------------------------------------------------------------- +class CFireBulletsInfoAccessor +{ +public: + CFireBulletsInfoAccessor( FireBulletsInfo_t *info ) { m_info = info; } + + int GetShots() { return m_info->m_iShots; } + void SetShots( int value ) { m_info->m_iShots = value; } + + Vector GetSource() { return m_info->m_vecSrc; } + void SetSource( Vector value ) { m_info->m_vecSrc = value; } + Vector GetDirShooting() { return m_info->m_vecDirShooting; } + void SetDirShooting( Vector value ) { m_info->m_vecDirShooting = value; } + Vector GetSpread() { return m_info->m_vecSpread; } + void SetSpread( Vector value ) { m_info->m_vecSpread = value; } + + float GetDistance() { return m_info->m_flDistance; } + void SetDistance( float value ) { m_info->m_flDistance = value; } + + int GetAmmoType() { return m_info->m_iAmmoType; } + void SetAmmoType( int value ) { m_info->m_iAmmoType = value; } + + int GetTracerFreq() { return m_info->m_iTracerFreq; } + void SetTracerFreq( int value ) { m_info->m_iTracerFreq = value; } + + float GetDamage() { return m_info->m_flDamage; } + void SetDamage( float value ) { m_info->m_flDamage = value; } + int GetPlayerDamage() { return m_info->m_iPlayerDamage; } + void SetPlayerDamage( float value ) { m_info->m_iPlayerDamage = value; } + + int GetFlags() { return m_info->m_nFlags; } + void SetFlags( float value ) { m_info->m_nFlags = value; } + + float GetDamageForceScale() { return m_info->m_flDamageForceScale; } + void SetDamageForceScale( float value ) { m_info->m_flDamageForceScale = value; } + + HSCRIPT GetAttacker(); + void SetAttacker( HSCRIPT value ); + HSCRIPT GetAdditionalIgnoreEnt(); + void SetAdditionalIgnoreEnt( HSCRIPT value ); + + bool GetPrimaryAttack() { return m_info->m_bPrimaryAttack; } + void SetPrimaryAttack( bool value ) { m_info->m_bPrimaryAttack = value; } + + FireBulletsInfo_t *GetInfo() { return m_info; } + + void Destroy() { delete m_info; delete this; } + +private: + FireBulletsInfo_t *m_info; +}; + +//----------------------------------------------------------------------------- +// Exposes CUserCmd to VScript +//----------------------------------------------------------------------------- +class CUserCmdAccessor +{ +public: + CUserCmdAccessor( CUserCmd *cmd ) { m_cmd = cmd; } + + int GetCommandNumber() { return m_cmd->command_number; } + + int ScriptGetTickCount() { return m_cmd->tick_count; } + + const QAngle& GetViewAngles() { return m_cmd->viewangles; } + void SetViewAngles( const QAngle& val ) { m_cmd->viewangles = val; } + + float GetForwardMove() { return m_cmd->forwardmove; } + void SetForwardMove( float val ) { m_cmd->forwardmove = val; } + float GetSideMove() { return m_cmd->sidemove; } + void SetSideMove( float val ) { m_cmd->sidemove = val; } + float GetUpMove() { return m_cmd->upmove; } + void SetUpMove( float val ) { m_cmd->upmove = val; } + + int GetButtons() { return m_cmd->buttons; } + void SetButtons( int val ) { m_cmd->buttons = val; } + int GetImpulse() { return m_cmd->impulse; } + void SetImpulse( int val ) { m_cmd->impulse = val; } + + int GetWeaponSelect() { return m_cmd->weaponselect; } + void SetWeaponSelect( int val ) { m_cmd->weaponselect = val; } + int GetWeaponSubtype() { return m_cmd->weaponsubtype; } + void SetWeaponSubtype( int val ) { m_cmd->weaponsubtype = val; } + + int GetRandomSeed() { return m_cmd->random_seed; } + + int GetMouseX() { return m_cmd->mousedx; } + void SetMouseX( int val ) { m_cmd->mousedx = val; } + int GetMouseY() { return m_cmd->mousedy; } + void SetMouseY( int val ) { m_cmd->mousedy = val; } + +private: + CUserCmd *m_cmd; +}; + +#endif diff --git a/sp/src/game/shared/multiplay_gamerules.cpp b/sp/src/game/shared/multiplay_gamerules.cpp index abecba9e..49ed4efe 100644 --- a/sp/src/game/shared/multiplay_gamerules.cpp +++ b/sp/src/game/shared/multiplay_gamerules.cpp @@ -204,7 +204,8 @@ int CMultiplayRules::Damage_GetShouldNotBleed( void ) bool CMultiplayRules::Damage_IsTimeBased( int iDmgType ) { // Damage types that are time-based. - return ( ( iDmgType & ( DMG_PARALYZE | DMG_NERVEGAS | DMG_POISON | DMG_RADIATION | DMG_DROWNRECOVER | DMG_ACID | DMG_SLOWBURN ) ) != 0 ); + //Tony; fixed. return Damage_GetTimeBased instead of checking them directly. + return ( ( iDmgType & Damage_GetTimeBased() ) != 0 ); } //----------------------------------------------------------------------------- @@ -368,7 +369,9 @@ ConVarRef suitcharger( "sk_suitcharger" ); if ( g_fGameOver ) // someone else quit the game already { - ChangeLevel(); // intermission is over + // Tony; wait for intermission to end + if ( m_flIntermissionEndTime && ( m_flIntermissionEndTime < gpGlobals->curtime ) ) + ChangeLevel(); // intermission is over return; } diff --git a/sp/src/game/shared/playernet_vars.h b/sp/src/game/shared/playernet_vars.h index e22baf71..961e0796 100644 --- a/sp/src/game/shared/playernet_vars.h +++ b/sp/src/game/shared/playernet_vars.h @@ -129,5 +129,50 @@ struct audioparams_t CNetworkHandle( CBaseEntity, ent ); // the entity setting the soundscape }; +//Tony; new tonemap information. +// In single player the values are coped directly from the single env_tonemap_controller entity. +// This will allow the controller to work as it always did. +// That way nothing in ep2 will break. With these new params, the controller can properly be used in mp. + + +// Map specific objectives, such as blowing out a wall ( and bringing in more light ) +// can still change values on a particular controller as necessary via inputs, but the +// effects will not directly affect any players who are referencing this controller +// unless the option to update on inputs is set. ( otherwise the values are simply cached +// and changes only take effect when the players controller target is changed ) + +struct tonemap_params_t +{ + DECLARE_CLASS_NOBASE( tonemap_params_t ); + DECLARE_EMBEDDED_NETWORKVAR(); + +#ifndef CLIENT_DLL + DECLARE_SIMPLE_DATADESC(); +#endif + tonemap_params_t() + { + m_flAutoExposureMin = -1.0f; + m_flAutoExposureMax = -1.0f; + m_flTonemapScale = -1.0f; + m_flBloomScale = -1.0f; + m_flTonemapRate = -1.0f; + } + //Tony; all of these are initialized to -1! + CNetworkVar( float, m_flTonemapScale ); + CNetworkVar( float, m_flTonemapRate ); + CNetworkVar( float, m_flBloomScale ); + + CNetworkVar( float, m_flAutoExposureMin ); + CNetworkVar( float, m_flAutoExposureMax ); + +// BLEND TODO +// +// //Tony; Time it takes for a blend to finish, default to 0; this is for the the effect of InputBlendTonemapScale. +// //When +// CNetworkVar( float, m_flBlendTime ); + + //Tony; these next 4 variables do not have to be networked; but I want to update them on the client whenever m_flBlendTime changes. + //TODO +}; #endif // PLAYERNET_VARS_H diff --git a/sp/src/game/shared/predicted_viewmodel.cpp b/sp/src/game/shared/predicted_viewmodel.cpp index 06691d02..53c024c2 100644 --- a/sp/src/game/shared/predicted_viewmodel.cpp +++ b/sp/src/game/shared/predicted_viewmodel.cpp @@ -6,6 +6,10 @@ #include "cbase.h" #include "predicted_viewmodel.h" +#ifdef CLIENT_DLL +#include "prediction.h" +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -24,6 +28,7 @@ CPredictedViewModel::CPredictedViewModel() : m_LagAnglesHistory("CPredictedViewM { m_vLagAngles.Init(); m_LagAnglesHistory.Setup( &m_vLagAngles, 0 ); + m_vPredictedOffset.Init(); } #else CPredictedViewModel::CPredictedViewModel() @@ -46,26 +51,53 @@ ConVar cl_wpn_sway_scale( "cl_wpn_sway_scale", "1.0", FCVAR_CLIENTDLL|FCVAR_CHEA void CPredictedViewModel::CalcViewModelLag( Vector& origin, QAngle& angles, QAngle& original_angles ) { - #ifdef CLIENT_DLL - // Calculate our drift - Vector forward, right, up; - AngleVectors( angles, &forward, &right, &up ); - - // Add an entry to the history. - m_vLagAngles = angles; - m_LagAnglesHistory.NoteChanged( gpGlobals->curtime, cl_wpn_sway_interp.GetFloat(), false ); - - // Interpolate back 100ms. - m_LagAnglesHistory.Interpolate( gpGlobals->curtime, cl_wpn_sway_interp.GetFloat() ); - - // Now take the 100ms angle difference and figure out how far the forward vector moved in local space. - Vector vLaggedForward; - QAngle angleDiff = m_vLagAngles - angles; - AngleVectors( -angleDiff, &vLaggedForward, 0, 0 ); - Vector vForwardDiff = Vector(1,0,0) - vLaggedForward; +#ifdef CLIENT_DLL +#ifdef SDK_DLL + //DM- take care of prediction first + if ( prediction->InPrediction() && !prediction->IsFirstTimePredicted() ) + { + origin += m_vPredictedOffset; + return; + } - // Now offset the origin using that. - vForwardDiff *= cl_wpn_sway_scale.GetFloat(); - origin += forward*vForwardDiff.x + right*-vForwardDiff.y + up*vForwardDiff.z; - #endif + Vector oldOrigin = origin; + BaseClass::CalcViewModelLag( origin, angles, original_angles ); + + m_vPredictedOffset = origin - oldOrigin; + + return; //kick it back off to CBaseViewModel for proper computation, + //don't perform the unnecessary checks below +#endif + float interp = cl_wpn_sway_interp.GetFloat(); + if ( !interp ) + return; + + if ( prediction->InPrediction() && !prediction->IsFirstTimePredicted() ) + { + origin += m_vPredictedOffset; + return; + } + + // Calculate our drift + Vector forward, right, up; + AngleVectors( angles, &forward, &right, &up ); + + // Add an entry to the history. + m_vLagAngles = angles; + m_LagAnglesHistory.NoteChanged( gpGlobals->curtime, interp, false ); + + // Interpolate back 100ms. + m_LagAnglesHistory.Interpolate( gpGlobals->curtime, interp ); + + // Now take the 100ms angle difference and figure out how far the forward vector moved in local space. + Vector vLaggedForward; + QAngle angleDiff = m_vLagAngles - angles; + AngleVectors( -angleDiff, &vLaggedForward, 0, 0 ); + Vector vForwardDiff = Vector(1,0,0) - vLaggedForward; + + // Now offset the origin using that. + vForwardDiff *= cl_wpn_sway_scale.GetFloat(); + m_vPredictedOffset = forward*vForwardDiff.x + right*-vForwardDiff.y + up*vForwardDiff.z; + origin += m_vPredictedOffset; +#endif } \ No newline at end of file diff --git a/sp/src/game/shared/predicted_viewmodel.h b/sp/src/game/shared/predicted_viewmodel.h index 8e5af39c..5284d508 100644 --- a/sp/src/game/shared/predicted_viewmodel.h +++ b/sp/src/game/shared/predicted_viewmodel.h @@ -49,6 +49,7 @@ private: // This is used to lag the angles. CInterpolatedVar m_LagAnglesHistory; QAngle m_vLagAngles; + Vector m_vPredictedOffset; CPredictedViewModel( const CPredictedViewModel & ); // not defined, not accessible diff --git a/sp/src/game/shared/shareddefs.h b/sp/src/game/shared/shareddefs.h index 349c986c..63080104 100644 --- a/sp/src/game/shared/shareddefs.h +++ b/sp/src/game/shared/shareddefs.h @@ -580,6 +580,7 @@ enum EFL_SETTING_UP_BONES = (1<<3), // Set while a model is setting up its bones. EFL_KEEP_ON_RECREATE_ENTITIES = (1<<4), // This is a special entity that should not be deleted when we restart entities only + //Tony; BUG?? I noticed this today while performing stealz on flag 16! look at the definition of the flag above... EFL_HAS_PLAYER_CHILD= (1<<4), // One of the child entities is a player. EFL_DIRTY_SHADOWUPDATE = (1<<5), // Client only- need shadow manager to update the shadow... @@ -601,7 +602,7 @@ enum EFL_DIRTY_ABSANGVELOCITY = (1<<13), EFL_DIRTY_SURROUNDING_COLLISION_BOUNDS = (1<<14), EFL_DIRTY_SPATIAL_PARTITION = (1<<15), -// UNUSED = (1<<16), + EFL_PLUGIN_BASED_BOT = (1<<16), //this is set on plugin bots, so that if any games include their own bot code, they won't affect plugin bots. EFL_IN_SKYBOX = (1<<17), // This is set if the entity detects that it's in the skybox. // This forces it to pass the "in PVS" for transmission. @@ -913,6 +914,39 @@ enum #define COMMENTARY_BUTTONS (IN_USE) #endif +enum tprbGameInfo_e +{ + // Teamplay Roundbased Game rules shared + TPRBGAMEINFO_GAMESTATE = 1, //gets the state of the current game (waiting for players, setup, active, overtime, stalemate, roundreset) + TPRBGAMEINFO_RESERVED1, + TPRBGAMEINFO_RESERVED2, + TPRBGAMEINFO_RESERVED3, + TPRBGAMEINFO_RESERVED4, + TPRBGAMEINFO_RESERVED5, + TPRBGAMEINFO_RESERVED6, + TPRBGAMEINFO_RESERVED7, + TPRBGAMEINFO_RESERVED8, + + TPRBGAMEINFO_LASTGAMEINFO, +}; +// Mark it off so valvegame_plugin_def.h ignores it, if both headers are included in a plugin. +#define TPRBGAMEINFO_x 1 + +//Tony; (t)eam(p)lay(r)ound(b)ased gamerules -- Game Info values +#define TPRB_STATE_WAITING (1<<0) +#define TPRB_STATE_SETUP (1<<1) +#define TPRB_STATE_ACTIVE (1<<2) +#define TPRB_STATE_ROUNDWON (1<<3) +#define TPRB_STATE_OVERTIME (1<<4) +#define TPRB_STATE_STALEMATE (1<<5) +#define TPRB_STATE_ROUNDRESET (1<<6) +#define TPRB_STATE_WAITINGREADYSTART (1<<7) + +//Tony; including sdk_shareddefs.h because I use it in a _lot_ of places that needs to be seen before many other things. +#ifdef SDK_DLL +#include "sdk_shareddefs.h" +#endif + #define TEAM_TRAIN_MAX_TEAMS 4 #define TEAM_TRAIN_MAX_HILLS 5 #define TEAM_TRAIN_FLOATS_PER_HILL 2 diff --git a/sp/src/game/shared/vscript_shared.h b/sp/src/game/shared/vscript_shared.h index ba27eaae..55e19a61 100644 --- a/sp/src/game/shared/vscript_shared.h +++ b/sp/src/game/shared/vscript_shared.h @@ -33,62 +33,6 @@ bool IsEntityCreationAllowedInScripts( void ); #ifdef MAPBASE_VSCRIPT void RegisterSharedScriptFunctions(); - -// -// Exposes FireBulletsInfo_t to VScript -// -class CFireBulletsInfoAccessor -{ -public: - CFireBulletsInfoAccessor( FireBulletsInfo_t *info ) { m_info = info; } - - int GetShots() { return m_info->m_iShots; } - void SetShots( int value ) { m_info->m_iShots = value; } - - Vector GetSource() { return m_info->m_vecSrc; } - void SetSource( Vector value ) { m_info->m_vecSrc = value; } - Vector GetDirShooting() { return m_info->m_vecDirShooting; } - void SetDirShooting( Vector value ) { m_info->m_vecDirShooting = value; } - Vector GetSpread() { return m_info->m_vecSpread; } - void SetSpread( Vector value ) { m_info->m_vecSpread = value; } - - float GetDistance() { return m_info->m_flDistance; } - void SetDistance( float value ) { m_info->m_flDistance = value; } - - int GetAmmoType() { return m_info->m_iAmmoType; } - void SetAmmoType( int value ) { m_info->m_iAmmoType = value; } - - int GetTracerFreq() { return m_info->m_iTracerFreq; } - void SetTracerFreq( int value ) { m_info->m_iTracerFreq = value; } - - float GetDamage() { return m_info->m_flDamage; } - void SetDamage( float value ) { m_info->m_flDamage = value; } - int GetPlayerDamage() { return m_info->m_iPlayerDamage; } - void SetPlayerDamage( float value ) { m_info->m_iPlayerDamage = value; } - - int GetFlags() { return m_info->m_nFlags; } - void SetFlags( float value ) { m_info->m_nFlags = value; } - - float GetDamageForceScale() { return m_info->m_flDamageForceScale; } - void SetDamageForceScale( float value ) { m_info->m_flDamageForceScale = value; } - - HSCRIPT GetAttacker(); - void SetAttacker( HSCRIPT value ); - HSCRIPT GetAdditionalIgnoreEnt(); - void SetAdditionalIgnoreEnt( HSCRIPT value ); - - bool GetPrimaryAttack() { return m_info->m_bPrimaryAttack; } - void SetPrimaryAttack( bool value ) { m_info->m_bPrimaryAttack = value; } - - FireBulletsInfo_t *GetInfo() { return m_info; } - - void Destroy() { delete m_info; delete this; } - -private: - FireBulletsInfo_t *m_info; -}; - -HSCRIPT ScriptCreateMatrixInstance( matrix3x4_t &matrix ); #endif #endif // VSCRIPT_SHARED_H diff --git a/sp/src/public/const.h b/sp/src/public/const.h index 8105f866..e923edb3 100644 --- a/sp/src/public/const.h +++ b/sp/src/public/const.h @@ -442,5 +442,17 @@ class CThreadNullMutex; typedef CThreadNullMutex CSourceMutex; #endif +//Tony; added for IPlayerInfo V3. +//Putting all standard possible stances, but GetStance in CBasePlayer will only return standing or ducking by default - +//up to the mod to specify the others, or override what GetStance returns. +enum player_Stance +{ + PINFO_STANCE_STANDING = 0, + PINFO_STANCE_DUCKING, + + PINFO_STANCE_SPRINTING, + PINFO_STANCE_PRONE, +}; + #endif diff --git a/sp/src/utils/vbsp/cubemap.cpp b/sp/src/utils/vbsp/cubemap.cpp index b44e739b..091253ec 100644 --- a/sp/src/utils/vbsp/cubemap.cpp +++ b/sp/src/utils/vbsp/cubemap.cpp @@ -283,7 +283,15 @@ void VTFNameToHDRVTFName( const char *pSrcName, char *pDest, int maxLen, bool bH Q_strncpy( pDot, ".hdr.vtf", maxLen - ( pDot - pDest ) ); } +#ifdef MAPBASE + +extern bool g_bSkyboxCubemaps; +extern int g_iDefaultCubemapSize; +#define DEFAULT_CUBEMAP_SIZE g_iDefaultCubemapSize + +#else #define DEFAULT_CUBEMAP_SIZE 32 +#endif void CreateDefaultCubemaps( bool bHDR ) { @@ -346,9 +354,17 @@ void CreateDefaultCubemaps( bool bHDR ) int iSize = pDstCubemap->ComputeMipSize( iMip ); int iSrcMipSize = pSrcVTFTextures[iFace]->ComputeMipSize( iMip + iMipLevelOffset ); +#ifdef MAPBASE + if (!g_bSkyboxCubemaps) + { + memset( pDstBits, 0, iSize ); + continue; + } +#else // !!! FIXME: Set this to black until HDR cubemaps are built properly! memset( pDstBits, 0, iSize ); continue; +#endif if ( ( pSrcVTFTextures[iFace]->Width() == 4 ) && ( pSrcVTFTextures[iFace]->Height() == 4 ) ) // If texture is 4x4 square { @@ -436,6 +452,14 @@ void CreateDefaultCubemaps( bool bHDR ) pDstCubemap->ConvertImageFormat( originalFormat, false ); } +#ifdef MAPBASE + // Apply a seam fix + pDstCubemap->ConvertImageFormat( IMAGE_FORMAT_RGBA8888, false ); + + pDstCubemap->MatchCubeMapBorders( 1, IMAGE_FORMAT_RGBA8888, false ); + pDstCubemap->MatchCubeMapBorders( 2, originalFormat, false ); +#endif + // Write the puppy out! char dstVTFFileName[1024]; if( bHDR ) diff --git a/sp/src/utils/vbsp/vbsp.cpp b/sp/src/utils/vbsp/vbsp.cpp index 083bc576..d9f8fb91 100644 --- a/sp/src/utils/vbsp/vbsp.cpp +++ b/sp/src/utils/vbsp/vbsp.cpp @@ -62,6 +62,8 @@ bool g_bAllowDetailCracks = false; bool g_bNoVirtualMesh = false; #ifdef MAPBASE bool g_bNoDefaultCubemaps = true; +bool g_bSkyboxCubemaps = false; +int g_iDefaultCubemapSize = 32; #endif float g_defaultLuxelSize = DEFAULT_LUXEL_SIZE; @@ -1156,13 +1158,28 @@ int RunVBSP( int argc, char **argv ) EnableFullMinidumps( true ); } #ifdef MAPBASE - // Thanks to Mapbase's shader changes, default cubemaps are no longer needed. + // Thanks to Mapbase's shader changes, default all-black cubemaps are no longer needed. // The command has been switched from "-nodefaultcubemap" to "-defaultcubemap", // meaning maps are compiled without them by default. else if ( !Q_stricmp( argv[i], "-defaultcubemap" ) ) { g_bNoDefaultCubemaps = false; } + // Default cubemaps are supposed to show the sky texture, but Valve disabled this + // because they didn't get it working for HDR cubemaps. As a result, all default + // cubemaps appear as all-black textures. However, this parameter has been added to + // re-enable skybox cubemaps for LDR cubemaps. (HDR skybox cubemaps are not supported) + else if ( !Q_stricmp( argv[i], "-skyboxcubemap" ) ) + { + g_bNoDefaultCubemaps = false; + g_bSkyboxCubemaps = true; + } + else if ( !Q_stricmp( argv[i], "-defaultcubemapres" ) ) + { + g_iDefaultCubemapSize = atoi( argv[i + 1] ); + Msg( "Default cubemap size = %i\n", g_iDefaultCubemapSize ); + i++; + } #endif else if (argv[i][0] == '-') {