Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HEV/Radiation Charging #160

Merged
merged 1 commit into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions gamedata/srccoop.games.txt
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,13 @@
}
}
}
"CPropChargerBase::ChargerThink"
{
"offset" "CPropChargerBase::ChargerThink"
"hooktype" "entity"
"return" "void"
"this" "entity"
}

// _____ ______ _______ ____ _ _ _____
// | __ \| ____|__ __/ __ \| | | | __ \
Expand Down Expand Up @@ -1360,6 +1367,11 @@
"windows" "39"
"linux" "40"
}
"CPropChargerBase::ChargerThink" // CPropChargerBase::ChargerThink()
{
"windows" "239"
"linux" "289"
}
}
}

Expand Down
35 changes: 34 additions & 1 deletion scripting/include/srccoop/blackmesa/classdef.inc
Original file line number Diff line number Diff line change
Expand Up @@ -217,4 +217,37 @@ methodmap CWeapon_Crossbow < CBlackMesaBaseCombatWeaponIronsights
{
SetEntProp(this.GetEntIndex(), Prop_Send, "m_bNeedsToRearm", bRearming);
}
}
}

methodmap CPropChargerBase < CBaseAnimating
{
public CPropChargerBase(const int iEntIndex = -1)
{
return view_as<CPropChargerBase>(CBaseAnimating(iEntIndex));
}

public float GetChargerRate()
{
return GetEntPropFloat(this.GetEntIndex(), Prop_Data, "m_flChargerRate");
}
public void SetChargerRate(const float flChargeRate)
{
SetEntPropFloat(this.GetEntIndex(), Prop_Data, "m_flChargerRate", flChargeRate);
}
public float GetChargerAmount()
{
return GetEntPropFloat(this.GetEntIndex(), Prop_Data, "m_flChargerAmt");
}
public void SetChargerAmount(const float flChargeAmount)
{
SetEntPropFloat(this.GetEntIndex(), Prop_Data, "m_flChargerAmt", flChargeAmount);
}
public float GetChargerRange()
{
return GetEntPropFloat(this.GetEntIndex(), Prop_Data, "m_flChargerRange");
}
public void SetChargerRange(const float flChargerRange)
{
SetEntPropFloat(this.GetEntIndex(), Prop_Data, "m_flChargerRange", flChargerRange);
}
}
100 changes: 90 additions & 10 deletions scripting/include/srccoop/blackmesa/entitypatch.inc
Original file line number Diff line number Diff line change
Expand Up @@ -114,21 +114,101 @@ public Action Hook_PuffballFungusDmg(int victim, int &attacker, int &inflictor,
}

