From d4be1b1ff22d68d3c24bccc6251bb45ec55b4dd4 Mon Sep 17 00:00:00 2001 From: luttje <2738114+luttje@users.noreply.github.com> Date: Sat, 24 Aug 2024 11:07:05 +0200 Subject: [PATCH] add missing functions, notably Get-/SetMaterial(s) --- docs/general/conventions.md | 1 + .../gmod_compatibility/sh_enumerations.lua | 17 +++-- .../modules/gmod_compatibility/sh_init.lua | 23 ++++-- src/game/client/c_baseanimating.cpp | 54 ++++++++++---- src/game/client/c_baseanimating.h | 12 ++++ src/game/server/baseanimating.cpp | 23 +++--- src/game/server/baseanimating.h | 11 +++ .../weapon_experimentbase_scriptedweapon.cpp | 26 ++++--- src/game/shared/lbaseanimating_shared.cpp | 70 +++++++++++++++++-- src/game/shared/lbaseentity_shared.cpp | 18 ++++- src/game/shared/lbaseplayer_shared.cpp | 61 ++++++++++++++-- src/game/shared/lutil_shared.cpp | 14 ---- src/public/lenumerations_shared.cpp | 7 ++ src/public/mathlib/langle.cpp | 8 +-- 14 files changed, 270 insertions(+), 75 deletions(-) diff --git a/docs/general/conventions.md b/docs/general/conventions.md index 81e4322ab2..0d7b1921b0 100644 --- a/docs/general/conventions.md +++ b/docs/general/conventions.md @@ -77,6 +77,7 @@ Additionally, we use the following conventions: - `Dx` (DirectX), `HDR` and other graphic settings - `Fcvar` (short for flag convar, kept this way due to the source engine using this abbreviation when explaining convars) + - `Fov` (short for field of view) - `Hltv` (short for Half-Life TV) - `Hud` - `Hwnd` (short for window handle) diff --git a/game/experiment/addons/gmod_compatibility/scripts/lua/includes/modules/gmod_compatibility/sh_enumerations.lua b/game/experiment/addons/gmod_compatibility/scripts/lua/includes/modules/gmod_compatibility/sh_enumerations.lua index b8bdfd89b3..35ca9b3db0 100644 --- a/game/experiment/addons/gmod_compatibility/scripts/lua/includes/modules/gmod_compatibility/sh_enumerations.lua +++ b/game/experiment/addons/gmod_compatibility/scripts/lua/includes/modules/gmod_compatibility/sh_enumerations.lua @@ -94,12 +94,12 @@ local enumsToMergeWithKey = { MOVE_TYPE = "MOVETYPE", OBSERVER_MODE = "OBS_MODE", SOLID = "SOLID", - SOUND_CHANNEL = "CHAN", - SURFACE = "SURF", + SOUND_CHANNEL = "CHAN", + SURFACE = "SURF", - DAMAGE_TYPE = {"DMG", stripUnderscores}, - HIT_GROUP = {"HITGROUP", stripUnderscores}, - MATERIAL_TYPE = {"MAT", stripUnderscores}, + DAMAGE_TYPE = {"DMG", stripUnderscores}, + HIT_GROUP = {"HITGROUP", stripUnderscores}, + MATERIAL_TYPE = {"MAT", stripUnderscores}, } for enumKey, enumTargetKey in pairs(enumsToMergeWithKey) do @@ -107,7 +107,7 @@ for enumKey, enumTargetKey in pairs(enumsToMergeWithKey) do error("Missing enumeration table for key: " .. enumKey) continue end - + local modifier if (istable(enumTargetKey)) then @@ -168,6 +168,11 @@ TRANSMIT_ALWAYS = _E.EDICT_FLAG.ALWAYS TRANSMIT_NEVER = _E.EDICT_FLAG.DONTSEND TRANSMIT_PVS = _E.EDICT_FLAG.PVSCHECK +HUD_PRINTNOTIFY = 1 +HUD_PRINTCONSOLE = 2 +HUD_PRINTTALK = 3 +HUD_PRINTCENTER = 4 + TYPE_NONE = -1 TYPE_NIL = 0 TYPE_BOOL = 1 diff --git a/game/experiment/addons/gmod_compatibility/scripts/lua/includes/modules/gmod_compatibility/sh_init.lua b/game/experiment/addons/gmod_compatibility/scripts/lua/includes/modules/gmod_compatibility/sh_init.lua index 4ea3fb06da..e8b65ee37e 100644 --- a/game/experiment/addons/gmod_compatibility/scripts/lua/includes/modules/gmod_compatibility/sh_init.lua +++ b/game/experiment/addons/gmod_compatibility/scripts/lua/includes/modules/gmod_compatibility/sh_init.lua @@ -27,6 +27,9 @@ include = Include Msg = PrintMessage MsgN = PrintMessageLine +OriginalPrintMessage = PrintMessage +PrintMessage = Players.ClientPrintToAll + function GetConVar_Internal(name) local consoleVariable = ConsoleVariables.Get(name) @@ -454,6 +457,8 @@ ENTITY_META.DontDeleteOnRemove = ENTITY_META.RemoveDeleteOnRemove ENTITY_META.GetFlexIDByName = ENTITY_META.GetFlexIdByName ENTITY_META.GetNumBodyGroups = ENTITY_META.GetBodyGroupsCount ENTITY_META.WaterLevel = ENTITY_META.GetWaterLevel +ENTITY_META.SetMaterial = ENTITY_META.SetMaterialOverride +ENTITY_META.GetMaterial = ENTITY_META.GetMaterialOverride function ENTITY_META:GetDTAngle(index) return self:GetNetworkDataValue(_E.NETWORK_VARIABLE_TYPE.ANGLE, index) @@ -602,6 +607,8 @@ end local WEAPON_META = FindMetaTable("Weapon") WEAPON_META.GetHoldType = WEAPON_META.GetAnimationPrefix WEAPON_META.SetHoldType = WEAPON_META.SetAnimationPrefix +WEAPON_META.Ammo1 = WEAPON_META.GetPrimaryAmmoCount +WEAPON_META.Ammo2 = WEAPON_META.GetSecondaryAmmoCount local PLAYER_META = FindMetaTable("Player") PLAYER_META.GetShootPos = ENTITY_META.GetEyePosition @@ -627,6 +634,12 @@ PLAYER_META.GetWalkSpeed = PLAYER_META.GetNormalSpeed PLAYER_META.GetCrouchedWalkSpeed = PLAYER_META.GetCrouchWalkFraction PLAYER_META.SetCrouchedWalkSpeed = PLAYER_META.SetCrouchWalkFraction PLAYER_META.Ping = PLAYER_META.GetPing +PLAYER_META.KeyDown = PLAYER_META.IsKeyDown +PLAYER_META.KeyDownLast = PLAYER_META.WasKeyDown +PLAYER_META.KeyPressed = PLAYER_META.WasKeyPressed +PLAYER_META.KeyReleased = PLAYER_META.WasKeyReleased +PLAYER_META.GetFOV = PLAYER_META.GetFov +PLAYER_META.SetFOV = PLAYER_META.SetFov function PLAYER_META:Crouching() return self:IsFlagSet(_E.ENGINE_FLAG.DUCKING) @@ -640,6 +653,10 @@ function PLAYER_META:GetInfoNum(consoleVariableName, default) return engine.GetClientConsoleVariableValueAsNumber(self, consoleVariableName) or default end +function PLAYER_META:PrintMessage(type, message) + Players.ClientPrint(self, type, message) +end + function PLAYER_META:IsDrivingEntity() return false -- TODO: implement this end @@ -1511,17 +1528,11 @@ end) hook.Add("PreEntityInitialize", "GModCompatibility.CallSetupDataTables", function(entity) if (entity.InstallDataTable) then - print("Installing data table for " .. tostring(entity)) entity:InstallDataTable() - else - print("No data table to install for " .. tostring(entity)) end if (entity.SetupDataTables) then - print("Setting up data tables for " .. tostring(entity)) entity:SetupDataTables() - else - print("No data tables to setup for " .. tostring(entity)) end end) diff --git a/src/game/client/c_baseanimating.cpp b/src/game/client/c_baseanimating.cpp index e0f45e41f8..e3c457301f 100644 --- a/src/game/client/c_baseanimating.cpp +++ b/src/game/client/c_baseanimating.cpp @@ -153,11 +153,13 @@ const unsigned int FCLIENTANIM_SEQUENCE_CYCLE = 0x00000001; static CUtlVector< clientanimating_t > g_ClientSideAnimationList; +// clang-format off + BEGIN_RECV_TABLE_NOBASE( C_BaseAnimating, DT_ServerAnimationData ) -RecvPropFloat( RECVINFO( m_flCycle ) ), - END_RECV_TABLE() + RecvPropFloat( RECVINFO( m_flCycle ) ), +END_RECV_TABLE() - void RecvProxy_Sequence( const CRecvProxyData *pData, void *pStruct, void *pOut ) +void RecvProxy_Sequence( const CRecvProxyData *pData, void *pStruct, void *pOut ) { // Have the regular proxy store the data. RecvProxy_Int32ToInt32( pData, pStruct, pOut ); @@ -174,7 +176,7 @@ RecvPropFloat( RECVINFO( m_flCycle ) ), } IMPLEMENT_CLIENTCLASS_DT( C_BaseAnimating, DT_BaseAnimating, CBaseAnimating ) -RecvPropInt( RECVINFO( m_nSequence ), 0, RecvProxy_Sequence ), + RecvPropInt( RECVINFO( m_nSequence ), 0, RecvProxy_Sequence ), RecvPropInt( RECVINFO( m_nForceBone ) ), RecvPropVector( RECVINFO( m_vecForce ) ), RecvPropInt( RECVINFO( m_nSkin ) ), @@ -207,11 +209,14 @@ RecvPropInt( RECVINFO( m_nSequence ), 0, RecvProxy_Sequence ), RecvPropFloat( RECVINFO( m_fadeMaxDist ) ), RecvPropFloat( RECVINFO( m_flFadeScale ) ), - END_RECV_TABLE() + // Experiment; Material override + RecvPropString( RECVINFO(m_MaterialOverride) ), + +END_RECV_TABLE() - BEGIN_PREDICTION_DATA( C_BaseAnimating ) +BEGIN_PREDICTION_DATA( C_BaseAnimating ) - DEFINE_PRED_FIELD( m_nSkin, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_nSkin, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), DEFINE_PRED_FIELD( m_nBody, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), // DEFINE_PRED_FIELD( m_nHitboxSet, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), // DEFINE_PRED_FIELD( m_flModelScale, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ), @@ -255,12 +260,12 @@ RecvPropInt( RECVINFO( m_nSequence ), 0, RecvProxy_Sequence ), // DEFINE_FIELD( C_BaseFlex, m_iEyeAttachment, FIELD_INTEGER ), - END_PREDICTION_DATA() +END_PREDICTION_DATA() - LINK_ENTITY_TO_CLASS( client_ragdoll, C_ClientRagdoll ); +LINK_ENTITY_TO_CLASS( client_ragdoll, C_ClientRagdoll ); BEGIN_DATADESC( C_ClientRagdoll ) -DEFINE_FIELD( m_bFadeOut, FIELD_BOOLEAN ), + DEFINE_FIELD( m_bFadeOut, FIELD_BOOLEAN ), DEFINE_FIELD( m_bImportant, FIELD_BOOLEAN ), DEFINE_FIELD( m_iCurrentFriction, FIELD_INTEGER ), DEFINE_FIELD( m_iMinFriction, FIELD_INTEGER ), @@ -282,9 +287,11 @@ DEFINE_FIELD( m_bFadeOut, FIELD_BOOLEAN ), DEFINE_AUTO_ARRAY( m_flScaleTimeEnd, FIELD_FLOAT ), DEFINE_EMBEDDEDBYREF( m_pRagdoll ), - END_DATADESC() +END_DATADESC() - C_ClientRagdoll::C_ClientRagdoll( bool bRestoring ) +static void* WORKAROUND_NASTY_FORMATTING_BUG; // clang-format on + +C_ClientRagdoll::C_ClientRagdoll( bool bRestoring ) { m_iCurrentFriction = 0; m_iFrictionAnimState = RAGDOLL_FRICTION_NONE; @@ -3132,6 +3139,11 @@ int C_BaseAnimating::DrawModel( int flags ) // Necessary for lighting blending CreateModelInstance(); + if ( m_MaterialOverrideReference.IsValid() ) + { + modelrender->ForcedMaterialOverride( m_MaterialOverrideReference ); + } + if ( !IsFollowingEntity() ) { drawn = InternalDrawModel( flags | extraFlags ); @@ -3154,6 +3166,11 @@ int C_BaseAnimating::DrawModel( int flags ) } } } + + if ( m_MaterialOverrideReference.IsValid() ) + { + modelrender->ForcedMaterialOverride( NULL ); + } } // If we're visualizing our bboxes, draw them @@ -4627,8 +4644,8 @@ C_BaseAnimating *C_BaseAnimating::CreateRagdollCopy() if ( L ) { LUA_CALL_HOOK_BEGIN( "CreateClientSideRagdoll" ); - this->PushLuaInstance( L ); // doc: entity - pRagdoll->PushLuaInstance( L ); // doc: ragdollEntity + this->PushLuaInstance( L ); // doc: entity + pRagdoll->PushLuaInstance( L ); // doc: ragdollEntity LUA_CALL_HOOK_END( 2, 0 ); } @@ -4828,6 +4845,15 @@ void C_BaseAnimating::OnDataChanged( DataUpdateType_t updateType ) delete m_pRagdollInfo; m_pRagdollInfo = NULL; } + + if ( m_MaterialOverride[0] != 0 ) + { + m_MaterialOverrideReference.Init( m_MaterialOverride, TEXTURE_GROUP_MODEL ); + } + else if ( m_MaterialOverrideReference.IsValid() ) + { + m_MaterialOverrideReference.Shutdown(); + } } //----------------------------------------------------------------------------- diff --git a/src/game/client/c_baseanimating.h b/src/game/client/c_baseanimating.h index ff06c494e3..2fa0fa36f0 100644 --- a/src/game/client/c_baseanimating.h +++ b/src/game/client/c_baseanimating.h @@ -501,6 +501,14 @@ class C_BaseAnimating : public C_BaseEntity, private IModelLoadCallback virtual bool IsViewModel() const; virtual void UpdateOnRemove( void ); + void SetMaterialOverride( const char *pMaterialName ) + { + Q_strncpy( m_MaterialOverride, pMaterialName, sizeof( m_MaterialOverride ) ); + } + void GetMaterialOverride( char *pOut, int nLength ) + { + Q_strncpy( pOut, m_MaterialOverride, nLength ); + } protected: // View models scale their attachment positions to account for FOV. To get the unmodified @@ -597,6 +605,10 @@ class C_BaseAnimating : public C_BaseEntity, private IModelLoadCallback float m_fadeMaxDist; float m_flFadeScale; + // Experiment; Material override + char m_MaterialOverride[MAX_PATH]; + CMaterialReference m_MaterialOverrideReference; + private: float m_flGroundSpeed; // computed linear movement rate for current sequence float m_flLastEventCheck; // cycle index of when events were last checked diff --git a/src/game/server/baseanimating.cpp b/src/game/server/baseanimating.cpp index f8ca85c3fb..1ff42f0661 100644 --- a/src/game/server/baseanimating.cpp +++ b/src/game/server/baseanimating.cpp @@ -151,6 +151,8 @@ int CInfoLightingRelative::UpdateTransmitState( void ) static CIKSaveRestoreOps s_IKSaveRestoreOp; +// clang-format off + BEGIN_DATADESC( CBaseAnimating ) DEFINE_FIELD( m_flGroundSpeed, FIELD_FLOAT ), @@ -215,19 +217,19 @@ DEFINE_FIELD( m_flGroundSpeed, FIELD_FLOAT ), DEFINE_FIELD( m_fBoneCacheFlags, FIELD_SHORT ), - END_DATADESC() +END_DATADESC() - // Sendtable for fields we don't want to send to clientside animating entities - BEGIN_SEND_TABLE_NOBASE( CBaseAnimating, DT_ServerAnimationData ) +// Sendtable for fields we don't want to send to clientside animating entities +BEGIN_SEND_TABLE_NOBASE( CBaseAnimating, DT_ServerAnimationData ) // ANIMATION_CYCLE_BITS is defined in shareddefs.h SendPropFloat( SENDINFO( m_flCycle ), ANIMATION_CYCLE_BITS, SPROP_CHANGES_OFTEN | SPROP_ROUNDDOWN, 0.0f, 1.0f ) - END_SEND_TABLE() +END_SEND_TABLE() - void *SendProxy_ClientSideAnimation( const SendProp *pProp, const void *pStruct, const void *pVarData, CSendProxyRecipients *pRecipients, int objectID ); +void *SendProxy_ClientSideAnimation( const SendProp *pProp, const void *pStruct, const void *pVarData, CSendProxyRecipients *pRecipients, int objectID ); // SendTable stuff. IMPLEMENT_SERVERCLASS_ST( CBaseAnimating, DT_BaseAnimating ) -SendPropInt( SENDINFO( m_nForceBone ), 8, 0 ), + SendPropInt( SENDINFO( m_nForceBone ), 8, 0 ), SendPropVector( SENDINFO( m_vecForce ), -1, SPROP_NOSCALE ), SendPropInt( SENDINFO( m_nSkin ), ANIMATION_SKIN_BITS ), @@ -261,9 +263,14 @@ SendPropInt( SENDINFO( m_nForceBone ), 8, 0 ), SendPropFloat( SENDINFO( m_fadeMaxDist ), 0, SPROP_NOSCALE ), SendPropFloat( SENDINFO( m_flFadeScale ), 0, SPROP_NOSCALE ), - END_SEND_TABLE() + // Experiment; material override + SendPropString( SENDINFO( m_MaterialOverride ) ), + +END_SEND_TABLE() + +static void* WORKAROUND_NASTY_FORMATTING_BUG; // clang-format on - CBaseAnimating::CBaseAnimating() +CBaseAnimating::CBaseAnimating() { m_vecForce.GetForModify().Init(); m_nForceBone = 0; diff --git a/src/game/server/baseanimating.h b/src/game/server/baseanimating.h index 05ba641cfa..97b98d728a 100644 --- a/src/game/server/baseanimating.h +++ b/src/game/server/baseanimating.h @@ -410,6 +410,14 @@ class CBaseAnimating : public CBaseEntity } bool PrefetchSequence( int iSequence ); + void SetMaterialOverride(const char* pMaterialName) + { + Q_strncpy( m_MaterialOverride.GetForModify(), pMaterialName, MAX_PATH ); + } + void GetMaterialOverride( char *pOut, int nLength ) + { + Q_strncpy( pOut, m_MaterialOverride.Get(), nLength ); + } private: void LockStudioHdr(); @@ -493,6 +501,9 @@ class CBaseAnimating : public CBaseEntity CNetworkVar( float, m_fadeMaxDist ); // Point at which fading is inactive CNetworkVar( float, m_flFadeScale ); // Scale applied to min / max + // Experiment; Material overrides + CNetworkString( m_MaterialOverride, MAX_PATH ); + public: COutputEvent m_OnIgnite; diff --git a/src/game/shared/experiment/weapon_experimentbase_scriptedweapon.cpp b/src/game/shared/experiment/weapon_experimentbase_scriptedweapon.cpp index 4b82b195f6..da08f90b02 100644 --- a/src/game/shared/experiment/weapon_experimentbase_scriptedweapon.cpp +++ b/src/game/shared/experiment/weapon_experimentbase_scriptedweapon.cpp @@ -22,30 +22,34 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +// clang-format off + IMPLEMENT_NETWORKCLASS_ALIASED( ExperimentScriptedWeapon, DT_ExperimentScriptedWeapon ) BEGIN_NETWORK_TABLE( CExperimentScriptedWeapon, DT_ExperimentScriptedWeapon ) #ifdef CLIENT_DLL -RecvPropString( RECVINFO( m_iScriptedClassname ) ), + RecvPropString( RECVINFO( m_iScriptedClassname ) ), #else -SendPropString( SENDINFO( m_iScriptedClassname ) ), + SendPropString( SENDINFO( m_iScriptedClassname ) ), #endif - END_NETWORK_TABLE() +END_NETWORK_TABLE() + +BEGIN_PREDICTION_DATA( CExperimentScriptedWeapon ) +END_PREDICTION_DATA() - BEGIN_PREDICTION_DATA( CExperimentScriptedWeapon ) END_PREDICTION_DATA() +//========================================================= +// >> CHLSelectFireScriptedWeapon +//========================================================= +BEGIN_DATADESC( CExperimentScriptedWeapon ) END_DATADESC() - //========================================================= - // >> CHLSelectFireScriptedWeapon - //========================================================= - BEGIN_DATADESC( CExperimentScriptedWeapon ) END_DATADESC() +// LINK_ENTITY_TO_CLASS( weapon_experimentbase_scriptedweapon, CExperimentScriptedWeapon ); PRECACHE_WEAPON_REGISTER( weapon_experimentbase_scriptedweapon ); -// LINK_ENTITY_TO_CLASS( weapon_experimentbase_scriptedweapon, CExperimentScriptedWeapon -// ); PRECACHE_WEAPON_REGISTER( weapon_experimentbase_scriptedweapon ); +static void* WORKAROUND_NASTY_FORMATTING_BUG; // clang-format on // These functions replace the macros above for runtime registration of // scripted weapons. #ifdef CLIENT_DLL - static C_BaseEntity *CCExperimentScriptedWeaponFactory( void ) +static C_BaseEntity *CCExperimentScriptedWeaponFactory( void ) { return static_cast< C_BaseEntity * >( new CExperimentScriptedWeapon ); }; diff --git a/src/game/shared/lbaseanimating_shared.cpp b/src/game/shared/lbaseanimating_shared.cpp index 46b64e464f..0f8b5c0037 100644 --- a/src/game/shared/lbaseanimating_shared.cpp +++ b/src/game/shared/lbaseanimating_shared.cpp @@ -8,6 +8,8 @@ #else #include "lbaseanimating.h" #endif +#include +#include // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -853,6 +855,66 @@ LUA_BINDING_BEGIN( CBaseAnimating, GetFlexName, "class", "Get the flex controlle } LUA_BINDING_END( "string", "The flex controller name" ) +LUA_BINDING_BEGIN( CBaseAnimating, SetMaterialOverride, "class", "Set the material override" ) +{ + lua_CBaseAnimating *pAnimating = LUA_BINDING_ARGUMENT( luaL_checkanimating, 1, "entity" ); + const char *pszMaterialName = LUA_BINDING_ARGUMENT( luaL_checkstring, 2, "materialName" ); + + pAnimating->SetMaterialOverride( pszMaterialName ); + + return 0; +} +LUA_BINDING_END() + +LUA_BINDING_BEGIN( CBaseAnimating, GetMaterialOverride, "class", "Get the material override" ) +{ + lua_CBaseAnimating *pAnimating = LUA_BINDING_ARGUMENT( luaL_checkanimating, 1, "entity" ); + char pszMaterialName[MAX_PATH]; + + pAnimating->GetMaterialOverride( pszMaterialName, sizeof( pszMaterialName ) ); + + lua_pushstring( L, pszMaterialName ); + + return 1; +} +LUA_BINDING_END( "string", "The material override" ) + +LUA_BINDING_BEGIN( CBaseAnimating, GetMaterials, "class", "Get the materials" ) +{ + lua_CBaseAnimating *pAnimating = LUA_BINDING_ARGUMENT( luaL_checkanimating, 1, "entity" ); + + CStudioHdr *pStudioHdr = pAnimating->GetModelPtr(); + + if ( !pStudioHdr ) + { + lua_pushnil( L ); + return 1; + } + + const studiohdr_t *pRenderHdr = pStudioHdr->GetRenderHdr(); + + IMaterial *pMaterials[128]; + int iMaterialCount = g_pStudioRender->GetMaterialList( ( studiohdr_t * )pRenderHdr, ARRAYSIZE( pMaterials ), pMaterials ); + + lua_newtable( L ); + + for ( int i = 0; i < iMaterialCount; i++ ) + { + IMaterial *pMaterial = pMaterials[i]; + + if ( !pMaterial ) + continue; + + lua_pushnumber( L, i + 1 ); + lua_pushmaterial( L, pMaterial ); + lua_settable( L, -3 ); + } + + lua_pushinteger( L, iMaterialCount ); + return 2; +} +LUA_BINDING_END( "table", "The materials", "integer", "The number of materials" ) + LUA_BINDING_BEGIN( CBaseAnimating, SetSequence, "class", "Set the sequence." ) { lua_CBaseAnimating *pAnimating = LUA_BINDING_ARGUMENT( luaL_checkanimating, 1, "entity" ); @@ -977,7 +1039,7 @@ LUA_BINDING_END() // } // Experiment; We only let CBaseEntity determine equality, which should be fine since they're pointers to the same entity. Disabled: -//LUA_BINDING_BEGIN( CBaseAnimating, __eq, "class", "Metamethod to check if the two entities are the same" ) +// LUA_BINDING_BEGIN( CBaseAnimating, __eq, "class", "Metamethod to check if the two entities are the same" ) //{ // lua_CBaseAnimating *pAnimating1 = LUA_BINDING_ARGUMENT( lua_toanimating, 1, "entity1" ); // lua_CBaseAnimating *pAnimating2 = LUA_BINDING_ARGUMENT( lua_toanimating, 2, "entity2" ); @@ -986,9 +1048,9 @@ LUA_BINDING_END() // // return 1; //} -//LUA_BINDING_END( "boolean", "True if the entities are the same, false otherwise" ) +// LUA_BINDING_END( "boolean", "True if the entities are the same, false otherwise" ) // -//LUA_BINDING_BEGIN( CBaseAnimating, __tostring, "class", "Metamethod to get the string representation of the entity" ) +// LUA_BINDING_BEGIN( CBaseAnimating, __tostring, "class", "Metamethod to get the string representation of the entity" ) //{ // lua_CBaseAnimating *pAnimating = LUA_BINDING_ARGUMENT( lua_toanimating, 1, "entity" ); // @@ -1003,7 +1065,7 @@ LUA_BINDING_END() // // return 1; //} -//LUA_BINDING_END( "string", "The string representation of the entity" ) +// LUA_BINDING_END( "string", "The string representation of the entity" ) /* ** Open CBaseAnimating object diff --git a/src/game/shared/lbaseentity_shared.cpp b/src/game/shared/lbaseentity_shared.cpp index 5898449036..ea16c4d5f3 100644 --- a/src/game/shared/lbaseentity_shared.cpp +++ b/src/game/shared/lbaseentity_shared.cpp @@ -1019,8 +1019,18 @@ LUA_BINDING_END( "boolean", "True if parameters for sound exist, false otherwise LUA_BINDING_BEGIN( Entity, GetRefTable, "class", "Get reference table." ) { - lua_CBaseEntity *pEntity = LUA_BINDING_ARGUMENT( luaL_checkentity, 1, "entity" ); - LUA_GET_REF_TABLE( L, pEntity ); + // Note: instead of luaL_checkentity, we soft-check here so NULL values can + // have a nil reference table returned. + lua_CBaseEntity *pEntity = LUA_BINDING_ARGUMENT( lua_toentity, 1, "entity" ); + + if (pEntity == NULL) + { + lua_pushnil( L ); + } + else + { + LUA_GET_REF_TABLE( L, pEntity ); + } return 1; } @@ -2859,7 +2869,7 @@ LUA_BINDING_BEGIN( Entity, SetNetworkDataValue, "class", "Sets a data table vari } case TYPE_ENTITY: { - CBaseEntity *newValueEntity = LUA_BINDING_ARGUMENT( luaL_checkentity, 4, "value" ); + CBaseEntity *newValueEntity = LUA_BINDING_ARGUMENT( lua_toentity, 4, "value" ); CBaseEntity::PushLuaInstanceSafe( L, CBaseEntity::Instance( entity->m_LuaVariables_Entity[slot] ) ); CBaseEntity::PushLuaInstanceSafe( L, newValueEntity ); #ifdef CLIENT_DLL @@ -2982,6 +2992,8 @@ LUA_BINDING_BEGIN( Entity, IsValid, "class", "Check if entity is valid." ) } LUA_BINDING_END() +// TODO: This is overwritten by Garry's Mod in lua/includes/extensions/entity.lua +// It is mentioned there that implementing it in Lua is faster, so perhaps we should do that too. LUA_BINDING_BEGIN( Entity, __index, "class", "Metamethod that is called when a non existing field is indexed" ) { lua_CBaseEntity *pEntity = LUA_BINDING_ARGUMENT( lua_toentity, 1, "entity" ); diff --git a/src/game/shared/lbaseplayer_shared.cpp b/src/game/shared/lbaseplayer_shared.cpp index bbfcbfc125..516725760c 100644 --- a/src/game/shared/lbaseplayer_shared.cpp +++ b/src/game/shared/lbaseplayer_shared.cpp @@ -151,7 +151,7 @@ LUA_BINDING_BEGIN( Player, GetActiveWeapon, "class", "Get the player's active we if ( !CExperimentScriptedWeapon::IsValidWeapon( pWeapon ) ) { - CBaseEntity::PushLuaInstanceSafe( L, nullptr ); + CBaseEntity::PushLuaInstanceSafe( L, NULL ); return 1; } @@ -913,15 +913,16 @@ LUA_BINDING_BEGIN( Player, SetBloodColor, "class", "Set the player's blood color } LUA_BINDING_END() +#define PLAYER_THEMSELVES nullptr LUA_BINDING_BEGIN( Player, SetFov, "class", "Set the player's field of view." ) { lua_CBasePlayer *player = LUA_BINDING_ARGUMENT( luaL_checkplayer, 1, "player" ); + lua_CBaseEntity *requester = LUA_BINDING_ARGUMENT_WITH_DEFAULT( luaL_optentity, 4, PLAYER_THEMSELVES, "requester" ); lua_pushboolean( L, player->SetFOV( - LUA_BINDING_ARGUMENT( luaL_checkentity, 2, "entity" ), - LUA_BINDING_ARGUMENT( luaL_checknumber, 3, "fov" ), - LUA_BINDING_ARGUMENT( luaL_checknumber, 4, "zoom rate" ), - LUA_BINDING_ARGUMENT_WITH_DEFAULT( luaL_optnumber, 5, 0, "zoom time" ) ) ); + requester ? requester : player, + LUA_BINDING_ARGUMENT( luaL_checknumber, 2, "fov" ), + LUA_BINDING_ARGUMENT_WITH_DEFAULT( luaL_optnumber, 3, 0, "transitionTime" ) ) ); return 1; } LUA_BINDING_END() @@ -1270,6 +1271,42 @@ LUA_BINDING_BEGIN( Player, SetLastWeapon, "class", "Set the player's last weapon } LUA_BINDING_END() +LUA_BINDING_BEGIN( Player, IsKeyDown, "class", "Check if a key is down." ) +{ + lua_CBasePlayer *player = LUA_BINDING_ARGUMENT( luaL_checkplayer, 1, "player" ); + int keys = ( int )LUA_BINDING_ARGUMENT( luaL_checknumber, 2, "keys" ); + lua_pushboolean( L, player->m_nButtons & keys ); + return 1; +} +LUA_BINDING_END( "boolean", "Whether the key is down." ) + +LUA_BINDING_BEGIN( Player, WasKeyDown, "class", "Get if the specified key was down one tick before the current." ) +{ + lua_CBasePlayer *player = LUA_BINDING_ARGUMENT( luaL_checkplayer, 1, "player" ); + int keys = ( int )LUA_BINDING_ARGUMENT( luaL_checknumber, 2, "keys" ); + lua_pushboolean( L, player->m_afButtonLast & keys ); + return 1; +} +LUA_BINDING_END( "boolean", "Whether the key was down." ) + +LUA_BINDING_BEGIN( Player, WasKeyPressed, "class", "Check if a key was pressed." ) +{ + lua_CBasePlayer *player = LUA_BINDING_ARGUMENT( luaL_checkplayer, 1, "player" ); + int keys = ( int )LUA_BINDING_ARGUMENT( luaL_checknumber, 2, "keys" ); + lua_pushboolean( L, player->m_afButtonPressed & keys ); + return 1; +} +LUA_BINDING_END( "boolean", "Whether the key was pressed." ) + +LUA_BINDING_BEGIN( Player, WasKeyReleased, "class", "Check if a key was released." ) +{ + lua_CBasePlayer *player = LUA_BINDING_ARGUMENT( luaL_checkplayer, 1, "player" ); + int keys = ( int )LUA_BINDING_ARGUMENT( luaL_checknumber, 2, "keys" ); + lua_pushboolean( L, player->m_afButtonReleased & keys ); + return 1; +} +LUA_BINDING_END( "boolean", "Whether the key was released." ) + LUA_BINDING_BEGIN( Player, WeaponShootPosition, "class", "Get the player's weapon shoot position." ) { Vector v = LUA_BINDING_ARGUMENT( luaL_checkplayer, 1, "player" )->Weapon_ShootPosition(); @@ -1609,6 +1646,20 @@ LUA_BINDING_BEGIN( Players, FindByUniqueID, "library", "Get a player by unique I } LUA_BINDING_END( "Player", "The player." ) +LUA_BINDING_BEGIN( Players, ClientPrint, "library", "Print message to client" ) +{ + CBasePlayer *player = LUA_BINDING_ARGUMENT( luaL_checkplayer, 1, "player" ); + int msgDest = LUA_BINDING_ARGUMENT( luaL_checknumber, 2, "msgDest" ); + const char *message = LUA_BINDING_ARGUMENT( luaL_checkstring, 3, "message" ); + const char *param1 = LUA_BINDING_ARGUMENT_WITH_DEFAULT( luaL_optstring, 4, 0, "param1" ); + const char *param2 = LUA_BINDING_ARGUMENT_WITH_DEFAULT( luaL_optstring, 5, 0, "param2" ); + const char *param3 = LUA_BINDING_ARGUMENT_WITH_DEFAULT( luaL_optstring, 6, 0, "param3" ); + const char *param4 = LUA_BINDING_ARGUMENT_WITH_DEFAULT( luaL_optstring, 7, 0, "param4" ); + ClientPrint( player, msgDest, message, param1, param2, param3, param4 ); + return 0; +} +LUA_BINDING_END() + #ifdef GAME_DLL LUA_BINDING_BEGIN( Players, IsTeamEqual, "library", "Check if two teams are equal." ) diff --git a/src/game/shared/lutil_shared.cpp b/src/game/shared/lutil_shared.cpp index 8ca799a5cf..033b877a6e 100644 --- a/src/game/shared/lutil_shared.cpp +++ b/src/game/shared/lutil_shared.cpp @@ -104,20 +104,6 @@ LUA_BINDING_BEGIN( Utilities, PrecacheOther, "library", "Precache an entity by c } LUA_BINDING_END() -LUA_BINDING_BEGIN( Utilities, ClientPrint, "library", "Print message to client" ) -{ - CBasePlayer *player = LUA_BINDING_ARGUMENT( luaL_checkplayer, 1, "player" ); - int msgDest = LUA_BINDING_ARGUMENT( luaL_checknumber, 2, "msgDest" ); - const char *message = LUA_BINDING_ARGUMENT( luaL_checkstring, 3, "message" ); - const char *param1 = LUA_BINDING_ARGUMENT_WITH_DEFAULT( luaL_optstring, 4, 0, "param1" ); - const char *param2 = LUA_BINDING_ARGUMENT_WITH_DEFAULT( luaL_optstring, 5, 0, "param2" ); - const char *param3 = LUA_BINDING_ARGUMENT_WITH_DEFAULT( luaL_optstring, 6, 0, "param3" ); - const char *param4 = LUA_BINDING_ARGUMENT_WITH_DEFAULT( luaL_optstring, 7, 0, "param4" ); - ClientPrint( player, msgDest, message, param1, param2, param3, param4 ); - return 0; -} -LUA_BINDING_END() - LUA_BINDING_BEGIN( Utilities, BoundToWorldSize, "library", "Bound the vector to the world size" ) { Vector *vec = &LUA_BINDING_ARGUMENT( luaL_checkvector, 1, "vec" ); diff --git a/src/public/lenumerations_shared.cpp b/src/public/lenumerations_shared.cpp index e77e6fa68a..c89c2d6dfb 100644 --- a/src/public/lenumerations_shared.cpp +++ b/src/public/lenumerations_shared.cpp @@ -308,6 +308,13 @@ LUALIB_API int luaopen_SharedEnumerations( lua_State *L ) lua_pushenum( L, TYPE_ENTITY, "ENTITY" ); LUA_SET_ENUM_LIB_END( L ); + LUA_SET_ENUM_LIB_BEGIN( L, "HUD_PRINT" ); + lua_pushenum( L, HUD_PRINTNOTIFY, "NOTIFY" ); + lua_pushenum( L, HUD_PRINTCONSOLE, "CONSOLE" ); + lua_pushenum( L, HUD_PRINTTALK, "TALK" ); + lua_pushenum( L, HUD_PRINTCENTER, "CENTER" ); + LUA_SET_ENUM_LIB_END( L ); + return 0; } diff --git a/src/public/mathlib/langle.cpp b/src/public/mathlib/langle.cpp index 23749bf9a9..c10235f66a 100644 --- a/src/public/mathlib/langle.cpp +++ b/src/public/mathlib/langle.cpp @@ -228,11 +228,11 @@ LUA_BINDING_BEGIN( Angle, __index, "class", "Metatable that is called when a key lua_QAngle angle = LUA_BINDING_ARGUMENT( luaL_checkangle, 1, "angle" ); const char *field = LUA_BINDING_ARGUMENT( luaL_checkstring, 2, "field" ); - if ( strcmp( field, "x" ) == 0 || strcmp( field, "p" ) == 0 || strcmp( field, "pitch" ) == 0 ) + if ( strcmp( field, "x" ) == 0 || strcmp( field, "p" ) == 0 || strcmp( field, "pitch" ) == 0 || strcmp( field, "1" ) == 0 ) lua_pushnumber( L, angle.x ); - else if ( strcmp( field, "y" ) == 0 || strcmp( field, "y" ) == 0 || strcmp( field, "yaw" ) == 0 ) + else if ( strcmp( field, "y" ) == 0 || strcmp( field, "y" ) == 0 || strcmp( field, "yaw" ) == 0 || strcmp( field, "2" ) == 0 ) lua_pushnumber( L, angle.y ); - else if ( strcmp( field, "z" ) == 0 || strcmp( field, "r" ) == 0 || strcmp( field, "roll" ) == 0 ) + else if ( strcmp( field, "z" ) == 0 || strcmp( field, "r" ) == 0 || strcmp( field, "roll" ) == 0 || strcmp( field, "3" ) == 0 ) lua_pushnumber( L, angle.z ); else { @@ -267,7 +267,7 @@ LUA_BINDING_END() LUA_BINDING_BEGIN( Angle, __tostring, "class", "Metatable that is called when the angle is to be converted to a string." ) { lua_QAngle angle = LUA_BINDING_ARGUMENT( luaL_checkangle, 1, "angle" ); - lua_pushfstring( L, VecToString( angle ) ); + lua_pushfstring( L, "Angle: %s", VecToString( angle ) ); return 1; } LUA_BINDING_END( "string", "The string representation of the angle." )