mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- added scriptable virtual overrides for PostBeginPlay, Tick, BeginPlay, Activate and Deactivate.
This commit is contained in:
parent
7d99552903
commit
97763b5a2b
6 changed files with 162 additions and 16 deletions
|
@ -258,6 +258,14 @@ void DThinker::PostBeginPlay ()
|
|||
{
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DThinker, PostBeginPlay)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DThinker);
|
||||
self->VMSuperCall();
|
||||
self->PostBeginPlay();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DThinker::PostSerialize()
|
||||
{
|
||||
}
|
||||
|
@ -421,6 +429,14 @@ void DThinker::Tick ()
|
|||
{
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DThinker, Tick)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DThinker);
|
||||
self->VMSuperCall();
|
||||
self->Tick();
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t DThinker::PropagateMark()
|
||||
{
|
||||
// Do not choke on partially initialized objects (as happens when loading a savegame fails)
|
||||
|
|
|
@ -4112,6 +4112,15 @@ void AActor::Tick ()
|
|||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, Tick)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
self->VMSuperCall();
|
||||
self->Tick();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// AActor :: CheckNoDelay
|
||||
|
@ -4580,6 +4589,15 @@ void AActor::BeginPlay ()
|
|||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, BeginPlay)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
self->VMSuperCall();
|
||||
self->BeginPlay();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void AActor::PostBeginPlay ()
|
||||
{
|
||||
if (Renderer != NULL)
|
||||
|
@ -4635,6 +4653,15 @@ void AActor::Activate (AActor *activator)
|
|||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, Activate)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_OBJECT(activator, AActor);
|
||||
self->VMSuperCall();
|
||||
self->Activate(activator);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AActor::Deactivate (AActor *activator)
|
||||
{
|
||||
if ((flags3 & MF3_ISMONSTER) && (health > 0 || (flags & MF_ICECORPSE)))
|
||||
|
@ -4655,6 +4682,15 @@ void AActor::Deactivate (AActor *activator)
|
|||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, Deactivate)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_OBJECT(activator, AActor);
|
||||
self->VMSuperCall();
|
||||
self->Deactivate(activator);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// P_RemoveMobj
|
||||
|
|
|
@ -1280,22 +1280,18 @@ void APlayerPawn::PlayRunning ()
|
|||
|
||||
void APlayerPawn::PlayAttacking ()
|
||||
{
|
||||
static int VIndex = -1;
|
||||
if (VIndex < 0) VIndex = GetVirtualIndex(RUNTIME_CLASS(APlayerPawn), "PlayAttacking");
|
||||
// Without the type cast this picks the 'void *' assignment...
|
||||
VINDEX(APlayerPawn, PlayAttacking);
|
||||
VMValue params[1] = { (DObject*)this };
|
||||
VMFrameStack stack;
|
||||
stack.Call(this->GetClass()->Virtuals[VIndex], params, 1, nullptr, 0, nullptr);
|
||||
stack.Call(VFUNC, params, 1, nullptr, 0, nullptr);
|
||||
}
|
||||
|
||||
void APlayerPawn::PlayAttacking2 ()
|
||||
{
|
||||
static int VIndex = -1;
|
||||
if (VIndex < 0) VIndex = GetVirtualIndex(RUNTIME_CLASS(APlayerPawn), "PlayAttacking2");
|
||||
// Without the type cast this picks the 'void *' assignment...
|
||||
VINDEX(APlayerPawn, PlayAttacking2);
|
||||
VMValue params[1] = { (DObject*)this };
|
||||
VMFrameStack stack;
|
||||
stack.Call(this->GetClass()->Virtuals[VIndex], params, 1, nullptr, 0, nullptr);
|
||||
stack.Call(VFUNC, params, 1, nullptr, 0, nullptr);
|
||||
}
|
||||
|
||||
void APlayerPawn::ThrowPoisonBag ()
|
||||
|
|
107
src/virtual.h
107
src/virtual.h
|
@ -35,6 +35,9 @@ VMEXPORTED_NATIVES_START
|
|||
VMEXPORTED_NATIVES_FUNC(Destroy)
|
||||
VMEXPORTED_NATIVES_FUNC(Tick)
|
||||
VMEXPORTED_NATIVES_FUNC(PostBeginPlay)
|
||||
VMEXPORTED_NATIVES_FUNC(BeginPlay)
|
||||
VMEXPORTED_NATIVES_FUNC(Activate)
|
||||
VMEXPORTED_NATIVES_FUNC(Deactivate)
|
||||
VMEXPORTED_NATIVES_END
|
||||
|
||||
|
||||
|
@ -48,6 +51,15 @@ inline int GetVirtualIndex(PClass *cls, const char *funcname)
|
|||
return VIndex;
|
||||
}
|
||||
|
||||
#define VINDEX(cls, funcname) \
|
||||
static int VIndex = -1; \
|
||||
if (VIndex < 0) { \
|
||||
VIndex = GetVirtualIndex(RUNTIME_CLASS(cls), #funcname); \
|
||||
if (VIndex < 0) I_Error("Unable to find virtual function in " #cls, #funcname); \
|
||||
}
|
||||
|
||||
#define VFUNC this->GetClass()->Virtuals[VIndex]
|
||||
|
||||
template<class T>
|
||||
class DVMObject : public T
|
||||
{
|
||||
|
@ -84,28 +96,103 @@ public:
|
|||
{
|
||||
if (this->ObjectFlags & OF_SuperCall)
|
||||
{
|
||||
this->ObjectFlags &= OF_SuperCall;
|
||||
this->ObjectFlags &= ~OF_SuperCall;
|
||||
ExportedNatives<T>::Get()->template Destroy<void, T>(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
static int VIndex = -1;
|
||||
if (VIndex < 0) VIndex = GetVirtualIndex(RUNTIME_CLASS(DObject), "Destroy");
|
||||
VINDEX(DObject, Destroy);
|
||||
// Without the type cast this picks the 'void *' assignment...
|
||||
VMValue params[1] = { (DObject*)this };
|
||||
VMFrameStack stack;
|
||||
stack.Call(this->GetClass()->Virtuals[VIndex], params, 1, nullptr, 0, nullptr);
|
||||
stack.Call(VFUNC, params, 1, nullptr, 0, nullptr);
|
||||
}
|
||||
}
|
||||
void Tick()
|
||||
{
|
||||
ExportedNatives<T>::Get()->template Tick<void, T>(this);
|
||||
if (this->ObjectFlags & OF_SuperCall)
|
||||
{
|
||||
this->ObjectFlags &= ~OF_SuperCall;
|
||||
ExportedNatives<T>::Get()->template Tick<void, T>(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
VINDEX(DThinker, Tick);
|
||||
// Without the type cast this picks the 'void *' assignment...
|
||||
VMValue params[1] = { (DObject*)this };
|
||||
VMFrameStack stack;
|
||||
stack.Call(VFUNC, params, 1, nullptr, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void PostBeginPlay()
|
||||
{
|
||||
ExportedNatives<T>::Get()->template PostBeginPlay<void, T>(this);
|
||||
if (this->ObjectFlags & OF_SuperCall)
|
||||
{
|
||||
this->ObjectFlags &= ~OF_SuperCall;
|
||||
ExportedNatives<T>::Get()->template PostBeginPlay<void, T>(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
VINDEX(DThinker, PostBeginPlay);
|
||||
// Without the type cast this picks the 'void *' assignment...
|
||||
VMValue params[1] = { (DObject*)this };
|
||||
VMFrameStack stack;
|
||||
stack.Call(VFUNC, params, 1, nullptr, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void BeginPlay()
|
||||
{
|
||||
if (this->ObjectFlags & OF_SuperCall)
|
||||
{
|
||||
this->ObjectFlags &= ~OF_SuperCall;
|
||||
ExportedNatives<T>::Get()->template BeginPlay<void, T>(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
VINDEX(AActor, BeginPlay);
|
||||
// Without the type cast this picks the 'void *' assignment...
|
||||
VMValue params[1] = { (DObject*)this };
|
||||
VMFrameStack stack;
|
||||
stack.Call(VFUNC, params, 1, nullptr, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void Activate(AActor *activator)
|
||||
{
|
||||
if (this->ObjectFlags & OF_SuperCall)
|
||||
{
|
||||
this->ObjectFlags &= ~OF_SuperCall;
|
||||
ExportedNatives<T>::Get()->template Activate<void, T>(this, activator);
|
||||
}
|
||||
else
|
||||
{
|
||||
VINDEX(AActor, Activate);
|
||||
// Without the type cast this picks the 'void *' assignment...
|
||||
VMValue params[2] = { (DObject*)this, (DObject*)activator };
|
||||
VMFrameStack stack;
|
||||
stack.Call(VFUNC, params, 2, nullptr, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void Deactivate(AActor *activator)
|
||||
{
|
||||
if (this->ObjectFlags & OF_SuperCall)
|
||||
{
|
||||
this->ObjectFlags &= ~OF_SuperCall;
|
||||
ExportedNatives<T>::Get()->template Deactivate<void, T>(this, activator);
|
||||
}
|
||||
else
|
||||
{
|
||||
VINDEX(AActor, Deactivate);
|
||||
// Without the type cast this picks the 'void *' assignment...
|
||||
VMValue params[2] = { (DObject*)this, (DObject*)activator };
|
||||
VMFrameStack stack;
|
||||
stack.Call(VFUNC, params, 2, nullptr, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<class T>
|
||||
|
@ -130,7 +217,13 @@ VMEXPORT_NATIVES_END(DObject)
|
|||
VMEXPORT_NATIVES_START(DThinker, DObject)
|
||||
VMEXPORT_NATIVES_FUNC(Tick)
|
||||
VMEXPORT_NATIVES_FUNC(PostBeginPlay)
|
||||
VMEXPORT_NATIVES_END(DThinker)
|
||||
VMEXPORT_NATIVES_END(DThinker)
|
||||
|
||||
VMEXPORT_NATIVES_START(AActor, DThinker)
|
||||
VMEXPORT_NATIVES_FUNC(BeginPlay)
|
||||
VMEXPORT_NATIVES_FUNC(Activate)
|
||||
VMEXPORT_NATIVES_FUNC(Deactivate)
|
||||
VMEXPORT_NATIVES_END(AActor)
|
||||
|
||||
/*
|
||||
VMEXPORT_NATIVES_START(AActor, DThinker)
|
||||
|
|
|
@ -62,7 +62,10 @@ class Actor : Thinker native
|
|||
{
|
||||
return sin(fb * (180./32)) * 8;
|
||||
}
|
||||
|
||||
|
||||
virtual native void BeginPlay();
|
||||
virtual native void Activate(Actor activator);
|
||||
virtual native void Deactivate(Actor activator);
|
||||
|
||||
native static readonly<Actor> GetDefaultByType(class<Actor> cls);
|
||||
native static double deltaangle(double ang1, double ang2);
|
||||
|
|
|
@ -10,6 +10,8 @@ class Object native
|
|||
|
||||
class Thinker : Object native
|
||||
{
|
||||
virtual native void Tick();
|
||||
virtual native void PostBeginPlay();
|
||||
}
|
||||
|
||||
class ThinkerIterator : Object native
|
||||
|
|
Loading…
Reference in a new issue