diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 369077d6c2..3adeb19d9f 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -317,7 +317,6 @@ namespace MWClass { if (!state.mHasCustomState) return; - const ESM::ContainerState& state2 = dynamic_cast (state); if (!ptr.getRefData().getCustomData()) { @@ -326,21 +325,21 @@ namespace MWClass ptr.getRefData().setCustomData (data.release()); } - dynamic_cast (*ptr.getRefData().getCustomData()).mContainerStore. - readState (state2.mInventory); + ContainerCustomData& customData = ptr.getRefData().getCustomData()->asContainerCustomData(); + const ESM::ContainerState& containerState = state.asContainerState(); + customData.mContainerStore.readState (containerState.mInventory); } void Container::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const { - ESM::ContainerState& state2 = dynamic_cast (state); - if (!ptr.getRefData().getCustomData()) { state.mHasCustomState = false; return; } - dynamic_cast (*ptr.getRefData().getCustomData()).mContainerStore. - writeState (state2.mInventory); + const ContainerCustomData& customData = ptr.getRefData().getCustomData()->asContainerCustomData(); + ESM::ContainerState& containerState = state.asContainerState(); + customData.mContainerStore.writeState (containerState.mInventory); } } diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 9d5bd14e49..d1a4395283 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -776,8 +776,6 @@ namespace MWClass if (!state.mHasCustomState) return; - const ESM::CreatureState& state2 = dynamic_cast (state); - if (state.mVersion > 0) { if (!ptr.getRefData().getCustomData()) @@ -797,16 +795,14 @@ namespace MWClass ensureCustomData(ptr); // in openmw 0.30 savegames not all state was saved yet, so need to load it regardless. CreatureCustomData& customData = ptr.getRefData().getCustomData()->asCreatureCustomData(); - - customData.mContainerStore->readState (state2.mInventory); - customData.mCreatureStats.readState (state2.mCreatureStats); + const ESM::CreatureState& creatureState = state.asCreatureState(); + customData.mContainerStore->readState (creatureState.mInventory); + customData.mCreatureStats.readState (creatureState.mCreatureStats); } void Creature::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const { - ESM::CreatureState& state2 = dynamic_cast (state); - if (!ptr.getRefData().getCustomData()) { state.mHasCustomState = false; @@ -814,9 +810,9 @@ namespace MWClass } const CreatureCustomData& customData = ptr.getRefData().getCustomData()->asCreatureCustomData(); - - customData.mContainerStore->writeState (state2.mInventory); - customData.mCreatureStats.writeState (state2.mCreatureStats); + ESM::CreatureState& creatureState = state.asCreatureState(); + customData.mContainerStore->writeState (creatureState.mInventory); + customData.mCreatureStats.writeState (creatureState.mCreatureStats); } int Creature::getBaseGold(const MWWorld::ConstPtr& ptr) const diff --git a/apps/openmw/mwclass/creaturelevlist.cpp b/apps/openmw/mwclass/creaturelevlist.cpp index 1dab9e4839..1f47b483f3 100644 --- a/apps/openmw/mwclass/creaturelevlist.cpp +++ b/apps/openmw/mwclass/creaturelevlist.cpp @@ -151,19 +151,16 @@ namespace MWClass if (!state.mHasCustomState) return; - const ESM::CreatureLevListState& state2 = dynamic_cast (state); - ensureCustomData(ptr); CreatureLevListCustomData& customData = ptr.getRefData().getCustomData()->asCreatureLevListCustomData(); - customData.mSpawnActorId = state2.mSpawnActorId; - customData.mSpawn = state2.mSpawn; + const ESM::CreatureLevListState& levListState = state.asCreatureLevListState(); + customData.mSpawnActorId = levListState.mSpawnActorId; + customData.mSpawn = levListState.mSpawn; } void CreatureLevList::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const { - ESM::CreatureLevListState& state2 = dynamic_cast (state); - if (!ptr.getRefData().getCustomData()) { state.mHasCustomState = false; @@ -171,7 +168,8 @@ namespace MWClass } const CreatureLevListCustomData& customData = ptr.getRefData().getCustomData()->asCreatureLevListCustomData(); - state2.mSpawnActorId = customData.mSpawnActorId; - state2.mSpawn = customData.mSpawn; + ESM::CreatureLevListState& levListState = state.asCreatureLevListState(); + levListState.mSpawnActorId = customData.mSpawnActorId; + levListState.mSpawn = customData.mSpawn; } } diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 6a0be86319..7d1c1d38a5 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -370,11 +370,11 @@ namespace MWClass { if (!state.mHasCustomState) return; + ensureCustomData(ptr); DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData(); - - const ESM::DoorState& state2 = dynamic_cast(state); - customData.mDoorState = static_cast(state2.mDoorState); + const ESM::DoorState& doorState = state.asDoorState(); + customData.mDoorState = MWWorld::DoorState(doorState.mDoorState); } void Door::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const @@ -384,10 +384,10 @@ namespace MWClass state.mHasCustomState = false; return; } - const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData(); - ESM::DoorState& state2 = dynamic_cast(state); - state2.mDoorState = static_cast(customData.mDoorState); + const DoorCustomData& customData = ptr.getRefData().getCustomData()->asDoorCustomData(); + ESM::DoorState& doorState = state.asDoorState(); + doorState.mDoorState = int(customData.mDoorState); } } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 4f1a996e7f..297471e07f 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -1299,8 +1299,6 @@ namespace MWClass if (!state.mHasCustomState) return; - const ESM::NpcState& state2 = dynamic_cast (state); - if (state.mVersion > 0) { if (!ptr.getRefData().getCustomData()) @@ -1314,17 +1312,15 @@ namespace MWClass ensureCustomData(ptr); // in openmw 0.30 savegames not all state was saved yet, so need to load it regardless. NpcCustomData& customData = ptr.getRefData().getCustomData()->asNpcCustomData(); - - customData.mInventoryStore.readState (state2.mInventory); - customData.mNpcStats.readState (state2.mNpcStats); - static_cast (customData.mNpcStats).readState (state2.mCreatureStats); + const ESM::NpcState& npcState = state.asNpcState(); + customData.mInventoryStore.readState (npcState.mInventory); + customData.mNpcStats.readState (npcState.mNpcStats); + customData.mNpcStats.readState (npcState.mCreatureStats); } void Npc::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const { - ESM::NpcState& state2 = dynamic_cast (state); - if (!ptr.getRefData().getCustomData()) { state.mHasCustomState = false; @@ -1332,10 +1328,10 @@ namespace MWClass } const NpcCustomData& customData = ptr.getRefData().getCustomData()->asNpcCustomData(); - - customData.mInventoryStore.writeState (state2.mInventory); - customData.mNpcStats.writeState (state2.mNpcStats); - static_cast (customData.mNpcStats).writeState (state2.mCreatureStats); + ESM::NpcState& npcState = state.asNpcState(); + customData.mInventoryStore.writeState (npcState.mInventory); + customData.mNpcStats.writeState (npcState.mNpcStats); + customData.mNpcStats.writeState (npcState.mCreatureStats); } int Npc::getBaseGold(const MWWorld::ConstPtr& ptr) const diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index aa6cd142ba..ee48ea7d5a 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -455,6 +455,11 @@ void MWMechanics::NpcStats::setTimeToStartDrowning(float time) mTimeToStartDrowning=time; } +void MWMechanics::NpcStats::writeState (ESM::CreatureStats& state) const +{ + CreatureStats::writeState(state); +} + void MWMechanics::NpcStats::writeState (ESM::NpcStats& state) const { for (std::map::const_iterator iter (mFactionRank.begin()); @@ -494,6 +499,10 @@ void MWMechanics::NpcStats::writeState (ESM::NpcStats& state) const state.mTimeToStartDrowning = mTimeToStartDrowning; } +void MWMechanics::NpcStats::readState (const ESM::CreatureStats& state) +{ + CreatureStats::readState(state); +} void MWMechanics::NpcStats::readState (const ESM::NpcStats& state) { diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 47784ac1de..9bd8e20ad7 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -127,8 +127,10 @@ namespace MWMechanics /// @param time value from [0,20] void setTimeToStartDrowning(float time); + void writeState (ESM::CreatureStats& state) const; void writeState (ESM::NpcStats& state) const; + void readState (const ESM::CreatureStats& state); void readState (const ESM::NpcStats& state); }; } diff --git a/components/esm/containerstate.hpp b/components/esm/containerstate.hpp index 1ecf2b46ea..33818d4f15 100644 --- a/components/esm/containerstate.hpp +++ b/components/esm/containerstate.hpp @@ -14,6 +14,15 @@ namespace ESM virtual void load (ESMReader &esm); virtual void save (ESMWriter &esm, bool inInventory = false) const; + + virtual ContainerState& asContainerState() + { + return *this; + } + virtual const ContainerState& asContainerState() const + { + return *this; + } }; } diff --git a/components/esm/creaturelevliststate.hpp b/components/esm/creaturelevliststate.hpp index da64cd7c2b..4d0b726a0e 100644 --- a/components/esm/creaturelevliststate.hpp +++ b/components/esm/creaturelevliststate.hpp @@ -14,6 +14,15 @@ namespace ESM virtual void load (ESMReader &esm); virtual void save (ESMWriter &esm, bool inInventory = false) const; + + virtual CreatureLevListState& asCreatureLevListState() + { + return *this; + } + virtual const CreatureLevListState& asCreatureLevListState() const + { + return *this; + } }; } diff --git a/components/esm/creaturestate.hpp b/components/esm/creaturestate.hpp index 9a3d41daae..ca0d2601a9 100644 --- a/components/esm/creaturestate.hpp +++ b/components/esm/creaturestate.hpp @@ -19,6 +19,15 @@ namespace ESM virtual void load (ESMReader &esm); virtual void save (ESMWriter &esm, bool inInventory = false) const; + + virtual CreatureState& asCreatureState() + { + return *this; + } + virtual const CreatureState& asCreatureState() const + { + return *this; + } }; } diff --git a/components/esm/doorstate.hpp b/components/esm/doorstate.hpp index c2e7658809..1251b90594 100644 --- a/components/esm/doorstate.hpp +++ b/components/esm/doorstate.hpp @@ -13,6 +13,15 @@ namespace ESM virtual void load (ESMReader &esm); virtual void save (ESMWriter &esm, bool inInventory = false) const; + + virtual DoorState& asDoorState() + { + return *this; + } + virtual const DoorState& asDoorState() const + { + return *this; + } }; } diff --git a/components/esm/npcstate.hpp b/components/esm/npcstate.hpp index b90cd85e6a..4ae026da6b 100644 --- a/components/esm/npcstate.hpp +++ b/components/esm/npcstate.hpp @@ -21,6 +21,15 @@ namespace ESM virtual void load (ESMReader &esm); virtual void save (ESMWriter &esm, bool inInventory = false) const; + + virtual NpcState& asNpcState() + { + return *this; + } + virtual const NpcState& asNpcState() const + { + return *this; + } }; } diff --git a/components/esm/objectstate.cpp b/components/esm/objectstate.cpp index 18c0302569..a7a452c820 100644 --- a/components/esm/objectstate.cpp +++ b/components/esm/objectstate.cpp @@ -1,5 +1,9 @@ #include "objectstate.hpp" +#include +#include +#include + #include "esmreader.hpp" #include "esmwriter.hpp" @@ -84,4 +88,74 @@ void ESM::ObjectState::blank() mHasCustomState = true; } +const ESM::NpcState& ESM::ObjectState::asNpcState() const +{ + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to NpcState"; + throw std::logic_error(error.str()); +} + +ESM::NpcState& ESM::ObjectState::asNpcState() +{ + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to NpcState"; + throw std::logic_error(error.str()); +} + +const ESM::CreatureState& ESM::ObjectState::asCreatureState() const +{ + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to CreatureState"; + throw std::logic_error(error.str()); +} + +ESM::CreatureState& ESM::ObjectState::asCreatureState() +{ + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to CreatureState"; + throw std::logic_error(error.str()); +} + +const ESM::ContainerState& ESM::ObjectState::asContainerState() const +{ + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to ContainerState"; + throw std::logic_error(error.str()); +} + +ESM::ContainerState& ESM::ObjectState::asContainerState() +{ + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to ContainerState"; + throw std::logic_error(error.str()); +} + +const ESM::DoorState& ESM::ObjectState::asDoorState() const +{ + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to DoorState"; + throw std::logic_error(error.str()); +} + +ESM::DoorState& ESM::ObjectState::asDoorState() +{ + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to DoorState"; + throw std::logic_error(error.str()); +} + +const ESM::CreatureLevListState& ESM::ObjectState::asCreatureLevListState() const +{ + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to CreatureLevListState"; + throw std::logic_error(error.str()); +} + +ESM::CreatureLevListState& ESM::ObjectState::asCreatureLevListState() +{ + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to CreatureLevListState"; + throw std::logic_error(error.str()); +} + ESM::ObjectState::~ObjectState() {} diff --git a/components/esm/objectstate.hpp b/components/esm/objectstate.hpp index d14c04b648..1079d6c727 100644 --- a/components/esm/objectstate.hpp +++ b/components/esm/objectstate.hpp @@ -12,6 +12,11 @@ namespace ESM { class ESMReader; class ESMWriter; + struct ContainerState; + struct CreatureLevListState; + struct CreatureState; + struct DoorState; + struct NpcState; // format 0, saved games only @@ -48,6 +53,21 @@ namespace ESM void blank(); virtual ~ObjectState(); + + virtual const NpcState& asNpcState() const; + virtual NpcState& asNpcState(); + + virtual const CreatureState& asCreatureState() const; + virtual CreatureState& asCreatureState(); + + virtual const ContainerState& asContainerState() const; + virtual ContainerState& asContainerState(); + + virtual const DoorState& asDoorState() const; + virtual DoorState& asDoorState(); + + virtual const CreatureLevListState& asCreatureLevListState() const; + virtual CreatureLevListState& asCreatureLevListState(); }; }