mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
- added an accessor to the actor defaults. This might have been possible with less work using a function but that would have necessitated some type casts when using it on subclasses.
- scriptified A_BarrelDestroy to test the above.
This commit is contained in:
parent
24925c88a8
commit
98fa3d2d93
8 changed files with 157 additions and 24 deletions
|
@ -1508,10 +1508,10 @@ void PPointer::SetOps()
|
||||||
|
|
||||||
bool PPointer::IsMatch(intptr_t id1, intptr_t id2) const
|
bool PPointer::IsMatch(intptr_t id1, intptr_t id2) const
|
||||||
{
|
{
|
||||||
assert(id2 == 0);
|
assert(id2 == 0 || id2 == 1);
|
||||||
PType *pointat = (PType *)id1;
|
PType *pointat = (PType *)id1;
|
||||||
|
|
||||||
return pointat == PointedType;
|
return pointat == PointedType && (!!id2) == IsConst;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -29,21 +29,3 @@
|
||||||
#include "a_revenant.cpp"
|
#include "a_revenant.cpp"
|
||||||
#include "a_scriptedmarine.cpp"
|
#include "a_scriptedmarine.cpp"
|
||||||
|
|
||||||
// The barrel of green goop ------------------------------------------------
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, A_BarrelDestroy)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
|
||||||
|
|
||||||
if (dmflags2 & DF2_BARRELS_RESPAWN)
|
|
||||||
{
|
|
||||||
self->Height = self->GetDefault()->Height;
|
|
||||||
self->renderflags |= RF_INVISIBLE;
|
|
||||||
self->flags &= ~MF_SOLID;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self->Destroy ();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -683,6 +683,7 @@ xx(BuiltinNameToClass)
|
||||||
xx(BuiltinFindMultiNameState)
|
xx(BuiltinFindMultiNameState)
|
||||||
xx(BuiltinFindSingleNameState)
|
xx(BuiltinFindSingleNameState)
|
||||||
xx(BuiltinHandleRuntimeState)
|
xx(BuiltinHandleRuntimeState)
|
||||||
|
xx(BuiltinGetDefault)
|
||||||
xx(Damage)
|
xx(Damage)
|
||||||
|
|
||||||
// basic type names
|
// basic type names
|
||||||
|
|
|
@ -5015,6 +5015,27 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
|
||||||
delete this;
|
delete this;
|
||||||
return x->Resolve(ctx);
|
return x->Resolve(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Identifier == NAME_Default)
|
||||||
|
{
|
||||||
|
if (ctx.Function->Variants[0].SelfClass == nullptr)
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_ERROR, "Unable to access class defaults from static function");
|
||||||
|
delete this;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (!ctx.Function->Variants[0].SelfClass->IsDescendantOf(RUNTIME_CLASS(AActor)))
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_ERROR, "'Default' requires an actor type.");
|
||||||
|
delete this;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
FxExpression * x = new FxClassDefaults(new FxSelf(ScriptPosition), ScriptPosition);
|
||||||
|
delete this;
|
||||||
|
return x->Resolve(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
// Ugh, the horror. Constants need to be taken from the owning class, but members from the self class to catch invalid accesses here...
|
// Ugh, the horror. Constants need to be taken from the owning class, but members from the self class to catch invalid accesses here...
|
||||||
// see if the current class (if valid) defines something with this name.
|
// see if the current class (if valid) defines something with this name.
|
||||||
PSymbolTable *symtbl;
|
PSymbolTable *symtbl;
|
||||||
|
@ -5348,6 +5369,95 @@ ExpEmit FxSelf::Emit(VMFunctionBuilder *build)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FxClassDefaults::FxClassDefaults(FxExpression *X, const FScriptPosition &pos)
|
||||||
|
: FxExpression(EFX_ClassDefaults, pos)
|
||||||
|
{
|
||||||
|
obj = X;
|
||||||
|
EmitTail = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FxClassDefaults::~FxClassDefaults()
|
||||||
|
{
|
||||||
|
SAFE_DELETE(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
PPrototype *FxClassDefaults::ReturnProto()
|
||||||
|
{
|
||||||
|
EmitTail = true;
|
||||||
|
return FxExpression::ReturnProto();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FxExpression *FxClassDefaults::Resolve(FCompileContext& ctx)
|
||||||
|
{
|
||||||
|
CHECKRESOLVED();
|
||||||
|
SAFE_RESOLVE(obj, ctx);
|
||||||
|
assert(obj->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)));
|
||||||
|
ValueType = NewPointer(static_cast<PPointer*>(obj->ValueType)->PointedType, true);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
int BuiltinGetDefault(VMFrameStack *stack, VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
|
||||||
|
{
|
||||||
|
assert(numparam == 1);
|
||||||
|
PARAM_POINTER_AT(0, obj, DObject);
|
||||||
|
ACTION_RETURN_OBJECT(obj->GetClass()->Defaults);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
ExpEmit FxClassDefaults::Emit(VMFunctionBuilder *build)
|
||||||
|
{
|
||||||
|
EmitParameter(build, obj, ScriptPosition);
|
||||||
|
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinGetDefault, BuiltinGetDefault);
|
||||||
|
|
||||||
|
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
|
||||||
|
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
||||||
|
auto callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||||
|
int opcode = (EmitTail ? OP_TAIL_K : OP_CALL_K);
|
||||||
|
build->Emit(opcode, build->GetConstantAddress(callfunc, ATAG_OBJECT), 1, 1);
|
||||||
|
|
||||||
|
if (EmitTail)
|
||||||
|
{
|
||||||
|
ExpEmit call;
|
||||||
|
call.Final = true;
|
||||||
|
return call;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpEmit out(build, REGT_POINTER);
|
||||||
|
build->Emit(OP_RESULT, 0, REGT_POINTER, out.RegNum);
|
||||||
|
return out;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -5465,6 +5575,21 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
|
||||||
CHECKRESOLVED();
|
CHECKRESOLVED();
|
||||||
SAFE_RESOLVE(classx, ctx);
|
SAFE_RESOLVE(classx, ctx);
|
||||||
|
|
||||||
|
if (membervar->SymbolName == NAME_Default)
|
||||||
|
{
|
||||||
|
if (!classx->ValueType->IsKindOf(RUNTIME_CLASS(PPointer))
|
||||||
|
|| !static_cast<PPointer *>(classx->ValueType)->PointedType->IsKindOf(RUNTIME_CLASS(AActor)))
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_ERROR, "'Default' requires an actor type.");
|
||||||
|
delete this;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
FxExpression * x = new FxClassDefaults(classx, ScriptPosition);
|
||||||
|
classx = nullptr;
|
||||||
|
delete this;
|
||||||
|
return x->Resolve(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
if (classx->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)))
|
if (classx->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)))
|
||||||
{
|
{
|
||||||
PPointer *ptrtype = dyn_cast<PPointer>(classx->ValueType);
|
PPointer *ptrtype = dyn_cast<PPointer>(classx->ValueType);
|
||||||
|
@ -5581,7 +5706,6 @@ FxClassMember::FxClassMember(FxExpression *x, PField* mem, const FScriptPosition
|
||||||
: FxStructMember(x, mem, pos)
|
: FxStructMember(x, mem, pos)
|
||||||
{
|
{
|
||||||
ExprType = EFX_ClassMember;
|
ExprType = EFX_ClassMember;
|
||||||
//if (classx->IsDefaultObject()) Readonly=true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -355,12 +355,14 @@ public:
|
||||||
class FxClassDefaults : public FxExpression
|
class FxClassDefaults : public FxExpression
|
||||||
{
|
{
|
||||||
FxExpression *obj;
|
FxExpression *obj;
|
||||||
|
bool EmitTail;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FxClassDefaults(FxExpression*, const FScriptPosition &);
|
FxClassDefaults(FxExpression *, const FScriptPosition &);
|
||||||
~FxClassDefaults();
|
~FxClassDefaults();
|
||||||
|
PPrototype *ReturnProto();
|
||||||
FxExpression *Resolve(FCompileContext&);
|
FxExpression *Resolve(FCompileContext&);
|
||||||
bool IsDefaultObject() const;
|
ExpEmit Emit(VMFunctionBuilder *build);
|
||||||
};
|
};
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -224,6 +224,14 @@ dottable_id(X) ::= dottable_id(A) DOT IDENTIFIER(B).
|
||||||
A->AppendSibling(id2);
|
A->AppendSibling(id2);
|
||||||
X = A; /*X-overwrites-A*/
|
X = A; /*X-overwrites-A*/
|
||||||
}
|
}
|
||||||
|
dottable_id(X) ::= dottable_id(A) DOT DEFAULT.
|
||||||
|
{
|
||||||
|
NEW_AST_NODE(Identifier,id2,A);
|
||||||
|
id2->Id = NAME_Default;
|
||||||
|
A->AppendSibling(id2);
|
||||||
|
X = A; /*X-overwrites-A*/
|
||||||
|
}
|
||||||
|
|
||||||
// a bit of a hack to allow the 'color' token to be used inside default properties.
|
// a bit of a hack to allow the 'color' token to be used inside default properties.
|
||||||
// as a variable name it is practically meaningless because it cannot defined
|
// as a variable name it is practically meaningless because it cannot defined
|
||||||
// as such anywhere so it will always produce an error during processing.
|
// as such anywhere so it will always produce an error during processing.
|
||||||
|
|
|
@ -357,7 +357,6 @@ class Actor : Thinker native
|
||||||
native int A_Explode(int damage = -1, int distance = -1, int flags = XF_HURTSOURCE, bool alert = false, int fulldamagedistance = 0, int nails = 0, int naildamage = 10, class<Actor> pufftype = "BulletPuff", name damagetype = "none");
|
native int A_Explode(int damage = -1, int distance = -1, int flags = XF_HURTSOURCE, bool alert = false, int fulldamagedistance = 0, int nails = 0, int naildamage = 10, class<Actor> pufftype = "BulletPuff", name damagetype = "none");
|
||||||
native void A_Stop();
|
native void A_Stop();
|
||||||
native void A_Respawn(int flags = 1);
|
native void A_Respawn(int flags = 1);
|
||||||
native void A_BarrelDestroy();
|
|
||||||
native void A_QueueCorpse();
|
native void A_QueueCorpse();
|
||||||
native void A_DeQueueCorpse();
|
native void A_DeQueueCorpse();
|
||||||
native void A_LookEx(int flags = 0, float minseedist = 0, float maxseedist = 0, float maxheardist = 0, float fov = 0, state label = null);
|
native void A_LookEx(int flags = 0, float minseedist = 0, float maxseedist = 0, float maxheardist = 0, float fov = 0, state label = null);
|
||||||
|
|
|
@ -34,6 +34,23 @@ class ExplosiveBarrel : Actor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extend class Actor
|
||||||
|
{
|
||||||
|
void A_BarrelDestroy()
|
||||||
|
{
|
||||||
|
if (GetCVar("sv_barrelrespawn"))
|
||||||
|
{
|
||||||
|
Height = Default.Height;
|
||||||
|
bInvisible = true;
|
||||||
|
bSolid = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Bullet puff -------------------------------------------------------------
|
// Bullet puff -------------------------------------------------------------
|
||||||
|
|
||||||
class BulletPuff : Actor
|
class BulletPuff : Actor
|
||||||
|
|
Loading…
Reference in a new issue