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 PtrToPawnAddress to action callbacks #43

Merged
merged 4 commits into from
Aug 23, 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
76 changes: 35 additions & 41 deletions extension/cbasenpc_behavior.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ ActionResult< INextBot > CBaseNPCPluginAction:: funcName (INextBot* me, ##__VA_A
ResetPluginActionResult(); \
IPluginFunction* pCallback = m_pFactory->GetCallback( CBaseNPCPluginActionFactory::CallbackType::typeName ); \
if (pCallback && pCallback->IsRunnable()) { \
pCallback->PushCell((cell_t)this); pCallback->PushCell(gamehelpers->EntityToBCompatRef(me->GetEntity()));
pCallback->PushCell(PtrToPawnAddress(this)); pCallback->PushCell(gamehelpers->EntityToBCompatRef(me->GetEntity()));

#define BEGINACTIONCALLBACK(funcName, ...) BEGINACTIONCALLBACKEX(funcName, funcName, ##__VA_ARGS__)

Expand All @@ -35,7 +35,7 @@ QueryResultType CBaseNPCPluginAction:: funcName ( const INextBot *me, ##__VA_ARG
cell_t result = ANSWER_UNDEFINED; \
IPluginFunction* pCallback = m_pFactory->GetQueryCallback( CBaseNPCPluginActionFactory::QueryCallbackType::funcName ); \
if (pCallback && pCallback->IsRunnable()) { \
CBPUSHCELL(this); CBPUSHCELL(me);
CBPUSHCELL(PtrToPawnAddress(this)); CBPUSHCELL(PtrToPawnAddress(me));

#define ENDQUERYCALLBACK() \
pCallback->Execute(&result); \
Expand All @@ -45,11 +45,11 @@ QueryResultType CBaseNPCPluginAction:: funcName ( const INextBot *me, ##__VA_ARG

#define BEGINEVENTCALLBACKEX(funcName, typeName, ...) \
EventDesiredResult< INextBot > CBaseNPCPluginAction:: funcName (INextBot* me, ##__VA_ARGS__) { \
m_eventResultStack.push( m_pluginEventResult ); \
m_inEventCallback++; \
ResetPluginEventResult(); \
IPluginFunction* pCallback = m_pFactory->GetEventCallback( CBaseNPCPluginActionFactory::EventResponderCallbackType::typeName ); \
if (pCallback && pCallback->IsRunnable()) { \
pCallback->PushCell((cell_t)this); \
pCallback->PushCell(PtrToPawnAddress(this)); \
pCallback->PushCell(gamehelpers->EntityToBCompatRef(me->GetEntity()));

#define BEGINEVENTCALLBACK(funcName, ...) BEGINEVENTCALLBACKEX(funcName, funcName, ##__VA_ARGS__)
Expand All @@ -63,18 +63,14 @@ EventDesiredResult< INextBot > CBaseNPCPluginAction:: funcName (INextBot* me, ##
#define ENDEVENTCALLBACK() \
pCallback->Execute(nullptr); \
} \
EventDesiredResult< INextBot > result = m_pluginEventResult; \
m_pluginEventResult = m_eventResultStack.front(); \
m_eventResultStack.pop(); \
return result; \
m_inEventCallback--; \
return m_pluginEventResult; \
}

#define ENDEVENTCALLBACK_NOEXECUTE() \
} \
EventDesiredResult< INextBot > result = m_pluginEventResult; \
m_pluginEventResult = m_eventResultStack.front(); \
m_eventResultStack.pop(); \
return result; \
m_inEventCallback--; \
return m_pluginEventResult; \
}

// https://github.com/alliedmodders/sourcemod/blob/6928d21bcf746920b0f2f54e2c28b34097a66be2/core/smn_keyvalues.h#L42
Expand Down Expand Up @@ -103,6 +99,7 @@ CBaseNPCPluginAction::CBaseNPCPluginAction(CBaseNPCPluginActionFactory* pFactory
ResetPluginEventResult();

m_bInActionCallback = false;
m_inEventCallback = 0;

pFactory->OnActionCreated(this);
}
Expand Down Expand Up @@ -188,30 +185,27 @@ void CBaseNPCPluginAction::PluginTryToSustain( EventResultPriorityType priority,
// Actions

BEGINACTIONCALLBACK(OnStart, Action< INextBot > *prevAction)
CBPUSHCELL(prevAction)
CBPUSHCELL(PtrToPawnAddress(prevAction))
ENDACTIONCALLBACK()

BEGINACTIONCALLBACK(Update, float interval)
CBPUSHFLOAT(interval)
ENDACTIONCALLBACK()

BEGINACTIONCALLBACK(OnSuspend, Action< INextBot > *interruptingAction)
CBPUSHCELL(interruptingAction)
CBPUSHCELL(PtrToPawnAddress(interruptingAction))
ENDACTIONCALLBACK()

BEGINACTIONCALLBACK(OnResume, Action< INextBot > *interruptingAction)
CBPUSHCELL(interruptingAction)
CBPUSHCELL(PtrToPawnAddress(interruptingAction))
ENDACTIONCALLBACK()

void CBaseNPCPluginAction::OnEnd( INextBot * me, Action< INextBot > *nextAction )
{
void CBaseNPCPluginAction::OnEnd( INextBot * me, Action< INextBot > *nextAction ) {
IPluginFunction* pCallback = m_pFactory->GetCallback( CBaseNPCPluginActionFactory::CallbackType::OnEnd );
if (pCallback && pCallback->IsRunnable())
{
CBPUSHCELL(this)
if (pCallback && pCallback->IsRunnable()) {
CBPUSHCELL(PtrToPawnAddress(this))
CBPUSHENTITY(me->GetEntity())
CBPUSHCELL(nextAction)

CBPUSHCELL(PtrToPawnAddress(nextAction))
pCallback->Execute(nullptr);
}
}
Expand All @@ -223,13 +217,13 @@ Action< INextBot >* CBaseNPCPluginAction::InitialContainedAction( INextBot * me
IPluginFunction* pCallback = m_pFactory->GetCallback( CBaseNPCPluginActionFactory::CallbackType::InitialContainedAction );
if (pCallback && pCallback->IsRunnable())
{
CBPUSHCELL(this)
CBPUSHCELL(PtrToPawnAddress(this))
CBPUSHENTITY(me->GetEntity())

pCallback->Execute(&result);
}

return (Action< INextBot >*)result;
return (Action< INextBot >*)PawnAddressToPtr(result);
}

bool CBaseNPCPluginAction::IsAbleToBlockMovementOf( const INextBot *botInMotion ) const
Expand All @@ -239,8 +233,8 @@ bool CBaseNPCPluginAction::IsAbleToBlockMovementOf( const INextBot *botInMotion
IPluginFunction* pCallback = m_pFactory->GetCallback( CBaseNPCPluginActionFactory::CallbackType::IsAbleToBlockMovementOf );
if (pCallback && pCallback->IsRunnable())
{
CBPUSHCELL(this)
CBPUSHCELL(botInMotion)
CBPUSHCELL(PtrToPawnAddress(this))
CBPUSHCELL(PtrToPawnAddress(botInMotion))

pCallback->Execute(&result);
}
Expand All @@ -261,7 +255,7 @@ BEGINQUERYCALLBACK(ShouldRetreat)
ENDQUERYCALLBACK()

BEGINQUERYCALLBACK(ShouldAttack, const CKnownEntity *them)
CBPUSHCELL(them)
CBPUSHCELL(PtrToPawnAddress(them))
ENDQUERYCALLBACK()

BEGINQUERYCALLBACK(IsHindrance, CBaseEntity* blocker)
Expand All @@ -280,8 +274,8 @@ Vector CBaseNPCPluginAction::SelectTargetPoint( const INextBot* me, const CBaseC
buffer[1] = sp_ftoc(result[1]);
buffer[2] = sp_ftoc(result[2]);

CBPUSHCELL(this)
CBPUSHCELL(me)
CBPUSHCELL(PtrToPawnAddress(this))
CBPUSHCELL(PtrToPawnAddress(me))
CBPUSHENTITY((CBaseCombatCharacter*)subject)
pCallback->PushArray(buffer, 3, SM_PARAM_COPYBACK);
pCallback->Execute(nullptr);
Expand All @@ -308,15 +302,15 @@ const CKnownEntity * CBaseNPCPluginAction::SelectMoreDangerousThreat( const INex
IPluginFunction* pCallback = m_pFactory->GetQueryCallback( CBaseNPCPluginActionFactory::QueryCallbackType::SelectMoreDangerousThreat );
if (pCallback && pCallback->IsRunnable())
{
CBPUSHCELL(this)
CBPUSHCELL(me)
CBPUSHCELL(PtrToPawnAddress(this))
CBPUSHCELL(PtrToPawnAddress(me))
CBPUSHENTITY((CBaseCombatCharacter*)subject)
CBPUSHCELL(threat1)
CBPUSHCELL(threat2)
CBPUSHCELL(PtrToPawnAddress(threat1))
CBPUSHCELL(PtrToPawnAddress(threat2))
pCallback->Execute(&result);
}

return (const CKnownEntity*)result;
return (const CKnownEntity*)PawnAddressToPtr(result);
}

// Events
Expand All @@ -331,15 +325,15 @@ ENDEVENTCALLBACK()

BEGINEVENTCALLBACK(OnContact, CBaseEntity* other, CGameTrace* traceResult)
EVENTPUSHENTITY(other)
EVENTPUSHCELL(traceResult)
EVENTPUSHCELL(PtrToPawnAddress(traceResult))
ENDEVENTCALLBACK()

BEGINEVENTCALLBACK(OnMoveToSuccess, const Path *path)
EVENTPUSHCELL(path)
EVENTPUSHCELL(PtrToPawnAddress(path))
ENDEVENTCALLBACK()

BEGINEVENTCALLBACK(OnMoveToFailure, const Path *path, MoveToFailureType reason)
EVENTPUSHCELL(path)
EVENTPUSHCELL(PtrToPawnAddress(path))
EVENTPUSHCELL(reason)
ENDEVENTCALLBACK()

Expand Down Expand Up @@ -438,7 +432,7 @@ ENDEVENTCALLBACK_NOEXECUTE()
BEGINEVENTCALLBACK(OnSpokeConcept, CBaseCombatCharacter* who, AIConcept_t concept, AI_Response *response)
EVENTPUSHENTITY(who)
EVENTPUSHCELL(concept)
EVENTPUSHCELL(response)
EVENTPUSHCELL(PtrToPawnAddress(response))
ENDEVENTCALLBACK()

BEGINEVENTCALLBACK(OnWeaponFired, CBaseCombatCharacter* whoFired, CBaseEntity* weapon )
Expand All @@ -447,8 +441,8 @@ BEGINEVENTCALLBACK(OnWeaponFired, CBaseCombatCharacter* whoFired, CBaseEntity* w
ENDEVENTCALLBACK()

BEGINEVENTCALLBACK(OnNavAreaChanged, CNavArea *newArea, CNavArea *oldArea)
EVENTPUSHCELL(newArea)
EVENTPUSHCELL(oldArea)
EVENTPUSHCELL(PtrToPawnAddress(newArea))
EVENTPUSHCELL(PtrToPawnAddress(oldArea))
ENDEVENTCALLBACK()

BEGINEVENTCALLBACK(OnModelChanged)
Expand Down Expand Up @@ -756,7 +750,7 @@ void CBaseNPCPluginActionFactory::OnCreateInitialAction(Action <INextBot>* pActi
IPluginFunction * pCallback = GetCallback( CreateInitialAction );
if (pCallback && pCallback->IsRunnable())
{
pCallback->PushCell((cell_t)pAction);
pCallback->PushCell(PtrToPawnAddress(pAction));
pCallback->Execute(nullptr);
}
}
30 changes: 3 additions & 27 deletions extension/cbasenpc_behavior.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,14 @@ class CBaseNPCPluginAction : public Action <INextBot>

private:
ActionResult< INextBot > m_pluginActionResult;

/**
* Stores event result states.
*
* A stack is used to maintain event result states for each event callback.
* This is because events are not atomic; an event can trigger another event
* during execution of a callback. Since the plugin natives write results
* to the shared m_pluginEventResult member, an inner event can overwrite
* the result of the outer event causing unexpected behavior, especially if
* the outer event does not actually use a Try*() native. Thus, the stack
* is used to restore the event result state when exiting an event
* callback.
*
* A stack is not used for m_pluginActionResult because OnStart(), Update(),
* OnSuspend(), OnResume(), and OnEnd() are all atomic; these callbacks
* will never execute within each other.
*/
SourceHook::CStack<EventDesiredResult< INextBot >> m_eventResultStack;
EventDesiredResult< INextBot > m_pluginEventResult;

void * m_pData;

CBaseNPCPluginActionFactory * m_pFactory;

bool m_bInActionCallback;
int m_inEventCallback;

public:
CBaseNPCPluginAction(CBaseNPCPluginActionFactory * pFactory);
Expand All @@ -64,15 +47,8 @@ class CBaseNPCPluginAction : public Action <INextBot>
void PluginSuspendFor( Action< INextBot > *action, const char *reason );
void PluginDone( const char *reason );

bool IsInActionCallback()
{
return m_bInActionCallback;
}

bool IsInEventCallback()
{
return m_eventResultStack.size() > 0;
}
bool IsInActionCallback() const { return m_bInActionCallback; }
bool IsInEventCallback() const { return m_inEventCallback > 0; }

virtual ActionResult< INextBot > OnStart( INextBot *me, Action< INextBot > *prevAction ) override final;
virtual ActionResult< INextBot > Update( INextBot *me, float interval ) override final;
Expand Down
2 changes: 1 addition & 1 deletion product.version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.10.0
1.10.1