- split Damage into two variables: DamageVal for the old constant and DamageFunc for the DECORATE function.

The way this was done was a major headache inducer, requiring reconstruction of the function each time the value was changed and in general made actor damage a major hassle.
There was a DECORATE wrapper to mimic the original behavior but this looked quite broken because it completely ignored the different semantics of both damage calculation types.
It also made it impossible to determine if damage was a function or a value.
This accessor has been reverted to what it should be, only returning the constant, which now is -1 for a damage function. I am sorry if this may break the odd mod out but a quick look over some DECORATE-heavy stuff showed that this was never combined in any of them so that accessing 'damage' in DECORATE code depended on an actual damage function.

To get proper damage, a future commit will add a DECORATE function which calls AActor::GetMissileDamage.
This commit is contained in:
Christoph Oelckers 2016-09-19 03:36:51 +02:00
commit f1ba19073f
16 changed files with 81 additions and 207 deletions

View file

@ -3218,11 +3218,6 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
ScriptPosition.Message(MSG_ERROR, "Invalid member identifier '%s'\n", Identifier.GetChars());
}
}
// the damage property needs special handling
else if (Identifier == NAME_Damage)
{
newex = new FxDamage(ScriptPosition);
}
// now check the global identifiers.
else if ((sym = ctx.FindGlobal(Identifier)) != NULL)
{
@ -3316,65 +3311,6 @@ ExpEmit FxSelf::Emit(VMFunctionBuilder *build)
}
//==========================================================================
//
//
//
//==========================================================================
FxDamage::FxDamage(const FScriptPosition &pos)
: FxExpression(pos)
{
}
//==========================================================================
//
// FxDamage :: Resolve
//
//==========================================================================
FxExpression *FxDamage::Resolve(FCompileContext& ctx)
{
CHECKRESOLVED();
ValueType = TypeSInt32;
return this;
}
//==========================================================================
//
// FxDamage :: Emit
//
// Call this actor's damage function, if it has one
//
//==========================================================================
ExpEmit FxDamage::Emit(VMFunctionBuilder *build)
{
ExpEmit dmgval(build, REGT_INT);
// Get damage function
ExpEmit dmgfunc(build, REGT_POINTER);
build->Emit(OP_LO, dmgfunc.RegNum, 0/*self*/, build->GetConstantInt(myoffsetof(AActor, Damage)));
// If it's non-null...
build->Emit(OP_EQA_K, 1, dmgfunc.RegNum, build->GetConstantAddress(nullptr, ATAG_GENERIC));
size_t nulljump = build->Emit(OP_JMP, 0);
// ...call it
build->Emit(OP_PARAM, 0, REGT_POINTER, 0/*self*/);
build->Emit(OP_CALL, dmgfunc.RegNum, 1, 1);
build->Emit(OP_RESULT, 0, REGT_INT, dmgval.RegNum);
size_t notnulljump = build->Emit(OP_JMP, 0);
// Otherwise, use 0
build->BackpatchToHere(nulljump);
build->EmitLoadInt(dmgval.RegNum, 0);
build->BackpatchToHere(notnulljump);
return dmgval;
}
//==========================================================================
//
//
@ -5225,18 +5161,12 @@ ExpEmit FxMultiNameState::Emit(VMFunctionBuilder *build)
//
//==========================================================================
FxDamageValue::FxDamageValue(FxExpression *v, bool calc)
FxDamageValue::FxDamageValue(FxExpression *v)
: FxExpression(v->ScriptPosition)
{
val = v;
ValueType = TypeVoid;
Calculated = calc;
MyFunction = NULL;
if (!calc)
{
assert(v->isConstant() && "Non-calculated damage must be constant");
}
}
FxDamageValue::~FxDamageValue()
@ -5272,7 +5202,7 @@ ExpEmit FxDamageValue::Emit(VMFunctionBuilder *build)
assert(emitval.RegType == REGT_INT);
build->Emit(OP_RET, 0, REGT_INT | (emitval.Konst ? REGT_KONST : 0), emitval.RegNum);
}
build->Emit(OP_RETI, 1 | RET_FINAL, Calculated);
build->Emit(OP_RETI, 1 | RET_FINAL, true);
return ExpEmit();
}