- exported a few more functions.

- refactored the ModifyDamage interface to be more scripting friendly.

In general it should be avoided having to call directly into chained inventory functions because they are very problematic and prone to errors. So this got wrapped into a single handler (on AActor, not AInventory!) which will later make it easier to refactor the parameters of ModifyDamage to work better for scripting and avoid the chaining.
This commit is contained in:
Christoph Oelckers 2016-11-27 11:59:47 +01:00
parent 096c51d546
commit b10ffb5133
8 changed files with 71 additions and 11 deletions

View file

@ -1420,6 +1420,7 @@ public:
}
int ApplyDamageFactor(FName damagetype, int damage) const;
int GetModifiedDamage(FName damagetype, int damage, bool passive);
};

View file

@ -822,6 +822,29 @@ AInventory *AInventory::CreateCopy (AActor *other)
return copy;
}
DEFINE_ACTION_FUNCTION(AInventory, CreateCopy)
{
PARAM_SELF_PROLOGUE(AInventory);
PARAM_OBJECT(other, AActor);
ACTION_RETURN_OBJECT(self->CreateCopy(other));
}
AInventory *AInventory::CallCreateCopy(AActor *other)
{
IFVIRTUAL(AActor, CreateCopy)
{
VMValue params[2] = { (DObject*)this, (DObject*)other };
VMReturn ret;
VMFrameStack stack;
AInventory *retval;
ret.PointerAt((void**)&retval);
stack.Call(func, params, 2, &ret, 1, nullptr);
return retval;
}
else return CreateCopy(other);
}
//===========================================================================
//
// AInventory::CreateTossable
@ -1538,7 +1561,7 @@ bool AInventory::TryPickup (AActor *&toucher)
{
// Add the item to the inventory. It is not already there, or HandlePickup
// would have already taken care of it.
AInventory *copy = CreateCopy (toucher);
AInventory *copy = CallCreateCopy (toucher);
if (copy == NULL)
{
return false;

View file

@ -199,6 +199,7 @@ public:
virtual void AttachToOwner (AActor *other);
virtual void DetachFromOwner ();
virtual AInventory *CreateCopy (AActor *other);
AInventory *CallCreateCopy(AActor *other);
virtual AInventory *CreateTossable ();
virtual bool GoAway ();
virtual void GoAwayAndDie ();

View file

@ -1105,15 +1105,15 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
damage = int(damage * source->DamageMultiply);
// Handle active damage modifiers (e.g. PowerDamage)
if (damage > 0 && source->Inventory != NULL)
if (damage > 0)
{
source->Inventory->ModifyDamage(damage, mod, damage, false);
damage = source->GetModifiedDamage(mod, damage, false);
}
}
// Handle passive damage modifiers (e.g. PowerProtection), provided they are not afflicted with protection penetrating powers.
if (damage > 0 && (target->Inventory != NULL) && !(flags & DMG_NO_PROTECT))
if (damage > 0 && !(flags & DMG_NO_PROTECT))
{
target->Inventory->ModifyDamage(damage, mod, damage, true);
damage = target->GetModifiedDamage(mod, damage, true);
}
if (damage > 0 && !(flags & DMG_NO_FACTOR))
{
@ -1749,8 +1749,7 @@ DEFINE_ACTION_FUNCTION(_PlayerInfo, PoisonPlayer)
//
//==========================================================================
void P_PoisonDamage (player_t *player, AActor *source, int damage,
bool playPainSound)
void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPainSound)
{
AActor *target;
@ -1771,10 +1770,7 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage,
// Take half damage in trainer mode
damage = int(damage * G_SkillProperty(SKILLP_DamageFactor));
// Handle passive damage modifiers (e.g. PowerProtection)
if (target->Inventory != NULL)
{
target->Inventory->ModifyDamage(damage, player->poisontype, damage, true);
}
damage = target->GetModifiedDamage(player->poisontype, damage, true);
// Modify with damage factors
damage = target->ApplyDamageFactor(player->poisontype, damage);
@ -1845,6 +1841,15 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage,
*/
}
DEFINE_ACTION_FUNCTION(_PlayerInfo, PoisonDamage)
{
PARAM_SELF_STRUCT_PROLOGUE(player_t);
PARAM_OBJECT(source, AActor);
PARAM_INT(damage);
PARAM_BOOL(playsound);
P_PoisonDamage(self, source, damage, playsound);
return 0;
}
CCMD (kill)
{

View file

@ -7158,6 +7158,23 @@ DEFINE_ACTION_FUNCTION(AActor, ClearCounters)
return 0;
}
int AActor::GetModifiedDamage(FName damagetype, int damage, bool passive)
{
if (Inventory != nullptr)
Inventory->ModifyDamage(damage, damagetype, damage, false);
return damage;
}
DEFINE_ACTION_FUNCTION(AActor, GetModifiedDamage)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_NAME(type);
PARAM_INT(damage);
PARAM_BOOL(passive);
ACTION_RETURN_INT(self->GetModifiedDamage(type, damage, passive));
}
int AActor::ApplyDamageFactor(FName damagetype, int damage) const
{
damage = int(damage * DamageFactor);
@ -7168,6 +7185,14 @@ int AActor::ApplyDamageFactor(FName damagetype, int damage) const
return damage;
}
DEFINE_ACTION_FUNCTION(AActor, ApplyDamageFactor)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_NAME(type);
PARAM_INT(damage);
ACTION_RETURN_INT(self->ApplyDamageFactor(type, damage));
}
void AActor::SetTranslation(FName trname)
{

View file

@ -303,6 +303,8 @@ class Actor : Thinker native
native Actor, Actor SpawnPlayerMissile(class<Actor> type, double angle = 0, double x = 0, double y = 0, double z = 0, out FTranslatedLineTarget pLineTarget = null, bool nofreeaim = false, bool noautoaim = false, int aimflags = 0);
native void SpawnTeleportFog(Vector3 pos, bool beforeTele, bool setTarget);
native Actor RoughMonsterSearch(int distance, bool onlyseekable = false);
native int ApplyDamageFactor(FName damagetype, int damage);
native int GetModifiedDamage(FName damagetype, int damage, bool passive);
void A_Light(int extralight) { if (player) player.extralight = clamp(extralight, -20, 20); }
void A_Light0() { if (player) player.extralight = 0; }

View file

@ -27,6 +27,8 @@ class Inventory : Actor native
virtual native bool Use (bool pickup);
virtual native color GetBlend ();
virtual native bool HandlePickup(Inventory item);
virtual native Inventory CreateCopy(Actor other);
// These are regular functions for the item itself.

View file

@ -228,6 +228,7 @@ FWeaponSlots weapons;
native bool UndoPlayerMorph(playerinfo player, int unmorphflag = 0, bool force = false);
native bool PoisonPlayer(Actor poisoner, Actor source, int poison);
native PoisonDamage(Actor source, int damage, bool playPainSound)
native void SetPsprite(int id, State stat, bool pending = false);
native void SetSafeFlash(Weapon weap, State flashstate, int index);
native PSprite GetPSprite(int id);