diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7d6c203065..feb43a3246 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1148,7 +1148,6 @@ set (PCH_SOURCES g_inventory/a_armor.cpp g_inventory/a_keys.cpp g_inventory/a_pickups.cpp - g_inventory/a_weaponpiece.cpp g_inventory/a_weapons.cpp g_strife/strife_sbar.cpp g_shared/a_action.cpp diff --git a/src/dobject.cpp b/src/dobject.cpp index e31a3dd232..10b37f636e 100644 --- a/src/dobject.cpp +++ b/src/dobject.cpp @@ -571,7 +571,7 @@ DEFINE_ACTION_FUNCTION(DObject, GetClassName) void *DObject::ScriptVar(FName field, PType *type) { auto sym = dyn_cast(GetClass()->Symbols.FindSymbol(field, true)); - if (sym && sym->Type == type) + if (sym && (sym->Type == type || type == nullptr)) { return (((char*)this) + sym->Offset); } diff --git a/src/dobject.h b/src/dobject.h index 3673504275..2f907d493a 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -482,6 +482,7 @@ public: PalEntry &ColorVar(FName field); FName &NameVar(FName field); double &FloatVar(FName field); + template T*& PointerVar(FName field); // If you need to replace one object with another and want to // change any pointers from the old object to the new object, diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index b135c1b657..2d41a57e3a 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -45,7 +45,6 @@ #include "autosegs.h" #include "v_text.h" #include "a_pickups.h" -#include "a_weaponpiece.h" #include "d_player.h" #include "doomerrors.h" #include "fragglescript/t_fs.h" diff --git a/src/dobjtype.h b/src/dobjtype.h index ee5d0984ea..12245795a6 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -1093,5 +1093,9 @@ inline double &DObject::FloatVar(FName field) return *(double*)ScriptVar(field, TypeFloat64); } - +template +inline T *&DObject::PointerVar(FName field) +{ + return *(T**)ScriptVar(field, nullptr); // pointer check is more tricky and for the handful of uses in the DECORATE parser not worth the hassle. +} #endif diff --git a/src/g_inventory/a_weaponpiece.cpp b/src/g_inventory/a_weaponpiece.cpp deleted file mode 100644 index 765547d4d1..0000000000 --- a/src/g_inventory/a_weaponpiece.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* -** a_weaponpieces.cpp -** Implements generic weapon pieces -** -**--------------------------------------------------------------------------- -** Copyright 2006-2016 Cheistoph Oelckers -** Copyright 2006-2016 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#include "a_pickups.h" -#include "a_weaponpiece.h" -#include "doomstat.h" -#include "serializer.h" - -IMPLEMENT_CLASS(AWeaponHolder, false, false) - -DEFINE_FIELD(AWeaponHolder, PieceMask); -DEFINE_FIELD(AWeaponHolder, PieceWeapon); - -//=========================================================================== -// -// -// -//=========================================================================== - -void AWeaponHolder::Serialize(FSerializer &arc) -{ - Super::Serialize(arc); - arc("piecemask", PieceMask) - ("pieceweapon", PieceWeapon); -} - -IMPLEMENT_CLASS(AWeaponPiece, false, true) - -IMPLEMENT_POINTERS_START(AWeaponPiece) - IMPLEMENT_POINTER(FullWeapon) - IMPLEMENT_POINTER(WeaponClass) -IMPLEMENT_POINTERS_END - -//=========================================================================== -// -// -// -//=========================================================================== - -void AWeaponPiece::Serialize(FSerializer &arc) -{ - Super::Serialize (arc); - auto def = (AWeaponPiece*)GetDefault(); - arc("weaponclass", WeaponClass, def->WeaponClass) - ("fullweapon", FullWeapon) - ("piecevalue", PieceValue, def->PieceValue); -} - -DEFINE_FIELD(AWeaponPiece, PieceValue); -DEFINE_FIELD(AWeaponPiece, WeaponClass); -DEFINE_FIELD(AWeaponPiece, FullWeapon); diff --git a/src/g_inventory/a_weaponpiece.h b/src/g_inventory/a_weaponpiece.h deleted file mode 100644 index de5d935363..0000000000 --- a/src/g_inventory/a_weaponpiece.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -#include "a_pickups.h" -#include "a_weapons.h" - -class AWeaponPiece : public AInventory -{ - DECLARE_CLASS (AWeaponPiece, AInventory) - HAS_OBJECT_POINTERS -protected: - bool PrivateShouldStay (); -public: - - virtual void Serialize(FSerializer &arc) override; - - int PieceValue; - PClassActor *WeaponClass; - TObjPtr FullWeapon; -}; - -// an internal class to hold the information for player class independent weapon piece handling -// [BL] Needs to be available for SBarInfo to check weaponpieces -class AWeaponHolder : public AInventory -{ - DECLARE_CLASS (AWeaponHolder, AInventory) - -public: - int PieceMask; - PClassActor * PieceWeapon; - - - virtual void Serialize(FSerializer &arc) override; -}; diff --git a/src/g_shared/sbarinfo.cpp b/src/g_shared/sbarinfo.cpp index ca94ebc845..83fc19de1e 100644 --- a/src/g_shared/sbarinfo.cpp +++ b/src/g_shared/sbarinfo.cpp @@ -51,7 +51,6 @@ #include "sbarinfo.h" #include "gi.h" #include "r_data/r_translate.h" -#include "a_weaponpiece.h" #include "g_level.h" #include "v_palette.h" #include "p_acs.h" diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index 85506edc54..883b2a460c 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -3145,12 +3145,12 @@ class CommandHasWeaponPiece : public SBarInfoCommandFlowControl for(AInventory *inv = statusBar->CPlayer->mo->Inventory;inv != NULL;inv=inv->Inventory) { - if(inv->IsKindOf(RUNTIME_CLASS(AWeaponHolder))) + auto hc = PClass::FindActor("WeaponHolder"); + if(inv->IsKindOf(hc)) { - AWeaponHolder *hold = static_cast(inv); - if(hold->PieceWeapon == weapon) + if(inv->PointerVar("PieceWeapon") == weapon) { - SetTruth(0 != (hold->PieceMask & (1 << (piece-1))), block, statusBar); + SetTruth(0 != (inv->IntVar("PieceMask") & (1 << (piece-1))), block, statusBar); return; } } diff --git a/src/scripting/thingdef.cpp b/src/scripting/thingdef.cpp index c94e320be0..c126e3d57b 100644 --- a/src/scripting/thingdef.cpp +++ b/src/scripting/thingdef.cpp @@ -56,7 +56,7 @@ #include "m_argv.h" #include "p_local.h" #include "doomerrors.h" -#include "a_weaponpiece.h" +#include "a_weapons.h" #include "p_conversation.h" #include "v_text.h" #include "thingdef.h" diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index eaad49e9c7..27165de847 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -67,7 +67,6 @@ #include "teaminfo.h" #include "v_video.h" #include "r_data/colormaps.h" -#include "a_weaponpiece.h" #include "vmbuilder.h" #include "a_keys.h" #include "g_levellocals.h" @@ -464,23 +463,6 @@ static bool PointerCheck(PType *symtype, PType *checktype) return symptype != nullptr && checkptype != nullptr && symptype->ClassRestriction->IsDescendantOf(checkptype->ClassRestriction); } -static void *ScriptVar(DObject *obj, PClass *cls, FName field, PType *type) -{ - auto sym = dyn_cast(cls->Symbols.FindSymbol(field, true)); - if (sym && (sym->Type == type || PointerCheck(sym->Type, type))) - { - return (((char*)obj) + sym->Offset); - } - I_Error("Variable %s of type %s not found in %s\n", field.GetChars(), type->DescriptiveName(), cls->TypeName.GetChars()); - return nullptr; -} - -template -T &TypedScriptVar(DObject *obj, PClass *cls, FName field, PType *type) -{ - return *(T*)ScriptVar(obj, cls, field, type); -} - //========================================================================== // // Info Property handlers @@ -2223,24 +2205,6 @@ DEFINE_CLASS_PROPERTY(preferredskin, S, Weapon) // NoOp - only for Skulltag compatibility } -//========================================================================== -// -//========================================================================== -DEFINE_CLASS_PROPERTY(number, I, WeaponPiece) -{ - PROP_INT_PARM(i, 0); - defaults->PieceValue = 1 << (i-1); -} - -//========================================================================== -// -//========================================================================== -DEFINE_CLASS_PROPERTY(weapon, S, WeaponPiece) -{ - PROP_STRING_PARM(str, 0); - defaults->WeaponClass = FindClassTentativeWeapon(str); -} - //========================================================================== // //========================================================================== @@ -2401,7 +2365,7 @@ DEFINE_SCRIPTED_PROPERTY_PREFIX(powerup, type, S, PowerupGiver) I_Error("Unknown powerup type %s", str); } } - TypedScriptVar(defaults, info, NAME_PowerupType, NewClassPointer(RUNTIME_CLASS(AActor))) = cls; + defaults->PointerVar(NAME_PowerupType) = cls; } //========================================================================== @@ -2990,7 +2954,7 @@ DEFINE_CLASS_PROPERTY(unmorphflash, S, MorphProjectile) DEFINE_SCRIPTED_PROPERTY(playerclass, S, PowerMorph) { PROP_STRING_PARM(str, 0); - TypedScriptVar(defaults, bag.Info, NAME_PlayerClass, NewClassPointer(RUNTIME_CLASS(APlayerPawn))) = FindClassTentativePlayerPawn(str, bag.fromDecorate); + defaults->PointerVar(NAME_PlayerClass) = FindClassTentativePlayerPawn(str, bag.fromDecorate); } //========================================================================== @@ -2999,7 +2963,7 @@ DEFINE_SCRIPTED_PROPERTY(playerclass, S, PowerMorph) DEFINE_SCRIPTED_PROPERTY(morphstyle, M, PowerMorph) { PROP_INT_PARM(i, 0); - TypedScriptVar(defaults, bag.Info, NAME_MorphStyle, TypeSInt32) = i; + defaults->IntVar(NAME_MorphStyle) = i; } //========================================================================== @@ -3008,7 +2972,7 @@ DEFINE_SCRIPTED_PROPERTY(morphstyle, M, PowerMorph) DEFINE_SCRIPTED_PROPERTY(morphflash, S, PowerMorph) { PROP_STRING_PARM(str, 0); - TypedScriptVar(defaults, bag.Info, NAME_MorphFlash, NewClassPointer(RUNTIME_CLASS(AActor))) = FindClassTentative(str, RUNTIME_CLASS(AActor), bag.fromDecorate); + defaults->PointerVar(NAME_MorphFlash) = FindClassTentative(str, RUNTIME_CLASS(AActor), bag.fromDecorate); } //========================================================================== @@ -3017,7 +2981,7 @@ DEFINE_SCRIPTED_PROPERTY(morphflash, S, PowerMorph) DEFINE_SCRIPTED_PROPERTY(unmorphflash, S, PowerMorph) { PROP_STRING_PARM(str, 0); - TypedScriptVar(defaults, bag.Info, NAME_UnMorphFlash, NewClassPointer(RUNTIME_CLASS(AActor))) = FindClassTentative(str, RUNTIME_CLASS(AActor), bag.fromDecorate); + defaults->PointerVar(NAME_UnMorphFlash) = FindClassTentative(str, RUNTIME_CLASS(AActor), bag.fromDecorate); } diff --git a/wadsrc/static/zscript/inventory/weaponpiece.txt b/wadsrc/static/zscript/inventory/weaponpiece.txt index bd729f4e88..af816aabc6 100644 --- a/wadsrc/static/zscript/inventory/weaponpiece.txt +++ b/wadsrc/static/zscript/inventory/weaponpiece.txt @@ -1,7 +1,42 @@ -class WeaponHolder : Inventory native +/* +** a_weaponpieces.cpp +** Implements generic weapon pieces +** +**--------------------------------------------------------------------------- +** Copyright 2006-2016 Cheistoph Oelckers +** Copyright 2006-2016 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +class WeaponHolder : Inventory { - native int PieceMask; - native Class PieceWeapon; + int PieceMask; + Class PieceWeapon; Default { @@ -11,16 +46,19 @@ class WeaponHolder : Inventory native } } -class WeaponPiece : Inventory native +class WeaponPiece : Inventory { Default { +WEAPONSPAWN; } - native int PieceValue; - native Class WeaponClass; - native Weapon FullWeapon; + int PieceValue; + Class WeaponClass; + Weapon FullWeapon; + + property number: PieceValue; + property weapon: WeaponClass; //========================================================================== // @@ -84,10 +122,11 @@ class WeaponPiece : Inventory native hold.PieceWeapon = WeaponClass; } + int pieceval = 1 << (PieceValue - 1); if (shouldStay) { // Cooperative net-game - if (hold.PieceMask & PieceValue) + if (hold.PieceMask & pieceval) { // Already has the piece return false; @@ -100,7 +139,7 @@ class WeaponPiece : Inventory native gaveAmmo = toucher.GiveAmmo (Defaults.AmmoType1, Defaults.AmmoGive1) + toucher.GiveAmmo (Defaults.AmmoType2, Defaults.AmmoGive2); - if (hold.PieceMask & PieceValue) + if (hold.PieceMask & pieceval) { // Already has the piece, check if mana needed if (!gaveAmmo) return false; @@ -109,7 +148,7 @@ class WeaponPiece : Inventory native } } - hold.PieceMask |= PieceValue; + hold.PieceMask |= pieceval; // Check if weapon assembled if (hold.PieceMask == (1 << Defaults.health) - 1)