diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 0225049192..1ebec242ed 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -634,6 +634,7 @@ void AActor::RemoveInventory(AInventory *item) bool AActor::TakeInventory(PClassActor *itemclass, int amount, bool fromdecorate, bool notakeinfinite) { + amount = abs(amount); AInventory *item = FindInventory(itemclass); if (item == NULL) @@ -666,6 +667,7 @@ bool AActor::TakeInventory(PClassActor *itemclass, int amount, bool fromdecorate item->IsKindOf(RUNTIME_CLASS(AAmmo))) { // Nothing to do here, except maybe res = false;? Would it make sense? + result = false; } else if (!amount || amount>=item->Amount) { diff --git a/src/p_pspr.h b/src/p_pspr.h index c0a695e041..084fe8fcee 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -57,6 +57,7 @@ enum PSPFlags PSPF_ADDBOB = 1 << 1, PSPF_POWDOUBLE = 1 << 2, PSPF_CVARFAST = 1 << 3, + PSPF_FLIP = 1 << 6, }; class DPSprite : public DObject diff --git a/src/r_things.cpp b/src/r_things.cpp index 179ffec97d..ab75c15b02 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -1404,7 +1404,7 @@ void R_DrawPSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double vis->pic = tex; vis->ColormapNum = 0; - if (flip) + if (!(flip) != !(pspr->Flags & PSPF_FLIP)) { vis->xiscale = -FLOAT2FIXED(pspritexiscale * tex->Scale.X); vis->startfrac = (tex->GetWidth() << FRACBITS) - 1; diff --git a/src/thingdef/thingdef.cpp b/src/thingdef/thingdef.cpp index 41e1e95422..9af031b04f 100644 --- a/src/thingdef/thingdef.cpp +++ b/src/thingdef/thingdef.cpp @@ -480,32 +480,3 @@ void LoadActors () if (!batchrun) Printf("DECORATE parsing took %.2f ms\n", timer.TimeMS()); // Base time: ~52 ms } - - -//========================================================================== -// -// CreateDamageFunction -// -// Creates a damage function suitable for a constant, non-expressioned -// value. -// -//========================================================================== - -VMScriptFunction *CreateDamageFunction(int dmg) -{ - if (dmg == 0) - { - // For zero damage, do not create a function so that the special collision detection case still works as before. - return NULL; - } - else - { - VMFunctionBuilder build; - build.Registers[REGT_POINTER].Get(1); // The self pointer - build.EmitRetInt(0, false, dmg); - build.EmitRetInt(1, true, 0); - VMScriptFunction *sfunc = build.MakeFunction(); - sfunc->NumArgs = 1; - return sfunc; - } -} diff --git a/src/thingdef/thingdef.h b/src/thingdef/thingdef.h index 3a419b112a..565da573af 100644 --- a/src/thingdef/thingdef.h +++ b/src/thingdef/thingdef.h @@ -164,14 +164,6 @@ inline void ResetBaggage (Baggage *bag, PClassActor *stateclass) bag->statedef.MakeStateDefines(stateclass); } -//========================================================================== -// -// Damage function creation -// -//========================================================================== - -VMScriptFunction *CreateDamageFunction(int dmg); - //========================================================================== // // Action function lookup diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 3b4e6203e6..c6bc8215b0 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2622,6 +2622,92 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GiveToSiblings) ACTION_RETURN_INT(count); } +//=========================================================================== +// +// A_SetInventory +// +//=========================================================================== + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetInventory) +{ + PARAM_ACTION_PROLOGUE; + PARAM_CLASS(itemtype, AInventory); + PARAM_INT(amount); + PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; } + PARAM_BOOL_OPT(beyondMax) { beyondMax = false; } + + bool res = false; + + if (itemtype == nullptr) + { + ACTION_RETURN_BOOL(false); + } + + AActor *mobj = COPY_AAPTR(self, ptr); + + if (mobj == nullptr) + { + ACTION_RETURN_BOOL(false); + } + + AInventory *item = mobj->FindInventory(itemtype); + + if (item != nullptr) + { + // A_SetInventory sets the absolute amount. + // Subtract or set the appropriate amount as necessary. + + if (amount == item->Amount) + { + // Nothing was changed. + ACTION_RETURN_BOOL(false); + } + else if (amount <= 0) + { + //Remove it all. + res = (mobj->TakeInventory(itemtype, item->Amount, true, false)); + ACTION_RETURN_BOOL(res); + } + else if (amount < item->Amount) + { + int amt = abs(item->Amount - amount); + res = (mobj->TakeInventory(itemtype, amt, true, false)); + ACTION_RETURN_BOOL(res); + } + else + { + item->Amount = (beyondMax ? amount : clamp(amount, 0, item->MaxAmount)); + ACTION_RETURN_BOOL(true); + } + } + else + { + if (amount <= 0) + { + ACTION_RETURN_BOOL(false); + } + item = static_cast(Spawn(itemtype)); + if (item == nullptr) + { + ACTION_RETURN_BOOL(false); + } + else + { + item->Amount = amount; + item->flags |= MF_DROPPED; + item->ItemFlags |= IF_IGNORESKILL; + item->ClearCounters(); + if (!item->CallTryPickup(mobj)) + { + item->Destroy(); + ACTION_RETURN_BOOL(false); + } + ACTION_RETURN_BOOL(true); + } + } + ACTION_RETURN_BOOL(false); +} + //=========================================================================== // // A_TakeInventory diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index d60cda823b..80ee6c22fc 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1435,7 +1435,7 @@ DEFINE_PROPERTY(spriterotation, F, Actor) //========================================================================== // //========================================================================== -DEFINE_PROPERTY(visibleangles, Ff, Actor) +DEFINE_PROPERTY(visibleangles, FF, Actor) { PROP_DOUBLE_PARM(visstart, 0); PROP_DOUBLE_PARM(visend, 1); @@ -1446,7 +1446,7 @@ DEFINE_PROPERTY(visibleangles, Ff, Actor) //========================================================================== // //========================================================================== -DEFINE_PROPERTY(visiblepitch, Ff, Actor) +DEFINE_PROPERTY(visiblepitch, FF, Actor) { PROP_DOUBLE_PARM(visstart, 0); PROP_DOUBLE_PARM(visend, 1); diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index fb6b4c832f..eecc843d39 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -211,6 +211,7 @@ ACTOR Actor native //: Thinker native state A_JumpIfTargetInsideMeleeRange(state label); native state A_JumpIfInventory(class itemtype, int itemamount, state label, int owner = AAPTR_DEFAULT); native state A_JumpIfArmorType(name Type, state label, int amount = 1); + action native bool A_SetInventory(class itemtype, int amount, int ptr = AAPTR_DEFAULT, bool beyondMax = false); native bool A_GiveInventory(class itemtype, int amount = 0, int giveto = AAPTR_DEFAULT); native bool A_TakeInventory(class itemtype, int amount = 0, int flags = 0, int giveto = AAPTR_DEFAULT); action native bool A_SpawnItem(class itemtype = "Unknown", float distance = 0, float zheight = 0, bool useammo = true, bool transfer_translation = false); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index dce2488c25..df3bb860bb 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -598,6 +598,7 @@ enum PSPF_ADDBOB = 1 << 1, PSPF_POWDOUBLE = 1 << 2, PSPF_CVARFAST = 1 << 3, + PSPF_FLIP = 1 << 6, }; // Default psprite layers