//------------------------------------------------------
// CPropRadiationCharger - prop_radiation_charger, CPropHevCharger - prop_hev_charger
// ToDo: reimplement on serverside (avoid clientside effects)
// CPropRadiationCharger - prop_radiation_charger
//
// # TODO
//
// - Set "m_bChargingPlayers" on charger to apply screen space effects (currently this will apply to all players)
// - Apply laser particle effect on each individual player within radius
// - Play active sound
// - Call `CBlackMesaPlayer::SetRadiationChargeState` on players to apply gluon weapon effects
//------------------------------------------------------
/**
public MRESReturn Hook_PropChargerThink(int _this)
public MRESReturn Hook_PropRadiationChargerThink(int _this)
{
SetLocalPlayerEntity(_this);
return MRES_Ignored;
CPropChargerBase pCharger = CPropChargerBase(_this);

//float flArmorCharge = (pCharger.GetChargerRate() / pCharger.GetChargerAmount()) * GetGameFrameTime();

float flChargerRange = pCharger.GetChargerRange();
float vec3EntityPosition[3];
pCharger.GetAbsOrigin(vec3EntityPosition);

for (int i = 1; i <= MaxClients; ++i)
{
CBlackMesaPlayer pPlayer = CBlackMesaPlayer(i);
if (pPlayer != NULL_CBASEENTITY)
{
float vec3PlayerPosition[3];
pPlayer.GetAbsOrigin(vec3PlayerPosition);

if (GetVectorDistance(vec3EntityPosition, vec3PlayerPosition) <= flChargerRange)
{
// Naive reimplementation of `CPropRadiationCharger::ShouldApplyEffect` and `CPropRadiationCharger::ApplyEffect`.
// The original implementation uses frametime while thinking every 0.1 seconds.
// As a result, the value will always increment by 1 unless
// `m_flChargerRate` is set to a extremely high value or `m_flChargerAmt` is set to a extremely low value.
// The original implementation also will overflow the max amount if the increment value is over `1`.
int iAmmoEnergy = pPlayer.GetAmmoFromIndex(AMMO_ENERGY);
if (iAmmoEnergy < 100) // TODO: Programatically get the max reserve ammo.
{
pPlayer.SetAmmoFromIndex(AMMO_ENERGY, iAmmoEnergy + 1);
}
}
}
}

pCharger.SetNextThink(GetGameTime() + 0.1);

return MRES_Supercede;
}
public MRESReturn Hook_PropChargerThinkPost(int _this)

//------------------------------------------------------
// CPropHevCharger - prop_hev_charger
//
// # TODO
//
// - Set "m_bChargingPlayers" on charger to apply screen space effects (currently this will apply to all players)
// - Apply laser particle effect on each individual player within radius
// - Play active sound
//------------------------------------------------------
public MRESReturn Hook_PropHevChargerThink(int _this)
{
ClearLocalPlayerEntity();
return MRES_Ignored;
CPropChargerBase pCharger = CPropChargerBase(_this);

//float flArmorCharge = (pCharger.GetChargerRate() / pCharger.GetChargerAmount()) * GetGameFrameTime();

float flChargerRange = pCharger.GetChargerRange();
float vec3EntityPosition[3];
pCharger.GetAbsOrigin(vec3EntityPosition);

for (int i = 1; i <= MaxClients; ++i)
{
CBlackMesaPlayer pPlayer = CBlackMesaPlayer(i);
if (pPlayer != NULL_CBASEENTITY)
{
float vec3PlayerPosition[3];
pPlayer.GetAbsOrigin(vec3PlayerPosition);

if (GetVectorDistance(vec3EntityPosition, vec3PlayerPosition) <= flChargerRange)
{
// Naive reimplementation of `CPropHevCharger::ShouldApplyEffect` and `CPropHevCharger::ApplyEffect`.
// The original implementation uses frametime while thinking every 0.1 seconds.
// As a result, the value will always increment by 1 unless
// `m_flChargerRate` is set to a extremely high value or `m_flChargerAmt` is set to a extremely low value.
// The original implementation also will overflow the max amount if the increment value is over `1`.
int iArmor = pPlayer.GetArmor();
if (pPlayer.HasSuit() && iArmor < 100)
{
pPlayer.SetArmor(iArmor + 1);
}
}
}
}

pCharger.SetNextThink(GetGameTime() + 0.1);

return MRES_Supercede;
}
**/

//------------------------------------------------------
// TE - BlackMesa Shot
Expand Down
30 changes: 28 additions & 2 deletions scripting/include/srccoop/classdef.inc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Handle g_pShouldPlayerAvoid;
Handle g_pRemoveAllItems;
Handle g_pCreateViewModel;
Handle g_pSetNextThink;
Handle g_pSetNextThinkNullString;
Handle g_pIsNPC;
Handle g_pSendWeaponAnim;
Handle g_pWeaponSwitch;
Expand Down Expand Up @@ -90,6 +91,16 @@ stock void InitClassdef(GameData pGameConfig)
if (!(g_pSetNextThink = EndPrepSDKCall())) SetFailState("Could not prep SDK call %s", szSetNextThink);
}

StartPrepSDKCall(SDKCall_Entity);
if (!PrepSDKCall_SetFromConf(pGameConfig, SDKConf_Signature, szSetNextThink))
LogMessage("Could not obtain gamedata signature %s", szSetNextThink);
else
{
PrepSDKCall_AddParameter(SDKType_Float, SDKPass_Plain);
PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
if (!(g_pSetNextThinkNullString = EndPrepSDKCall())) SetFailState("Could not prep SDK call %s", szSetNextThink);
}

