mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 00:42:08 +00:00
- added compile time validation for SetAction, SetAI and SetMove.
the expression classes were deleted again, this can be done without them.
This commit is contained in:
parent
bf577916ec
commit
47f9642294
6 changed files with 118 additions and 218 deletions
|
@ -46,6 +46,7 @@
|
|||
#include "v_font.h"
|
||||
#include "gamecontrol.h"
|
||||
#include "gi.h"
|
||||
#include "games/duke/src/duke3d.h"
|
||||
|
||||
PFunction* FindBuiltinFunction(FName funcname);
|
||||
|
||||
|
@ -177,14 +178,81 @@ static FxExpression *ResolveGlobalCustomFunction(FxFunctionCall *func, FCompileC
|
|||
return newfunc->Resolve(ctx);
|
||||
}
|
||||
}
|
||||
// the following 3 are just for compile time argument validation, they do not affect code generation.
|
||||
else if (func->MethodName == NAME_SetAction && isDukeEngine())
|
||||
{
|
||||
auto cls = ctx.Function->Variants[0].SelfClass;
|
||||
if (cls == nullptr || !cls->isClass()) return func;
|
||||
auto clas = static_cast<PClassType*>(cls)->Descriptor;
|
||||
if (!clas->IsDescendantOf(RUNTIME_CLASS(Duke3d::DDukeActor))) return func;
|
||||
if (CheckArgSize(NAME_SetAction, func->ArgList, 1, 1, ScriptPosition))
|
||||
{
|
||||
FxExpression* x;
|
||||
x = func->ArgList[0] = func->ArgList[0]->Resolve(ctx);
|
||||
if (x && x->isConstant() && (x->ValueType == TypeName || x->ValueType == TypeString))
|
||||
{
|
||||
auto c = static_cast<FxConstant*>(x);
|
||||
auto nm = c->GetValue().GetName();
|
||||
if (nm == NAME_None) return func;
|
||||
int pos = Duke3d::LookupAction(clas, nm);
|
||||
if (pos == 0)
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Invalid action '%s'", nm.GetChars());
|
||||
delete func;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (func->MethodName == NAME_SetAI && isDukeEngine())
|
||||
{
|
||||
auto cls = ctx.Function->Variants[0].SelfClass;
|
||||
if (cls == nullptr || !cls->isClass()) return func;
|
||||
auto clas = static_cast<PClassType*>(cls)->Descriptor;
|
||||
if (!clas->IsDescendantOf(RUNTIME_CLASS(Duke3d::DDukeActor))) return func;
|
||||
if (CheckArgSize(NAME_SetAI, func->ArgList, 1, 1, ScriptPosition))
|
||||
{
|
||||
FxExpression* x;
|
||||
x = func->ArgList[0] = func->ArgList[0]->Resolve(ctx);
|
||||
if (x && x->isConstant() && (x->ValueType == TypeName || x->ValueType == TypeString))
|
||||
{
|
||||
auto c = static_cast<FxConstant*>(x);
|
||||
auto nm = c->GetValue().GetName();
|
||||
if (nm == NAME_None) return func;
|
||||
int pos = Duke3d::LookupAI(clas, nm);
|
||||
if (pos == 0)
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Invalid AI '%s'", nm.GetChars());
|
||||
delete func;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (func->MethodName == NAME_SetMove && isDukeEngine())
|
||||
{
|
||||
auto cls = ctx.Function->Variants[0].SelfClass;
|
||||
if (cls == nullptr || !cls->isClass()) return func;
|
||||
auto clas = static_cast<PClassType*>(cls)->Descriptor;
|
||||
if (!clas->IsDescendantOf(RUNTIME_CLASS(Duke3d::DDukeActor))) return func;
|
||||
if (CheckArgSize(NAME_SetMove, func->ArgList, 1, 2, ScriptPosition))
|
||||
{
|
||||
FxExpression* x;
|
||||
x = func->ArgList[0] = func->ArgList[0]->Resolve(ctx);
|
||||
if (x && x->isConstant() && (x->ValueType == TypeName || x->ValueType == TypeString))
|
||||
{
|
||||
auto c = static_cast<FxConstant*>(x);
|
||||
auto nm = c->GetValue().GetName();
|
||||
if (nm == NAME_None) return func;
|
||||
int pos = Duke3d::LookupMove(clas, nm);
|
||||
if (pos == 0)
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Invalid move '%s'", nm.GetChars());
|
||||
delete func;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// most of these can be resolved right here. Only isWorldTour, isPlutoPak and isShareware can not if Duke is being played.
|
||||
else if (func->MethodName == NAME_isDuke)
|
||||
|
@ -258,152 +326,6 @@ static FxExpression *ResolveGlobalCustomFunction(FxFunctionCall *func, FCompileC
|
|||
return func;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxSetActionCall
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxSetActionCall::FxSetActionCall(FxExpression *self, FxExpression* arg, const FScriptPosition &pos)
|
||||
: FxExpression(EFX_ActionSpecialCall, pos)
|
||||
{
|
||||
Self = self;
|
||||
Arg = arg;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxSetActionCall::~FxSetActionCall()
|
||||
{
|
||||
SAFE_DELETE(Self);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxExpression *FxSetActionCall::Resolve(FCompileContext& ctx)
|
||||
{
|
||||
CHECKRESOLVED();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
ExpEmit FxSetActionCall::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
return ExpEmit();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxSetAICall
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxSetAICall::FxSetAICall(FxExpression *self, FxExpression* arg, const FScriptPosition &pos)
|
||||
: FxExpression(EFX_ActionSpecialCall, pos)
|
||||
{
|
||||
Self = self;
|
||||
Arg = arg;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxSetAICall::~FxSetAICall()
|
||||
{
|
||||
SAFE_DELETE(Self);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxExpression *FxSetAICall::Resolve(FCompileContext& ctx)
|
||||
{
|
||||
CHECKRESOLVED();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
ExpEmit FxSetAICall::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
return ExpEmit();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxSetMoveCall
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxSetMoveCall::FxSetMoveCall(FxExpression *self, FxExpression* arg, const FScriptPosition &pos)
|
||||
: FxExpression(EFX_ActionSpecialCall, pos)
|
||||
{
|
||||
Self = self;
|
||||
Arg = arg;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxSetMoveCall::~FxSetMoveCall()
|
||||
{
|
||||
SAFE_DELETE(Self);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxExpression *FxSetMoveCall::Resolve(FCompileContext& ctx)
|
||||
{
|
||||
CHECKRESOLVED();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
ExpEmit FxSetMoveCall::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
return ExpEmit();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// code generation is only performed for some Duke checks that depend on CON
|
||||
|
|
|
@ -2,62 +2,6 @@
|
|||
#include "codegen.h"
|
||||
#include "coreactor.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FxSetActionCall : public FxExpression
|
||||
{
|
||||
FxExpression *Self;
|
||||
FxExpression *Arg;
|
||||
|
||||
public:
|
||||
|
||||
FxSetActionCall(FxExpression *self, FxExpression* arg, const FScriptPosition &pos);
|
||||
~FxSetActionCall();
|
||||
FxExpression *Resolve(FCompileContext&);
|
||||
ExpEmit Emit(VMFunctionBuilder *build);
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FxSetAICall : public FxExpression
|
||||
{
|
||||
FxExpression *Self;
|
||||
FxExpression *Arg;
|
||||
|
||||
public:
|
||||
|
||||
FxSetAICall(FxExpression *self, FxExpression* arg, const FScriptPosition &pos);
|
||||
~FxSetAICall();
|
||||
FxExpression *Resolve(FCompileContext&);
|
||||
ExpEmit Emit(VMFunctionBuilder *build);
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FxSetMoveCall : public FxExpression
|
||||
{
|
||||
FxExpression *Self;
|
||||
FxExpression *Arg;
|
||||
|
||||
public:
|
||||
|
||||
FxSetMoveCall(FxExpression *self, FxExpression* arg, const FScriptPosition &pos);
|
||||
~FxSetMoveCall();
|
||||
FxExpression *Resolve(FCompileContext&);
|
||||
ExpEmit Emit(VMFunctionBuilder *build);
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Raze specific names
|
||||
|
||||
xx(0)
|
||||
xx(no)
|
||||
xx(IngameMenu)
|
||||
xx(ListMenuItemBloodDripDrawer)
|
||||
xx(UsermapMenu)
|
||||
|
@ -53,3 +54,6 @@ xx(isDukeEngine)
|
|||
xx(isBlood)
|
||||
xx(isSW)
|
||||
xx(isExhumed)
|
||||
xx(ChangeAction)
|
||||
xx(ChangeAI)
|
||||
xx(ChangeMove)
|
||||
|
|
|
@ -247,9 +247,9 @@ bool checkhitswitch(int snum, walltype* wwal, DDukeActor* act);
|
|||
void drawshadows(tspriteArray& tsprites, tspritetype* t, DDukeActor* h);
|
||||
void applyanimations(tspritetype* t, DDukeActor* h, const DVector2& viewVec, DAngle viewang);
|
||||
|
||||
int LookupAction(DDukeActor* self, FName name);
|
||||
int LookupMove(DDukeActor* self, FName name);
|
||||
int LookupAI(DDukeActor* self, FName name);
|
||||
int LookupAction(PClass* self, FName name);
|
||||
int LookupMove(PClass* self, FName name);
|
||||
int LookupAI(PClass* self, FName name);
|
||||
|
||||
|
||||
inline int32_t krand(void)
|
||||
|
|
|
@ -506,22 +506,46 @@ void GameInterface::FinalizeSetup()
|
|||
}
|
||||
|
||||
|
||||
int LookupAction(DDukeActor* self, FName name)
|
||||
int LookupAction(PClass* cls, FName name)
|
||||
{
|
||||
// todo
|
||||
return 0;
|
||||
while (true)
|
||||
{
|
||||
auto ainf = static_cast<PClassActor*>(cls)->ActorInfo();
|
||||
for (int i = 0; i < ainf->NumActions; i++)
|
||||
{
|
||||
if (actions[ainf->FirstAction + i].name == name) return ainf->FirstAction + i;
|
||||
}
|
||||
if (cls == RUNTIME_CLASS(DDukeActor)) return 0;
|
||||
cls = cls->ParentClass;
|
||||
}
|
||||
}
|
||||
|
||||
int LookupMove(DDukeActor* self, FName name)
|
||||
int LookupMove(PClass* cls, FName name)
|
||||
{
|
||||
// todo
|
||||
return 0;
|
||||
while (true)
|
||||
{
|
||||
auto ainf = static_cast<PClassActor*>(cls)->ActorInfo();
|
||||
for (int i = 0; i < ainf->NumMoves; i++)
|
||||
{
|
||||
if (actions[ainf->FirstMove + i].name == name) return ainf->FirstMove + i;
|
||||
}
|
||||
if (cls == RUNTIME_CLASS(DDukeActor)) return 0;
|
||||
cls = cls->ParentClass;
|
||||
}
|
||||
}
|
||||
|
||||
int LookupAI(DDukeActor* self, FName name)
|
||||
int LookupAI(PClass* cls, FName name)
|
||||
{
|
||||
// todo
|
||||
return 0;
|
||||
while (true)
|
||||
{
|
||||
auto ainf = static_cast<PClassActor*>(cls)->ActorInfo();
|
||||
for (int i = 0; i < ainf->NumAIs; i++)
|
||||
{
|
||||
if (actions[ainf->FirstAI + i].name == name) return ainf->FirstAI + i;
|
||||
}
|
||||
if (cls == RUNTIME_CLASS(DDukeActor)) return 0;
|
||||
cls = cls->ParentClass;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -714,8 +714,10 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, aim, aim_)
|
|||
|
||||
void Duke_SetAction(DDukeActor* self, int intname)
|
||||
{
|
||||
int ndx = LookupAction(self, FName(ENamedName(intname)));
|
||||
int ndx = LookupAction(self->GetClass(), FName(ENamedName(intname)));
|
||||
self->curAction = &actions[ndx];
|
||||
self->actioncounter = self->curframe = 0;
|
||||
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, SetAction, Duke_SetAction)
|
||||
|
@ -728,7 +730,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, SetAction, Duke_SetAction)
|
|||
|
||||
void Duke_SetMove(DDukeActor* self, int intname, int flags)
|
||||
{
|
||||
int ndx = LookupMove(self, FName(ENamedName(intname)));
|
||||
int ndx = LookupMove(self->GetClass(), FName(ENamedName(intname)));
|
||||
self->curMove = &moves[ndx];
|
||||
self->spr.hitag = flags;
|
||||
}
|
||||
|
@ -744,11 +746,15 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, SetMove, Duke_SetMove)
|
|||
|
||||
void Duke_SetAI(DDukeActor* self, int intname)
|
||||
{
|
||||
int ndx = LookupAI(self, FName(ENamedName(intname)));
|
||||
int ndx = LookupAI(self->GetClass(), FName(ENamedName(intname)));
|
||||
self->curMove = &moves[ais[ndx].move];
|
||||
self->curAction = &actions[ais[ndx].action];
|
||||
self->spr.hitag = ais[ndx].moveflags;
|
||||
self->curAI = ais[ndx].name;
|
||||
self->actioncounter = self->curframe = 0;
|
||||
self->counter = 0;
|
||||
if (self->spr.hitag & random_angle)
|
||||
self->spr.Angles.Yaw = randomAngle();
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, SetAI, Duke_SetAI)
|
||||
|
|
Loading…
Reference in a new issue