mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-28 06:42:09 +00:00
- extended state caller check to work on CustomInventory items as well
Since CallStateChain is a public member in CustomInventory we cannot really be sure that the given state is valid so it needs checking as well.
This commit is contained in:
parent
0a21d19723
commit
cf590d73e4
4 changed files with 36 additions and 27 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -56,3 +56,4 @@
|
||||||
/mapfiles_release/*.map
|
/mapfiles_release/*.map
|
||||||
.DS_Store
|
.DS_Store
|
||||||
/build_vc2017-32
|
/build_vc2017-32
|
||||||
|
/build2
|
||||||
|
|
48
src/info.cpp
48
src/info.cpp
|
@ -119,28 +119,8 @@ void FState::SetAction(const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, FState **stateret)
|
void FState::CheckCallerType(AActor *self, AActor *stateowner)
|
||||||
{
|
{
|
||||||
if (ActionFunc != nullptr)
|
|
||||||
{
|
|
||||||
ActionCycles.Clock();
|
|
||||||
|
|
||||||
VMValue params[3] = { self, stateowner, VMValue(info) };
|
|
||||||
// If the function returns a state, store it at *stateret.
|
|
||||||
// If it doesn't return a state but stateret is non-nullptr, we need
|
|
||||||
// to set *stateret to nullptr.
|
|
||||||
if (stateret != nullptr)
|
|
||||||
{
|
|
||||||
*stateret = nullptr;
|
|
||||||
if (ActionFunc->Proto == nullptr ||
|
|
||||||
ActionFunc->Proto->ReturnTypes.Size() == 0 ||
|
|
||||||
ActionFunc->Proto->ReturnTypes[0] != TypeState)
|
|
||||||
{
|
|
||||||
stateret = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
auto CheckType = [=](AActor *check, PType *requiredType)
|
auto CheckType = [=](AActor *check, PType *requiredType)
|
||||||
{
|
{
|
||||||
// This should really never happen. Any valid action function must have actor pointers here.
|
// This should really never happen. Any valid action function must have actor pointers here.
|
||||||
|
@ -165,10 +145,34 @@ bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info,
|
||||||
{
|
{
|
||||||
CheckType(stateowner, argtypes[1]);
|
CheckType(stateowner, argtypes[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, FState **stateret)
|
||||||
|
{
|
||||||
|
if (ActionFunc != nullptr)
|
||||||
|
{
|
||||||
|
ActionCycles.Clock();
|
||||||
|
|
||||||
|
VMValue params[3] = { self, stateowner, VMValue(info) };
|
||||||
|
// If the function returns a state, store it at *stateret.
|
||||||
|
// If it doesn't return a state but stateret is non-nullptr, we need
|
||||||
|
// to set *stateret to nullptr.
|
||||||
|
if (stateret != nullptr)
|
||||||
|
{
|
||||||
|
*stateret = nullptr;
|
||||||
|
if (ActionFunc->Proto == nullptr ||
|
||||||
|
ActionFunc->Proto->ReturnTypes.Size() == 0 ||
|
||||||
|
ActionFunc->Proto->ReturnTypes[0] != TypeState)
|
||||||
|
{
|
||||||
|
stateret = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CheckCallerType(self, stateowner);
|
||||||
|
|
||||||
if (stateret == nullptr)
|
if (stateret == nullptr)
|
||||||
{
|
{
|
||||||
VMCall(ActionFunc, params, ActionFunc->ImplicitArgs, nullptr, 0);
|
VMCall(ActionFunc, params, ActionFunc->ImplicitArgs, nullptr, 0);
|
||||||
|
|
|
@ -175,10 +175,13 @@ public:
|
||||||
void ClearAction() { ActionFunc = NULL; }
|
void ClearAction() { ActionFunc = NULL; }
|
||||||
void SetAction(const char *name);
|
void SetAction(const char *name);
|
||||||
bool CallAction(AActor *self, AActor *stateowner, FStateParamInfo *stateinfo, FState **stateret);
|
bool CallAction(AActor *self, AActor *stateowner, FStateParamInfo *stateinfo, FState **stateret);
|
||||||
|
void CheckCallerType(AActor *self, AActor *stateowner);
|
||||||
|
|
||||||
static PClassActor *StaticFindStateOwner (const FState *state);
|
static PClassActor *StaticFindStateOwner (const FState *state);
|
||||||
static PClassActor *StaticFindStateOwner (const FState *state, PClassActor *info);
|
static PClassActor *StaticFindStateOwner (const FState *state, PClassActor *info);
|
||||||
static FString StaticGetStateName(const FState *state);
|
static FString StaticGetStateName(const FState *state);
|
||||||
static FRandom pr_statetics;
|
static FRandom pr_statetics;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FStateLabels;
|
struct FStateLabels;
|
||||||
|
|
|
@ -169,6 +169,7 @@ bool AStateProvider::CallStateChain (AActor *actor, FState *state)
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
state->CheckCallerType(actor, this);
|
||||||
VMCall(state->ActionFunc, params, state->ActionFunc->ImplicitArgs, wantret, numret);
|
VMCall(state->ActionFunc, params, state->ActionFunc->ImplicitArgs, wantret, numret);
|
||||||
}
|
}
|
||||||
catch (CVMAbortException &err)
|
catch (CVMAbortException &err)
|
||||||
|
|
Loading…
Reference in a new issue