From a6785afddbd8d9891e10cbbfbf8a1e2405094020 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 8 Feb 2017 15:47:22 +0100 Subject: [PATCH] - optimized the FName versions of IsDescendantOf and IsKindOf. These can be done without first looking up the class type itself. --- src/am_map.cpp | 2 +- src/b_bot.cpp | 2 +- src/b_think.cpp | 2 +- src/c_cmds.cpp | 2 +- src/d_dehacked.cpp | 4 +-- src/dobject.h | 6 ++++ src/dobjtype.h | 13 +++++++ src/fragglescript/t_func.cpp | 12 +++---- src/g_inventory/a_keys.cpp | 2 +- src/g_inventory/a_weapons.cpp | 12 +++---- src/g_shared/a_morph.cpp | 2 +- src/g_shared/shared_hud.cpp | 6 ++-- src/g_statusbar/sbarinfo_commands.cpp | 38 ++++++++++----------- src/gl/dynlights/gl_dynlight.cpp | 2 +- src/info.cpp | 2 +- src/m_cheat.cpp | 4 +-- src/p_acs.cpp | 6 ++-- src/p_actionfunctions.cpp | 6 ++-- src/p_conversation.cpp | 4 +-- src/p_enemy.cpp | 4 +-- src/p_mobj.cpp | 4 +-- src/p_pspr.cpp | 6 ++-- src/p_user.cpp | 24 ++++++------- src/portal.cpp | 2 +- src/scripting/thingdef.cpp | 6 ++-- src/scripting/thingdef_properties.cpp | 12 +++---- src/zstring.h | 10 ++++++ wadsrc/static/zscript/inventory/weapons.txt | 28 +++++++-------- 28 files changed, 126 insertions(+), 97 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index be92fd37ab..57eccc19d2 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -2857,7 +2857,7 @@ void AM_drawThings () // Find the key's own color. // Only works correctly if single-key locks have lower numbers than any-key locks. // That is the case for all default keys, however. - if (t->IsKindOf(PClass::FindActor(NAME_Key))) + if (t->IsKindOf(NAME_Key)) { if (G_SkillProperty(SKILLP_EasyKey)) { diff --git a/src/b_bot.cpp b/src/b_bot.cpp index 54d154a3e0..637494333c 100644 --- a/src/b_bot.cpp +++ b/src/b_bot.cpp @@ -263,7 +263,7 @@ void InitBotStuff() for(unsigned i=0;iIsDescendantOf(RUNTIME_CLASS(AWeapon))) + if (cls != NULL && cls->IsDescendantOf(NAME_Weapon)) { AWeapon *w = (AWeapon*)GetDefaultByType(cls); if (w != NULL) diff --git a/src/b_think.cpp b/src/b_think.cpp index 7ce276aa00..da3fb61246 100644 --- a/src/b_think.cpp +++ b/src/b_think.cpp @@ -328,7 +328,7 @@ void DBot::WhatToGet (AActor *item) //if(pos && !bglobal.thingvis[pos->id][item->id]) continue; // if (item->IsKindOf (RUNTIME_CLASS(AArtifact))) // return; // don't know how to use artifacts - if (item->IsKindOf (RUNTIME_CLASS(AWeapon))) + if (item->IsKindOf(NAME_Weapon)) { // FIXME AWeapon *heldWeapon; diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 7428fceea2..e8f9509e56 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -1210,7 +1210,7 @@ static void PrintSecretString(const char *string, bool thislevel) { while ((actor = it.Next())) { - if (!actor->IsKindOf(PClass::FindClass("SecretTrigger"))) continue; + if (!actor->IsKindOf("SecretTrigger")) continue; foundone = true; break; } diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 7ad5e63443..c30fc64aec 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -2916,7 +2916,7 @@ static bool LoadDehSupp () else { auto cls = PClass::FindActor(sc.String); - if (cls == NULL || !cls->IsDescendantOf(PClass::FindActor(NAME_Ammo))) + if (cls == NULL || !cls->IsDescendantOf(NAME_Ammo)) { sc.ScriptError("Unknown ammo type '%s'", sc.String); } @@ -2934,7 +2934,7 @@ static bool LoadDehSupp () { sc.MustGetString(); PClass *cls = PClass::FindClass(sc.String); - if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(AWeapon))) + if (cls == NULL || !cls->IsDescendantOf(NAME_Weapon)) { sc.ScriptError("Unknown weapon type '%s'", sc.String); } diff --git a/src/dobject.h b/src/dobject.h index 82051e3bd7..f3c2904430 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -458,6 +458,7 @@ public: virtual ~DObject (); inline bool IsKindOf (const PClass *base) const; + inline bool IsKindOf(FName base) const; inline bool IsA (const PClass *type) const; void SerializeUserVars(FSerializer &arc); @@ -615,6 +616,11 @@ inline bool DObject::IsKindOf (const PClass *base) const return base->IsAncestorOf (GetClass ()); } +inline bool DObject::IsKindOf(FName base) const +{ + return GetClass()->IsDescendantOf(base); +} + inline bool DObject::IsA (const PClass *type) const { return (type == GetClass()); diff --git a/src/dobjtype.h b/src/dobjtype.h index 6c07b047bc..42280a12b5 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -622,11 +622,24 @@ public: } return false; } + inline bool IsDescendantOf(const PClass *ti) const { return ti->IsAncestorOf(this); } + inline bool IsDescendantOf(FName ti) const + { + auto me = this; + while (me) + { + if (me->TypeName == ti) + return true; + me = me->ParentClass; + } + return false; + } + // Find a type, given its name. const PClass *FindParentClass(FName name) const; PClass *FindParentClass(FName name) { return const_cast(const_cast(this)->FindParentClass(name)); } diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 0ee391e215..e8cde02224 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -2629,7 +2629,7 @@ void FParser::SF_MaxPlayerAmmo() for (AInventory *item = players[playernum].mo->Inventory; item != NULL; item = item->Inventory) { - if (item->IsKindOf(PClass::FindClass(NAME_BackpackItem))) + if (item->IsKindOf(NAME_BackpackItem)) { if (t_argc>=4) amount = intvalue(t_argv[3]); else amount*=2; @@ -2676,7 +2676,7 @@ void FParser::SF_PlayerWeapon() return; } auto ti = PClass::FindActor(WeaponNames[weaponnum]); - if (!ti || !ti->IsDescendantOf(RUNTIME_CLASS(AWeapon))) + if (!ti || !ti->IsDescendantOf(NAME_Weapon)) { script_error("incompatibility in playerweapon %d\n", weaponnum); return; @@ -2712,7 +2712,7 @@ void FParser::SF_PlayerWeapon() { if (!wp) { - AWeapon * pw=players[playernum].PendingWeapon; + auto pw=players[playernum].PendingWeapon; players[playernum].mo->GiveInventoryType(ti); players[playernum].PendingWeapon=pw; } @@ -2757,7 +2757,7 @@ void FParser::SF_PlayerSelectedWeapon() return; } auto ti = PClass::FindActor(WeaponNames[weaponnum]); - if (!ti || !ti->IsDescendantOf(RUNTIME_CLASS(AWeapon))) + if (!ti || !ti->IsDescendantOf(NAME_Weapon)) { script_error("incompatibility in playerweapon %d\n", weaponnum); return; @@ -2862,7 +2862,7 @@ void FParser::SF_SetWeapon() { AInventory *item = players[playernum].mo->FindInventory (PClass::FindActor (stringvalue(t_argv[1]))); - if (item == NULL || !item->IsKindOf (RUNTIME_CLASS(AWeapon))) + if (item == NULL || !item->IsKindOf(NAME_Weapon)) { } else if (players[playernum].ReadyWeapon == item) @@ -2874,7 +2874,7 @@ void FParser::SF_SetWeapon() } else { - AWeapon *weap = static_cast (item); + auto weap = static_cast (item); if (weap->CheckAmmo (AWeapon::EitherFire, false)) { diff --git a/src/g_inventory/a_keys.cpp b/src/g_inventory/a_keys.cpp index 0ad6b72f13..75d98c2c7d 100644 --- a/src/g_inventory/a_keys.cpp +++ b/src/g_inventory/a_keys.cpp @@ -187,7 +187,7 @@ static void AddOneKey(Keygroup *keygroup, PClassActor *mi, FScanner &sc) keygroup->anykeylist.Push (k); //... but only keys get key numbers! - if (mi->IsDescendantOf(PClass::FindActor(NAME_Key))) + if (mi->IsDescendantOf(NAME_Key)) { if (!ignorekey && GetDefaultByType(mi)->special1 == 0) diff --git a/src/g_inventory/a_weapons.cpp b/src/g_inventory/a_weapons.cpp index a916531be6..8882590985 100644 --- a/src/g_inventory/a_weapons.cpp +++ b/src/g_inventory/a_weapons.cpp @@ -528,7 +528,7 @@ bool FWeaponSlot::AddWeapon(PClassActor *type) return false; } - if (!type->IsDescendantOf(RUNTIME_CLASS(AWeapon))) + if (!type->IsDescendantOf(NAME_Weapon)) { Printf("Can't add non-weapon %s to weapon slots\n", type->TypeName.GetChars()); return false; @@ -635,7 +635,7 @@ AWeapon *FWeaponSlot::PickWeapon(player_t *player, bool checkammo) { AWeapon *weap = static_cast (player->mo->FindInventory(Weapons[j].Type)); - if (weap != nullptr && weap->IsKindOf(RUNTIME_CLASS(AWeapon))) + if (weap != nullptr && weap->IsKindOf(NAME_Weapon)) { if (!checkammo || weap->CheckAmmo(AWeapon::EitherFire, false)) { @@ -650,7 +650,7 @@ AWeapon *FWeaponSlot::PickWeapon(player_t *player, bool checkammo) { AWeapon *weap = static_cast (player->mo->FindInventory(Weapons[i].Type)); - if (weap != nullptr && weap->IsKindOf(RUNTIME_CLASS(AWeapon))) + if (weap != nullptr && weap->IsKindOf(NAME_Weapon)) { if (!checkammo || weap->CheckAmmo(AWeapon::EitherFire, false)) { @@ -982,7 +982,7 @@ void FWeaponSlots::AddExtraWeapons() { PClassActor *cls = PClassActor::AllActorClasses[i]; - if (!cls->IsDescendantOf(RUNTIME_CLASS(AWeapon))) + if (!cls->IsDescendantOf(NAME_Weapon)) { continue; } @@ -1342,7 +1342,7 @@ CCMD (weaponsection) //=========================================================================== void FWeaponSlots::AddSlotDefault(int slot, PClassActor *type, bool feedback) { - if (type != nullptr && type->IsDescendantOf(RUNTIME_CLASS(AWeapon))) + if (type != nullptr && type->IsDescendantOf(NAME_Weapon)) { switch (AddDefaultWeapon(slot, type)) { @@ -1441,7 +1441,7 @@ void P_SetupWeapons_ntohton() { PClassActor *cls = PClassActor::AllActorClasses[i]; - if (cls->IsDescendantOf(RUNTIME_CLASS(AWeapon))) + if (cls->IsDescendantOf(NAME_Weapon)) { Weapons_ntoh.Push(static_cast(cls)); } diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index 0c95c77b8e..cd72bca796 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -337,7 +337,7 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, if (correctweapon) { // Better "lose morphed weapon" semantics PClassActor *morphweapon = PClass::FindActor(pmo->MorphWeapon); - if (morphweapon != nullptr && morphweapon->IsDescendantOf(RUNTIME_CLASS(AWeapon))) + if (morphweapon != nullptr && morphweapon->IsDescendantOf(NAME_Weapon)) { AWeapon *OriginalMorphWeapon = static_cast(mo->FindInventory (morphweapon)); if ((OriginalMorphWeapon != nullptr) && (OriginalMorphWeapon->GivenAsMorphWeapon)) diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 4ab0c81338..79c51350b7 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -612,7 +612,7 @@ static int DrawAmmo(player_t *CPlayer, int x, int y) // Now check for the remaining weapons that are in the inventory but not in the weapon slots for(inv=CPlayer->mo->Inventory;inv;inv=inv->Inventory) { - if (inv->IsKindOf(RUNTIME_CLASS(AWeapon))) + if (inv->IsKindOf(NAME_Weapon)) { AddAmmoToList((AWeapon*)inv); } @@ -713,7 +713,7 @@ FTextureID GetInventoryIcon(AInventory *item, DWORD flags, bool *applyscale=NULL } } // no spawn state - now try the ready state if it's weapon - else if (!(flags & DI_SKIPREADY) && item->GetClass()->IsDescendantOf(RUNTIME_CLASS(AWeapon)) && (ReadyState = item->FindState(NAME_Ready)) && ReadyState->sprite!=0) + else if (!(flags & DI_SKIPREADY) && item->GetClass()->IsDescendantOf(NAME_Weapon) && (ReadyState = item->FindState(NAME_Ready)) && ReadyState->sprite!=0) { state = ReadyState; } @@ -767,7 +767,7 @@ static void DrawWeapons(player_t *CPlayer, int x, int y) // First draw all weapons in the inventory that are not assigned to a weapon slot for(inv = CPlayer->mo->Inventory; inv; inv = inv->Inventory) { - if (inv->IsKindOf(RUNTIME_CLASS(AWeapon)) && + if (inv->IsKindOf(NAME_Weapon) && !CPlayer->weapons.LocateWeapon(static_cast(inv)->GetClass(), NULL, NULL)) { DrawOneWeapon(CPlayer, x, y, static_cast(inv)); diff --git a/src/g_statusbar/sbarinfo_commands.cpp b/src/g_statusbar/sbarinfo_commands.cpp index c3950571f1..6e6b55bec6 100644 --- a/src/g_statusbar/sbarinfo_commands.cpp +++ b/src/g_statusbar/sbarinfo_commands.cpp @@ -148,7 +148,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl { type = INVENTORYICON; const PClass* item = PClass::FindClass(sc.String); - if(item == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(item)) //must be a kind of Inventory + if(item == NULL || !item->IsDescendantOf(NAME_Inventory)) //must be a kind of Inventory { sc.ScriptMessage("'%s' is not a type of inventory item.", sc.String); } @@ -418,7 +418,7 @@ class CommandDrawSwitchableImage : public CommandDrawImage for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i) { PClassActor *cls = PClassActor::AllActorClasses[i]; - if (cls->IsDescendantOf(PClass::FindActor(NAME_Key))) + if (cls->IsDescendantOf(NAME_Key)) { auto key = GetDefaultByType(cls); if (key->special1 == keynum) @@ -471,7 +471,7 @@ class CommandDrawSwitchableImage : public CommandDrawImage { inventoryItem[0] = sc.String; const PClass* item = PClass::FindClass(sc.String); - if(item == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(item)) //must be a kind of Inventory + if(item == NULL || !item->IsDescendantOf(NAME_Inventory)) //must be a kind of Inventory { sc.ScriptMessage("'%s' is not a type of inventory item.", sc.String); } @@ -498,7 +498,7 @@ class CommandDrawSwitchableImage : public CommandDrawImage sc.MustGetToken(TK_Identifier); inventoryItem[1] = sc.String; const PClass* item = PClass::FindClass(sc.String); - if(item == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(item)) //must be a kind of Inventory + if(item == NULL || !item->IsDescendantOf(NAME_Inventory)) //must be a kind of Inventory { sc.ScriptMessage("'%s' is not a type of inventory item.", sc.String); } @@ -556,7 +556,7 @@ class CommandDrawSwitchableImage : public CommandDrawImage for(AInventory *item = statusBar->CPlayer->mo->Inventory;item != NULL;item = item->Inventory) { - if(item->IsKindOf(PClass::FindActor(NAME_Key))) + if(item->IsKindOf(NAME_Key)) { int keynum = item->special1; if(keynum) @@ -1078,7 +1078,7 @@ class CommandDrawNumber : public CommandDrawString if(!parenthesized || !sc.CheckToken(TK_StringConst)) sc.MustGetToken(TK_Identifier); inventoryItem = PClass::FindActor(sc.String); - if(inventoryItem == NULL || !PClass::FindActor(NAME_Ammo)->IsAncestorOf(inventoryItem)) //must be a kind of ammo + if(inventoryItem == NULL || !inventoryItem->IsDescendantOf(NAME_Ammo)) //must be a kind of ammo { sc.ScriptMessage("'%s' is not a type of ammo.", sc.String); inventoryItem = PClass::FindActor(NAME_Ammo); @@ -1094,7 +1094,7 @@ class CommandDrawNumber : public CommandDrawString if(!parenthesized || !sc.CheckToken(TK_StringConst)) sc.MustGetToken(TK_Identifier); inventoryItem = PClass::FindActor(sc.String); - if(inventoryItem == NULL || !PClass::FindActor(NAME_Ammo)->IsAncestorOf(inventoryItem)) //must be a kind of ammo + if (inventoryItem == NULL || !inventoryItem->IsDescendantOf(NAME_Ammo)) //must be a kind of ammo { sc.ScriptMessage("'%s' is not a type of ammo.", sc.String); inventoryItem = PClass::FindActor(NAME_Ammo); @@ -1160,7 +1160,7 @@ class CommandDrawNumber : public CommandDrawString if(!parenthesized || !sc.CheckToken(TK_StringConst)) sc.MustGetToken(TK_Identifier); inventoryItem = PClass::FindActor(sc.String); - if(inventoryItem == NULL || !PClass::FindActor(NAME_PowerupGiver)->IsAncestorOf(inventoryItem)) + if (inventoryItem == NULL || !inventoryItem->IsDescendantOf(NAME_PowerupGiver)) { sc.ScriptMessage("'%s' is not a type of PowerupGiver.", sc.String); inventoryItem = PClass::FindActor(NAME_PowerupGiver); @@ -1203,7 +1203,7 @@ class CommandDrawNumber : public CommandDrawString if(value == INVENTORY) { inventoryItem = PClass::FindActor(sc.String); - if(inventoryItem == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(inventoryItem)) //must be a kind of ammo + if (inventoryItem == NULL || !inventoryItem->IsDescendantOf(NAME_Inventory)) { sc.ScriptMessage("'%s' is not a type of inventory item.", sc.String); inventoryItem = RUNTIME_CLASS(AInventory); @@ -1476,7 +1476,7 @@ class CommandDrawNumber : public CommandDrawString num = 0; for(AInventory *item = statusBar->CPlayer->mo->Inventory;item != NULL;item = item->Inventory) { - if(item->IsKindOf(PClass::FindActor(NAME_Key))) + if(item->IsKindOf(NAME_Key)) num++; } break; @@ -2431,7 +2431,7 @@ class CommandDrawKeyBar : public SBarInfoCommand int rowWidth = 0; for(unsigned int i = 0;i < number+keyOffset;i++) { - while(!item->Icon.isValid() || !item->IsKindOf(PClass::FindActor(NAME_Key))) + while(!item->Icon.isValid() || !item->IsKindOf(NAME_Key)) { item = item->Inventory; if(item == NULL) @@ -2632,7 +2632,7 @@ class CommandDrawBar : public SBarInfoCommand sc.MustGetToken(TK_Identifier); type = AMMO; data.inventoryItem = PClass::FindActor(sc.String); - if(data.inventoryItem == NULL || !PClass::FindActor(NAME_Ammo)->IsAncestorOf(data.inventoryItem)) //must be a kind of ammo + if (data.inventoryItem == NULL || !data.inventoryItem->IsDescendantOf(NAME_Ammo)) //must be a kind of ammo { sc.ScriptMessage("'%s' is not a type of ammo.", sc.String); data.inventoryItem = PClass::FindActor(NAME_Ammo); @@ -2660,7 +2660,7 @@ class CommandDrawBar : public SBarInfoCommand if(!parenthesized || !sc.CheckToken(TK_StringConst)) sc.MustGetToken(TK_Identifier); data.inventoryItem = PClass::FindActor(sc.String); - if(data.inventoryItem == NULL || !PClass::FindActor(NAME_PowerupGiver)->IsAncestorOf(data.inventoryItem)) + if(data.inventoryItem == NULL || !data.inventoryItem->IsDescendantOf(NAME_PowerupGiver)) { sc.ScriptMessage("'%s' is not a type of PowerupGiver.", sc.String); data.inventoryItem = PClass::FindActor(NAME_PowerupGiver); @@ -2672,7 +2672,7 @@ class CommandDrawBar : public SBarInfoCommand { type = INVENTORY; data.inventoryItem = PClass::FindActor(sc.String); - if(data.inventoryItem == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(data.inventoryItem)) + if(data.inventoryItem == NULL || !data.inventoryItem->IsDescendantOf(NAME_Inventory)) { sc.ScriptMessage("'%s' is not a type of inventory item.", sc.String); data.inventoryItem = RUNTIME_CLASS(AInventory); @@ -2894,7 +2894,7 @@ class CommandDrawBar : public SBarInfoCommand if(sc.CheckToken(TK_Identifier) || (extendedSyntax && sc.CheckToken(TK_StringConst))) //comparing reference { data.inventoryItem = PClass::FindActor(sc.String); - if(data.inventoryItem == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(data.inventoryItem)) //must be a kind of inventory + if(data.inventoryItem == NULL || !data.inventoryItem->IsDescendantOf(NAME_Inventory)) //must be a kind of inventory { sc.ScriptMessage("'%s' is not a type of inventory item.", sc.String); data.inventoryItem = RUNTIME_CLASS(AInventory); @@ -2977,7 +2977,7 @@ class CommandIsSelected : public SBarInfoNegatableFlowControl for(int i = 0;i < 2;i++) { weapon[i] = PClass::FindClass(sc.String); - if(weapon[i] == NULL || !RUNTIME_CLASS(AWeapon)->IsAncestorOf(weapon[i])) + 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); @@ -3130,7 +3130,7 @@ class CommandHasWeaponPiece : public SBarInfoCommandFlowControl if(!sc.CheckToken(TK_StringConst)) sc.MustGetToken(TK_Identifier); weapon = PClass::FindClass(sc.String); - if(weapon == NULL || !RUNTIME_CLASS(AWeapon)->IsAncestorOf(weapon)) //must be a weapon + 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); @@ -3317,7 +3317,7 @@ class CommandWeaponAmmo : public SBarInfoNegatableFlowControl for(int i = 0;i < 2;i++) { ammo[i] = PClass::FindClass(sc.String); - if(ammo[i] == NULL || !PClass::FindActor(NAME_Ammo)->IsAncestorOf(ammo[i])) //must be a kind of ammo + if(ammo[i] == NULL || !ammo[i]->IsDescendantOf(NAME_Ammo)) //must be a kind of ammo { sc.ScriptMessage("'%s' is not a type of ammo.", sc.String); ammo[i] = PClass::FindActor(NAME_Ammo); @@ -3400,7 +3400,7 @@ class CommandInInventory : public SBarInfoNegatableFlowControl for(int i = 0;i < 2;i++) { item[i] = PClass::FindActor(sc.String); - if(item[i] == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(item[i])) + if (item[i] == NULL || !item[i]->IsDescendantOf(NAME_Inventory)) //must be a kind of ammo { sc.ScriptMessage("'%s' is not a type of inventory item.", sc.String); item[i] = RUNTIME_CLASS(AInventory); diff --git a/src/gl/dynlights/gl_dynlight.cpp b/src/gl/dynlights/gl_dynlight.cpp index 7a548eaa24..5ce79fd09a 100644 --- a/src/gl/dynlights/gl_dynlight.cpp +++ b/src/gl/dynlights/gl_dynlight.cpp @@ -77,7 +77,7 @@ void gl_ParseVavoomSkybox(); inline PClassActor * GetRealType(PClassActor * ti) { PClassActor *rep = ti->GetReplacement(false); - if (rep != ti && rep != NULL && rep->IsDescendantOf(PClass::FindActor(NAME_DehackedPickup))) + if (rep != ti && rep != NULL && rep->IsDescendantOf(NAME_DehackedPickup)) { return rep; } diff --git a/src/info.cpp b/src/info.cpp index 18eecc2d18..48a22c2d42 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -110,7 +110,7 @@ bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, const char *callinfo = ""; if (info != nullptr && info->mStateType == STATE_Psprite) { - if (stateowner->IsKindOf(RUNTIME_CLASS(AWeapon)) && stateowner != self) callinfo = "weapon "; + if (stateowner->IsKindOf(NAME_Weapon) && stateowner != self) callinfo = "weapon "; else callinfo = "overlay "; } err.stacktrace.AppendFormat("Called from %sstate %s.%d in %s\n", callinfo, owner->TypeName.GetChars(), offs, stateowner->GetClass()->TypeName.GetChars()); diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 23c2f1ded7..bf687c09df 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -317,7 +317,7 @@ void cht_DoCheat (player_t *player, int cheat) case CHT_RESSURECT: if (player->playerstate != PST_LIVE && player->mo != nullptr) { - if (player->mo->IsKindOf(PClass::FindActor("PlayerChunk"))) + if (player->mo->IsKindOf("PlayerChunk")) { Printf("Unable to resurrect. Player is no longer connected to its body.\n"); } @@ -421,7 +421,7 @@ void cht_DoCheat (player_t *player, int cheat) { lastinvp = invp; invp = &(*invp)->Inventory; - if (item->IsKindOf (RUNTIME_CLASS(AWeapon))) + if (item->IsKindOf(NAME_Weapon)) { AWeapon *weap = static_cast (item); if (!(weap->WeaponFlags & WIF_WIMPY_WEAPON) || diff --git a/src/p_acs.cpp b/src/p_acs.cpp index bddcd7f95d..8b0075475f 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -5716,7 +5716,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) if (argCount >= 2) { PClassActor *powerupclass = PClass::FindActor(FBehavior::StaticLookupString(args[1])); - if (powerupclass == NULL || !powerupclass->IsDescendantOf(PClass::FindActor(NAME_Powerup))) + if (powerupclass == NULL || !powerupclass->IsDescendantOf(NAME_Powerup)) { Printf("'%s' is not a type of Powerup.\n", FBehavior::StaticLookupString(args[1])); return 0; @@ -9042,7 +9042,7 @@ scriptwait: AInventory *item = activator->FindInventory (dyn_cast( PClass::FindClass (FBehavior::StaticLookupString (STACK(1))))); - if (item == NULL || !item->IsKindOf (RUNTIME_CLASS(AWeapon))) + if (item == NULL || !item->IsKindOf(NAME_Weapon)) { STACK(1) = 0; } @@ -9110,7 +9110,7 @@ scriptwait: } else { - if (activator != nullptr && activator->IsKindOf(PClass::FindClass("ScriptedMarine"))) + if (activator != nullptr && activator->IsKindOf("ScriptedMarine")) { SetMarineSprite(activator, type); } diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index c732ea18ca..ea271967be 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -2387,7 +2387,7 @@ static bool DoGiveInventory(AActor *receiver, bool orresult, VM_ARGS) { return false; } - if (item->IsKindOf(PClass::FindActor(NAME_Health))) + if (item->IsKindOf(NAME_Health)) { item->Amount *= amount; } @@ -3123,7 +3123,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SelectWeapon) AWeapon *weaponitem = static_cast(self->FindInventory(cls)); - if (weaponitem != NULL && weaponitem->IsKindOf(RUNTIME_CLASS(AWeapon))) + if (weaponitem != NULL && weaponitem->IsKindOf(NAME_Weapon)) { if (self->player->ReadyWeapon != weaponitem) { @@ -5668,7 +5668,7 @@ static bool DoRadiusGive(AActor *self, AActor *thing, PClassActor *item, int amo if ((flags & RGF_NOSIGHT) || P_CheckSight(thing, self, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)) { // OK to give; target is in direct path, or the monster doesn't care about it being in line of sight. AInventory *gift = static_cast(Spawn(item)); - if (gift->IsKindOf(PClass::FindActor(NAME_Health))) + if (gift->IsKindOf(NAME_Health)) { gift->Amount *= amount; } diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index a77a7358d5..e9ad0ff0d5 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -1331,7 +1331,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply { if (reply->GiveType->IsDescendantOf(RUNTIME_CLASS(AInventory))) { - if (reply->GiveType->IsDescendantOf(RUNTIME_CLASS(AWeapon))) + if (reply->GiveType->IsDescendantOf(NAME_Weapon)) { if (player->mo->FindInventory(reply->GiveType) != NULL) { @@ -1357,7 +1357,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply } } - if (reply->GiveType->IsDescendantOf(PClass::FindActor("SlideshowStarter"))) + if (reply->GiveType->IsDescendantOf("SlideshowStarter")) gameaction = ga_slideshow; } else diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index bd5a9cb17e..2fb040a933 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -3226,7 +3226,7 @@ void ModifyDropAmount(AInventory *inv, int dropamount) if (dropamount > 0) { - if (flagmask != 0 && inv->IsKindOf(PClass::FindActor(NAME_Ammo))) + if (flagmask != 0 && inv->IsKindOf(NAME_Ammo)) { inv->Amount = int(dropamount * dropammofactor); inv->ItemFlags |= IF_IGNORESKILL; @@ -3252,7 +3252,7 @@ void ModifyDropAmount(AInventory *inv, int dropamount) inv->FloatVar("AmmoFactor") = dropammofactor; inv->ItemFlags |= flagmask; } - else if (inv->IsKindOf (RUNTIME_CLASS(AWeapon))) + else if (inv->IsKindOf(NAME_Weapon)) { // The same goes for ammo from a weapon. static_cast(inv)->AmmoGive1 = int(static_cast(inv)->AmmoGive1 * dropammofactor); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 758b4ac18a..d39786311e 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -789,7 +789,7 @@ bool AActor::GiveInventory(PClassInventory *type, int amount, bool givecheat) item->ClearCounters(); if (!givecheat || amount > 0) { - if (type->IsDescendantOf (PClass::FindActor(NAME_BasicArmorPickup)) || type->IsDescendantOf(PClass::FindActor(NAME_BasicArmorBonus))) + if (type->IsDescendantOf (NAME_BasicArmorPickup) || type->IsDescendantOf(NAME_BasicArmorBonus)) { item->IntVar(NAME_SaveAmount) *= amount; } @@ -903,7 +903,7 @@ bool AActor::TakeInventory(PClassActor *itemclass, int amount, bool fromdecorate // and infinite ammo is on if (notakeinfinite && ((dmflags & DF_INFINITE_AMMO) || (player && player->cheats & CF_INFINITEAMMO)) && - item->IsKindOf(PClass::FindActor(NAME_Ammo))) + item->IsKindOf(NAME_Ammo)) { // Nothing to do here, except maybe res = false;? Would it make sense? result = false; diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index c443ca7da1..bf6c79a82e 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -166,7 +166,7 @@ DPSprite::DPSprite(player_t *owner, AActor *caller, int id) if (Next && Next->ID == ID && ID != 0) Next->Destroy(); // Replace it. - if (Caller->IsKindOf(RUNTIME_CLASS(AWeapon)) || Caller->IsKindOf(RUNTIME_CLASS(APlayerPawn))) + if (Caller->IsKindOf(NAME_Weapon) || Caller->IsKindOf(RUNTIME_CLASS(APlayerPawn))) Flags = (PSPF_ADDWEAPON|PSPF_ADDBOB|PSPF_POWDOUBLE|PSPF_CVARFAST); } @@ -353,7 +353,7 @@ void DPSprite::SetState(FState *newstate, bool pending) } else if (!(newstate->UseFlags & SUF_WEAPON)) { - if (Caller->IsKindOf(RUNTIME_CLASS(AWeapon))) + if (Caller->IsKindOf(NAME_Weapon)) { auto so = FState::StaticFindStateOwner(newstate); Printf(TEXTCOLOR_RED "State %s.%d not flagged for use in weapons\n", so->TypeName.GetChars(), int(newstate - so->OwnedStates)); @@ -1333,7 +1333,7 @@ void player_t::TickPSprites() // or if it's from an inventory item that the player no longer owns. if ((pspr->Caller == nullptr || (pspr->Caller->IsKindOf(RUNTIME_CLASS(AInventory)) && barrier_cast(pspr->Caller)->Owner != pspr->Owner->mo) || - (pspr->Caller->IsKindOf(RUNTIME_CLASS(AWeapon)) && pspr->Caller != pspr->Owner->ReadyWeapon))) + (pspr->Caller->IsKindOf(NAME_Weapon) && pspr->Caller != pspr->Owner->ReadyWeapon))) { pspr->Destroy(); } diff --git a/src/p_user.cpp b/src/p_user.cpp index c6b0a7d583..1b9cedf4a5 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -963,7 +963,7 @@ AWeapon *APlayerPawn::BestWeapon(PClassInventory *ammotype) // Find the best weapon the player has. for (item = Inventory; item != NULL; item = item->Inventory) { - if (!item->IsKindOf (RUNTIME_CLASS(AWeapon))) + if (!item->IsKindOf(NAME_Weapon)) continue; weap = static_cast (item); @@ -1136,29 +1136,29 @@ void APlayerPawn::FilterCoopRespawnInventory (APlayerPawn *oldplayer) if ((dmflags & DF_COOP_LOSE_KEYS) && defitem == NULL && - item->IsKindOf(PClass::FindActor(NAME_Key))) + item->IsKindOf(NAME_Key)) { item->Destroy(); } else if ((dmflags & DF_COOP_LOSE_WEAPONS) && defitem == NULL && - item->IsKindOf(RUNTIME_CLASS(AWeapon))) + item->IsKindOf(NAME_Weapon)) { item->Destroy(); } else if ((dmflags & DF_COOP_LOSE_ARMOR) && - item->IsKindOf(PClass::FindActor(NAME_Armor))) + item->IsKindOf(NAME_Armor)) { if (defitem == NULL) { item->Destroy(); } - else if (item->IsKindOf(PClass::FindActor(NAME_BasicArmor))) + else if (item->IsKindOf(NAME_BasicArmor)) { item->IntVar(NAME_SavePercent) = defitem->IntVar(NAME_SavePercent); item->Amount = defitem->Amount; } - else if (item->IsKindOf(PClass::FindActor(NAME_HexenArmor))) + else if (item->IsKindOf(NAME_HexenArmor)) { double *SlotsTo = (double*)item->ScriptVar(NAME_Slots, nullptr); double *SlotsFrom = (double*)defitem->ScriptVar(NAME_Slots, nullptr); @@ -1167,12 +1167,12 @@ void APlayerPawn::FilterCoopRespawnInventory (APlayerPawn *oldplayer) } else if ((dmflags & DF_COOP_LOSE_POWERUPS) && defitem == NULL && - item->IsKindOf(PClass::FindActor(NAME_PowerupGiver))) + item->IsKindOf(NAME_PowerupGiver)) { item->Destroy(); } else if ((dmflags & (DF_COOP_LOSE_AMMO | DF_COOP_HALVE_AMMO)) && - item->IsKindOf(PClass::FindActor(NAME_Ammo))) + item->IsKindOf(NAME_Ammo)) { if (defitem == NULL) { @@ -1412,7 +1412,7 @@ void APlayerPawn::GiveDefaultInventory () item = static_cast(Spawn(ti)); item->ItemFlags |= IF_IGNORESKILL; // no skill multiplicators here item->Amount = di->Amount; - if (item->IsKindOf(RUNTIME_CLASS(AWeapon))) + if (item->IsKindOf(NAME_Weapon)) { // To allow better control any weapon is emptied of // ammo before being given to the player. @@ -1432,7 +1432,7 @@ void APlayerPawn::GiveDefaultInventory () item = NULL; } } - if (item != NULL && item->IsKindOf(RUNTIME_CLASS(AWeapon)) && + if (item != NULL && item->IsKindOf(NAME_Weapon) && static_cast(item)->CheckAmmo(AWeapon::EitherFire, false)) { player->ReadyWeapon = player->PendingWeapon = static_cast (item); @@ -1536,7 +1536,7 @@ void APlayerPawn::Die (AActor *source, AActor *inflictor, int dmgflags) weap->SpawnState != ::GetDefault()->SpawnState) { item = P_DropItem (this, weap->GetClass(), -1, 256); - if (item != NULL && item->IsKindOf(RUNTIME_CLASS(AWeapon))) + if (item != NULL && item->IsKindOf(NAME_Weapon)) { if (weap->AmmoGive1 && weap->Ammo1) { @@ -1709,7 +1709,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullPop) player_t *player; // [GRB] Parameterized version - if (spawntype == NULL || !spawntype->IsDescendantOf(PClass::FindActor("PlayerChunk"))) + if (spawntype == NULL || !spawntype->IsDescendantOf("PlayerChunk")) { spawntype = dyn_cast(PClass::FindClass("BloodySkull")); if (spawntype == NULL) diff --git a/src/portal.cpp b/src/portal.cpp index 43b7ef7b6d..f354faa65d 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -670,7 +670,7 @@ unsigned P_GetSkyboxPortal(AActor *actor) unsigned i = level.sectorPortals.Reserve(1); memset(&level.sectorPortals[i], 0, sizeof(level.sectorPortals[i])); level.sectorPortals[i].mType = PORTS_SKYVIEWPOINT; - level.sectorPortals[i].mFlags = actor->GetClass()->IsDescendantOf(PClass::FindActor("SkyCamCompat")) ? 0 : PORTSF_SKYFLATONLY; + level.sectorPortals[i].mFlags = actor->GetClass()->IsDescendantOf("SkyCamCompat") ? 0 : PORTSF_SKYFLATONLY; level.sectorPortals[i].mSkybox = actor; level.sectorPortals[i].mDestination = actor->Sector; return i; diff --git a/src/scripting/thingdef.cpp b/src/scripting/thingdef.cpp index f2849eb39b..51fb0239c0 100644 --- a/src/scripting/thingdef.cpp +++ b/src/scripting/thingdef.cpp @@ -246,7 +246,7 @@ static void CheckForUnsafeStates(PClassActor *obj) TMap checked; ENamedName *test; - if (obj->IsDescendantOf(RUNTIME_CLASS(AWeapon))) + if (obj->IsDescendantOf(NAME_Weapon)) { if (obj->Size == RUNTIME_CLASS(AWeapon)->Size) return; // This class cannot have user variables. test = weaponstates; @@ -336,11 +336,11 @@ static void CheckStates(PClassActor *obj) CheckStateLabels(obj, actorstates, SUF_ACTOR, "actor sprites"); - if (obj->IsDescendantOf(RUNTIME_CLASS(AWeapon))) + if (obj->IsDescendantOf(NAME_Weapon)) { CheckStateLabels(obj, weaponstates, SUF_WEAPON, "weapon sprites"); } - else if (obj->IsDescendantOf(PClass::FindActor(NAME_CustomInventory))) + else if (obj->IsDescendantOf(NAME_CustomInventory)) { CheckStateLabels(obj, pickupstates, SUF_ITEM, "CustomInventory state chain"); } diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index 22d6610ce8..8cffbc347b 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -2096,9 +2096,9 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, color, C_f, Inventory) int alpha; PalEntry *pBlendColor; - bool isgiver = info->IsDescendantOf(PClass::FindActor(NAME_PowerupGiver)); + bool isgiver = info->IsDescendantOf(NAME_PowerupGiver); - if (info->IsDescendantOf(PClass::FindActor(NAME_Powerup)) || isgiver) + if (info->IsDescendantOf(NAME_Powerup) || isgiver) { pBlendColor = &defaults->ColorVar(NAME_BlendColor); } @@ -2148,7 +2148,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, colormap, FFFfff, Inventory) { PalEntry BlendColor; - if (!info->IsDescendantOf(PClass::FindActor(NAME_Powerup)) && !info->IsDescendantOf(PClass::FindActor(NAME_PowerupGiver))) + if (!info->IsDescendantOf(NAME_Powerup) && !info->IsDescendantOf(NAME_PowerupGiver)) { I_Error("\"powerup.colormap\" requires an actor of type \"Powerup\"\n"); return; @@ -2183,7 +2183,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, colormap, FFFfff, Inventory) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(powerup, duration, I, Inventory) { - if (!info->IsDescendantOf(PClass::FindActor(NAME_Powerup)) && !info->IsDescendantOf(PClass::FindActor(NAME_PowerupGiver))) + if (!info->IsDescendantOf(NAME_Powerup) && !info->IsDescendantOf(NAME_PowerupGiver)) { I_Error("\"powerup.duration\" requires an actor of type \"Powerup\"\n"); return; @@ -2198,7 +2198,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, duration, I, Inventory) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(powerup, strength, F, Inventory) { - if (!info->IsDescendantOf(PClass::FindActor(NAME_Powerup)) && !info->IsDescendantOf(PClass::FindActor(NAME_PowerupGiver))) + if (!info->IsDescendantOf(NAME_Powerup) && !info->IsDescendantOf(NAME_PowerupGiver)) { I_Error("\"powerup.strength\" requires an actor of type \"Powerup\"\n"); return; @@ -2214,7 +2214,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, mode, S, Inventory) { PROP_STRING_PARM(str, 0); - if (!info->IsDescendantOf(PClass::FindActor(NAME_Powerup)) && !info->IsDescendantOf(PClass::FindActor(NAME_PowerupGiver))) + if (!info->IsDescendantOf(NAME_Powerup) && !info->IsDescendantOf(NAME_PowerupGiver)) { I_Error("\"powerup.mode\" requires an actor of type \"Powerup\"\n"); return; diff --git a/src/zstring.h b/src/zstring.h index c696f7fd6a..c58fb111a3 100644 --- a/src/zstring.h +++ b/src/zstring.h @@ -449,4 +449,14 @@ template<> struct THashTraits // Compares two keys, returning zero if they are the same. int Compare(const FString &left, const FString &right) { return left.Compare(right); } }; + +class FStringNoInit +{ + char mem[sizeof(FString)]; + operator FString&() + { + return *reinterpret_cast(&mem); + } +}; + #endif diff --git a/wadsrc/static/zscript/inventory/weapons.txt b/wadsrc/static/zscript/inventory/weapons.txt index 7bda52e528..c1fbf43846 100644 --- a/wadsrc/static/zscript/inventory/weapons.txt +++ b/wadsrc/static/zscript/inventory/weapons.txt @@ -252,7 +252,7 @@ class Weapon : StateProvider native //=========================================================================== // - // AWeapon :: TryPickup + // Weapon :: TryPickup // // If you can't see the weapon when it's active, then you can't pick it up. // @@ -277,7 +277,7 @@ class Weapon : StateProvider native //=========================================================================== // - // AWeapon :: TryPickup + // Weapon :: TryPickup // //=========================================================================== @@ -293,7 +293,7 @@ class Weapon : StateProvider native //=========================================================================== // - // AWeapon :: Use + // Weapon :: Use // // Make the player switch to self weapon. // @@ -324,7 +324,7 @@ class Weapon : StateProvider native //=========================================================================== // - // AWeapon :: Destroy + // Weapon :: Destroy // //=========================================================================== @@ -347,7 +347,7 @@ class Weapon : StateProvider native //=========================================================================== // - // AWeapon :: HandlePickup + // Weapon :: HandlePickup // // Try to leach ammo from the weapon if you have it already. // @@ -372,7 +372,7 @@ class Weapon : StateProvider native //=========================================================================== // - // AWeapon :: PickupForAmmo + // Weapon :: PickupForAmmo // // The player already has self weapon, so try to pick it up for ammo. // @@ -411,7 +411,7 @@ class Weapon : StateProvider native //=========================================================================== // - // AWeapon :: CreateCopy + // Weapon :: CreateCopy // //=========================================================================== @@ -428,7 +428,7 @@ class Weapon : StateProvider native //=========================================================================== // - // AWeapon :: CreateTossable + // Weapon :: CreateTossable // // A weapon that's tossed out should contain no ammo, so you can't cheat // by dropping it and then picking it back up. @@ -464,7 +464,7 @@ class Weapon : StateProvider native //=========================================================================== // - // AWeapon :: AttachToOwner + // Weapon :: AttachToOwner // //=========================================================================== @@ -491,7 +491,7 @@ class Weapon : StateProvider native //=========================================================================== // - // AWeapon :: AddAmmo + // Weapon :: AddAmmo // // Give some ammo to the owner, even if it's just 0. // @@ -536,7 +536,7 @@ class Weapon : StateProvider native //=========================================================================== // - // AWeapon :: AddExistingAmmo + // Weapon :: AddExistingAmmo // // Give the owner some more ammo he already has. // @@ -563,7 +563,7 @@ class Weapon : StateProvider native //=========================================================================== // - // AWeapon :: AddWeapon + // Weapon :: AddWeapon // // Give the owner a weapon if they don't have it already. // @@ -588,7 +588,7 @@ class Weapon : StateProvider native //=========================================================================== // - // AWeapon :: ShouldStay + // Weapon :: ShouldStay // //=========================================================================== @@ -606,7 +606,7 @@ class Weapon : StateProvider native //=========================================================================== // - // AWeapon :: EndPowerUp + // Weapon :: EndPowerUp // // The Tome of Power just expired. //