more inventory scriptification

* completely scriptified DehackedPickup and FakeInventory.
* scriptified all remaining virtual functions of Inventory, so that its inheritance is now 100% script-side.
* scriptified CallTryPickup and most of the code called by that.

- fixed: Passing local variables by reference did not work in the VM.
This commit is contained in:
Christoph Oelckers 2017-01-19 23:42:12 +01:00
commit 3c30b59bab
19 changed files with 483 additions and 612 deletions

View file

@ -420,6 +420,10 @@ PPrototype *FxExpression::ReturnProto()
static int EncodeRegType(ExpEmit reg)
{
int regtype = reg.RegType;
if (reg.Fixed && reg.Target)
{
regtype |= REGT_ADDROF;
}
if (reg.Konst)
{
regtype |= REGT_KONST;
@ -10008,10 +10012,9 @@ FxExpression *FxReturnStatement::Resolve(FCompileContext &ctx)
{
for (unsigned i = 0; i < Args.Size(); i++)
{
auto &Value = Args[0];
Value = new FxTypeCast(Value, ctx.ReturnProto->ReturnTypes[i], false, false);
Value = Value->Resolve(ctx);
if (Value == nullptr) fail = true;
Args[i] = new FxTypeCast(Args[i], ctx.ReturnProto->ReturnTypes[i], false, false);
Args[i] = Args[i]->Resolve(ctx);
if (Args[i] == nullptr) fail = true;
}
if (fail)
{

View file

@ -65,40 +65,6 @@ struct FExtraInfo
double DeathHeight, BurnHeight;
};
class AFakeInventory : public AInventory
{
DECLARE_CLASS (AFakeInventory, AInventory);
public:
bool Respawnable;
bool ShouldRespawn ()
{
return Respawnable && Super::ShouldRespawn();
}
bool TryPickup (AActor *&toucher)
{
INTBOOL success = P_ExecuteSpecial(special, NULL, toucher, false,
args[0], args[1], args[2], args[3], args[4]);
if (success)
{
GoAwayAndDie ();
return true;
}
return false;
}
void DoPickupSpecial (AActor *toucher)
{
// The special was already executed by TryPickup, so do nothing here
}
};
IMPLEMENT_CLASS(AFakeInventory, false, false)
DEFINE_FIELD(AFakeInventory, Respawnable)
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
@ -125,16 +91,6 @@ static const char *RenderStyles[] =
// CODE --------------------------------------------------------------------
//==========================================================================
//
//==========================================================================
DEFINE_CLASS_PROPERTY(respawns, 0, FakeInventory)
{
defaults->Respawnable = true;
}
//==========================================================================
//
// ParseOldDecoration
@ -154,7 +110,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
PClassActor *parent;
FName typeName;
parent = (def == DEF_Pickup) ? RUNTIME_CLASS(AFakeInventory) : RUNTIME_CLASS(AActor);
parent = (def == DEF_Pickup) ? PClass::FindActor("FakeInventory") : RUNTIME_CLASS(AActor);
sc.MustGetString();
typeName = FName(sc.String);
@ -360,7 +316,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
static void ParseInsideDecoration (Baggage &bag, AActor *defaults,
FExtraInfo &extra, EDefinitionType def, FScanner &sc, TArray<FState> &StateArray, TArray<FScriptPosition> &SourceLines)
{
AFakeInventory *const inv = static_cast<AFakeInventory *>(defaults);
AInventory *const inv = static_cast<AInventory *>(defaults);
char sprite[5] = "TNT1";
sc.MustGetString ();
@ -588,7 +544,7 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults,
}
else if (def == DEF_Pickup && sc.Compare ("Respawns"))
{
inv->Respawnable = true;
inv->BoolVar("Respawnable") = true;
}
else if (def == DEF_BreakableDecoration && sc.Compare ("SolidOnDeath"))
{

View file

@ -842,7 +842,12 @@ static void DispatchScriptProperty(FScanner &sc, PProperty *prop, AActor *defaul
addr = ((char*)defaults) + f->Offset;
}
if (f->Type->IsKindOf(RUNTIME_CLASS(PInt)))
if (f->Type == TypeBool)
{
bool val = sc.CheckNumber() ? !!sc.Number : true;
static_cast<PBool*>(f->Type)->SetValue(addr, !!val);
}
else if (f->Type->IsKindOf(RUNTIME_CLASS(PInt)))
{
sc.MustGetNumber();
static_cast<PInt*>(f->Type)->SetValue(addr, sc.Number);

View file

@ -69,8 +69,6 @@
void InitThingdef();
// STATIC FUNCTION PROTOTYPES --------------------------------------------
PClassActor *QuestItemClasses[31];
static TMap<FState *, FScriptPosition> StateSourceLines;
static FScriptPosition unknownstatesource("unknown file", 0);
@ -448,12 +446,5 @@ void LoadActors()
// Now we may call the scripted OnDestroy method.
PClass::bVMOperational = true;
// Since these are defined in DECORATE now the table has to be initialized here.
for (int i = 0; i < 31; i++)
{
char fmt[20];
mysnprintf(fmt, countof(fmt), "QuestItem%d", i + 1);
QuestItemClasses[i] = PClass::FindActor(fmt);
}
StateSourceLines.Clear();
}

View file

@ -1926,6 +1926,7 @@ void ZCCCompiler::DispatchProperty(FPropertyInfo *prop, ZCC_PropertyStmt *proper
void ZCCCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *property, AActor *defaults, Baggage &bag)
{
ZCC_ExprConstant one;
unsigned parmcount = 1;
ZCC_TreeNode *x = property->Values;
while (x->SiblingNext != property->Values)
@ -1933,7 +1934,16 @@ void ZCCCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *prop
x = x->SiblingNext;
parmcount++;
}
if (parmcount != prop->Variables.Size())
if (parmcount == 0 && prop->Variables.Size() == 1 && prop->Variables[0]->Type == TypeBool)
{
// allow boolean properties to have the parameter omitted
one.Operation = PEX_ConstValue;
one.NodeType = AST_ExprConstant;
one.Type = TypeBool;
one.IntVal = 1;
property->Values = &one;
}
else if (parmcount != prop->Variables.Size())
{
Error(x, "Argument count mismatch: Got %u, expected %u", parmcount, prop->Variables.Size());
return;
@ -1954,6 +1964,10 @@ void ZCCCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *prop
addr = ((char*)defaults) + f->Offset;
}
if (f->Type == TypeBool)
{
static_cast<PBool*>(f->Type)->SetValue(addr, !!GetInt(exp));
}
if (f->Type->IsKindOf(RUNTIME_CLASS(PInt)))
{
static_cast<PInt*>(f->Type)->SetValue(addr, GetInt(exp));