diff --git a/src/b_bot.h b/src/b_bot.h index 285216f0c..f2cfdee81 100644 --- a/src/b_bot.h +++ b/src/b_bot.h @@ -50,7 +50,6 @@ #define MMAXSELECT 100 //Maximum number of monsters that can be selected at a time. struct FCheckPosition; -class AWeapon; struct botskill_t { @@ -100,7 +99,7 @@ using BotInfoMap = TMap; extern BotInfoMap BotInfo; -inline BotInfoData GetBotInfo(AWeapon *weap) +inline BotInfoData GetBotInfo(AInventory *weap) { if (weap == nullptr) return BotInfoData(); auto k = BotInfo.CheckKey(weap->GetClass()->TypeName); diff --git a/src/b_think.cpp b/src/b_think.cpp index 2099c9045..c335a3402 100644 --- a/src/b_think.cpp +++ b/src/b_think.cpp @@ -362,9 +362,9 @@ void DBot::WhatToGet (AActor *item) if (item->IsKindOf(NAME_Weapon)) { // FIXME - AWeapon *heldWeapon; + AInventory *heldWeapon; - heldWeapon = dyn_cast(player->mo->FindInventory(item->GetClass())); + heldWeapon = player->mo->FindInventory(item->GetClass()); if (heldWeapon != NULL) { if (!weapgiveammo) diff --git a/src/ct_chat.cpp b/src/ct_chat.cpp index 9f131ab8a..5f8a8e126 100644 --- a/src/ct_chat.cpp +++ b/src/ct_chat.cpp @@ -374,7 +374,7 @@ static void ShoveChatStr (const char *str, uint8_t who) static bool DoSubstitution (FString &out, const char *in) { player_t *player = &players[consoleplayer]; - AWeapon *weapon = player->ReadyWeapon; + auto weapon = player->ReadyWeapon; auto ammo1 = weapon ? weapon->PointerVar(NAME_Ammo1) : nullptr; auto ammo2 = weapon ? weapon->PointerVar(NAME_Ammo2) : nullptr; const char *a, *b; diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 92b3630cd..506e49ff2 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -761,8 +761,8 @@ void SetDehParams(FState *state, int codepointer) // Let's identify the codepointer we're dealing with. PFunction *sym; - sym = dyn_cast(RUNTIME_CLASS(AWeapon)->FindSymbol(FName(MBFCodePointers[codepointer].name), true)); - if (sym == NULL) return; + sym = dyn_cast(PClass::FindActor(NAME_Weapon)->FindSymbol(FName(MBFCodePointers[codepointer].name), true)); + if (sym == NULL ) return; if (codepointer < 0 || (unsigned)codepointer >= countof(MBFCodePointerFactories)) { @@ -1580,9 +1580,9 @@ static int PatchAmmo (int ammoNum) defaultAmmo->MaxAmount = *max; defaultAmmo->Amount = Scale (defaultAmmo->Amount, *per, oldclip); } - else if (type->IsDescendantOf (RUNTIME_CLASS(AWeapon))) + else if (type->IsDescendantOf (NAME_Weapon)) { - AWeapon *defWeap = (AWeapon *)GetDefaultByType (type); + auto defWeap = GetDefaultByType (type); if (defWeap->PointerVar(NAME_AmmoType1) == ammoType) { auto &AmmoGive1 = defWeap->IntVar(NAME_AmmoGive1); @@ -1603,9 +1603,8 @@ static int PatchAmmo (int ammoNum) static int PatchWeapon (int weapNum) { int result; - PClassActor *type = NULL; - uint8_t dummy[sizeof(AWeapon)]; - AWeapon *info = (AWeapon *)&dummy; + PClassActor *type = nullptr; + AInventory *info = nullptr; bool patchedStates = false; FStateDefinitions statedef; @@ -1614,7 +1613,7 @@ static int PatchWeapon (int weapNum) type = WeaponNames[weapNum]; if (type != NULL) { - info = (AWeapon *)GetDefaultByType (type); + info = (AInventory*)GetDefaultByType (type); DPrintf (DMSG_SPAMMY, "Weapon %d\n", weapNum); } } @@ -1657,15 +1656,18 @@ static int PatchWeapon (int weapNum) { val = 5; } - auto &AmmoType = info->PointerVar(NAME_AmmoType1); - AmmoType = AmmoNames[val]; - if (AmmoType != nullptr) + if (info) { - info->IntVar(NAME_AmmoGive1) = ((AInventory*)GetDefaultByType (AmmoType))->Amount * 2; - auto &AmmoUse = info->IntVar(NAME_AmmoUse1); - if (AmmoUse == 0) + auto &AmmoType = info->PointerVar(NAME_AmmoType1); + AmmoType = AmmoNames[val]; + if (AmmoType != nullptr) { - AmmoUse = 1; + info->IntVar(NAME_AmmoGive1) = ((AInventory*)GetDefaultByType(AmmoType))->Amount * 2; + auto &AmmoUse = info->IntVar(NAME_AmmoUse1); + if (AmmoUse == 0) + { + AmmoUse = 1; + } } } } @@ -1680,7 +1682,7 @@ static int PatchWeapon (int weapNum) const FDecalTemplate *decal = DecalLibrary.GetDecalByName (Line2); if (decal != NULL) { - info->DecalGenerator = const_cast (decal); + if (info) info->DecalGenerator = const_cast (decal); } else { @@ -1689,12 +1691,15 @@ static int PatchWeapon (int weapNum) } else if (stricmp (Line1, "Ammo use") == 0 || stricmp (Line1, "Ammo per shot") == 0) { - info->IntVar(NAME_AmmoUse1) = val; - info->flags6 |= MF6_INTRYMOVE; // flag the weapon for postprocessing (reuse a flag that can't be set by external means) + if (info) + { + info->IntVar(NAME_AmmoUse1) = val; + info->flags6 |= MF6_INTRYMOVE; // flag the weapon for postprocessing (reuse a flag that can't be set by external means) + } } else if (stricmp (Line1, "Min ammo") == 0) { - info->IntVar(NAME_MinSelAmmo1) = val; + if (info) info->IntVar(NAME_MinSelAmmo1) = val; } else { @@ -1702,14 +1707,17 @@ static int PatchWeapon (int weapNum) } } - if (info->PointerVar(NAME_AmmoType1) == nullptr) + if (info) { - info->IntVar(NAME_AmmoUse1) = 0; - } + if (info->PointerVar(NAME_AmmoType1) == nullptr) + { + info->IntVar(NAME_AmmoUse1) = 0; + } - if (patchedStates) - { - statedef.InstallStates(type, info); + if (patchedStates) + { + statedef.InstallStates(type, info); + } } return result; @@ -2121,7 +2129,7 @@ static int PatchCodePtrs (int dummy) // This skips the action table and goes directly to the internal symbol table // DEH compatible functions are easy to recognize. - PFunction *sym = dyn_cast(RUNTIME_CLASS(AWeapon)->FindSymbol(symname, true)); + PFunction *sym = dyn_cast(PClass::FindActor(NAME_Weapon)->FindSymbol(symname, true)); if (sym == NULL) { Printf(TEXTCOLOR_RED "Frame %d: Unknown code pointer '%s'\n", frame, Line2); @@ -2728,6 +2736,7 @@ static bool LoadDehSupp () sc.OpenLumpNum(lump); sc.SetCMode(true); + auto wcls = PClass::FindActor(NAME_Weapon); while (sc.GetString()) { if (sc.Compare("ActionList")) @@ -2742,11 +2751,11 @@ static bool LoadDehSupp () } else { - // all relevant code pointers are either defined in AWeapon - // or AActor so this will find all of them. + // all relevant code pointers are either defined in Weapon + // or Actor so this will find all of them. FString name = "A_"; name << sc.String; - PFunction *sym = dyn_cast(RUNTIME_CLASS(AWeapon)->FindSymbol(name, true)); + PFunction *sym = dyn_cast(wcls->FindSymbol(name, true)); if (sym == NULL) { sc.ScriptError("Unknown code pointer '%s'", sc.String); @@ -3088,9 +3097,10 @@ void FinishDehPatch () // Now it gets nasty: We have to fiddle around with the weapons' ammo use info to make Doom's original // ammo consumption work as intended. + auto wcls = PClass::FindActor(NAME_Weapon); for(unsigned i = 0; i < WeaponNames.Size(); i++) { - AWeapon *weap = (AWeapon*)GetDefaultByType(WeaponNames[i]); + AInventory *weap = (AInventory*)GetDefaultByType(WeaponNames[i]); bool found = false; if (weap->flags6 & MF6_INTRYMOVE) { @@ -3119,7 +3129,7 @@ void FinishDehPatch () { if (AmmoPerAttacks[j].ptr == nullptr) { - auto p = dyn_cast(RUNTIME_CLASS(AWeapon)->FindSymbol(AmmoPerAttacks[j].func, true)); + auto p = dyn_cast(wcls->FindSymbol(AmmoPerAttacks[j].func, true)); if (p != nullptr) AmmoPerAttacks[j].ptr = p->Variants[0].Implementation; } if (state->ActionFunc == AmmoPerAttacks[j].ptr) diff --git a/src/d_player.h b/src/d_player.h index 1008f837d..67c409ba3 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -97,8 +97,8 @@ public: bool ResetAirSupply (bool playgasp = true); int GetMaxHealth(bool withupgrades = false) const; - AWeapon *PickNewWeapon (PClassActor *ammotype); - AWeapon *BestWeapon (PClassActor *ammotype); + AInventory *PickNewWeapon (PClassActor *ammotype); + AInventory *BestWeapon (PClassActor *ammotype); void GiveDeathmatchInventory (); void GiveDefaultInventory (); @@ -231,7 +231,7 @@ enum // The VM cannot deal with this as an invalid pointer because it performs a read barrier on every object pointer read. // This doesn't have to point to a valid weapon, though, because WP_NOCHANGE is never dereferenced, but it must point to a valid object // and the class descriptor just works fine for that. -extern AWeapon *WP_NOCHANGE; +extern AInventory *WP_NOCHANGE; #define MAXPLAYERNAME 15 @@ -417,8 +417,8 @@ public: uint8_t spreecount = 0; // [RH] Keep track of killing sprees uint16_t WeaponState = 0; - AWeapon *ReadyWeapon = nullptr; - AWeapon *PendingWeapon = nullptr; // WP_NOCHANGE if not changing + AInventory *ReadyWeapon = nullptr; + AInventory *PendingWeapon = nullptr; // WP_NOCHANGE if not changing TObjPtr psprites = nullptr; // view sprites (gun, etc) int cheats = 0; // bit flags @@ -443,7 +443,7 @@ public: PClassActor *MorphedPlayerClass = nullptr; // [MH] (for SBARINFO) class # for this player instance when morphed int MorphStyle = 0; // which effects to apply for this player instance when morphed PClassActor *MorphExitFlash = nullptr; // flash to apply when demorphing (cache of value given to MorphPlayer) - TObjPtr PremorphWeapon = nullptr; // ready weapon before morphing + TObjPtr PremorphWeapon = nullptr; // ready weapon before morphing int chickenPeck = 0; // chicken peck countdown int jumpTics = 0; // delay the next jump for a moment bool onground = 0; // Identifies if this player is on the ground or other object diff --git a/src/dobject.h b/src/dobject.h index fb561e2c6..ff885d4ca 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -426,6 +426,8 @@ template T *dyn_cast(DObject *p) return NULL; } + + template const T *dyn_cast(const DObject *p) { return dyn_cast(const_cast(p)); diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index e3dfd232a..990382016 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -75,7 +75,7 @@ bool PClass::bVMOperational; // that does not work anymore. WP_NOCHANGE needs to point to a vaild object to work as intended. // This Object does not need to be garbage collected, though, but it needs to provide the proper structure so that the // GC can process it. -AWeapon *WP_NOCHANGE; +AInventory *WP_NOCHANGE; DEFINE_GLOBAL(WP_NOCHANGE); @@ -231,7 +231,7 @@ void PClass::StaticInit () // WP_NOCHANGE must point to a valid object, although it does not need to be a weapon. // A simple DObject is enough to give the GC the ability to deal with it, if subjected to it. - WP_NOCHANGE = (AWeapon*)Create(); + WP_NOCHANGE = (AInventory*)Create(); WP_NOCHANGE->Release(); } diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index c16896f31..b26f54d0e 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -2713,7 +2713,7 @@ void FParser::SF_PlayerSelectedWeapon() return; } - players[playernum].PendingWeapon = (AWeapon*)players[playernum].mo->FindInventory(ti); + players[playernum].PendingWeapon = (AInventory*)players[playernum].mo->FindInventory(ti); } t_return.type = svt_int; diff --git a/src/g_inventory/a_weapons.cpp b/src/g_inventory/a_weapons.cpp index 94e65a33c..0e2f1b6ab 100644 --- a/src/g_inventory/a_weapons.cpp +++ b/src/g_inventory/a_weapons.cpp @@ -47,45 +47,6 @@ #include "serializer.h" #include "vm.h" -IMPLEMENT_CLASS(AWeapon, false, true) - -IMPLEMENT_POINTERS_START(AWeapon) - IMPLEMENT_POINTER(Ammo1) - IMPLEMENT_POINTER(Ammo2) - IMPLEMENT_POINTER(SisterWeapon) -IMPLEMENT_POINTERS_END - -DEFINE_FIELD(AWeapon, AmmoType1) -DEFINE_FIELD(AWeapon, AmmoType2) -DEFINE_FIELD(AWeapon, AmmoGive1) -DEFINE_FIELD(AWeapon, AmmoGive2) -DEFINE_FIELD(AWeapon, MinAmmo1) -DEFINE_FIELD(AWeapon, MinAmmo2) -DEFINE_FIELD(AWeapon, AmmoUse1) -DEFINE_FIELD(AWeapon, AmmoUse2) -DEFINE_FIELD(AWeapon, Kickback) -DEFINE_FIELD(AWeapon, YAdjust) -DEFINE_FIELD(AWeapon, UpSound) -DEFINE_FIELD(AWeapon, ReadySound) -DEFINE_FIELD(AWeapon, SisterWeaponType) -DEFINE_FIELD(AWeapon, SelectionOrder) -DEFINE_FIELD(AWeapon, MinSelAmmo1) -DEFINE_FIELD(AWeapon, MinSelAmmo2) -DEFINE_FIELD(AWeapon, ReloadCounter) -DEFINE_FIELD(AWeapon, BobStyle) -DEFINE_FIELD(AWeapon, BobSpeed) -DEFINE_FIELD(AWeapon, BobRangeX) -DEFINE_FIELD(AWeapon, BobRangeY) -DEFINE_FIELD(AWeapon, Ammo1) -DEFINE_FIELD(AWeapon, Ammo2) -DEFINE_FIELD(AWeapon, SisterWeapon) -DEFINE_FIELD(AWeapon, FOVScale) -DEFINE_FIELD(AWeapon, Crosshair) -DEFINE_FIELD(AWeapon, GivenAsMorphWeapon) -DEFINE_FIELD(AWeapon, bAltFire) -DEFINE_FIELD(AWeapon, WeaponFlags) -DEFINE_FIELD(AWeapon, bDehAmmo) - //=========================================================================== // // @@ -101,50 +62,6 @@ TMap Weapons_hton; static int ntoh_cmp(const void *a, const void *b); -//=========================================================================== -// -// AWeapon :: Serialize -// -//=========================================================================== - -void AWeapon::Serialize(FSerializer &arc) -{ - Super::Serialize (arc); - auto def = (AWeapon*)GetDefault(); - arc("weaponflags", WeaponFlags, def->WeaponFlags) - ("ammogive1", AmmoGive1, def->AmmoGive1) - ("ammogive2", AmmoGive2, def->AmmoGive2) - ("minammo1", MinAmmo1, def->MinAmmo1) - ("minammo2", MinAmmo2, def->MinAmmo2) - ("ammouse1", AmmoUse1, def->AmmoUse1) - ("ammouse2", AmmoUse2, def->AmmoUse2) - ("kickback", Kickback, Kickback) - ("yadjust", YAdjust, def->YAdjust) - ("upsound", UpSound, def->UpSound) - ("readysound", ReadySound, def->ReadySound) - ("selectionorder", SelectionOrder, def->SelectionOrder) - ("ammo1", Ammo1) - ("ammo2", Ammo2) - ("sisterweapon", SisterWeapon) - ("givenasmorphweapon", GivenAsMorphWeapon, def->GivenAsMorphWeapon) - ("altfire", bAltFire, def->bAltFire) - ("reloadcounter", ReloadCounter, def->ReloadCounter) - ("bobstyle", BobStyle, def->BobStyle) - ("bobspeed", BobSpeed, def->BobSpeed) - ("bobrangex", BobRangeX, def->BobRangeX) - ("bobrangey", BobRangeY, def->BobRangeY) - ("fovscale", FOVScale, def->FOVScale) - ("crosshair", Crosshair, def->Crosshair) - ("minselammo1", MinSelAmmo1, def->MinSelAmmo1) - ("minselammo2", MinSelAmmo2, def->MinSelAmmo2); - /* these can never change - ("ammotype1", AmmoType1, def->AmmoType1) - ("ammotype2", AmmoType2, def->AmmoType2) - ("sisterweapontype", SisterWeaponType, def->SisterWeaponType) - */ - -} - /* Weapon slots ***********************************************************/ @@ -376,7 +293,7 @@ bool FWeaponSlots::LocateWeapon (PClassActor *type, int *const slot, int *const DEFINE_ACTION_FUNCTION(FWeaponSlots, LocateWeapon) { PARAM_SELF_STRUCT_PROLOGUE(FWeaponSlots); - PARAM_CLASS(weap, AWeapon); + PARAM_CLASS(weap, AInventory); int slot = 0, index = 0; bool retv = self->LocateWeapon(weap, &slot, &index); if (numret >= 1) ret[0].SetInt(retv); @@ -434,10 +351,10 @@ void FWeaponSlots::AddExtraWeapons() { continue; } - auto weapdef = ((AWeapon*)GetDefaultByType(cls)); + auto weapdef = ((AInventory*)GetDefaultByType(cls)); // Let the weapon decide for itself if it wants to get added to a slot. - IFVIRTUALPTR(weapdef, AWeapon, CheckAddToSlots) + IFVIRTUALPTRNAME(weapdef, NAME_Weapon, CheckAddToSlots) { VMValue param = weapdef; int slot = -1, slotpriority; diff --git a/src/g_inventory/a_weapons.h b/src/g_inventory/a_weapons.h index 8fb67f8d5..ac2c9f14d 100644 --- a/src/g_inventory/a_weapons.h +++ b/src/g_inventory/a_weapons.h @@ -2,7 +2,6 @@ #include "a_pickups.h" class PClassActor; -class AWeapon; class APlayerPawn; class FWeaponSlot @@ -128,40 +127,6 @@ void P_WriteDemoWeaponsChunk(uint8_t **demo); void P_ReadDemoWeaponsChunk(uint8_t **demo); -class AWeapon : public AStateProvider -{ - DECLARE_CLASS(AWeapon, AStateProvider) - HAS_OBJECT_POINTERS -public: - uint32_t WeaponFlags; - PClassActor *AmmoType1, *AmmoType2; // Types of ammo used by this weapon - int AmmoGive1, AmmoGive2; // Amount of each ammo to get when picking up weapon - int MinAmmo1, MinAmmo2; // Minimum ammo needed to switch to this weapon - int AmmoUse1, AmmoUse2; // How much ammo to use with each shot - int Kickback; - double YAdjust; // For viewing the weapon fullscreen (visual only so no need to be a double) - FSoundIDNoInit UpSound, ReadySound; // Sounds when coming up and idle - PClassActor *SisterWeaponType; // Another weapon to pick up with this one - int SelectionOrder; // Lower-numbered weapons get picked first - int MinSelAmmo1, MinSelAmmo2; // Ignore in BestWeapon() if inadequate ammo - int ReloadCounter; // For A_CheckForReload - int BobStyle; // [XA] Bobbing style. Defines type of bobbing (e.g. Normal, Alpha) (visual only so no need to be a double) - float BobSpeed; // [XA] Bobbing speed. Defines how quickly a weapon bobs. - float BobRangeX, BobRangeY; // [XA] Bobbing range. Defines how far a weapon bobs in either direction. - - // In-inventory instance variables - TObjPtr Ammo1, Ammo2; - TObjPtr SisterWeapon; - double FOVScale; - int Crosshair; // 0 to use player's crosshair - bool GivenAsMorphWeapon; - - bool bAltFire; - bool bDehAmmo; - - void Serialize(FSerializer &arc) override; -}; - enum class EBobStyle { BobNormal, diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 92b664baa..6f6ddf53d 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -507,7 +507,7 @@ static int DrawKeys(player_t * CPlayer, int x, int y) //--------------------------------------------------------------------------- static TArray orderedammos; -static void AddAmmoToList(AWeapon * weapdef) +static void AddAmmoToList(AInventory * weapdef) { for (int i = 0; i < 2; i++) @@ -570,7 +570,7 @@ static int DrawAmmo(player_t *CPlayer, int x, int y) char buf[256]; AInventory *inv; - AWeapon *wi=CPlayer->ReadyWeapon; + auto wi=CPlayer->ReadyWeapon; orderedammos.Clear(); @@ -593,7 +593,7 @@ static int DrawAmmo(player_t *CPlayer, int x, int y) if (hud_showammo > 1 || CPlayer->mo->FindInventory(weap)) { - AddAmmoToList((AWeapon*)GetDefaultByType(weap)); + AddAmmoToList((AInventory*)GetDefaultByType(weap)); } } } @@ -603,7 +603,7 @@ static int DrawAmmo(player_t *CPlayer, int x, int y) { if (inv->IsKindOf(NAME_Weapon)) { - AddAmmoToList((AWeapon*)inv); + AddAmmoToList(inv); } } } @@ -736,7 +736,7 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, GetInventoryIcon) return MIN(numret, 2); } -static void DrawOneWeapon(player_t * CPlayer, int x, int & y, AWeapon * weapon) +static void DrawOneWeapon(player_t * CPlayer, int x, int & y, AInventory * weapon) { double trans; @@ -776,9 +776,9 @@ static void DrawWeapons(player_t *CPlayer, int x, int y) for(inv = CPlayer->mo->Inventory; inv; inv = inv->Inventory) { if (inv->IsKindOf(NAME_Weapon) && - !CPlayer->weapons.LocateWeapon(static_cast(inv)->GetClass(), NULL, NULL)) + !CPlayer->weapons.LocateWeapon(inv->GetClass(), NULL, NULL)) { - DrawOneWeapon(CPlayer, x, y, static_cast(inv)); + DrawOneWeapon(CPlayer, x, y, inv); } } @@ -791,7 +791,7 @@ static void DrawWeapons(player_t *CPlayer, int x, int y) inv=CPlayer->mo->FindInventory(weap); if (inv) { - DrawOneWeapon(CPlayer, x, y, static_cast(inv)); + DrawOneWeapon(CPlayer, x, y, inv); } } } diff --git a/src/g_statusbar/sbar.h b/src/g_statusbar/sbar.h index 9f7bbb4cc..f38e06d6b 100644 --- a/src/g_statusbar/sbar.h +++ b/src/g_statusbar/sbar.h @@ -52,8 +52,6 @@ enum EHudState HUD_AltHud // Used for passing through popups to the alt hud }; -class AWeapon; - bool ST_IsTimeVisible(); bool ST_IsLatencyVisible(); diff --git a/src/g_statusbar/sbarinfo_commands.cpp b/src/g_statusbar/sbarinfo_commands.cpp index 2c94970f5..38373f328 100644 --- a/src/g_statusbar/sbarinfo_commands.cpp +++ b/src/g_statusbar/sbarinfo_commands.cpp @@ -2882,7 +2882,7 @@ class CommandIsSelected : public SBarInfoNegatableFlowControl if(weapon[i] == NULL || !weapon[i]->IsDescendantOf(NAME_Weapon)) { sc.ScriptMessage("'%s' is not a type of weapon.", sc.String); - weapon[i] = RUNTIME_CLASS(AWeapon); + weapon[i] = PClass::FindClass(NAME_Weapon); } if(sc.CheckToken(',')) @@ -3035,7 +3035,7 @@ class CommandHasWeaponPiece : public SBarInfoCommandFlowControl if (weapon == NULL || !weapon->IsDescendantOf(NAME_Weapon)) //must be a weapon { sc.ScriptMessage("%s is not a kind of weapon.", sc.String); - weapon = RUNTIME_CLASS(AWeapon); + weapon = PClass::FindClass(NAME_Weapon); } sc.MustGetToken(','); sc.MustGetToken(TK_IntConst); diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 2935605a2..f9c0f6783 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -480,7 +480,7 @@ void cht_DoCheat (player_t *player, int cheat) } else { - player->PendingWeapon = static_cast (item); + player->PendingWeapon = item; } } } diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index 3dea0a8a7..9d20b5bc5 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -1874,7 +1874,7 @@ enum SW_Flags DEFINE_ACTION_FUNCTION(AActor, A_SelectWeapon) { PARAM_SELF_PROLOGUE(AActor); - PARAM_CLASS(cls, AWeapon); + PARAM_CLASS(cls, AInventory); PARAM_INT(flags); bool selectPriority = !!(flags & SWF_SELECTPRIORITY); @@ -1884,7 +1884,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SelectWeapon) ACTION_RETURN_BOOL(false); } - AWeapon *weaponitem = static_cast(self->FindInventory(cls)); + auto weaponitem = self->FindInventory(cls); if (weaponitem != NULL && weaponitem->IsKindOf(NAME_Weapon)) { diff --git a/src/p_map.cpp b/src/p_map.cpp index e6b2e33c9..eeee54bc6 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4458,7 +4458,7 @@ DAngle P_AimLineAttack(AActor *t1, DAngle angle, double distance, FTranslatedLin else { // [BB] Disable autoaim on weapons with WIF_NOAUTOAIM. - AWeapon *weapon = t1->player->ReadyWeapon; + auto weapon = t1->player->ReadyWeapon; if ((weapon && (weapon->IntVar(NAME_WeaponFlags) & WIF_NOAUTOAIM)) && !(flags & ALF_NOWEAPONCHECK)) { vrange = 0.5; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 1fd612acf..4d5e34523 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -804,7 +804,7 @@ bool AActor::GiveInventory(PClassActor *type, int amount, bool givecheat) if (type == nullptr || !type->IsDescendantOf(RUNTIME_CLASS(AInventory))) return false; - AWeapon *savedPendingWeap = player != NULL ? player->PendingWeapon : NULL; + auto savedPendingWeap = player != NULL ? player->PendingWeapon : NULL; bool hadweap = player != NULL ? player->ReadyWeapon != NULL : true; AInventory *item; diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 82434f148..222ab9523 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -604,7 +604,7 @@ static void P_CheckWeaponButtons (player_t *player) { return; } - AWeapon *weapon = player->ReadyWeapon; + auto weapon = player->ReadyWeapon; if (weapon == nullptr) { return; @@ -1057,12 +1057,13 @@ void player_t::DestroyPSprites() // //------------------------------------------------------------------------------------ -void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int index) +void P_SetSafeFlash(AInventory *weapon, player_t *player, FState *flashstate, int index) { + auto wcls = PClass::FindActor(NAME_Weapon); if (flashstate != nullptr) { PClassActor *cls = weapon->GetClass(); - while (cls != RUNTIME_CLASS(AWeapon)) + while (cls != wcls) { if (cls->OwnsState(flashstate)) { @@ -1100,7 +1101,7 @@ void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int i DEFINE_ACTION_FUNCTION(_PlayerInfo, SetSafeFlash) { PARAM_SELF_STRUCT_PROLOGUE(player_t); - PARAM_OBJECT_NOT_NULL(weapon, AWeapon); + PARAM_OBJECT_NOT_NULL(weapon, AInventory); PARAM_POINTER(state, FState); PARAM_INT(index); P_SetSafeFlash(weapon, self, state, index); @@ -1147,8 +1148,8 @@ void DPSprite::OnDestroy() float DPSprite::GetYAdjust(bool fullscreen) { - AWeapon *weapon = dyn_cast(GetCaller()); - if (weapon != nullptr) + auto weapon = GetCaller(); + if (weapon != nullptr && weapon->IsKindOf(NAME_Weapon)) { auto fYAd = weapon->FloatVar(NAME_YAdjust); if (fYAd != 0) diff --git a/src/p_user.cpp b/src/p_user.cpp index 9a8463c9d..1a9ef4b1f 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1057,9 +1057,9 @@ bool APlayerPawn::UseInventory (AInventory *item) // //=========================================================================== -AWeapon *APlayerPawn::PickNewWeapon(PClassActor *ammotype) +AInventory *APlayerPawn::PickNewWeapon(PClassActor *ammotype) { - AWeapon *best = nullptr; + AInventory *best = nullptr; IFVM(PlayerPawn, DropWeapon) { VMValue param = player->mo; diff --git a/src/scripting/thingdef.cpp b/src/scripting/thingdef.cpp index 4ca9a2eb5..186f5275a 100644 --- a/src/scripting/thingdef.cpp +++ b/src/scripting/thingdef.cpp @@ -310,9 +310,10 @@ static void CheckForUnsafeStates(PClassActor *obj) TMap checked; ENamedName *test; - if (obj->IsDescendantOf(NAME_Weapon)) + auto cwtype = PClass::FindActor(NAME_Weapon); + if (obj->IsDescendantOf(cwtype)) { - if (obj->Size == RUNTIME_CLASS(AWeapon)->Size) return; // This class cannot have user variables. + if (obj->Size == cwtype->Size) return; // This class cannot have user variables. test = weaponstates; } else diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 575a689c3..a4dfbc16c 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -442,17 +442,6 @@ static FFlagDef InventoryFlagDefs[] = DEFINE_DEPRECATED_FLAG(INTERHUBSTRIP), }; -static FFlagDef WeaponFlagDefs[] = -{ - // Weapon flags - DEFINE_DUMMY_FLAG(NOLMS, false), - DEFINE_DUMMY_FLAG(ALLOW_WITH_RESPAWN_INVUL, false), - DEFINE_DUMMY_FLAG(BFG, false), - DEFINE_DUMMY_FLAG(EXPLOSIVE, false), -}; - - - static FFlagDef PlayerPawnFlagDefs[] = { // PlayerPawn flags @@ -485,7 +474,6 @@ static const struct FFlagList { const PClass * const *Type; FFlagDef *Defs; int { &RUNTIME_CLASS_CASTLESS(AActor), MoreFlagDefs, countof(MoreFlagDefs), 1 }, { &RUNTIME_CLASS_CASTLESS(AActor), InternalActorFlagDefs, countof(InternalActorFlagDefs), 2 }, { &RUNTIME_CLASS_CASTLESS(AInventory), InventoryFlagDefs, countof(InventoryFlagDefs), 3 }, - { &RUNTIME_CLASS_CASTLESS(AWeapon), WeaponFlagDefs, countof(WeaponFlagDefs), 3 }, { &RUNTIME_CLASS_CASTLESS(APlayerPawn), PlayerPawnFlagDefs, countof(PlayerPawnFlagDefs), 3 }, { &RUNTIME_CLASS_CASTLESS(ADynamicLight),DynLightFlagDefs, countof(DynLightFlagDefs), 3 }, }; @@ -542,8 +530,8 @@ FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2, bo { forInternalFlags.fieldsize = 4; forInternalFlags.name = ""; - forInternalFlags.flagbit = 1 << field->bitval; - forInternalFlags.structoffset = field->Offset->Offset; + forInternalFlags.flagbit = field->bitval >= 0? 1 << field->bitval : DEPF_UNUSED; + forInternalFlags.structoffset = field->bitval >= 0 ? field->Offset->Offset : -1; forInternalFlags.varflags = 0; return &forInternalFlags; } @@ -560,8 +548,8 @@ FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2, bo { forInternalFlags.fieldsize = 4; forInternalFlags.name = ""; - forInternalFlags.flagbit = 1 << field->bitval; - forInternalFlags.structoffset = field->Offset->Offset; + forInternalFlags.flagbit = field->bitval >= 0 ? 1 << field->bitval : DEPF_UNUSED; + forInternalFlags.structoffset = field->bitval >= 0 ? field->Offset->Offset : -1; forInternalFlags.varflags = 0; return &forInternalFlags; } @@ -994,17 +982,6 @@ void InitThingdef() void SynthesizeFlagFields() { - // These are needed for inserting the flag symbols - /* - NewClassType(RUNTIME_CLASS(DObject)); - NewClassType(RUNTIME_CLASS(DThinker)); - NewClassType(RUNTIME_CLASS(AActor)); - NewClassType(RUNTIME_CLASS(AInventory)); - NewClassType(RUNTIME_CLASS(AStateProvider)); - NewClassType(RUNTIME_CLASS(AWeapon)); - NewClassType(RUNTIME_CLASS(APlayerPawn)); - NewClassType(RUNTIME_CLASS(ADynamicLight)); - */ // synthesize a symbol for each flag from the flag name tables to avoid redundant declaration of them. for (auto &fl : FlagLists) { diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index 0c5f836b8..4db78bdf1 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -1179,7 +1179,7 @@ DEFINE_CLASS_PROPERTY(pickupannouncerentry, S, Inventory) //========================================================================== // //========================================================================== -DEFINE_CLASS_PROPERTY(defaultkickback, 0, Weapon) +DEFINE_SCRIPTED_PROPERTY(defaultkickback, 0, Weapon) { defaults->IntVar(NAME_Kickback) = gameinfo.defKickback; } @@ -1187,7 +1187,7 @@ DEFINE_CLASS_PROPERTY(defaultkickback, 0, Weapon) //========================================================================== // //========================================================================== -DEFINE_CLASS_PROPERTY(bobstyle, S, Weapon) +DEFINE_SCRIPTED_PROPERTY(bobstyle, S, Weapon) { static const char *names[] = { "Normal", "Inverse", "Alpha", "InverseAlpha", "Smooth", "InverseSmooth", NULL }; static const EBobStyle styles[] = { EBobStyle::BobNormal, @@ -1206,7 +1206,7 @@ DEFINE_CLASS_PROPERTY(bobstyle, S, Weapon) //========================================================================== // //========================================================================== -DEFINE_CLASS_PROPERTY(preferredskin, S, Weapon) +DEFINE_SCRIPTED_PROPERTY(preferredskin, S, Weapon) { PROP_STRING_PARM(str, 0); // NoOp - only for Skulltag compatibility diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index ae36d3589..512a2f801 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -1498,7 +1498,8 @@ bool ZCCCompiler::CompileFlagDefs(PClass *type, TArray &Propertie } } - type->VMType->AddNativeField(FStringf("b%s", name.GetChars()), TypeSInt32, field->Offset, 0, 1 << p->BitValue); + if (p->BitValue >= 0) + type->VMType->AddNativeField(FStringf("b%s", name.GetChars()), TypeSInt32, field->Offset, 0, 1 << p->BitValue); } } return true; diff --git a/src/version.h b/src/version.h index 61c6ceff8..de314043b 100644 --- a/src/version.h +++ b/src/version.h @@ -87,11 +87,11 @@ const char *GetVersionString(); #define SAVEGAME_EXT "zds" // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 4551 +#define MINSAVEVER 4553 // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4552 +#define SAVEVER 4553 // This is so that derivates can use the same savegame versions without worrying about engine compatibility #define GAMESIG "GZDOOM" diff --git a/wadsrc/static/zscript/inventory/weapons.txt b/wadsrc/static/zscript/inventory/weapons.txt index 58b2a071d..eabe72292 100644 --- a/wadsrc/static/zscript/inventory/weapons.txt +++ b/wadsrc/static/zscript/inventory/weapons.txt @@ -1,4 +1,4 @@ -class Weapon : StateProvider native +class Weapon : StateProvider { enum EFireMode { @@ -10,29 +10,29 @@ class Weapon : StateProvider native const ZOOM_INSTANT = 1; const ZOOM_NOSCALETURNING = 2; - deprecated("3.7") native uint WeaponFlags; // not to be used directly. - native class AmmoType1, AmmoType2; // Types of ammo used by self weapon - native int AmmoGive1, AmmoGive2; // Amount of each ammo to get when picking up weapon - deprecated("3.7") native int MinAmmo1, MinAmmo2; // not used anywhere and thus deprecated. - native int AmmoUse1, AmmoUse2; // How much ammo to use with each shot - native int Kickback; - native double YAdjust; // For viewing the weapon fullscreen - native sound UpSound, ReadySound; // Sounds when coming up and idle - native class SisterWeaponType; // Another weapon to pick up with self one - native int SelectionOrder; // Lower-numbered weapons get picked first - native int MinSelAmmo1, MinSelAmmo2; // Ignore in BestWeapon() if inadequate ammo - native int ReloadCounter; // For A_CheckForReload - native int BobStyle; // [XA] Bobbing style. Defines type of bobbing (e.g. Normal, Alpha) (visual only so no need to be a double) - native float BobSpeed; // [XA] Bobbing speed. Defines how quickly a weapon bobs. - native float BobRangeX, BobRangeY; // [XA] Bobbing range. Defines how far a weapon bobs in either direction. - native Ammo Ammo1, Ammo2; // In-inventory instance variables - native Weapon SisterWeapon; - native double FOVScale; - native int Crosshair; // 0 to use player's crosshair - native bool GivenAsMorphWeapon; - native bool bAltFire; // Set when this weapon's alternate fire is used. - native readonly bool bDehAmmo; // Uses Doom's original amount of ammo for the respective attack functions so that old DEHACKED patches work as intended. - // AmmoUse1 will be set to the first attack's ammo use so that checking for empty weapons still works + deprecated("3.7") uint WeaponFlags; // not to be used directly. + class AmmoType1, AmmoType2; // Types of ammo used by self weapon + int AmmoGive1, AmmoGive2; // Amount of each ammo to get when picking up weapon + deprecated("3.7") int MinAmmo1, MinAmmo2; // not used anywhere and thus deprecated. + int AmmoUse1, AmmoUse2; // How much ammo to use with each shot + int Kickback; + double YAdjust; // For viewing the weapon fullscreen + sound UpSound, ReadySound; // Sounds when coming up and idle + class SisterWeaponType; // Another weapon to pick up with self one + int SelectionOrder; // Lower-numbered weapons get picked first + int MinSelAmmo1, MinSelAmmo2; // Ignore in BestWeapon() if inadequate ammo + int ReloadCounter; // For A_CheckForReload + int BobStyle; // [XA] Bobbing style. Defines type of bobbing (e.g. Normal, Alpha) (visual only so no need to be a double) + float BobSpeed; // [XA] Bobbing speed. Defines how quickly a weapon bobs. + float BobRangeX, BobRangeY; // [XA] Bobbing range. Defines how far a weapon bobs in either direction. + Ammo Ammo1, Ammo2; // In-inventory instance variables + Weapon SisterWeapon; + double FOVScale; + int Crosshair; // 0 to use player's crosshair + bool GivenAsMorphWeapon; + bool bAltFire; // Set when this weapon's alternate fire is used. + readonly bool bDehAmmo; // Uses Doom's original amount of ammo for the respective attack functions so that old DEHACKED patches work as intended. + // AmmoUse1 will be set to the first attack's ammo use so that checking for empty weapons still works meta int SlotNumber; meta int SlotPriority; @@ -79,6 +79,12 @@ class Weapon : StateProvider native flagdef NoDeathInput: WeaponFlags, 17; // The weapon cannot be fired/reloaded/whatever when the player is dead flagdef CheatNotWeapon: WeaponFlags, 18; // Give cheat considers this not a weapon (used by Sigil) + // no-op flags + flagdef NoLMS: WeaponFlags, -1; + flagdef Allow_With_Respawn_Invul: WeaponFlags, -1; + flagdef BFG: WeaponFlags, -1; + flagdef Explosive: WeaponFlags, -1; + Default { Inventory.PickupSound "misc/w_pkup"; @@ -100,7 +106,7 @@ class Weapon : StateProvider native //=========================================================================== // - // AWeapon :: MarkPrecacheSounds + // Weapon :: MarkPrecacheSounds // //=========================================================================== @@ -856,7 +862,7 @@ class Weapon : StateProvider native //=========================================================================== // - // AWeapon :: CheckAmmo + // Weapon :: CheckAmmo // // Returns true if there is enough ammo to shoot. If not, selects the // next weapon to use. @@ -934,7 +940,7 @@ class Weapon : StateProvider native //=========================================================================== // - // AWeapon :: DepleteAmmo + // Weapon :: DepleteAmmo // // Use up some of the weapon's ammo. Returns true if the ammo was successfully // depleted. If checkEnough is false, then the ammo will always be depleted,