char szIsNpc[] = "CBaseEntity::IsNPC";
StartPrepSDKCall(SDKCall_Entity);
if (!PrepSDKCall_SetFromConf(pGameConfig, SDKConf_Virtual, szIsNpc))
Expand Down Expand Up @@ -598,6 +609,14 @@ methodmap CBaseEntity
{
SetEntProp(this.GetEntIndex(), Prop_Data, "m_iEFlags", iEFlags);
}
public void AddEFlags(const int iEFlags)
{
this.SetEFlags(this.GetEFlags() | iEFlags);
}
public void RemoveEFlags(const int iEFlags)
{
this.SetEFlags(this.GetEFlags() & ~iEFlags);
}
public int GetEdictFlags()
{
return GetEdictFlags(this.GetEntIndex());
Expand Down Expand Up @@ -781,11 +800,18 @@ methodmap CBaseEntity
public float GetNextThink()
{
int iThinkTick = this.GetNextThinkTick();
return iThinkTick == -1? -1.0 : TICKS_TO_TIME(iThinkTick);
return iThinkTick == -1 ? -1.0 : TICKS_TO_TIME(iThinkTick);
}
public void SetNextThink(float flNextThink, const char[] szContext = NULL_STRING)
{
SDKCall(g_pSetNextThink, this.entindex, flNextThink, szContext);
if (strlen(szContext) > 0)
{
SDKCall(g_pSetNextThink, this.entindex, flNextThink, szContext);
}
else
{
SDKCall(g_pSetNextThinkNullString, this.entindex, flNextThink, 0);
}
}
public int GetSimulationTick()
{
Expand Down
4 changes: 4 additions & 0 deletions scripting/include/srccoop/globals.inc
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ DynamicDetour hkIgnorePredictionCull;
DynamicHook hkDispatchEffect;
#endif

#if defined ENTPATCH_BM_PROP_CHARGERS
DynamicHook hkPropChargerThink;
#endif

#if defined SRCCOOP_HL2DM && defined PLAYERPATCH_SERVERSIDE_RAGDOLLS
DynamicHook hkCreateRagdollEntity;
#endif
Expand Down
2 changes: 0 additions & 2 deletions scripting/include/srccoop/playerpatch.inc
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ public void Hook_PlayerPreThinkPost(int iClient)
if (pPlayer.IsAlive())
{
#if defined SRCCOOP_BLACKMESA

CBaseCombatWeapon pWeapon = pPlayer.GetActiveWeapon();
if (pWeapon.IsValid())
{
Expand Down Expand Up @@ -86,7 +85,6 @@ public void Hook_PlayerPreThinkPost(int iClient)
}
}
}

#endif // SRCCOOP_BLACKMESA
}
else // Dead
Expand Down
15 changes: 12 additions & 3 deletions scripting/srccoop.sp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ void LoadGameData()
LoadDHookVirtual(pGameConfig, hkBaseNpcRunTask, "CAI_BaseNPC::RunTask");
#endif

#if defined ENTPATCH_BM_PROP_CHARGERS
LoadDHookVirtual(pGameConfig, hkPropChargerThink, "CPropChargerBase::ChargerThink");
#endif

#if defined SRCCOOP_HL2DM && defined PLAYERPATCH_SERVERSIDE_RAGDOLLS
LoadDHookVirtual(pGameConfig, hkCreateRagdollEntity, "CBasePlayer::CreateRagdollEntity");
#endif
Expand Down Expand Up @@ -856,10 +860,15 @@ public void OnEntityCreated(int iEntIndex, const char[] szClassname)
#endif

#if defined ENTPATCH_BM_PROP_CHARGERS
if (strcmp(szClassname, "prop_hev_charger") == 0 || strcmp(szClassname, "prop_radiation_charger") == 0)
if (strcmp(szClassname, "prop_radiation_charger") == 0)
{
DHookEntity(hkPropChargerThink, false, iEntIndex, _, Hook_PropRadiationChargerThink);
return;
}

if (strcmp(szClassname, "prop_hev_charger") == 0)
{
//DHookEntity(hkThink, false, iEntIndex, _, Hook_PropChargerThink);
//DHookEntity(hkThink, true, iEntIndex, _, Hook_PropChargerThinkPost);
DHookEntity(hkPropChargerThink, false, iEntIndex, _, Hook_PropHevChargerThink);
return;
}
#endif
Expand Down