mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-23 20:43:15 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
475077f1de
18 changed files with 115 additions and 207 deletions
23
src/actor.h
23
src/actor.h
|
@ -111,6 +111,8 @@ struct FPortalGroupArray;
|
|||
// Any questions?
|
||||
//
|
||||
|
||||
|
||||
|
||||
// --- mobj.flags ---
|
||||
enum ActorFlag
|
||||
{
|
||||
|
@ -1014,7 +1016,9 @@ public:
|
|||
|
||||
SDWORD tics; // state tic counter
|
||||
FState *state;
|
||||
VMFunction *Damage; // For missiles and monster railgun
|
||||
//VMFunction *Damage; // For missiles and monster railgun
|
||||
int DamageVal;
|
||||
VMFunction *DamageFunc;
|
||||
int projectileKickback;
|
||||
ActorFlags flags;
|
||||
ActorFlags2 flags2; // Heretic flags
|
||||
|
@ -1201,6 +1205,23 @@ public:
|
|||
FState *GetRaiseState();
|
||||
void Revive();
|
||||
|
||||
void SetDamage(int dmg)
|
||||
{
|
||||
DamageVal = dmg;
|
||||
DamageFunc = nullptr;
|
||||
}
|
||||
|
||||
bool IsZeroDamage() const
|
||||
{
|
||||
return DamageVal == 0 && DamageFunc == nullptr;
|
||||
}
|
||||
|
||||
void RestoreDamage()
|
||||
{
|
||||
DamageVal = GetDefault()->DamageVal;
|
||||
DamageFunc = GetDefault()->DamageFunc;
|
||||
}
|
||||
|
||||
FState *FindState (FName label) const
|
||||
{
|
||||
return GetClass()->FindState(1, &label);
|
||||
|
|
|
@ -915,7 +915,7 @@ static int PatchThing (int thingy)
|
|||
}
|
||||
else if (linelen == 14 && stricmp (Line1, "Missile damage") == 0)
|
||||
{
|
||||
info->Damage = CreateDamageFunction(val);
|
||||
info->SetDamage(val);
|
||||
}
|
||||
else if (linelen == 5)
|
||||
{
|
||||
|
|
|
@ -47,7 +47,7 @@ static void BrainishExplosion (const DVector3 &pos)
|
|||
boom->SetState (state);
|
||||
}
|
||||
boom->effects = 0;
|
||||
boom->Damage = NULL; // disables collision detection which is not wanted here
|
||||
boom->SetDamage(0); // disables collision detection which is not wanted here
|
||||
boom->tics -= pr_brainscream() & 7;
|
||||
if (boom->tics < 1)
|
||||
boom->tics = 1;
|
||||
|
|
|
@ -115,7 +115,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack)
|
|||
fire->target = baseFire->target;
|
||||
fire->Angles.Yaw = baseFire->Angles.Yaw;
|
||||
fire->Vel = baseFire->Vel;
|
||||
fire->Damage = NULL;
|
||||
fire->SetDamage(0);
|
||||
fire->health = (i+1) * 2;
|
||||
P_CheckMissileSpawn (fire, self->radius);
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichFireGrow)
|
|||
self->AddZ(9.);
|
||||
if (self->health == 0)
|
||||
{
|
||||
self->Damage = self->GetDefault()->Damage;
|
||||
self->RestoreDamage();
|
||||
self->SetState (self->FindState("NoGrow"));
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -340,7 +340,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LastZap)
|
|||
{
|
||||
mo->SetState (mo->FindState (NAME_Death));
|
||||
mo->Vel.Z = 40;
|
||||
mo->Damage = NULL;
|
||||
mo->SetDamage(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -344,7 +344,7 @@ size_t PClassActor::PropagateMark()
|
|||
// Mark damage function
|
||||
if (Defaults != NULL)
|
||||
{
|
||||
GC::Mark(((AActor *)Defaults)->Damage);
|
||||
GC::Mark(((AActor *)Defaults)->DamageFunc);
|
||||
}
|
||||
|
||||
// marked += ActorInfo->NumOwnedStates * sizeof(FState);
|
||||
|
|
|
@ -3791,7 +3791,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
|
|||
break;
|
||||
|
||||
case APROP_Damage:
|
||||
actor->Damage = CreateDamageFunction(value);
|
||||
actor->SetDamage(value);
|
||||
break;
|
||||
|
||||
case APROP_Alpha:
|
||||
|
|
|
@ -1320,7 +1320,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch
|
|||
// [RH] What is the point of this check, again? In Hexen, it is unconditional,
|
||||
// but here we only do it if the missile's damage is 0.
|
||||
// MBF bouncer might have a non-0 damage value, but they must not deal damage on impact either.
|
||||
if ((tm.thing->BounceFlags & BOUNCE_Actors) && (tm.thing->Damage == 0 || !(tm.thing->flags & MF_MISSILE)))
|
||||
if ((tm.thing->BounceFlags & BOUNCE_Actors) && (tm.thing->IsZeroDamage() || !(tm.thing->flags & MF_MISSILE)))
|
||||
{
|
||||
return (tm.thing->target == thing || !(thing->flags & MF_SOLID));
|
||||
}
|
||||
|
|
116
src/p_mobj.cpp
116
src/p_mobj.cpp
|
@ -139,7 +139,8 @@ IMPLEMENT_POINTY_CLASS (AActor)
|
|||
DECLARE_POINTER (LastHeard)
|
||||
DECLARE_POINTER (master)
|
||||
DECLARE_POINTER (Poisoner)
|
||||
DECLARE_POINTER (Damage)
|
||||
DECLARE_POINTER (DamageFunc)
|
||||
DECLARE_POINTER (alternative)
|
||||
END_POINTERS
|
||||
|
||||
AActor::~AActor ()
|
||||
|
@ -148,73 +149,6 @@ AActor::~AActor ()
|
|||
// Use Destroy() instead.
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CalcDamageValue
|
||||
//
|
||||
// Given a script function, returns an integer to represent it in a
|
||||
// savegame. This encoding is compatible with previous incarnations
|
||||
// where damage was an integer.
|
||||
//
|
||||
// 0 : use null function
|
||||
// 0x40000000 : use default function
|
||||
// anything else : use function that returns this number
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static int CalcDamageValue(VMFunction *func)
|
||||
{
|
||||
if (func == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
VMScriptFunction *sfunc = dyn_cast<VMScriptFunction>(func);
|
||||
if (sfunc == NULL)
|
||||
{
|
||||
return 0x40000000;
|
||||
}
|
||||
VMOP *op = sfunc->Code;
|
||||
// If the function was created by CreateDamageFunction(), extract
|
||||
// the value used to create it and return that. Otherwise, return
|
||||
// indicating to use the default function.
|
||||
if (op->op == OP_RETI && op->a == 0)
|
||||
{
|
||||
return op->i16;
|
||||
}
|
||||
if (op->op == OP_RET && op->a == 0 && op->b == (REGT_INT | REGT_KONST))
|
||||
{
|
||||
return sfunc->KonstD[op->c];
|
||||
}
|
||||
return 0x40000000;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// UncalcDamageValue
|
||||
//
|
||||
// Given a damage integer, returns a script function for it.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static VMFunction *UncalcDamageValue(int dmg, VMFunction *def)
|
||||
{
|
||||
if (dmg == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if ((dmg & 0xC0000000) == 0x40000000)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
// Does the default version return this? If so, use it. Otherwise,
|
||||
// create a new function.
|
||||
if (CalcDamageValue(def) == dmg)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
return CreateDamageFunction(dmg);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// AActor :: Serialize
|
||||
|
@ -262,18 +196,16 @@ void AActor::Serialize(FArchive &arc)
|
|||
<< projectilepassheight
|
||||
<< Vel
|
||||
<< tics
|
||||
<< state;
|
||||
if (arc.IsStoring())
|
||||
<< state
|
||||
<< DamageVal;
|
||||
if (DamageVal == 0x40000000 || DamageVal == -1)
|
||||
{
|
||||
int dmg;
|
||||
dmg = CalcDamageValue(Damage);
|
||||
arc << dmg;
|
||||
DamageVal = -1;
|
||||
DamageFunc = GetDefault()->DamageFunc;
|
||||
}
|
||||
else
|
||||
{
|
||||
int dmg;
|
||||
arc << dmg;
|
||||
Damage = UncalcDamageValue(dmg, GetDefault()->Damage);
|
||||
DamageFunc = nullptr;
|
||||
}
|
||||
P_SerializeTerrain(arc, floorterrain);
|
||||
arc << projectileKickback
|
||||
|
@ -2974,8 +2906,21 @@ CCMD(utid)
|
|||
|
||||
int AActor::GetMissileDamage (int mask, int add)
|
||||
{
|
||||
if (Damage == NULL)
|
||||
if (DamageVal >= 0)
|
||||
{
|
||||
if (mask == 0)
|
||||
{
|
||||
return add * DamageVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((pr_missiledamage() & mask) + add) * DamageVal;
|
||||
}
|
||||
}
|
||||
if (DamageFunc == nullptr)
|
||||
{
|
||||
// This should never happen
|
||||
assert(false && "No damage function found");
|
||||
return 0;
|
||||
}
|
||||
VMFrameStack stack;
|
||||
|
@ -2987,22 +2932,11 @@ int AActor::GetMissileDamage (int mask, int add)
|
|||
results[0].IntAt(&amount);
|
||||
results[1].IntAt(&calculated);
|
||||
|
||||
if (stack.Call(Damage, ¶m, 1, results, 2) < 1)
|
||||
if (stack.Call(DamageFunc, ¶m, 1, results, 2) < 1)
|
||||
{ // No results
|
||||
return 0;
|
||||
}
|
||||
if (calculated)
|
||||
{
|
||||
return amount;
|
||||
}
|
||||
else if (mask == 0)
|
||||
{
|
||||
return add * amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((pr_missiledamage() & mask) + add) * amount;
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
void AActor::Howl ()
|
||||
|
@ -3694,7 +3628,7 @@ void AActor::Tick ()
|
|||
// still have missiles that go straight up and down through actors without
|
||||
// damaging anything.
|
||||
// (for backwards compatibility this must check for lack of damage function, not for zero damage!)
|
||||
if ((flags & MF_MISSILE) && Vel.X == 0 && Vel.Y == 0 && Damage != NULL)
|
||||
if ((flags & MF_MISSILE) && Vel.X == 0 && Vel.Y == 0 && !IsZeroDamage())
|
||||
{
|
||||
Vel.X = MinVel;
|
||||
}
|
||||
|
|
|
@ -496,8 +496,7 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults,
|
|||
else if (def == DEF_Projectile && sc.Compare ("Damage"))
|
||||
{
|
||||
sc.MustGetNumber ();
|
||||
FxDamageValue *x = new FxDamageValue(new FxConstant(sc.Number, sc), false);
|
||||
defaults->Damage = (VMFunction *)(uintptr_t)(ActorDamageFuncs.Push(x) + 1);
|
||||
defaults->SetDamage(sc.Number);
|
||||
}
|
||||
else if (def == DEF_Projectile && sc.Compare ("DamageType"))
|
||||
{
|
||||
|
|
|
@ -348,12 +348,12 @@ static void FinishThingdef()
|
|||
continue;
|
||||
}
|
||||
|
||||
if (def->Damage != NULL)
|
||||
if (def->DamageFunc != nullptr)
|
||||
{
|
||||
FxDamageValue *dmg = (FxDamageValue *)ActorDamageFuncs[(uintptr_t)def->Damage - 1];
|
||||
FxDamageValue *dmg = (FxDamageValue *)ActorDamageFuncs[(uintptr_t)def->DamageFunc - 1];
|
||||
VMScriptFunction *sfunc;
|
||||
sfunc = dmg->GetFunction();
|
||||
if (sfunc == NULL)
|
||||
if (sfunc == nullptr)
|
||||
{
|
||||
FCompileContext ctx(ti);
|
||||
dmg = static_cast<FxDamageValue *>(dmg->Resolve(ctx));
|
||||
|
@ -365,15 +365,15 @@ static void FinishThingdef()
|
|||
dmg->Emit(&buildit);
|
||||
sfunc = buildit.MakeFunction();
|
||||
sfunc->NumArgs = 1;
|
||||
sfunc->Proto = NULL; ///FIXME: Need a proper prototype here
|
||||
sfunc->Proto = nullptr; ///FIXME: Need a proper prototype here
|
||||
// Save this function in case this damage value was reused
|
||||
// (which happens quite easily with inheritance).
|
||||
dmg->SetFunction(sfunc);
|
||||
}
|
||||
}
|
||||
def->Damage = sfunc;
|
||||
def->DamageFunc = sfunc;
|
||||
|
||||
if (dump != NULL && sfunc != NULL)
|
||||
if (dump != nullptr && sfunc != nullptr)
|
||||
{
|
||||
char label[64];
|
||||
int labellen = mysnprintf(label, countof(label), "Function %s.Damage",
|
||||
|
|
|
@ -231,6 +231,38 @@ DEFINE_ACTION_FUNCTION(AActor, CheckClass)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CheckClass
|
||||
//
|
||||
// NON-ACTION function to calculate missile damage for the given actor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetMissileDamage)
|
||||
{
|
||||
if (numret > 0)
|
||||
{
|
||||
assert(ret != NULL);
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_INT(mask);
|
||||
PARAM_INT(add)
|
||||
PARAM_INT_OPT(pick_pointer) { pick_pointer = AAPTR_DEFAULT; }
|
||||
|
||||
self = COPY_AAPTR(self, pick_pointer);
|
||||
if (self == NULL)
|
||||
{
|
||||
ret->SetInt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret->SetInt(self->GetMissileDamage(mask, add));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// IsPointerEqual
|
||||
|
|
|
@ -666,4 +666,5 @@ void InitThingdef()
|
|||
symt.AddSymbol(new PField(NAME_Speed, TypeFloat64, VARF_Native, myoffsetof(AActor, Speed)));
|
||||
symt.AddSymbol(new PField(NAME_Threshold, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, threshold)));
|
||||
symt.AddSymbol(new PField(NAME_DefThreshold, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, DefThreshold)));
|
||||
symt.AddSymbol(new PField(NAME_Damage, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, DamageVal)));
|
||||
}
|
||||
|
|
|
@ -854,20 +854,6 @@ public:
|
|||
ExpEmit Emit(VMFunctionBuilder *build);
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxDamage
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FxDamage : public FxExpression
|
||||
{
|
||||
public:
|
||||
FxDamage(const FScriptPosition&);
|
||||
FxExpression *Resolve(FCompileContext&);
|
||||
ExpEmit Emit(VMFunctionBuilder *build);
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxArrayElement
|
||||
|
@ -1188,12 +1174,11 @@ public:
|
|||
class FxDamageValue : public FxExpression
|
||||
{
|
||||
FxExpression *val;
|
||||
bool Calculated;
|
||||
VMScriptFunction *MyFunction;
|
||||
|
||||
public:
|
||||
|
||||
FxDamageValue(FxExpression *v, bool calc);
|
||||
FxDamageValue(FxExpression *v);
|
||||
~FxDamageValue();
|
||||
FxExpression *Resolve(FCompileContext&);
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -865,19 +865,21 @@ static bool ParsePropertyParams(FScanner &sc, FPropertyInfo *prop, AActor *defau
|
|||
|
||||
if (sc.CheckString ("("))
|
||||
{
|
||||
x = new FxDamageValue(new FxIntCast(ParseExpression(sc, bag.Info)), true);
|
||||
conv.i = -1;
|
||||
params.Push(conv);
|
||||
x = new FxDamageValue(new FxIntCast(ParseExpression(sc, bag.Info)));
|
||||
sc.MustGetStringName(")");
|
||||
conv.exp = x;
|
||||
params.Push(conv);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
if (sc.Number != 0)
|
||||
{
|
||||
x = new FxDamageValue(new FxConstant(sc.Number, bag.ScriptPosition), false);
|
||||
}
|
||||
conv.i = sc.Number;
|
||||
params.Push(conv);
|
||||
conv.exp = nullptr;
|
||||
}
|
||||
conv.exp = x;
|
||||
params.Push(conv);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -636,7 +636,8 @@ DEFINE_PROPERTY(threshold, I, Actor)
|
|||
//==========================================================================
|
||||
DEFINE_PROPERTY(damage, X, Actor)
|
||||
{
|
||||
PROP_EXP_PARM(id, 0);
|
||||
PROP_INT_PARM(dmgval, 0);
|
||||
PROP_EXP_PARM(id, 1);
|
||||
|
||||
// Damage can either be a single number, in which case it is subject
|
||||
// to the original damage calculation rules. Or, it can be an expression
|
||||
|
@ -646,13 +647,15 @@ DEFINE_PROPERTY(damage, X, Actor)
|
|||
|
||||
// Store this expression here for now. It will be converted to a function
|
||||
// later once all actors have been processed.
|
||||
if (id == NULL)
|
||||
defaults->DamageVal = dmgval;
|
||||
|
||||
if (id == nullptr)
|
||||
{
|
||||
defaults->Damage = NULL;
|
||||
defaults->DamageFunc = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
defaults->Damage = (VMFunction *)(uintptr_t)(ActorDamageFuncs.Push(id) + 1);
|
||||
defaults->DamageFunc = (VMFunction *)(uintptr_t)(ActorDamageFuncs.Push(id) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ ACTOR Actor native //: Thinker
|
|||
native int CountProximity(class<Actor> classname, float distance, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||
native float GetSpriteAngle(int ptr = AAPTR_DEFAULT);
|
||||
native float GetSpriteRotation(int ptr = AAPTR_DEFAULT);
|
||||
native int GetMissileDamage(int mask, int add, int ptr = AAPTR_DEFAULT);
|
||||
|
||||
// Action functions
|
||||
// Meh, MBF redundant functions. Only for DeHackEd support.
|
||||
|
|
Loading…
Reference in a new issue