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

Add CTakeDamageInfo natives to use with TakeDamage #48

Merged
merged 4 commits into from
Dec 28, 2023
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
19 changes: 18 additions & 1 deletion extension/natives/baseentity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,22 @@ cell_t IsCombatCharacter(IPluginContext* context, const cell_t* params) {
return entity->MyCombatCharacterPointer() ? 1 : 0;
}

cell_t TakeDamage(IPluginContext* context, const cell_t* params) {
auto entity = Get(context, params[1]);
if (!entity) {
return 0;
}

CTakeDamageInfo* inputInfo = (CTakeDamageInfo*)PawnAddressToPtr(params[2]);
if (!inputInfo) {
context->ThrowNativeError("CTakeDamageInfo is a null ptr!");
return 0;
}

entity->TakeDamage(*inputInfo);
return 0;
}

void setup(std::vector<sp_nativeinfo_t>& natives) {
sp_nativeinfo_t list[] = {
{"CBaseEntity.iUpdateOnRemove", iUpdateOnRemove},
Expand Down Expand Up @@ -554,7 +570,8 @@ void setup(std::vector<sp_nativeinfo_t>& natives) {
{"CBaseEntity.MyNextBotPointer", MyNextBotPointer},
{"CBaseEntity.GetBaseAnimating", GetBaseAnimating},
{"CBaseEntity.MyCombatCharacterPointer", MyCombatCharacterPointer},
{"CBaseEntity.IsCombatCharacter", IsCombatCharacter}
{"CBaseEntity.IsCombatCharacter", IsCombatCharacter},
{"CBaseEntity.TakeDamage", TakeDamage}
};
natives.insert(natives.end(), std::begin(list), std::end(list));
}
Expand Down
77 changes: 72 additions & 5 deletions extension/natives/takedamageinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
#include <IGameHelpers.h>
extern SourceMod::IGameHelpers* gamehelpers;

CTakeDamageInfo::CTakeDamageInfo(){}

namespace natives::takedamageinfo {

CTakeDamageInfo g_GlobalDamageInfo;

inline CTakeDamageInfo* Get(IPluginContext* context, const cell_t param) {
CTakeDamageInfo* info = (CTakeDamageInfo*)PawnAddressToPtr(param);
if (!info) {
Expand All @@ -30,6 +30,69 @@ cell_t CTakeDamageInfo_Ctor(IPluginContext* context, const cell_t* params) {
return PtrToPawnAddress(PawnAddressToPtr(params[1]));
}

cell_t GetGlobalDamageInfo(IPluginContext* context, const cell_t* params) {
return PtrToPawnAddress(&g_GlobalDamageInfo);
}

cell_t Init(IPluginContext* context, const cell_t* params) {
CTakeDamageInfo* info = Get(context, params[1]);
if (!info) {
return 0;
}

CBaseEntity* inflictor = gamehelpers->ReferenceToEntity(params[2]);
if (!inflictor && params[2] != -1) {
return context->ThrowNativeError("Invalid inflictor index!");
}

CBaseEntity* attacker = gamehelpers->ReferenceToEntity(params[3]);
if (!attacker && params[3] != -1) {
return context->ThrowNativeError("Invalid attacker index!");
}

CBaseEntity* weapon = gamehelpers->ReferenceToEntity(params[4]);
if (!attacker && params[4] != -1) {
return context->ThrowNativeError("Invalid weapon index!");
}

cell_t* damageForceAddr;
context->LocalToPhysAddr(params[5], &damageForceAddr);
Vector damageForce;
if (context->GetNullRef(SP_NULL_VECTOR) == damageForceAddr) {
damageForce = vec3_origin;
}
else {
PawnVectorToVector(damageForceAddr, &damageForce);
}

cell_t* damagePositionAddr;
context->LocalToPhysAddr(params[6], &damagePositionAddr);
Vector damagePosition;
if (context->GetNullRef(SP_NULL_VECTOR) == damagePositionAddr) {
damagePosition = vec3_origin;
}
else {
PawnVectorToVector(damagePositionAddr, &damagePosition);
}

float damage = sp_ctof(params[7]);
int bitsDamageType = params[8];
int customDamage = params[9];

cell_t* reportedPositionAddr;
context->LocalToPhysAddr(params[10], &reportedPositionAddr);
Vector reportedPosition;
if (context->GetNullRef(SP_NULL_VECTOR) == reportedPositionAddr) {
reportedPosition = vec3_origin;
}
else {
PawnVectorToVector(reportedPositionAddr, &reportedPosition);
}

info->Set(inflictor, attacker, weapon, damageForce, damagePosition, damage, bitsDamageType, customDamage, &reportedPosition);
return 0;
}

cell_t GetInflictor(IPluginContext* context, const cell_t* params) {
CTakeDamageInfo* info = Get(context, params[1]);
if (!info) {
Expand All @@ -47,7 +110,7 @@ cell_t SetInflictor(IPluginContext* context, const cell_t* params) {

CBaseEntity* inflictor = gamehelpers->ReferenceToEntity(params[2]);
if (!inflictor && params[2] != -1) {
context->ThrowNativeError("Invalid inflictor index!");
return context->ThrowNativeError("Invalid inflictor index!");
}
info->m_hInflictor = inflictor;
return 0;
Expand All @@ -70,7 +133,7 @@ cell_t SetWeapon(IPluginContext* context, const cell_t* params) {

CBaseEntity* weapon = gamehelpers->ReferenceToEntity(params[2]);
if (!weapon && params[2] != -1) {
context->ThrowNativeError("Invalid weapon index!");
return context->ThrowNativeError("Invalid weapon index!");
}
info->m_hWeapon = weapon;
return 0;
Expand All @@ -90,7 +153,7 @@ cell_t SetAttacker(IPluginContext* context, const cell_t* params) {

CBaseEntity* attacker = gamehelpers->ReferenceToEntity(params[2]);
if (!attacker && params[2] != -1) {
context->ThrowNativeError("Invalid attacker index!");
return context->ThrowNativeError("Invalid attacker index!");
}
info->m_hAttacker = attacker;
return 0;
Expand Down Expand Up @@ -503,6 +566,10 @@ void setup(std::vector<sp_nativeinfo_t>& natives) {
sp_nativeinfo_t list[] = {
{"CTakeDamageInfo.CTakeDamageInfo", CTakeDamageInfo_Ctor},

{"GetGlobalDamageInfo", GetGlobalDamageInfo},

{"CTakeDamageInfo.Init", Init},

{"CTakeDamageInfo.GetInflictor", GetInflictor},
{"CTakeDamageInfo.SetInflictor", SetInflictor},

Expand Down
7 changes: 7 additions & 0 deletions extension/sourcesdk/baseentity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ VCall<CBaseAnimating*> CBaseEntity::vGetBaseAnimating;
VCall<INextBot*> CBaseEntity::vMyNextBotPointer;
MCall<void, int> CBaseEntity::mInvalidatePhysicsRecursive;
VCall<const Vector&> CBaseEntity::vWorldSpaceCenter;
MCall<void, const CTakeDamageInfo&> CBaseEntity::mTakeDamage;
VCall<int, const CTakeDamageInfo&> CBaseEntity::vOnTakeDamage;
VCall<bool> CBaseEntity::vIsAlive;
MCall<void> CBaseEntity::mCalcAbsolutePosition;
Expand Down Expand Up @@ -120,6 +121,7 @@ bool CBaseEntity::Init(SourceMod::IGameConfig* config, char* error, size_t maxle
vMyNextBotPointer.Init(config, "CBaseEntity::MyNextBotPointer");
vWorldSpaceCenter.Init(config, "CBaseEntity::WorldSpaceCenter");
vEyeAngles.Init(config, "CBaseEntity::EyeAngles");
mTakeDamage.Init(config, "CBaseEntity::TakeDamage");
vOnTakeDamage.Init(configSDKHooks, "OnTakeDamage");
vIsAlive.Init(config, "CBaseEntity::IsAlive");

Expand Down Expand Up @@ -303,6 +305,11 @@ const Vector& CBaseEntity::WorldSpaceCenter(void)
return vWorldSpaceCenter(this);
}

void CBaseEntity::TakeDamage(const CTakeDamageInfo& inputInfo)
{
return mTakeDamage(this, inputInfo);
}

int CBaseEntity::OnTakeDamage(const CTakeDamageInfo& info)
{
return vOnTakeDamage(this, info);
Expand Down
3 changes: 3 additions & 0 deletions extension/sourcesdk/baseentity.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ class CBaseEntity : public IServerEntity
void CalcAbsolutePosition(void);
void CalcAbsoluteVelocity(void);

static MCall<void, const CTakeDamageInfo&> mTakeDamage;
void TakeDamage(const CTakeDamageInfo& inputInfo);

static VCall<int, const CTakeDamageInfo&> vOnTakeDamage;
int OnTakeDamage(const CTakeDamageInfo& info);

Expand Down
52 changes: 52 additions & 0 deletions extension/sourcesdk/takedamageinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,58 @@
#include <isaverestore.h>
#include <takedamageinfo.h>

CTakeDamageInfo::CTakeDamageInfo()
{
Init( NULL, NULL, NULL, vec3_origin, vec3_origin, vec3_origin, 0, 0, 0 );
}

void CTakeDamageInfo::Init( CBaseEntity *pInflictor, CBaseEntity *pAttacker, CBaseEntity *pWeapon, const Vector &damageForce, const Vector &damagePosition, const Vector &reportedPosition, float flDamage, int bitsDamageType, int iCustomDamage )
{
m_hInflictor = pInflictor;
if ( pAttacker )
{
m_hAttacker = pAttacker;
}
else
{
m_hAttacker = pInflictor;
}

m_hWeapon = pWeapon;

m_flDamage = flDamage;

m_flBaseDamage = BASEDAMAGE_NOT_SPECIFIED;

m_bitsDamageType = bitsDamageType;
m_iDamageCustom = iCustomDamage;

m_flMaxDamage = flDamage;
m_vecDamageForce = damageForce;
m_vecDamagePosition = damagePosition;
m_vecReportedPosition = reportedPosition;
m_iAmmoType = -1;
m_iDamagedOtherPlayers = 0;
m_iPlayerPenetrationCount = 0;
m_flDamageBonus = 0.f;
m_bForceFriendlyFire = false;
m_flDamageForForce = 0.f;

#if SOURCE_ENGINE == SE_TF2
m_eCritType = kCritType_None;
#endif
}

void CTakeDamageInfo::Set( CBaseEntity *pInflictor, CBaseEntity *pAttacker, CBaseEntity *pWeapon, const Vector &damageForce, const Vector &damagePosition, float flDamage, int bitsDamageType, int iKillType, Vector *reportedPosition )
{
Vector vecReported = vec3_origin;
if ( reportedPosition )
{
vecReported = *reportedPosition;
}
Init( pInflictor, pAttacker, pWeapon, damageForce, damagePosition, vecReported, flDamage, bitsDamageType, iKillType );
}

#if SOURCE_ENGINE == SE_TF2
void CTakeDamageInfo::SetCritType( ECritType eType )
{
Expand Down
7 changes: 7 additions & 0 deletions gamedata/cbasenpc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,13 @@
"windows" ""
"linux" "@_ZN11CBaseEntity15SetGroundEntityEPS_"
}
// Find string "CBaseEntity::TakeDamage: with inputInfo.GetDamageForce() == vec3_origin\n"
"CBaseEntity::TakeDamage"
{
"library" "server"
"windows" "\x55\x8B\xEC\x81\xEC\x98\x00\x00\x00\x53\x8B\xD9"
"linux" "@_ZN11CBaseEntity10TakeDamageERK15CTakeDamageInfo"
}
// "g_EntityListPool"
"g_EntityListPool"
{
Expand Down
2 changes: 1 addition & 1 deletion product.version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.10.3
1.11.0
12 changes: 12 additions & 0 deletions scripting/include/cbasenpc/baseentity.inc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#endif
#define _CBASENPC_BASEENTITY_INC_

#include "takedamageinfo.inc"

methodmap CBaseEntity
{
public CBaseEntity(int iEnt)
Expand Down Expand Up @@ -910,4 +912,14 @@ methodmap CBaseEntity
{
SetEntityMoveType(this.index, val);
}

/**
* Causes the entity to take damage with the given parameters.
* Filters are checked and damage scaling is applied before it calls the
* entity's OnTakeDamage().
*
* @param inputInfo The damage parameters to use
* @error Invalid entity or a NULL pointer is given
*/
public native void TakeDamage(CTakeDamageInfo inputInfo);
}
31 changes: 28 additions & 3 deletions scripting/include/cbasenpc/takedamageinfo.inc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@ methodmap CTakeDamageInfo
*/
public native CTakeDamageInfo(Address ptr);

/**
* Initializes the CTakeDamageInfo's values.
*
* @param inflictor The inflictor entity index.
* @param attacker The attacker entity index.
* @param weapon The weapon entity index.
* @param damageForce The damage force vector.
* @param damagePosition The damage position vector.
* @param damage The amount of damage to set.
* @param bitsDamageType The damage type bitmask.
* @param customDamage The custom damage to set.
* @param reportedPosition The position to report to players on where the damage came from.
* @error Invalid takedamageinfo, or invalid inflictor, attacker, and weapon entity index.
*/
public native void Init(int inflictor = -1, int attacker = -1, int weapon = -1, const float damageForce[3] = NULL_VECTOR, const float damagePosition[3] = NULL_VECTOR, float damage = 0.0, int bitsDamageType = 0, int customDamage = 0, const float reportedPosition[3] = NULL_VECTOR);

/**
* Gets the inflictor.
*
Expand Down Expand Up @@ -249,15 +265,15 @@ methodmap CTakeDamageInfo
* @param bitmask The damage type bitmask.
* @error Invalid takedamageinfo.
*/
public native int SetDamageType();
public native int SetDamageType(int bitmask);

/**
* Adds the damage bitmask to the current damage bitmask.
*
* @param bitmask The damage type bitmask to add.
* @error Invalid takedamageinfo.
*/
public native int AddDamageType();
public native int AddDamageType(int bitmask);

/**
* Gets the custom damage.
Expand Down Expand Up @@ -370,4 +386,13 @@ methodmap CTakeDamageInfo
* @error Invalid takedamageinfo.
*/
public native TakeDamageInfo_CritType GetCritType();
};
};

/**
* Returns the address of a global CTakeDamageInfo object. Make sure to
* initialize the values of the object first using CTakeDamageInfo.Init()
* before modifying and using it in a function call.
*
* @return Address to the global CTakeDamageInfo object.
*/
native CTakeDamageInfo GetGlobalDamageInfo();