2012-02-20 14:14:39 +01:00
|
|
|
#include "containerstore.hpp"
|
2023-06-28 09:32:15 +00:00
|
|
|
#include "inventorystore.hpp"
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
#include <cassert>
|
2012-02-23 12:34:25 +01:00
|
|
|
#include <stdexcept>
|
2012-02-20 14:14:39 +01:00
|
|
|
|
2018-08-14 23:05:43 +04:00
|
|
|
#include <components/debug/debuglog.hpp>
|
2022-01-22 15:58:41 +01:00
|
|
|
#include <components/esm3/inventorystate.hpp>
|
2022-09-05 19:35:15 +02:00
|
|
|
#include <components/esm3/loadench.hpp>
|
2023-04-06 08:52:37 +02:00
|
|
|
#include <components/esm3/loadlevlist.hpp>
|
2022-08-03 00:00:54 +02:00
|
|
|
#include <components/misc/strings/algorithm.hpp>
|
|
|
|
#include <components/misc/strings/lower.hpp>
|
Store RefData::mBaseNode as osg::ref_ptr
Direct leak of 16197408 byte(s) in 56241 object(s) allocated from:
#0 0x5572356d4d42 in operator new(unsigned long) (/home/elsid/dev/openmw/build/clang/asan/openmw+0xae0d42)
#1 0x557236938196 in (anonymous namespace)::addObject(MWWorld::Ptr const&, MWWorld::World const&, std::__1::vector<ESM::RefNum, std::__1::allocator<ESM::RefNum> > const&, MWPhysics::PhysicsSystem&, MWRender::RenderingManager&) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:119:42
#2 0x55723692e51b in MWWorld::Scene::insertCell(MWWorld::CellStore&, Loading::Listener*)::$_7::operator()(MWWorld::Ptr const&) const /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:913:62
#3 0x55723692e51b in void (anonymous namespace)::InsertVisitor::insert<MWWorld::Scene::insertCell(MWWorld::CellStore&, Loading::Listener*)::$_7>(MWWorld::Scene::insertCell(MWWorld::CellStore&, Loading::Listener*)::$_7&&) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:230:21
#4 0x55723692e51b in MWWorld::Scene::insertCell(MWWorld::CellStore&, Loading::Listener*) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:913:23
#5 0x55723692d451 in MWWorld::Scene::loadCell(MWWorld::CellStore*, Loading::Listener*, bool, osg::Vec3f const&) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:449:9
#6 0x5572369299f5 in MWWorld::Scene::changeCellGrid(osg::Vec3f const&, int, int, bool) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:612:17
#7 0x557236928521 in MWWorld::Scene::update(float) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:315:13
#8 0x5572368d4c98 in MWWorld::World::update(float, bool) /home/elsid/dev/openmw/apps/openmw/mwworld/worldimp.cpp:1833:22
#9 0x557236ebbb72 in OMW::Engine::frame(float) /home/elsid/dev/openmw/apps/openmw/engine.cpp:418:25
#10 0x557236ed250a in OMW::Engine::go() /home/elsid/dev/openmw/apps/openmw/engine.cpp:1102:14
#11 0x557236eb621a in runApplication(int, char**) /home/elsid/dev/openmw/apps/openmw/main.cpp:228:17
#12 0x55723774d622 in wrapApplication(int (*)(int, char**), int, char**, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool) /home/elsid/dev/openmw/components/debug/debugging.cpp:328:19
#13 0x557236eb651f in main /home/elsid/dev/openmw/apps/openmw/main.cpp:240:12
#14 0x7fbf58a3f2cf (/usr/lib/libc.so.6+0x232cf) (BuildId: e637217a46491314667a7a37b2155cb07afc1a40)
Direct leak of 396288 byte(s) in 1376 object(s) allocated from:
#0 0x5572356d4d42 in operator new(unsigned long) (/home/elsid/dev/openmw/build/clang/asan/openmw+0xae0d42)
#1 0x557236938196 in (anonymous namespace)::addObject(MWWorld::Ptr const&, MWWorld::World const&, std::__1::vector<ESM::RefNum, std::__1::allocator<ESM::RefNum> > const&, MWPhysics::PhysicsSystem&, MWRender::RenderingManager&) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:119:42
#2 0x55723692e51b in MWWorld::Scene::insertCell(MWWorld::CellStore&, Loading::Listener*)::$_7::operator()(MWWorld::Ptr const&) const /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:913:62
#3 0x55723692e51b in void (anonymous namespace)::InsertVisitor::insert<MWWorld::Scene::insertCell(MWWorld::CellStore&, Loading::Listener*)::$_7>(MWWorld::Scene::insertCell(MWWorld::CellStore&, Loading::Listener*)::$_7&&) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:230:21
#4 0x55723692e51b in MWWorld::Scene::insertCell(MWWorld::CellStore&, Loading::Listener*) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:913:23
#5 0x55723692d451 in MWWorld::Scene::loadCell(MWWorld::CellStore*, Loading::Listener*, bool, osg::Vec3f const&) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:449:9
#6 0x5572369299f5 in MWWorld::Scene::changeCellGrid(osg::Vec3f const&, int, int, bool) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:612:17
#7 0x557236936eb2 in MWWorld::Scene::changeToExteriorCell(ESM::Position const&, bool, bool) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:888:9
#8 0x55723689a5ac in MWWorld::World::changeToExteriorCell(ESM::Position const&, bool, bool) /home/elsid/dev/openmw/apps/openmw/mwworld/worldimp.cpp:1003:22
#9 0x5572368c249d in MWWorld::World::changeToCell(ESM::CellId const&, ESM::Position const&, bool, bool) /home/elsid/dev/openmw/apps/openmw/mwworld/worldimp.cpp:1014:13
#10 0x557236e9bbce in MWState::StateManager::loadGame(MWState::Character const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) /home/elsid/dev/openmw/apps/openmw/mwstate/statemanagerimp.cpp:545:52
#11 0x557236e998db in MWState::StateManager::loadGame(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) /home/elsid/dev/openmw/apps/openmw/mwstate/statemanagerimp.cpp:377:17
#12 0x557236ed18fb in OMW::Engine::go() /home/elsid/dev/openmw/apps/openmw/engine.cpp:1066:24
#13 0x557236eb621a in runApplication(int, char**) /home/elsid/dev/openmw/apps/openmw/main.cpp:228:17
#14 0x55723774d622 in wrapApplication(int (*)(int, char**), int, char**, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool) /home/elsid/dev/openmw/components/debug/debugging.cpp:328:19
#15 0x557236eb651f in main /home/elsid/dev/openmw/apps/openmw/main.cpp:240:12
#16 0x7fbf58a3f2cf (/usr/lib/libc.so.6+0x232cf) (BuildId: e637217a46491314667a7a37b2155cb07afc1a40)
2022-07-08 18:58:23 +02:00
|
|
|
#include <components/sceneutil/positionattitudetransform.hpp>
|
2014-01-31 13:25:32 +01:00
|
|
|
|
2012-05-16 17:22:25 +02:00
|
|
|
#include "../mwbase/environment.hpp"
|
2012-07-03 12:30:50 +02:00
|
|
|
#include "../mwbase/world.hpp"
|
2012-05-16 17:22:25 +02:00
|
|
|
|
2014-01-14 05:37:06 +01:00
|
|
|
#include "../mwmechanics/levelledlist.hpp"
|
2018-12-15 10:23:50 +04:00
|
|
|
#include "../mwmechanics/recharge.hpp"
|
2023-06-17 22:25:47 +02:00
|
|
|
#include "../mwmechanics/spellutil.hpp"
|
2013-04-07 21:01:02 +02:00
|
|
|
|
2012-05-12 16:17:03 +02:00
|
|
|
#include "class.hpp"
|
2022-06-26 16:42:29 +02:00
|
|
|
#include "esmstore.hpp"
|
2013-01-13 19:49:56 +00:00
|
|
|
#include "localscripts.hpp"
|
2012-03-10 12:11:07 +01:00
|
|
|
#include "manualref.hpp"
|
2013-01-13 19:49:56 +00:00
|
|
|
#include "player.hpp"
|
2022-06-26 16:42:29 +02:00
|
|
|
#include "refdata.hpp"
|
2023-04-23 20:37:28 +02:00
|
|
|
#include "worldmodel.hpp"
|
2012-03-10 12:11:07 +01:00
|
|
|
|
2012-03-22 09:45:48 +01:00
|
|
|
namespace
|
|
|
|
{
|
2020-10-13 17:46:32 +02:00
|
|
|
void addScripts(MWWorld::ContainerStore& store, MWWorld::CellStore* cell)
|
|
|
|
{
|
|
|
|
auto& scripts = MWBase::Environment::get().getWorld()->getLocalScripts();
|
2020-12-04 18:34:51 +01:00
|
|
|
for (const auto&& ptr : store)
|
2020-10-13 17:46:32 +02:00
|
|
|
{
|
2022-11-13 12:04:57 +01:00
|
|
|
const auto& script = ptr.getClass().getScript(ptr);
|
2020-10-13 17:46:32 +02:00
|
|
|
if (!script.empty())
|
|
|
|
{
|
|
|
|
MWWorld::Ptr item = ptr;
|
|
|
|
item.mCell = cell;
|
|
|
|
scripts.add(script, item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-22 09:45:48 +01:00
|
|
|
template <typename T>
|
2012-06-29 18:54:23 +02:00
|
|
|
float getTotalWeight(const MWWorld::CellRefList<T>& cellRefList)
|
2012-03-22 09:45:48 +01:00
|
|
|
{
|
|
|
|
float sum = 0;
|
|
|
|
|
2022-07-02 00:47:07 +02:00
|
|
|
for (const MWWorld::LiveCellRef<T>& liveCellRef : cellRefList.mList)
|
2012-03-22 09:45:48 +01:00
|
|
|
{
|
2022-07-02 00:47:07 +02:00
|
|
|
if (const int count = liveCellRef.mData.getCount(); count > 0)
|
|
|
|
sum += count * liveCellRef.mBase->mData.mWeight;
|
2012-03-22 09:45:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return sum;
|
|
|
|
}
|
2013-08-15 18:29:09 +02:00
|
|
|
|
|
|
|
template <typename T>
|
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type
The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID
Slowly going through all the changes to make, still hundreds of errors
a lot of functions/structures use std::string or stringview to designate an ID. So it takes time
Continues slowly replacing ids. There are technically more and more compilation errors
I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type
Continue moving forward, changes to the stores
slowly moving along
Starting to see the fruit of those changes.
still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type.
More replacements. Things are starting to get easier
I can see more and more often the issue is that the function is awaiting a RefId, but is given a string
there is less need to go down functions and to fix a long list of them.
Still moving forward, and for the first time error count is going down!
Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably
Cells are back to using string for the name, haven't fixed everything yet. Many other changes
Under the bar of 400 compilation errors.
more good progress <100 compile errors!
More progress
Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string
some more progress on other fronts
Mostly game settings clean
one error opened a lot of other errors. Down to 18, but more will prbably appear
only link errors left??
Fixed link errors
OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
|
|
|
MWWorld::Ptr searchId(MWWorld::CellRefList<T>& list, const ESM::RefId& id, MWWorld::ContainerStore* store)
|
2013-08-15 18:29:09 +02:00
|
|
|
{
|
2020-10-13 17:46:32 +02:00
|
|
|
store->resolve();
|
2013-08-15 18:29:09 +02:00
|
|
|
|
2022-07-02 00:47:07 +02:00
|
|
|
for (MWWorld::LiveCellRef<T>& liveCellRef : list.mList)
|
2013-08-15 18:29:09 +02:00
|
|
|
{
|
2022-10-03 14:02:59 +02:00
|
|
|
if ((liveCellRef.mBase->mId == id) && liveCellRef.mData.getCount())
|
2013-08-15 18:29:09 +02:00
|
|
|
{
|
2022-07-02 00:47:07 +02:00
|
|
|
MWWorld::Ptr ptr(&liveCellRef, nullptr);
|
2013-08-15 18:29:09 +02:00
|
|
|
ptr.setContainerStore(store);
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return MWWorld::Ptr();
|
|
|
|
}
|
2012-03-22 09:45:48 +01:00
|
|
|
}
|
|
|
|
|
2020-10-13 17:46:32 +02:00
|
|
|
MWWorld::ResolutionListener::~ResolutionListener()
|
|
|
|
{
|
2021-04-14 23:03:35 +04:00
|
|
|
try
|
2020-10-13 17:46:32 +02:00
|
|
|
{
|
2021-04-14 23:03:35 +04:00
|
|
|
mStore.unresolve();
|
|
|
|
}
|
|
|
|
catch (const std::exception& e)
|
|
|
|
{
|
2021-04-17 22:11:51 +04:00
|
|
|
Log(Debug::Error) << "Failed to clear temporary container contents: " << e.what();
|
2020-10-13 17:46:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-01 15:24:01 +01:00
|
|
|
template <typename T>
|
2014-02-01 17:07:08 +01:00
|
|
|
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::getState(
|
|
|
|
CellRefList<T>& collection, const ESM::ObjectState& state)
|
2014-02-01 15:24:01 +01:00
|
|
|
{
|
|
|
|
if (!LiveCellRef<T>::checkState(state))
|
2014-02-01 17:07:08 +01:00
|
|
|
return ContainerStoreIterator(this); // not valid anymore with current content files -> skip
|
2014-01-31 13:25:32 +01:00
|
|
|
|
2023-04-20 21:07:53 +02:00
|
|
|
const T* record = MWBase::Environment::get().getESMStore()->get<T>().search(state.mRef.mRefID);
|
2014-01-31 13:25:32 +01:00
|
|
|
|
2014-02-01 15:24:01 +01:00
|
|
|
if (!record)
|
2014-02-01 17:07:08 +01:00
|
|
|
return ContainerStoreIterator(this);
|
2014-01-31 13:25:32 +01:00
|
|
|
|
2014-02-01 15:24:01 +01:00
|
|
|
LiveCellRef<T> ref(record);
|
|
|
|
ref.load(state);
|
|
|
|
collection.mList.push_back(ref);
|
2014-02-01 17:07:08 +01:00
|
|
|
|
|
|
|
return ContainerStoreIterator(this, --collection.mList.end());
|
2014-02-01 15:24:01 +01:00
|
|
|
}
|
2014-01-31 13:25:32 +01:00
|
|
|
|
2015-01-23 16:45:47 +01:00
|
|
|
void MWWorld::ContainerStore::storeEquipmentState(
|
|
|
|
const MWWorld::LiveCellRefBase& ref, int index, ESM::InventoryState& inventory) const
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void MWWorld::ContainerStore::readEquipmentState(
|
|
|
|
const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-02-01 15:24:01 +01:00
|
|
|
template <typename T>
|
2014-02-01 17:07:08 +01:00
|
|
|
void MWWorld::ContainerStore::storeState(const LiveCellRef<T>& ref, ESM::ObjectState& state) const
|
2014-02-01 15:24:01 +01:00
|
|
|
{
|
|
|
|
ref.save(state);
|
|
|
|
}
|
2014-01-31 13:25:32 +01:00
|
|
|
|
2014-02-01 15:24:01 +01:00
|
|
|
template <typename T>
|
2015-12-18 00:18:06 +01:00
|
|
|
void MWWorld::ContainerStore::storeStates(
|
2015-01-23 16:45:47 +01:00
|
|
|
const CellRefList<T>& collection, ESM::InventoryState& inventory, int& index, bool equipable) const
|
2014-02-01 15:24:01 +01:00
|
|
|
{
|
2022-07-02 00:47:07 +02:00
|
|
|
for (const LiveCellRef<T>& liveCellRef : collection.mList)
|
2014-01-31 13:25:32 +01:00
|
|
|
{
|
2022-07-02 00:47:07 +02:00
|
|
|
if (liveCellRef.mData.getCount() == 0)
|
2014-06-18 21:39:17 +02:00
|
|
|
continue;
|
2014-02-01 15:24:01 +01:00
|
|
|
ESM::ObjectState state;
|
2022-07-02 00:47:07 +02:00
|
|
|
storeState(liveCellRef, state);
|
2015-01-23 16:45:47 +01:00
|
|
|
if (equipable)
|
2022-07-02 00:47:07 +02:00
|
|
|
storeEquipmentState(liveCellRef, index, inventory);
|
|
|
|
inventory.mItems.push_back(std::move(state));
|
2015-01-23 16:45:47 +01:00
|
|
|
++index;
|
2014-01-31 13:25:32 +01:00
|
|
|
}
|
2012-03-22 09:45:48 +01:00
|
|
|
}
|
|
|
|
|
2022-10-18 09:26:55 +02:00
|
|
|
const ESM::RefId MWWorld::ContainerStore::sGoldId = ESM::RefId::stringRefId("gold_001");
|
2014-01-08 23:37:46 +01:00
|
|
|
|
2018-12-15 10:23:50 +04:00
|
|
|
MWWorld::ContainerStore::ContainerStore()
|
|
|
|
: mListener(nullptr)
|
|
|
|
, mRechargingItemsUpToDate(false)
|
|
|
|
, mCachedWeight(0)
|
2020-10-13 17:46:32 +02:00
|
|
|
, mWeightUpToDate(false)
|
|
|
|
, mModified(false)
|
|
|
|
, mResolved(false)
|
|
|
|
, mSeed()
|
|
|
|
, mPtr()
|
|
|
|
{
|
|
|
|
}
|
2012-03-21 12:48:05 +01:00
|
|
|
|
2012-03-10 12:43:48 +01:00
|
|
|
MWWorld::ContainerStore::~ContainerStore() {}
|
|
|
|
|
2017-02-19 14:30:26 +00:00
|
|
|
MWWorld::ConstContainerStoreIterator MWWorld::ContainerStore::cbegin(int mask) const
|
2012-02-20 14:14:39 +01:00
|
|
|
{
|
2017-02-19 14:30:26 +00:00
|
|
|
return ConstContainerStoreIterator(mask, this);
|
2012-02-20 14:14:39 +01:00
|
|
|
}
|
|
|
|
|
2017-02-19 14:30:26 +00:00
|
|
|
MWWorld::ConstContainerStoreIterator MWWorld::ContainerStore::cend() const
|
2012-02-20 14:14:39 +01:00
|
|
|
{
|
2017-02-19 14:30:26 +00:00
|
|
|
return ConstContainerStoreIterator(this);
|
2012-02-20 14:14:39 +01:00
|
|
|
}
|
|
|
|
|
2017-02-19 14:30:26 +00:00
|
|
|
MWWorld::ConstContainerStoreIterator MWWorld::ContainerStore::begin(int mask) const
|
2017-02-14 19:34:54 +00:00
|
|
|
{
|
2017-02-19 14:30:26 +00:00
|
|
|
return cbegin(mask);
|
2017-02-14 19:34:54 +00:00
|
|
|
}
|
|
|
|
|
2017-02-19 14:30:26 +00:00
|
|
|
MWWorld::ConstContainerStoreIterator MWWorld::ContainerStore::end() const
|
2017-02-14 19:34:54 +00:00
|
|
|
{
|
2017-02-19 14:30:26 +00:00
|
|
|
return cend();
|
|
|
|
}
|
|
|
|
|
|
|
|
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::begin(int mask)
|
|
|
|
{
|
|
|
|
return ContainerStoreIterator(mask, this);
|
|
|
|
}
|
|
|
|
|
|
|
|
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::end()
|
|
|
|
{
|
|
|
|
return ContainerStoreIterator(this);
|
2017-02-14 19:34:54 +00:00
|
|
|
}
|
|
|
|
|
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type
The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID
Slowly going through all the changes to make, still hundreds of errors
a lot of functions/structures use std::string or stringview to designate an ID. So it takes time
Continues slowly replacing ids. There are technically more and more compilation errors
I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type
Continue moving forward, changes to the stores
slowly moving along
Starting to see the fruit of those changes.
still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type.
More replacements. Things are starting to get easier
I can see more and more often the issue is that the function is awaiting a RefId, but is given a string
there is less need to go down functions and to fix a long list of them.
Still moving forward, and for the first time error count is going down!
Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably
Cells are back to using string for the name, haven't fixed everything yet. Many other changes
Under the bar of 400 compilation errors.
more good progress <100 compile errors!
More progress
Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string
some more progress on other fronts
Mostly game settings clean
one error opened a lot of other errors. Down to 18, but more will prbably appear
only link errors left??
Fixed link errors
OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
|
|
|
int MWWorld::ContainerStore::count(const ESM::RefId& id) const
|
2017-06-15 21:59:13 -05:00
|
|
|
{
|
|
|
|
int total = 0;
|
2020-12-04 18:34:51 +01:00
|
|
|
for (const auto&& iter : *this)
|
2022-10-18 09:26:55 +02:00
|
|
|
if (iter.getCellRef().getRefId() == id)
|
2020-10-13 17:46:32 +02:00
|
|
|
total += iter.getRefData().getCount();
|
2017-06-15 21:59:13 -05:00
|
|
|
return total;
|
|
|
|
}
|
|
|
|
|
2023-01-17 03:04:34 +01:00
|
|
|
void MWWorld::ContainerStore::clearRefNums()
|
|
|
|
{
|
|
|
|
for (const auto& iter : *this)
|
|
|
|
iter.getCellRef().unsetRefNum();
|
|
|
|
}
|
|
|
|
|
2016-10-08 03:49:50 +02:00
|
|
|
MWWorld::ContainerStoreListener* MWWorld::ContainerStore::getContListener() const
|
|
|
|
{
|
|
|
|
return mListener;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MWWorld::ContainerStore::setContListener(MWWorld::ContainerStoreListener* listener)
|
|
|
|
{
|
|
|
|
mListener = listener;
|
|
|
|
}
|
|
|
|
|
2023-01-16 23:51:04 +01:00
|
|
|
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::unstack(const Ptr& ptr, int count)
|
2013-11-14 21:02:37 +01:00
|
|
|
{
|
2020-10-13 17:46:32 +02:00
|
|
|
resolve();
|
2016-01-18 19:56:35 -06:00
|
|
|
if (ptr.getRefData().getCount() <= count)
|
|
|
|
return end();
|
2020-10-13 17:46:32 +02:00
|
|
|
MWWorld::ContainerStoreIterator it = addNewStack(ptr, subtractItems(ptr.getRefData().getCount(false), count));
|
2023-07-08 14:44:50 +02:00
|
|
|
|
|
|
|
MWWorld::Ptr newPtr = *it;
|
|
|
|
newPtr.getCellRef().unsetRefNum();
|
|
|
|
newPtr.getRefData().setLuaScripts(nullptr);
|
|
|
|
MWBase::Environment::get().getWorldModel()->registerPtr(newPtr);
|
|
|
|
|
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type
The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID
Slowly going through all the changes to make, still hundreds of errors
a lot of functions/structures use std::string or stringview to designate an ID. So it takes time
Continues slowly replacing ids. There are technically more and more compilation errors
I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type
Continue moving forward, changes to the stores
slowly moving along
Starting to see the fruit of those changes.
still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type.
More replacements. Things are starting to get easier
I can see more and more often the issue is that the function is awaiting a RefId, but is given a string
there is less need to go down functions and to fix a long list of them.
Still moving forward, and for the first time error count is going down!
Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably
Cells are back to using string for the name, haven't fixed everything yet. Many other changes
Under the bar of 400 compilation errors.
more good progress <100 compile errors!
More progress
Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string
some more progress on other fronts
Mostly game settings clean
one error opened a lot of other errors. Down to 18, but more will prbably appear
only link errors left??
Fixed link errors
OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
|
|
|
const ESM::RefId& script = it->getClass().getScript(*it);
|
2015-10-07 02:43:21 +02:00
|
|
|
if (!script.empty())
|
|
|
|
MWBase::Environment::get().getWorld()->getLocalScripts().add(script, *it);
|
|
|
|
|
2023-01-16 23:51:04 +01:00
|
|
|
remove(ptr, ptr.getRefData().getCount() - count);
|
2016-01-18 19:56:35 -06:00
|
|
|
|
|
|
|
return it;
|
2013-11-14 21:02:37 +01:00
|
|
|
}
|
|
|
|
|
2014-07-16 15:30:06 +02:00
|
|
|
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::restack(const MWWorld::Ptr& item)
|
|
|
|
{
|
2020-10-13 17:46:32 +02:00
|
|
|
resolve();
|
2014-07-16 15:30:06 +02:00
|
|
|
MWWorld::ContainerStoreIterator retval = end();
|
|
|
|
for (MWWorld::ContainerStoreIterator iter(begin()); iter != end(); ++iter)
|
|
|
|
{
|
|
|
|
if (item == *iter)
|
|
|
|
{
|
|
|
|
retval = iter;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (retval == end())
|
|
|
|
throw std::runtime_error("item is not from this container");
|
|
|
|
|
|
|
|
for (MWWorld::ContainerStoreIterator iter(begin()); iter != end(); ++iter)
|
|
|
|
{
|
|
|
|
if (stacks(*iter, item))
|
|
|
|
{
|
2020-10-13 17:46:32 +02:00
|
|
|
iter->getRefData().setCount(
|
|
|
|
addItems(iter->getRefData().getCount(false), item.getRefData().getCount(false)));
|
2014-07-16 15:30:06 +02:00
|
|
|
item.getRefData().setCount(0);
|
|
|
|
retval = iter;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2017-02-19 14:30:26 +00:00
|
|
|
bool MWWorld::ContainerStore::stacks(const ConstPtr& ptr1, const ConstPtr& ptr2) const
|
2012-05-12 23:09:03 +02:00
|
|
|
{
|
2014-05-22 20:37:22 +02:00
|
|
|
const MWWorld::Class& cls1 = ptr1.getClass();
|
|
|
|
const MWWorld::Class& cls2 = ptr2.getClass();
|
2013-10-23 14:36:55 +02:00
|
|
|
|
2022-10-18 09:26:55 +02:00
|
|
|
if (!(ptr1.getCellRef().getRefId() == ptr2.getCellRef().getRefId()))
|
2013-11-14 21:02:37 +01:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// If it has an enchantment, don't stack when some of the charge is already used
|
|
|
|
if (!ptr1.getClass().getEnchantment(ptr1).empty())
|
|
|
|
{
|
2023-04-20 21:07:53 +02:00
|
|
|
const ESM::Enchantment* enchantment = MWBase::Environment::get().getESMStore()->get<ESM::Enchantment>().find(
|
|
|
|
ptr1.getClass().getEnchantment(ptr1));
|
2023-06-17 22:25:47 +02:00
|
|
|
const float maxCharge = static_cast<float>(MWMechanics::getEnchantmentCharge(*enchantment));
|
2014-05-25 14:13:07 +02:00
|
|
|
float enchantCharge1
|
|
|
|
= ptr1.getCellRef().getEnchantmentCharge() == -1 ? maxCharge : ptr1.getCellRef().getEnchantmentCharge();
|
|
|
|
float enchantCharge2
|
|
|
|
= ptr2.getCellRef().getEnchantmentCharge() == -1 ? maxCharge : ptr2.getCellRef().getEnchantmentCharge();
|
2013-11-14 21:02:37 +01:00
|
|
|
if (enchantCharge1 != maxCharge || enchantCharge2 != maxCharge)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-11-12 23:12:56 +01:00
|
|
|
return ptr1 != ptr2 // an item never stacks onto itself
|
2014-05-25 14:13:07 +02:00
|
|
|
&& ptr1.getCellRef().getSoul() == ptr2.getCellRef().getSoul()
|
2013-10-23 14:36:55 +02:00
|
|
|
|
2013-12-16 13:31:03 +01:00
|
|
|
&& ptr1.getClass().getRemainingUsageTime(ptr1) == ptr2.getClass().getRemainingUsageTime(ptr2)
|
|
|
|
|
2018-12-06 18:31:47 +03:00
|
|
|
// Items with scripts never stack
|
|
|
|
&& cls1.getScript(ptr1).empty()
|
|
|
|
&& cls2.getScript(ptr2).empty()
|
2013-10-23 14:36:55 +02:00
|
|
|
|
|
|
|
// item that is already partly used up never stacks
|
2014-05-25 14:13:07 +02:00
|
|
|
&& (!cls1.hasItemHealth(ptr1)
|
|
|
|
|| (cls1.getItemHealth(ptr1) == cls1.getItemMaxHealth(ptr1)
|
|
|
|
&& cls2.getItemHealth(ptr2) == cls2.getItemMaxHealth(ptr2)));
|
2012-05-12 23:09:03 +02:00
|
|
|
}
|
|
|
|
|
2023-01-16 23:51:04 +01:00
|
|
|
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add(const ESM::RefId& id, int count)
|
2013-11-21 04:11:06 +01:00
|
|
|
{
|
2023-04-20 21:07:53 +02:00
|
|
|
MWWorld::ManualRef ref(*MWBase::Environment::get().getESMStore(), id, count);
|
2023-01-16 23:51:04 +01:00
|
|
|
return add(ref.getPtr(), count);
|
2013-11-21 04:11:06 +01:00
|
|
|
}
|
|
|
|
|
2020-10-20 09:22:43 +00:00
|
|
|
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add(
|
2023-01-16 23:51:04 +01:00
|
|
|
const Ptr& itemPtr, int count, bool /*allowAutoEquip*/, bool resolve)
|
2013-01-13 19:49:56 +00:00
|
|
|
{
|
2014-04-27 05:40:07 +02:00
|
|
|
Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
|
|
|
|
2020-10-20 09:22:43 +00:00
|
|
|
MWWorld::ContainerStoreIterator it = addImp(itemPtr, count, resolve);
|
2023-04-23 20:37:28 +02:00
|
|
|
itemPtr.getRefData().setLuaScripts(nullptr); // clear Lua scripts on the original (removed) item.
|
2015-02-04 21:18:43 +01:00
|
|
|
|
2014-04-27 05:54:19 +02:00
|
|
|
// The copy of the original item we just made
|
|
|
|
MWWorld::Ptr item = *it;
|
2023-05-30 21:44:54 +02:00
|
|
|
MWBase::Environment::get().getWorldModel()->registerPtr(item);
|
2014-04-27 05:54:19 +02:00
|
|
|
|
|
|
|
// we may have copied an item from the world, so reset a few things first
|
2018-10-09 10:21:12 +04:00
|
|
|
item.getRefData().setBaseNode(
|
|
|
|
nullptr); // Especially important, otherwise scripts on the item could think that it's actually in a cell
|
2014-05-25 14:13:07 +02:00
|
|
|
ESM::Position pos;
|
|
|
|
pos.rot[0] = 0;
|
|
|
|
pos.rot[1] = 0;
|
|
|
|
pos.rot[2] = 0;
|
|
|
|
pos.pos[0] = 0;
|
|
|
|
pos.pos[1] = 0;
|
|
|
|
pos.pos[2] = 0;
|
|
|
|
item.getCellRef().setPosition(pos);
|
2015-02-04 21:18:43 +01:00
|
|
|
|
2019-10-05 16:47:41 +04:00
|
|
|
// We do not need to store owners for items in container stores - we do not use it anyway.
|
2023-02-17 19:20:29 +01:00
|
|
|
item.getCellRef().setOwner(ESM::RefId());
|
2015-02-04 21:18:43 +01:00
|
|
|
item.getCellRef().resetGlobalVariable();
|
2023-02-17 19:20:29 +01:00
|
|
|
item.getCellRef().setFaction(ESM::RefId());
|
2020-03-17 17:12:04 +04:00
|
|
|
item.getCellRef().setFactionRank(-2);
|
2015-02-04 21:18:43 +01:00
|
|
|
|
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type
The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID
Slowly going through all the changes to make, still hundreds of errors
a lot of functions/structures use std::string or stringview to designate an ID. So it takes time
Continues slowly replacing ids. There are technically more and more compilation errors
I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type
Continue moving forward, changes to the stores
slowly moving along
Starting to see the fruit of those changes.
still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type.
More replacements. Things are starting to get easier
I can see more and more often the issue is that the function is awaiting a RefId, but is given a string
there is less need to go down functions and to fix a long list of them.
Still moving forward, and for the first time error count is going down!
Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably
Cells are back to using string for the name, haven't fixed everything yet. Many other changes
Under the bar of 400 compilation errors.
more good progress <100 compile errors!
More progress
Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string
some more progress on other fronts
Mostly game settings clean
one error opened a lot of other errors. Down to 18, but more will prbably appear
only link errors left??
Fixed link errors
OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
|
|
|
const ESM::RefId& script = item.getClass().getScript(item);
|
2018-12-06 18:31:47 +03:00
|
|
|
if (!script.empty())
|
2013-01-13 19:49:56 +00:00
|
|
|
{
|
2023-01-16 23:51:04 +01:00
|
|
|
if (mActor == player)
|
2013-02-02 17:36:12 +00:00
|
|
|
{
|
2014-05-28 18:45:07 +02:00
|
|
|
// Items in player's inventory have cell set to 0, so their scripts will never be removed
|
2020-11-13 11:39:47 +04:00
|
|
|
item.mCell = nullptr;
|
2013-02-02 17:36:12 +00:00
|
|
|
}
|
2013-01-13 19:49:56 +00:00
|
|
|
else
|
2014-05-28 18:45:07 +02:00
|
|
|
{
|
|
|
|
// Set mCell to the cell of the container/actor, so that the scripts are removed properly when
|
|
|
|
// the cell of the container/actor goes inactive
|
2023-01-16 23:51:04 +01:00
|
|
|
if (!mPtr.isEmpty())
|
|
|
|
item.mCell = mPtr.getCell();
|
|
|
|
else if (!mActor.isEmpty())
|
|
|
|
item.mCell = mActor.getCell();
|
2014-05-28 18:45:07 +02:00
|
|
|
}
|
2013-01-13 19:49:56 +00:00
|
|
|
|
2014-10-24 18:49:38 +02:00
|
|
|
item.mContainerStore = this;
|
2014-05-28 18:45:07 +02:00
|
|
|
|
|
|
|
MWBase::Environment::get().getWorld()->getLocalScripts().add(script, item);
|
|
|
|
|
|
|
|
// Set OnPCAdd special variable, if it is declared
|
|
|
|
// Make sure to do this *after* we have added the script to LocalScripts
|
2023-01-16 23:51:04 +01:00
|
|
|
if (mActor == player)
|
2014-05-28 18:45:07 +02:00
|
|
|
item.getRefData().getLocals().setVarByInt(script, "onpcadd", 1);
|
2013-01-13 19:49:56 +00:00
|
|
|
}
|
|
|
|
|
2018-03-03 14:16:21 +04:00
|
|
|
// we should not fire event for InventoryStore yet - it has some custom logic
|
2023-01-16 23:51:04 +01:00
|
|
|
if (mListener && !(!mActor.isEmpty() && mActor.getClass().hasInventoryStore(mActor)))
|
2016-10-08 03:49:50 +02:00
|
|
|
mListener->itemAdded(item, count);
|
|
|
|
|
2013-01-13 19:49:56 +00:00
|
|
|
return it;
|
|
|
|
}
|
|
|
|
|
2020-10-13 17:46:32 +02:00
|
|
|
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp(const Ptr& ptr, int count, bool markModified)
|
2012-02-23 12:34:25 +01:00
|
|
|
{
|
2020-10-13 17:46:32 +02:00
|
|
|
if (markModified)
|
|
|
|
resolve();
|
2012-05-12 16:30:27 +02:00
|
|
|
int type = getType(ptr);
|
|
|
|
|
2023-04-20 21:07:53 +02:00
|
|
|
const MWWorld::ESMStore& esmStore = *MWBase::Environment::get().getESMStore();
|
2012-11-06 12:36:21 +04:00
|
|
|
|
2012-05-19 00:36:01 +02:00
|
|
|
// gold needs special handling: when it is inserted into a container, the base object automatically becomes Gold_001
|
|
|
|
// this ensures that gold piles of different sizes stack with each other (also, several scripts rely on Gold_001 for
|
|
|
|
// detecting player gold)
|
2015-07-20 12:43:58 +09:00
|
|
|
if (ptr.getClass().isGold(ptr))
|
2012-05-16 17:22:25 +02:00
|
|
|
{
|
2015-07-20 12:43:58 +09:00
|
|
|
int realCount = count * ptr.getClass().getValue(ptr);
|
|
|
|
|
2013-03-30 16:27:06 +01:00
|
|
|
for (MWWorld::ContainerStoreIterator iter(begin(type)); iter != end(); ++iter)
|
|
|
|
{
|
2022-10-18 09:26:55 +02:00
|
|
|
if (iter->getCellRef().getRefId() == MWWorld::ContainerStore::sGoldId)
|
2012-05-19 00:36:01 +02:00
|
|
|
{
|
2020-10-13 17:46:32 +02:00
|
|
|
iter->getRefData().setCount(addItems(iter->getRefData().getCount(false), realCount));
|
2013-03-30 16:27:06 +01:00
|
|
|
flagAsModified();
|
|
|
|
return iter;
|
2012-05-16 17:22:25 +02:00
|
|
|
}
|
2012-05-19 00:36:01 +02:00
|
|
|
}
|
2013-03-30 16:27:06 +01:00
|
|
|
|
2015-07-20 12:43:58 +09:00
|
|
|
MWWorld::ManualRef ref(esmStore, MWWorld::ContainerStore::sGoldId, realCount);
|
|
|
|
return addNewStack(ref.getPtr(), realCount);
|
2012-05-16 17:22:25 +02:00
|
|
|
}
|
|
|
|
|
2012-05-12 16:17:03 +02:00
|
|
|
// determine whether to stack or not
|
2012-05-12 16:30:27 +02:00
|
|
|
for (MWWorld::ContainerStoreIterator iter(begin(type)); iter != end(); ++iter)
|
2012-05-12 16:17:03 +02:00
|
|
|
{
|
2023-06-28 09:32:15 +00:00
|
|
|
// Don't stack with equipped items
|
|
|
|
if (!mActor.isEmpty() && mActor.getClass().hasInventoryStore(mActor))
|
|
|
|
if (mActor.getClass().getInventoryStore(mActor).isEquipped(*iter))
|
|
|
|
continue;
|
|
|
|
|
2012-05-12 23:09:03 +02:00
|
|
|
if (stacks(*iter, ptr))
|
2012-05-12 16:17:03 +02:00
|
|
|
{
|
|
|
|
// stack
|
2020-10-13 17:46:32 +02:00
|
|
|
iter->getRefData().setCount(addItems(iter->getRefData().getCount(false), count));
|
2012-05-12 16:17:03 +02:00
|
|
|
|
|
|
|
flagAsModified();
|
2012-05-15 20:33:34 +02:00
|
|
|
return iter;
|
2012-05-12 16:17:03 +02:00
|
|
|
}
|
|
|
|
}
|
2012-05-13 11:52:17 +02:00
|
|
|
// if we got here, this means no stacking
|
2014-01-05 20:53:45 +01:00
|
|
|
return addNewStack(ptr, count);
|
2012-05-13 11:52:17 +02:00
|
|
|
}
|
|
|
|
|
2015-12-18 17:04:54 +01:00
|
|
|
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addNewStack(const ConstPtr& ptr, int count)
|
2012-05-13 11:52:17 +02:00
|
|
|
{
|
2012-05-16 00:02:05 +02:00
|
|
|
ContainerStoreIterator it = begin();
|
|
|
|
|
2012-05-13 11:52:17 +02:00
|
|
|
switch (getType(ptr))
|
2012-02-23 12:34:25 +01:00
|
|
|
{
|
2012-11-05 16:07:59 +04:00
|
|
|
case Type_Potion:
|
|
|
|
potions.mList.push_back(*ptr.get<ESM::Potion>());
|
|
|
|
it = ContainerStoreIterator(this, --potions.mList.end());
|
|
|
|
break;
|
|
|
|
case Type_Apparatus:
|
|
|
|
appas.mList.push_back(*ptr.get<ESM::Apparatus>());
|
|
|
|
it = ContainerStoreIterator(this, --appas.mList.end());
|
|
|
|
break;
|
|
|
|
case Type_Armor:
|
|
|
|
armors.mList.push_back(*ptr.get<ESM::Armor>());
|
|
|
|
it = ContainerStoreIterator(this, --armors.mList.end());
|
|
|
|
break;
|
|
|
|
case Type_Book:
|
|
|
|
books.mList.push_back(*ptr.get<ESM::Book>());
|
|
|
|
it = ContainerStoreIterator(this, --books.mList.end());
|
|
|
|
break;
|
|
|
|
case Type_Clothing:
|
|
|
|
clothes.mList.push_back(*ptr.get<ESM::Clothing>());
|
|
|
|
it = ContainerStoreIterator(this, --clothes.mList.end());
|
|
|
|
break;
|
|
|
|
case Type_Ingredient:
|
|
|
|
ingreds.mList.push_back(*ptr.get<ESM::Ingredient>());
|
|
|
|
it = ContainerStoreIterator(this, --ingreds.mList.end());
|
|
|
|
break;
|
|
|
|
case Type_Light:
|
|
|
|
lights.mList.push_back(*ptr.get<ESM::Light>());
|
|
|
|
it = ContainerStoreIterator(this, --lights.mList.end());
|
|
|
|
break;
|
2013-03-22 05:50:54 +01:00
|
|
|
case Type_Lockpick:
|
|
|
|
lockpicks.mList.push_back(*ptr.get<ESM::Lockpick>());
|
|
|
|
it = ContainerStoreIterator(this, --lockpicks.mList.end());
|
|
|
|
break;
|
2012-11-05 16:07:59 +04:00
|
|
|
case Type_Miscellaneous:
|
|
|
|
miscItems.mList.push_back(*ptr.get<ESM::Miscellaneous>());
|
|
|
|
it = ContainerStoreIterator(this, --miscItems.mList.end());
|
|
|
|
break;
|
|
|
|
case Type_Probe:
|
|
|
|
probes.mList.push_back(*ptr.get<ESM::Probe>());
|
|
|
|
it = ContainerStoreIterator(this, --probes.mList.end());
|
|
|
|
break;
|
|
|
|
case Type_Repair:
|
|
|
|
repairs.mList.push_back(*ptr.get<ESM::Repair>());
|
|
|
|
it = ContainerStoreIterator(this, --repairs.mList.end());
|
|
|
|
break;
|
|
|
|
case Type_Weapon:
|
|
|
|
weapons.mList.push_back(*ptr.get<ESM::Weapon>());
|
|
|
|
it = ContainerStoreIterator(this, --weapons.mList.end());
|
|
|
|
break;
|
2012-02-23 12:34:25 +01:00
|
|
|
}
|
2012-03-21 12:48:05 +01:00
|
|
|
|
2014-01-05 20:53:45 +01:00
|
|
|
it->getRefData().setCount(count);
|
|
|
|
|
2012-03-21 12:48:05 +01:00
|
|
|
flagAsModified();
|
2012-05-16 00:02:05 +02:00
|
|
|
return it;
|
2012-02-23 12:34:25 +01:00
|
|
|
}
|
|
|
|
|
2018-12-15 10:23:50 +04:00
|
|
|
void MWWorld::ContainerStore::rechargeItems(float duration)
|
|
|
|
{
|
|
|
|
if (!mRechargingItemsUpToDate)
|
|
|
|
{
|
|
|
|
updateRechargingItems();
|
|
|
|
mRechargingItemsUpToDate = true;
|
|
|
|
}
|
2020-12-04 18:34:51 +01:00
|
|
|
for (auto& it : mRechargingItems)
|
2018-12-15 10:23:50 +04:00
|
|
|
{
|
2020-12-04 18:34:51 +01:00
|
|
|
if (!MWMechanics::rechargeItem(*it.first, it.second, duration))
|
2018-12-15 10:23:50 +04:00
|
|
|
continue;
|
|
|
|
|
|
|
|
// attempt to restack when fully recharged
|
2020-12-04 18:34:51 +01:00
|
|
|
if (it.first->getCellRef().getEnchantmentCharge() == it.second)
|
|
|
|
it.first = restack(*it.first);
|
2018-12-15 10:23:50 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MWWorld::ContainerStore::updateRechargingItems()
|
|
|
|
{
|
|
|
|
mRechargingItems.clear();
|
|
|
|
for (ContainerStoreIterator it = begin(); it != end(); ++it)
|
|
|
|
{
|
2022-11-18 01:55:07 +01:00
|
|
|
const auto& enchantmentId = it->getClass().getEnchantment(*it);
|
2018-12-15 10:23:50 +04:00
|
|
|
if (!enchantmentId.empty())
|
|
|
|
{
|
|
|
|
const ESM::Enchantment* enchantment
|
2023-04-20 21:07:53 +02:00
|
|
|
= MWBase::Environment::get().getESMStore()->get<ESM::Enchantment>().search(enchantmentId);
|
2018-12-15 10:23:50 +04:00
|
|
|
if (!enchantment)
|
|
|
|
{
|
|
|
|
Log(Debug::Warning) << "Warning: Can't find enchantment '" << enchantmentId << "' on item "
|
|
|
|
<< it->getCellRef().getRefId();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (enchantment->mData.mType == ESM::Enchantment::WhenUsed
|
|
|
|
|| enchantment->mData.mType == ESM::Enchantment::WhenStrikes)
|
2023-06-17 22:25:47 +02:00
|
|
|
mRechargingItems.emplace_back(it, static_cast<float>(MWMechanics::getEnchantmentCharge(*enchantment)));
|
2018-12-15 10:23:50 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-16 23:51:04 +01:00
|
|
|
int MWWorld::ContainerStore::remove(const ESM::RefId& itemId, int count, bool equipReplacement, bool resolveFirst)
|
2013-08-13 01:19:33 +02:00
|
|
|
{
|
2020-10-20 09:22:43 +00:00
|
|
|
if (resolveFirst)
|
|
|
|
resolve();
|
2013-08-13 01:19:33 +02:00
|
|
|
int toRemove = count;
|
|
|
|
|
|
|
|
for (ContainerStoreIterator iter(begin()); iter != end() && toRemove > 0; ++iter)
|
2022-10-18 09:26:55 +02:00
|
|
|
if (iter->getCellRef().getRefId() == itemId)
|
2023-01-16 23:51:04 +01:00
|
|
|
toRemove -= remove(*iter, toRemove, equipReplacement, resolveFirst);
|
2013-08-13 01:19:33 +02:00
|
|
|
|
2013-11-12 23:17:03 +01:00
|
|
|
flagAsModified();
|
|
|
|
|
2013-08-13 01:19:33 +02:00
|
|
|
// number of removed items
|
|
|
|
return count - toRemove;
|
|
|
|
}
|
|
|
|
|
2018-12-03 20:21:40 +04:00
|
|
|
bool MWWorld::ContainerStore::hasVisibleItems() const
|
|
|
|
{
|
2020-12-04 18:34:51 +01:00
|
|
|
for (const auto&& iter : *this)
|
2018-12-03 20:21:40 +04:00
|
|
|
{
|
2020-12-04 18:34:51 +01:00
|
|
|
if (iter.getClass().showsInInventory(iter))
|
2018-12-03 20:21:40 +04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-01-16 23:51:04 +01:00
|
|
|
int MWWorld::ContainerStore::remove(const Ptr& item, int count, bool equipReplacement, bool resolveFirst)
|
2013-08-13 01:19:33 +02:00
|
|
|
{
|
|
|
|
assert(this == item.getContainerStore());
|
2020-10-26 20:13:24 +01:00
|
|
|
if (resolveFirst)
|
|
|
|
resolve();
|
2020-10-20 09:22:43 +00:00
|
|
|
|
2013-08-13 01:19:33 +02:00
|
|
|
int toRemove = count;
|
|
|
|
RefData& itemRef = item.getRefData();
|
|
|
|
|
|
|
|
if (itemRef.getCount() <= toRemove)
|
|
|
|
{
|
|
|
|
toRemove -= itemRef.getCount();
|
|
|
|
itemRef.setCount(0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-10-13 17:46:32 +02:00
|
|
|
itemRef.setCount(subtractItems(itemRef.getCount(false), toRemove));
|
2013-08-13 01:19:33 +02:00
|
|
|
toRemove = 0;
|
|
|
|
}
|
|
|
|
|
2013-11-12 23:17:03 +01:00
|
|
|
flagAsModified();
|
|
|
|
|
2018-03-03 14:16:21 +04:00
|
|
|
// we should not fire event for InventoryStore yet - it has some custom logic
|
2023-01-16 23:51:04 +01:00
|
|
|
if (mListener && !(!mActor.isEmpty() && mActor.getClass().hasInventoryStore(mActor)))
|
2016-10-08 03:49:50 +02:00
|
|
|
mListener->itemRemoved(item, count - toRemove);
|
|
|
|
|
2013-08-13 01:19:33 +02:00
|
|
|
// number of removed items
|
|
|
|
return count - toRemove;
|
|
|
|
}
|
|
|
|
|
2022-10-18 09:26:55 +02:00
|
|
|
void MWWorld::ContainerStore::fill(const ESM::InventoryList& items, const ESM::RefId& owner, Misc::Rng::Generator& prng)
|
2020-10-13 17:46:32 +02:00
|
|
|
{
|
|
|
|
for (const ESM::ContItem& iter : items.mList)
|
|
|
|
{
|
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type
The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID
Slowly going through all the changes to make, still hundreds of errors
a lot of functions/structures use std::string or stringview to designate an ID. So it takes time
Continues slowly replacing ids. There are technically more and more compilation errors
I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type
Continue moving forward, changes to the stores
slowly moving along
Starting to see the fruit of those changes.
still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type.
More replacements. Things are starting to get easier
I can see more and more often the issue is that the function is awaiting a RefId, but is given a string
there is less need to go down functions and to fix a long list of them.
Still moving forward, and for the first time error count is going down!
Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably
Cells are back to using string for the name, haven't fixed everything yet. Many other changes
Under the bar of 400 compilation errors.
more good progress <100 compile errors!
More progress
Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string
some more progress on other fronts
Mostly game settings clean
one error opened a lot of other errors. Down to 18, but more will prbably appear
only link errors left??
Fixed link errors
OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
|
|
|
addInitialItem(iter.mItem, owner, iter.mCount, &prng);
|
2020-10-13 17:46:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
flagAsModified();
|
|
|
|
mResolved = true;
|
|
|
|
}
|
|
|
|
|
2022-10-18 09:26:55 +02:00
|
|
|
void MWWorld::ContainerStore::fillNonRandom(const ESM::InventoryList& items, const ESM::RefId& owner, unsigned int seed)
|
2012-03-10 12:11:07 +01:00
|
|
|
{
|
2020-10-13 17:46:32 +02:00
|
|
|
mSeed = seed;
|
|
|
|
for (const ESM::ContItem& iter : items.mList)
|
2012-03-10 12:11:07 +01:00
|
|
|
{
|
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type
The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID
Slowly going through all the changes to make, still hundreds of errors
a lot of functions/structures use std::string or stringview to designate an ID. So it takes time
Continues slowly replacing ids. There are technically more and more compilation errors
I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type
Continue moving forward, changes to the stores
slowly moving along
Starting to see the fruit of those changes.
still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type.
More replacements. Things are starting to get easier
I can see more and more often the issue is that the function is awaiting a RefId, but is given a string
there is less need to go down functions and to fix a long list of them.
Still moving forward, and for the first time error count is going down!
Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably
Cells are back to using string for the name, haven't fixed everything yet. Many other changes
Under the bar of 400 compilation errors.
more good progress <100 compile errors!
More progress
Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string
some more progress on other fronts
Mostly game settings clean
one error opened a lot of other errors. Down to 18, but more will prbably appear
only link errors left??
Fixed link errors
OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
|
|
|
addInitialItem(iter.mItem, owner, iter.mCount, nullptr);
|
2013-04-07 21:01:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
flagAsModified();
|
2020-10-13 17:46:32 +02:00
|
|
|
mResolved = false;
|
2013-04-07 21:01:02 +02:00
|
|
|
}
|
|
|
|
|
2022-08-24 20:38:52 +02:00
|
|
|
void MWWorld::ContainerStore::addInitialItem(
|
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type
The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID
Slowly going through all the changes to make, still hundreds of errors
a lot of functions/structures use std::string or stringview to designate an ID. So it takes time
Continues slowly replacing ids. There are technically more and more compilation errors
I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type
Continue moving forward, changes to the stores
slowly moving along
Starting to see the fruit of those changes.
still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type.
More replacements. Things are starting to get easier
I can see more and more often the issue is that the function is awaiting a RefId, but is given a string
there is less need to go down functions and to fix a long list of them.
Still moving forward, and for the first time error count is going down!
Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably
Cells are back to using string for the name, haven't fixed everything yet. Many other changes
Under the bar of 400 compilation errors.
more good progress <100 compile errors!
More progress
Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string
some more progress on other fronts
Mostly game settings clean
one error opened a lot of other errors. Down to 18, but more will prbably appear
only link errors left??
Fixed link errors
OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
|
|
|
const ESM::RefId& id, const ESM::RefId& owner, int count, Misc::Rng::Generator* prng, bool topLevel)
|
2013-04-07 21:01:02 +02:00
|
|
|
{
|
2015-12-08 22:38:26 +01:00
|
|
|
if (count == 0)
|
|
|
|
return; // Don't restock with nothing.
|
2019-09-29 13:08:52 +04:00
|
|
|
try
|
|
|
|
{
|
2023-04-20 21:07:53 +02:00
|
|
|
ManualRef ref(*MWBase::Environment::get().getESMStore(), id, count);
|
2019-09-29 13:08:52 +04:00
|
|
|
if (ref.getPtr().getClass().getScript(ref.getPtr()).empty())
|
2013-04-25 04:44:30 +02:00
|
|
|
{
|
2022-03-06 15:58:16 +02:00
|
|
|
addInitialItemImp(ref.getPtr(), owner, count, prng, topLevel);
|
2013-04-25 04:44:30 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-09-29 13:08:52 +04:00
|
|
|
// Adding just one item per time to make sure there isn't a stack of scripted items
|
2020-10-13 17:46:32 +02:00
|
|
|
for (int i = 0; i < std::abs(count); i++)
|
2022-03-06 15:58:16 +02:00
|
|
|
addInitialItemImp(ref.getPtr(), owner, count < 0 ? -1 : 1, prng, topLevel);
|
2013-04-07 21:01:02 +02:00
|
|
|
}
|
|
|
|
}
|
2015-09-24 16:42:10 +02:00
|
|
|
catch (const std::exception& e)
|
2013-04-07 21:01:02 +02:00
|
|
|
{
|
2018-08-14 23:05:43 +04:00
|
|
|
Log(Debug::Warning) << "Warning: MWWorld::ContainerStore::addInitialItem: " << e.what();
|
2012-03-10 12:11:07 +01:00
|
|
|
}
|
2019-09-29 13:08:52 +04:00
|
|
|
}
|
|
|
|
|
2020-10-13 17:46:32 +02:00
|
|
|
void MWWorld::ContainerStore::addInitialItemImp(
|
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type
The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID
Slowly going through all the changes to make, still hundreds of errors
a lot of functions/structures use std::string or stringview to designate an ID. So it takes time
Continues slowly replacing ids. There are technically more and more compilation errors
I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type
Continue moving forward, changes to the stores
slowly moving along
Starting to see the fruit of those changes.
still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type.
More replacements. Things are starting to get easier
I can see more and more often the issue is that the function is awaiting a RefId, but is given a string
there is less need to go down functions and to fix a long list of them.
Still moving forward, and for the first time error count is going down!
Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably
Cells are back to using string for the name, haven't fixed everything yet. Many other changes
Under the bar of 400 compilation errors.
more good progress <100 compile errors!
More progress
Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string
some more progress on other fronts
Mostly game settings clean
one error opened a lot of other errors. Down to 18, but more will prbably appear
only link errors left??
Fixed link errors
OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
|
|
|
const MWWorld::Ptr& ptr, const ESM::RefId& owner, int count, Misc::Rng::Generator* prng, bool topLevel)
|
2019-09-29 13:08:52 +04:00
|
|
|
{
|
2021-10-11 11:46:21 +00:00
|
|
|
if (ptr.getType() == ESM::ItemLevList::sRecordId)
|
2019-09-29 13:08:52 +04:00
|
|
|
{
|
2022-03-06 15:58:16 +02:00
|
|
|
if (!prng)
|
2020-10-13 17:46:32 +02:00
|
|
|
return;
|
2019-09-29 13:08:52 +04:00
|
|
|
const ESM::ItemLevList* levItemList = ptr.get<ESM::ItemLevList>()->mBase;
|
|
|
|
|
|
|
|
if (topLevel && std::abs(count) > 1 && levItemList->mFlags & ESM::ItemLevList::Each)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < std::abs(count); ++i)
|
2022-03-06 15:58:16 +02:00
|
|
|
addInitialItem(ptr.getCellRef().getRefId(), owner, count > 0 ? 1 : -1, prng, true);
|
2019-09-29 13:08:52 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-12-01 20:02:39 +01:00
|
|
|
const auto& itemId = MWMechanics::getLevelledItem(ptr.get<ESM::ItemLevList>()->mBase, false, *prng);
|
2019-09-29 13:08:52 +04:00
|
|
|
if (itemId.empty())
|
|
|
|
return;
|
2022-03-06 15:58:16 +02:00
|
|
|
addInitialItem(itemId, owner, count, prng, false);
|
2019-09-29 13:08:52 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ptr.getCellRef().setOwner(owner);
|
2020-10-13 17:46:32 +02:00
|
|
|
addImp(ptr, count, false);
|
2019-09-29 13:08:52 +04:00
|
|
|
}
|
2012-03-10 12:11:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void MWWorld::ContainerStore::clear()
|
|
|
|
{
|
2020-12-04 18:34:51 +01:00
|
|
|
for (auto&& iter : *this)
|
|
|
|
iter.getRefData().setCount(0);
|
2012-03-21 12:48:05 +01:00
|
|
|
|
|
|
|
flagAsModified();
|
2020-10-13 17:46:32 +02:00
|
|
|
mModified = true;
|
2012-03-21 12:48:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void MWWorld::ContainerStore::flagAsModified()
|
|
|
|
{
|
2012-03-22 09:45:48 +01:00
|
|
|
mWeightUpToDate = false;
|
2018-12-15 10:23:50 +04:00
|
|
|
mRechargingItemsUpToDate = false;
|
2012-03-21 12:48:05 +01:00
|
|
|
}
|
|
|
|
|
2020-10-13 17:46:32 +02:00
|
|
|
bool MWWorld::ContainerStore::isResolved() const
|
|
|
|
{
|
|
|
|
return mResolved;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MWWorld::ContainerStore::resolve()
|
|
|
|
{
|
|
|
|
if (!mResolved && !mPtr.isEmpty())
|
|
|
|
{
|
2020-12-04 18:34:51 +01:00
|
|
|
for (const auto&& ptr : *this)
|
2020-10-13 17:46:32 +02:00
|
|
|
ptr.getRefData().setCount(0);
|
2022-03-06 15:58:16 +02:00
|
|
|
Misc::Rng::Generator prng{ mSeed };
|
2023-02-17 19:20:29 +01:00
|
|
|
fill(mPtr.get<ESM::Container>()->mBase->mInventory, ESM::RefId(), prng);
|
2020-10-13 17:46:32 +02:00
|
|
|
addScripts(*this, mPtr.mCell);
|
|
|
|
}
|
|
|
|
mModified = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
MWWorld::ResolutionHandle MWWorld::ContainerStore::resolveTemporarily()
|
|
|
|
{
|
|
|
|
if (mModified)
|
|
|
|
return {};
|
|
|
|
std::shared_ptr<ResolutionListener> listener = mResolutionListener.lock();
|
|
|
|
if (!listener)
|
|
|
|
{
|
|
|
|
listener = std::make_shared<ResolutionListener>(*this);
|
|
|
|
mResolutionListener = listener;
|
|
|
|
}
|
|
|
|
if (!mResolved && !mPtr.isEmpty())
|
|
|
|
{
|
2020-12-04 18:34:51 +01:00
|
|
|
for (const auto&& ptr : *this)
|
2020-10-13 17:46:32 +02:00
|
|
|
ptr.getRefData().setCount(0);
|
2022-03-06 15:58:16 +02:00
|
|
|
Misc::Rng::Generator prng{ mSeed };
|
2023-02-17 19:20:29 +01:00
|
|
|
fill(mPtr.get<ESM::Container>()->mBase->mInventory, ESM::RefId(), prng);
|
2020-10-13 17:46:32 +02:00
|
|
|
addScripts(*this, mPtr.mCell);
|
|
|
|
}
|
|
|
|
return { listener };
|
|
|
|
}
|
|
|
|
|
2021-04-14 23:03:35 +04:00
|
|
|
void MWWorld::ContainerStore::unresolve()
|
|
|
|
{
|
|
|
|
if (mModified)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (mResolved && !mPtr.isEmpty())
|
|
|
|
{
|
|
|
|
for (const auto&& ptr : *this)
|
|
|
|
ptr.getRefData().setCount(0);
|
2023-02-17 19:20:29 +01:00
|
|
|
fillNonRandom(mPtr.get<ESM::Container>()->mBase->mInventory, ESM::RefId(), mSeed);
|
2021-04-14 23:03:35 +04:00
|
|
|
addScripts(*this, mPtr.mCell);
|
|
|
|
mResolved = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-22 09:45:48 +01:00
|
|
|
float MWWorld::ContainerStore::getWeight() const
|
|
|
|
{
|
|
|
|
if (!mWeightUpToDate)
|
|
|
|
{
|
|
|
|
mCachedWeight = 0;
|
|
|
|
|
|
|
|
mCachedWeight += getTotalWeight(potions);
|
|
|
|
mCachedWeight += getTotalWeight(appas);
|
|
|
|
mCachedWeight += getTotalWeight(armors);
|
|
|
|
mCachedWeight += getTotalWeight(books);
|
|
|
|
mCachedWeight += getTotalWeight(clothes);
|
|
|
|
mCachedWeight += getTotalWeight(ingreds);
|
|
|
|
mCachedWeight += getTotalWeight(lights);
|
|
|
|
mCachedWeight += getTotalWeight(lockpicks);
|
|
|
|
mCachedWeight += getTotalWeight(miscItems);
|
|
|
|
mCachedWeight += getTotalWeight(probes);
|
|
|
|
mCachedWeight += getTotalWeight(repairs);
|
|
|
|
mCachedWeight += getTotalWeight(weapons);
|
|
|
|
|
|
|
|
mWeightUpToDate = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mCachedWeight;
|
|
|
|
}
|
|
|
|
|
2015-12-18 17:03:49 +01:00
|
|
|
int MWWorld::ContainerStore::getType(const ConstPtr& ptr)
|
2012-02-23 12:34:25 +01:00
|
|
|
{
|
|
|
|
if (ptr.isEmpty())
|
|
|
|
throw std::runtime_error("can't put a non-existent object into a container");
|
|
|
|
|
2021-10-11 11:46:21 +00:00
|
|
|
if (ptr.getType() == ESM::Potion::sRecordId)
|
2012-02-23 12:34:25 +01:00
|
|
|
return Type_Potion;
|
|
|
|
|
2021-10-11 11:46:21 +00:00
|
|
|
if (ptr.getType() == ESM::Apparatus::sRecordId)
|
2012-02-23 12:34:25 +01:00
|
|
|
return Type_Apparatus;
|
|
|
|
|
2021-10-11 11:46:21 +00:00
|
|
|
if (ptr.getType() == ESM::Armor::sRecordId)
|
2012-02-23 12:34:25 +01:00
|
|
|
return Type_Armor;
|
|
|
|
|
2021-10-11 11:46:21 +00:00
|
|
|
if (ptr.getType() == ESM::Book::sRecordId)
|
2012-02-23 12:34:25 +01:00
|
|
|
return Type_Book;
|
|
|
|
|
2021-10-11 11:46:21 +00:00
|
|
|
if (ptr.getType() == ESM::Clothing::sRecordId)
|
2012-02-23 12:34:25 +01:00
|
|
|
return Type_Clothing;
|
|
|
|
|
2021-10-11 11:46:21 +00:00
|
|
|
if (ptr.getType() == ESM::Ingredient::sRecordId)
|
2012-02-23 12:34:25 +01:00
|
|
|
return Type_Ingredient;
|
|
|
|
|
2021-10-11 11:46:21 +00:00
|
|
|
if (ptr.getType() == ESM::Light::sRecordId)
|
2012-02-23 12:34:25 +01:00
|
|
|
return Type_Light;
|
|
|
|
|
2021-10-11 11:46:21 +00:00
|
|
|
if (ptr.getType() == ESM::Lockpick::sRecordId)
|
2012-02-23 12:34:25 +01:00
|
|
|
return Type_Lockpick;
|
|
|
|
|
2021-10-11 11:46:21 +00:00
|
|
|
if (ptr.getType() == ESM::Miscellaneous::sRecordId)
|
2012-02-23 12:34:25 +01:00
|
|
|
return Type_Miscellaneous;
|
|
|
|
|
2021-10-11 11:46:21 +00:00
|
|
|
if (ptr.getType() == ESM::Probe::sRecordId)
|
2012-02-23 12:34:25 +01:00
|
|
|
return Type_Probe;
|
|
|
|
|
2021-10-11 11:46:21 +00:00
|
|
|
if (ptr.getType() == ESM::Repair::sRecordId)
|
2012-02-23 12:34:25 +01:00
|
|
|
return Type_Repair;
|
|
|
|
|
2021-10-11 11:46:21 +00:00
|
|
|
if (ptr.getType() == ESM::Weapon::sRecordId)
|
2012-02-23 12:34:25 +01:00
|
|
|
return Type_Weapon;
|
|
|
|
|
2023-02-20 23:11:18 +01:00
|
|
|
throw std::runtime_error("Object " + ptr.getCellRef().getRefId().toDebugString() + " of type "
|
2021-10-12 00:18:23 +02:00
|
|
|
+ std::string(ptr.getTypeDescription()) + " can not be placed into a container");
|
2012-02-23 12:34:25 +01:00
|
|
|
}
|
2012-02-20 14:14:39 +01:00
|
|
|
|
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type
The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID
Slowly going through all the changes to make, still hundreds of errors
a lot of functions/structures use std::string or stringview to designate an ID. So it takes time
Continues slowly replacing ids. There are technically more and more compilation errors
I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type
Continue moving forward, changes to the stores
slowly moving along
Starting to see the fruit of those changes.
still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type.
More replacements. Things are starting to get easier
I can see more and more often the issue is that the function is awaiting a RefId, but is given a string
there is less need to go down functions and to fix a long list of them.
Still moving forward, and for the first time error count is going down!
Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably
Cells are back to using string for the name, haven't fixed everything yet. Many other changes
Under the bar of 400 compilation errors.
more good progress <100 compile errors!
More progress
Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string
some more progress on other fronts
Mostly game settings clean
one error opened a lot of other errors. Down to 18, but more will prbably appear
only link errors left??
Fixed link errors
OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
|
|
|
MWWorld::Ptr MWWorld::ContainerStore::findReplacement(const ESM::RefId& id)
|
2018-06-13 12:56:58 +04:00
|
|
|
{
|
|
|
|
MWWorld::Ptr item;
|
|
|
|
int itemHealth = 1;
|
2020-12-04 18:34:51 +01:00
|
|
|
for (auto&& iter : *this)
|
2018-06-13 12:56:58 +04:00
|
|
|
{
|
2020-12-04 18:34:51 +01:00
|
|
|
int iterHealth = iter.getClass().hasItemHealth(iter) ? iter.getClass().getItemHealth(iter) : 1;
|
2022-10-18 09:26:55 +02:00
|
|
|
if (iter.getCellRef().getRefId() == id)
|
2018-06-13 12:56:58 +04:00
|
|
|
{
|
|
|
|
// Prefer the stack with the lowest remaining uses
|
|
|
|
// Try to get item with zero durability only if there are no other items found
|
|
|
|
if (item.isEmpty() || (iterHealth > 0 && iterHealth < itemHealth) || (itemHealth <= 0 && iterHealth > 0))
|
|
|
|
{
|
2020-12-04 18:34:51 +01:00
|
|
|
item = iter;
|
2018-06-13 12:56:58 +04:00
|
|
|
itemHealth = iterHealth;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type
The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID
Slowly going through all the changes to make, still hundreds of errors
a lot of functions/structures use std::string or stringview to designate an ID. So it takes time
Continues slowly replacing ids. There are technically more and more compilation errors
I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type
Continue moving forward, changes to the stores
slowly moving along
Starting to see the fruit of those changes.
still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type.
More replacements. Things are starting to get easier
I can see more and more often the issue is that the function is awaiting a RefId, but is given a string
there is less need to go down functions and to fix a long list of them.
Still moving forward, and for the first time error count is going down!
Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably
Cells are back to using string for the name, haven't fixed everything yet. Many other changes
Under the bar of 400 compilation errors.
more good progress <100 compile errors!
More progress
Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string
some more progress on other fronts
Mostly game settings clean
one error opened a lot of other errors. Down to 18, but more will prbably appear
only link errors left??
Fixed link errors
OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
|
|
|
MWWorld::Ptr MWWorld::ContainerStore::search(const ESM::RefId& id)
|
2013-08-15 14:45:13 +02:00
|
|
|
{
|
2020-10-13 17:46:32 +02:00
|
|
|
resolve();
|
2013-08-15 18:29:09 +02:00
|
|
|
{
|
|
|
|
Ptr ptr = searchId(potions, id, this);
|
|
|
|
if (!ptr.isEmpty())
|
|
|
|
return ptr;
|
|
|
|
}
|
2013-08-15 14:45:13 +02:00
|
|
|
|
2013-08-15 18:29:09 +02:00
|
|
|
{
|
|
|
|
Ptr ptr = searchId(appas, id, this);
|
|
|
|
if (!ptr.isEmpty())
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
Ptr ptr = searchId(armors, id, this);
|
|
|
|
if (!ptr.isEmpty())
|
|
|
|
return ptr;
|
|
|
|
}
|
2013-08-15 14:45:13 +02:00
|
|
|
|
|
|
|
{
|
2013-08-15 18:29:09 +02:00
|
|
|
Ptr ptr = searchId(books, id, this);
|
|
|
|
if (!ptr.isEmpty())
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
Ptr ptr = searchId(clothes, id, this);
|
|
|
|
if (!ptr.isEmpty())
|
|
|
|
return ptr;
|
|
|
|
}
|
2013-08-15 14:45:13 +02:00
|
|
|
|
2013-08-15 18:29:09 +02:00
|
|
|
{
|
|
|
|
Ptr ptr = searchId(ingreds, id, this);
|
|
|
|
if (!ptr.isEmpty())
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
Ptr ptr = searchId(lights, id, this);
|
|
|
|
if (!ptr.isEmpty())
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
Ptr ptr = searchId(lockpicks, id, this);
|
|
|
|
if (!ptr.isEmpty())
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
Ptr ptr = searchId(miscItems, id, this);
|
|
|
|
if (!ptr.isEmpty())
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
Ptr ptr = searchId(probes, id, this);
|
|
|
|
if (!ptr.isEmpty())
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
Ptr ptr = searchId(repairs, id, this);
|
|
|
|
if (!ptr.isEmpty())
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
Ptr ptr = searchId(weapons, id, this);
|
|
|
|
if (!ptr.isEmpty())
|
2013-08-15 14:45:13 +02:00
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Ptr();
|
|
|
|
}
|
|
|
|
|
2020-10-13 17:46:32 +02:00
|
|
|
int MWWorld::ContainerStore::addItems(int count1, int count2)
|
|
|
|
{
|
|
|
|
int sum = std::abs(count1) + std::abs(count2);
|
|
|
|
if (count1 < 0 || count2 < 0)
|
|
|
|
return -sum;
|
|
|
|
return sum;
|
|
|
|
}
|
|
|
|
|
|
|
|
int MWWorld::ContainerStore::subtractItems(int count1, int count2)
|
|
|
|
{
|
|
|
|
int sum = std::abs(count1) - std::abs(count2);
|
|
|
|
if (count1 < 0 || count2 < 0)
|
|
|
|
return -sum;
|
|
|
|
return sum;
|
|
|
|
}
|
|
|
|
|
2015-12-18 00:18:06 +01:00
|
|
|
void MWWorld::ContainerStore::writeState(ESM::InventoryState& state) const
|
2014-01-31 13:25:32 +01:00
|
|
|
{
|
|
|
|
state.mItems.clear();
|
|
|
|
|
2015-01-23 16:45:47 +01:00
|
|
|
int index = 0;
|
|
|
|
storeStates(potions, state, index);
|
|
|
|
storeStates(appas, state, index);
|
|
|
|
storeStates(armors, state, index, true);
|
|
|
|
storeStates(books, state, index, true); // not equipable as such, but for selectedEnchantItem
|
|
|
|
storeStates(clothes, state, index, true);
|
|
|
|
storeStates(ingreds, state, index);
|
|
|
|
storeStates(lockpicks, state, index, true);
|
|
|
|
storeStates(miscItems, state, index);
|
|
|
|
storeStates(probes, state, index, true);
|
|
|
|
storeStates(repairs, state, index);
|
|
|
|
storeStates(weapons, state, index, true);
|
|
|
|
storeStates(lights, state, index, true);
|
2014-01-31 13:25:32 +01:00
|
|
|
}
|
2022-09-22 21:26:05 +03:00
|
|
|
|
2015-01-23 16:45:47 +01:00
|
|
|
void MWWorld::ContainerStore::readState(const ESM::InventoryState& inventory)
|
2014-01-31 13:25:32 +01:00
|
|
|
{
|
|
|
|
clear();
|
2020-10-13 17:46:32 +02:00
|
|
|
mModified = true;
|
|
|
|
mResolved = true;
|
2014-01-31 13:25:32 +01:00
|
|
|
|
2015-01-23 16:45:47 +01:00
|
|
|
int index = 0;
|
2020-12-04 18:34:51 +01:00
|
|
|
for (const ESM::ObjectState& state : inventory.mItems)
|
2014-01-31 13:25:32 +01:00
|
|
|
{
|
2023-04-20 21:07:53 +02:00
|
|
|
int type = MWBase::Environment::get().getESMStore()->find(state.mRef.mRefID);
|
2015-01-19 10:34:49 +01:00
|
|
|
|
2015-01-23 16:45:47 +01:00
|
|
|
int thisIndex = index++;
|
|
|
|
|
2015-01-19 10:34:49 +01:00
|
|
|
switch (type)
|
2014-01-31 13:25:32 +01:00
|
|
|
{
|
2015-01-23 16:45:47 +01:00
|
|
|
case ESM::REC_ALCH:
|
|
|
|
getState(potions, state);
|
|
|
|
break;
|
|
|
|
case ESM::REC_APPA:
|
|
|
|
getState(appas, state);
|
|
|
|
break;
|
|
|
|
case ESM::REC_ARMO:
|
|
|
|
readEquipmentState(getState(armors, state), thisIndex, inventory);
|
|
|
|
break;
|
|
|
|
case ESM::REC_BOOK:
|
|
|
|
readEquipmentState(getState(books, state), thisIndex, inventory);
|
|
|
|
break; // not equipable as such, but for selectedEnchantItem
|
|
|
|
case ESM::REC_CLOT:
|
|
|
|
readEquipmentState(getState(clothes, state), thisIndex, inventory);
|
|
|
|
break;
|
|
|
|
case ESM::REC_INGR:
|
|
|
|
getState(ingreds, state);
|
|
|
|
break;
|
|
|
|
case ESM::REC_LOCK:
|
|
|
|
readEquipmentState(getState(lockpicks, state), thisIndex, inventory);
|
|
|
|
break;
|
|
|
|
case ESM::REC_MISC:
|
|
|
|
getState(miscItems, state);
|
|
|
|
break;
|
|
|
|
case ESM::REC_PROB:
|
|
|
|
readEquipmentState(getState(probes, state), thisIndex, inventory);
|
|
|
|
break;
|
|
|
|
case ESM::REC_REPA:
|
|
|
|
getState(repairs, state);
|
|
|
|
break;
|
|
|
|
case ESM::REC_WEAP:
|
|
|
|
readEquipmentState(getState(weapons, state), thisIndex, inventory);
|
|
|
|
break;
|
|
|
|
case ESM::REC_LIGH:
|
|
|
|
readEquipmentState(getState(lights, state), thisIndex, inventory);
|
|
|
|
break;
|
2015-01-22 03:39:00 +01:00
|
|
|
case 0:
|
2018-08-14 23:05:43 +04:00
|
|
|
Log(Debug::Warning) << "Dropping inventory reference to '" << state.mRef.mRefID
|
|
|
|
<< "' (object no longer exists)";
|
2015-01-22 03:39:00 +01:00
|
|
|
break;
|
2014-01-31 13:25:32 +01:00
|
|
|
default:
|
2018-08-14 23:05:43 +04:00
|
|
|
Log(Debug::Warning) << "Warning: Invalid item type in inventory state, refid " << state.mRef.mRefID;
|
2015-01-19 10:34:49 +01:00
|
|
|
break;
|
2014-01-31 13:25:32 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
template <class PtrType>
|
|
|
|
template <class T>
|
2017-02-19 14:30:26 +00:00
|
|
|
void MWWorld::ContainerStoreIteratorBase<PtrType>::copy(const ContainerStoreIteratorBase<T>& src)
|
2012-02-20 14:14:39 +01:00
|
|
|
{
|
2017-02-14 19:34:54 +00:00
|
|
|
mType = src.mType;
|
|
|
|
mMask = src.mMask;
|
|
|
|
mContainer = src.mContainer;
|
|
|
|
mPtr = src.mPtr;
|
2012-05-16 00:02:05 +02:00
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
switch (src.mType)
|
|
|
|
{
|
|
|
|
case MWWorld::ContainerStore::Type_Potion:
|
|
|
|
mPotion = src.mPotion;
|
|
|
|
break;
|
|
|
|
case MWWorld::ContainerStore::Type_Apparatus:
|
|
|
|
mApparatus = src.mApparatus;
|
|
|
|
break;
|
|
|
|
case MWWorld::ContainerStore::Type_Armor:
|
|
|
|
mArmor = src.mArmor;
|
|
|
|
break;
|
|
|
|
case MWWorld::ContainerStore::Type_Book:
|
|
|
|
mBook = src.mBook;
|
|
|
|
break;
|
|
|
|
case MWWorld::ContainerStore::Type_Clothing:
|
|
|
|
mClothing = src.mClothing;
|
|
|
|
break;
|
|
|
|
case MWWorld::ContainerStore::Type_Ingredient:
|
|
|
|
mIngredient = src.mIngredient;
|
|
|
|
break;
|
|
|
|
case MWWorld::ContainerStore::Type_Light:
|
|
|
|
mLight = src.mLight;
|
|
|
|
break;
|
|
|
|
case MWWorld::ContainerStore::Type_Lockpick:
|
|
|
|
mLockpick = src.mLockpick;
|
|
|
|
break;
|
|
|
|
case MWWorld::ContainerStore::Type_Miscellaneous:
|
|
|
|
mMiscellaneous = src.mMiscellaneous;
|
|
|
|
break;
|
|
|
|
case MWWorld::ContainerStore::Type_Probe:
|
|
|
|
mProbe = src.mProbe;
|
|
|
|
break;
|
|
|
|
case MWWorld::ContainerStore::Type_Repair:
|
|
|
|
mRepair = src.mRepair;
|
|
|
|
break;
|
|
|
|
case MWWorld::ContainerStore::Type_Weapon:
|
|
|
|
mWeapon = src.mWeapon;
|
|
|
|
break;
|
|
|
|
case -1:
|
2022-09-22 21:26:05 +03:00
|
|
|
break;
|
2017-02-14 19:34:54 +00:00
|
|
|
default:
|
|
|
|
assert(0);
|
|
|
|
}
|
2014-01-04 07:27:50 +02:00
|
|
|
}
|
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
template <class PtrType>
|
|
|
|
void MWWorld::ContainerStoreIteratorBase<PtrType>::incType()
|
2012-02-20 14:14:39 +01:00
|
|
|
{
|
|
|
|
if (mType == 0)
|
|
|
|
mType = 1;
|
|
|
|
else if (mType != -1)
|
|
|
|
{
|
|
|
|
mType <<= 1;
|
|
|
|
|
|
|
|
if (mType > ContainerStore::Type_Last)
|
|
|
|
mType = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
template <class PtrType>
|
|
|
|
void MWWorld::ContainerStoreIteratorBase<PtrType>::nextType()
|
2012-02-20 14:14:39 +01:00
|
|
|
{
|
|
|
|
while (mType != -1)
|
|
|
|
{
|
|
|
|
incType();
|
|
|
|
|
2012-05-18 22:24:19 +02:00
|
|
|
if ((mType & mMask) && mType > 0)
|
2012-02-20 14:14:39 +01:00
|
|
|
if (resetIterator())
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
template <class PtrType>
|
|
|
|
bool MWWorld::ContainerStoreIteratorBase<PtrType>::resetIterator()
|
2012-02-20 14:14:39 +01:00
|
|
|
{
|
|
|
|
switch (mType)
|
|
|
|
{
|
|
|
|
case ContainerStore::Type_Potion:
|
|
|
|
|
2012-11-05 16:07:59 +04:00
|
|
|
mPotion = mContainer->potions.mList.begin();
|
|
|
|
return mPotion != mContainer->potions.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Apparatus:
|
|
|
|
|
2012-11-05 16:07:59 +04:00
|
|
|
mApparatus = mContainer->appas.mList.begin();
|
|
|
|
return mApparatus != mContainer->appas.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Armor:
|
|
|
|
|
2012-11-05 16:07:59 +04:00
|
|
|
mArmor = mContainer->armors.mList.begin();
|
|
|
|
return mArmor != mContainer->armors.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Book:
|
|
|
|
|
2012-11-05 16:07:59 +04:00
|
|
|
mBook = mContainer->books.mList.begin();
|
|
|
|
return mBook != mContainer->books.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Clothing:
|
|
|
|
|
2012-11-05 16:07:59 +04:00
|
|
|
mClothing = mContainer->clothes.mList.begin();
|
|
|
|
return mClothing != mContainer->clothes.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Ingredient:
|
|
|
|
|
2012-11-05 16:07:59 +04:00
|
|
|
mIngredient = mContainer->ingreds.mList.begin();
|
|
|
|
return mIngredient != mContainer->ingreds.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Light:
|
|
|
|
|
2012-11-05 16:07:59 +04:00
|
|
|
mLight = mContainer->lights.mList.begin();
|
|
|
|
return mLight != mContainer->lights.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Lockpick:
|
|
|
|
|
2012-11-05 16:07:59 +04:00
|
|
|
mLockpick = mContainer->lockpicks.mList.begin();
|
|
|
|
return mLockpick != mContainer->lockpicks.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Miscellaneous:
|
|
|
|
|
2012-11-05 16:07:59 +04:00
|
|
|
mMiscellaneous = mContainer->miscItems.mList.begin();
|
|
|
|
return mMiscellaneous != mContainer->miscItems.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Probe:
|
|
|
|
|
2012-11-05 16:07:59 +04:00
|
|
|
mProbe = mContainer->probes.mList.begin();
|
|
|
|
return mProbe != mContainer->probes.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Repair:
|
|
|
|
|
2012-11-05 16:07:59 +04:00
|
|
|
mRepair = mContainer->repairs.mList.begin();
|
|
|
|
return mRepair != mContainer->repairs.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Weapon:
|
|
|
|
|
2012-11-05 16:07:59 +04:00
|
|
|
mWeapon = mContainer->weapons.mList.begin();
|
|
|
|
return mWeapon != mContainer->weapons.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
template <class PtrType>
|
|
|
|
bool MWWorld::ContainerStoreIteratorBase<PtrType>::incIterator()
|
2012-02-20 14:14:39 +01:00
|
|
|
{
|
|
|
|
switch (mType)
|
|
|
|
{
|
|
|
|
case ContainerStore::Type_Potion:
|
|
|
|
|
|
|
|
++mPotion;
|
2012-11-05 16:07:59 +04:00
|
|
|
return mPotion == mContainer->potions.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Apparatus:
|
|
|
|
|
|
|
|
++mApparatus;
|
2012-11-05 16:07:59 +04:00
|
|
|
return mApparatus == mContainer->appas.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Armor:
|
|
|
|
|
|
|
|
++mArmor;
|
2012-11-05 16:07:59 +04:00
|
|
|
return mArmor == mContainer->armors.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Book:
|
|
|
|
|
|
|
|
++mBook;
|
2012-11-05 16:07:59 +04:00
|
|
|
return mBook == mContainer->books.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Clothing:
|
|
|
|
|
|
|
|
++mClothing;
|
2012-11-05 16:07:59 +04:00
|
|
|
return mClothing == mContainer->clothes.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Ingredient:
|
|
|
|
|
|
|
|
++mIngredient;
|
2012-11-05 16:07:59 +04:00
|
|
|
return mIngredient == mContainer->ingreds.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Light:
|
|
|
|
|
|
|
|
++mLight;
|
2012-11-05 16:07:59 +04:00
|
|
|
return mLight == mContainer->lights.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Lockpick:
|
|
|
|
|
|
|
|
++mLockpick;
|
2012-11-05 16:07:59 +04:00
|
|
|
return mLockpick == mContainer->lockpicks.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Miscellaneous:
|
|
|
|
|
|
|
|
++mMiscellaneous;
|
2012-11-05 16:07:59 +04:00
|
|
|
return mMiscellaneous == mContainer->miscItems.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Probe:
|
|
|
|
|
|
|
|
++mProbe;
|
2012-11-05 16:07:59 +04:00
|
|
|
return mProbe == mContainer->probes.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Repair:
|
|
|
|
|
|
|
|
++mRepair;
|
2012-11-05 16:07:59 +04:00
|
|
|
return mRepair == mContainer->repairs.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
|
|
|
|
case ContainerStore::Type_Weapon:
|
|
|
|
|
|
|
|
++mWeapon;
|
2012-11-05 16:07:59 +04:00
|
|
|
return mWeapon == mContainer->weapons.mList.end();
|
2012-02-20 14:14:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
template <class PtrType>
|
|
|
|
template <class T>
|
|
|
|
bool MWWorld::ContainerStoreIteratorBase<PtrType>::isEqual(const ContainerStoreIteratorBase<T>& other) const
|
|
|
|
{
|
|
|
|
if (mContainer != other.mContainer)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (mType != other.mType)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
switch (mType)
|
|
|
|
{
|
|
|
|
case ContainerStore::Type_Potion:
|
|
|
|
return mPotion == other.mPotion;
|
|
|
|
case ContainerStore::Type_Apparatus:
|
|
|
|
return mApparatus == other.mApparatus;
|
|
|
|
case ContainerStore::Type_Armor:
|
|
|
|
return mArmor == other.mArmor;
|
|
|
|
case ContainerStore::Type_Book:
|
|
|
|
return mBook == other.mBook;
|
|
|
|
case ContainerStore::Type_Clothing:
|
|
|
|
return mClothing == other.mClothing;
|
|
|
|
case ContainerStore::Type_Ingredient:
|
|
|
|
return mIngredient == other.mIngredient;
|
|
|
|
case ContainerStore::Type_Light:
|
|
|
|
return mLight == other.mLight;
|
|
|
|
case ContainerStore::Type_Lockpick:
|
|
|
|
return mLockpick == other.mLockpick;
|
|
|
|
case ContainerStore::Type_Miscellaneous:
|
|
|
|
return mMiscellaneous == other.mMiscellaneous;
|
|
|
|
case ContainerStore::Type_Probe:
|
|
|
|
return mProbe == other.mProbe;
|
|
|
|
case ContainerStore::Type_Repair:
|
|
|
|
return mRepair == other.mRepair;
|
|
|
|
case ContainerStore::Type_Weapon:
|
|
|
|
return mWeapon == other.mWeapon;
|
|
|
|
case -1:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class PtrType>
|
|
|
|
PtrType* MWWorld::ContainerStoreIteratorBase<PtrType>::operator->() const
|
2012-02-20 14:14:39 +01:00
|
|
|
{
|
|
|
|
mPtr = **this;
|
|
|
|
return &mPtr;
|
|
|
|
}
|
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
template <class PtrType>
|
|
|
|
PtrType MWWorld::ContainerStoreIteratorBase<PtrType>::operator*() const
|
2012-02-20 14:14:39 +01:00
|
|
|
{
|
2017-02-14 19:34:54 +00:00
|
|
|
PtrType ptr;
|
2012-03-21 12:20:19 +01:00
|
|
|
|
2012-02-20 14:14:39 +01:00
|
|
|
switch (mType)
|
|
|
|
{
|
2020-11-13 11:39:47 +04:00
|
|
|
case ContainerStore::Type_Potion:
|
|
|
|
ptr = PtrType(&*mPotion, nullptr);
|
|
|
|
break;
|
|
|
|
case ContainerStore::Type_Apparatus:
|
|
|
|
ptr = PtrType(&*mApparatus, nullptr);
|
|
|
|
break;
|
|
|
|
case ContainerStore::Type_Armor:
|
|
|
|
ptr = PtrType(&*mArmor, nullptr);
|
|
|
|
break;
|
|
|
|
case ContainerStore::Type_Book:
|
|
|
|
ptr = PtrType(&*mBook, nullptr);
|
|
|
|
break;
|
|
|
|
case ContainerStore::Type_Clothing:
|
|
|
|
ptr = PtrType(&*mClothing, nullptr);
|
|
|
|
break;
|
|
|
|
case ContainerStore::Type_Ingredient:
|
|
|
|
ptr = PtrType(&*mIngredient, nullptr);
|
|
|
|
break;
|
|
|
|
case ContainerStore::Type_Light:
|
|
|
|
ptr = PtrType(&*mLight, nullptr);
|
|
|
|
break;
|
|
|
|
case ContainerStore::Type_Lockpick:
|
|
|
|
ptr = PtrType(&*mLockpick, nullptr);
|
|
|
|
break;
|
|
|
|
case ContainerStore::Type_Miscellaneous:
|
|
|
|
ptr = PtrType(&*mMiscellaneous, nullptr);
|
|
|
|
break;
|
|
|
|
case ContainerStore::Type_Probe:
|
|
|
|
ptr = PtrType(&*mProbe, nullptr);
|
|
|
|
break;
|
|
|
|
case ContainerStore::Type_Repair:
|
|
|
|
ptr = PtrType(&*mRepair, nullptr);
|
|
|
|
break;
|
|
|
|
case ContainerStore::Type_Weapon:
|
|
|
|
ptr = PtrType(&*mWeapon, nullptr);
|
|
|
|
break;
|
2012-02-20 14:14:39 +01:00
|
|
|
}
|
|
|
|
|
2012-03-21 12:20:19 +01:00
|
|
|
if (ptr.isEmpty())
|
|
|
|
throw std::runtime_error("invalid iterator");
|
|
|
|
|
|
|
|
ptr.setContainerStore(mContainer);
|
|
|
|
|
|
|
|
return ptr;
|
2012-02-20 14:14:39 +01:00
|
|
|
}
|
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
template <class PtrType>
|
|
|
|
MWWorld::ContainerStoreIteratorBase<PtrType>& MWWorld::ContainerStoreIteratorBase<PtrType>::operator++()
|
2012-02-20 14:14:39 +01:00
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (incIterator())
|
|
|
|
nextType();
|
|
|
|
} while (mType != -1 && !(**this).getRefData().getCount());
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
template <class PtrType>
|
|
|
|
MWWorld::ContainerStoreIteratorBase<PtrType> MWWorld::ContainerStoreIteratorBase<PtrType>::operator++(int)
|
2012-02-20 14:14:39 +01:00
|
|
|
{
|
2017-02-14 19:34:54 +00:00
|
|
|
ContainerStoreIteratorBase<PtrType> iter(*this);
|
2012-02-20 14:14:39 +01:00
|
|
|
++*this;
|
|
|
|
return iter;
|
|
|
|
}
|
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
template <class PtrType>
|
|
|
|
MWWorld::ContainerStoreIteratorBase<PtrType>& MWWorld::ContainerStoreIteratorBase<PtrType>::operator=(
|
|
|
|
const ContainerStoreIteratorBase<PtrType>& rhs)
|
2012-02-20 14:14:39 +01:00
|
|
|
{
|
2017-02-14 19:34:54 +00:00
|
|
|
if (this != &rhs)
|
2012-02-20 14:14:39 +01:00
|
|
|
{
|
2017-02-14 19:34:54 +00:00
|
|
|
copy(rhs);
|
2012-02-20 14:14:39 +01:00
|
|
|
}
|
2017-02-14 19:34:54 +00:00
|
|
|
return *this;
|
2012-02-20 14:14:39 +01:00
|
|
|
}
|
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
template <class PtrType>
|
|
|
|
int MWWorld::ContainerStoreIteratorBase<PtrType>::getType() const
|
2012-02-20 14:14:39 +01:00
|
|
|
{
|
|
|
|
return mType;
|
|
|
|
}
|
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
template <class PtrType>
|
|
|
|
const MWWorld::ContainerStore* MWWorld::ContainerStoreIteratorBase<PtrType>::getContainerStore() const
|
2012-03-13 14:04:19 +01:00
|
|
|
{
|
|
|
|
return mContainer;
|
|
|
|
}
|
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
template <class PtrType>
|
|
|
|
MWWorld::ContainerStoreIteratorBase<PtrType>::ContainerStoreIteratorBase(ContainerStoreType container)
|
|
|
|
: mType(-1)
|
|
|
|
, mMask(0)
|
|
|
|
, mContainer(container)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class PtrType>
|
|
|
|
MWWorld::ContainerStoreIteratorBase<PtrType>::ContainerStoreIteratorBase(int mask, ContainerStoreType container)
|
|
|
|
: mType(0)
|
|
|
|
, mMask(mask)
|
|
|
|
, mContainer(container)
|
2014-01-04 07:27:50 +02:00
|
|
|
{
|
2017-02-14 19:34:54 +00:00
|
|
|
nextType();
|
2014-01-07 14:32:14 +02:00
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
if (mType == -1 || (**this).getRefData().getCount())
|
|
|
|
return;
|
2014-01-04 07:27:50 +02:00
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
++*this;
|
2014-01-04 07:27:50 +02:00
|
|
|
}
|
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
template <class PtrType>
|
|
|
|
MWWorld::ContainerStoreIteratorBase<PtrType>::ContainerStoreIteratorBase(
|
|
|
|
ContainerStoreType container, typename Iterator<ESM::Potion>::type iterator)
|
|
|
|
: mType(MWWorld::ContainerStore::Type_Potion)
|
|
|
|
, mMask(MWWorld::ContainerStore::Type_All)
|
|
|
|
, mContainer(container)
|
|
|
|
, mPotion(iterator)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2017-02-14 19:34:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class PtrType>
|
|
|
|
MWWorld::ContainerStoreIteratorBase<PtrType>::ContainerStoreIteratorBase(
|
|
|
|
ContainerStoreType container, typename Iterator<ESM::Apparatus>::type iterator)
|
|
|
|
: mType(MWWorld::ContainerStore::Type_Apparatus)
|
|
|
|
, mMask(MWWorld::ContainerStore::Type_All)
|
|
|
|
, mContainer(container)
|
|
|
|
, mApparatus(iterator)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2017-02-14 19:34:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class PtrType>
|
|
|
|
MWWorld::ContainerStoreIteratorBase<PtrType>::ContainerStoreIteratorBase(
|
|
|
|
ContainerStoreType container, typename Iterator<ESM::Armor>::type iterator)
|
|
|
|
: mType(MWWorld::ContainerStore::Type_Armor)
|
|
|
|
, mMask(MWWorld::ContainerStore::Type_All)
|
|
|
|
, mContainer(container)
|
|
|
|
, mArmor(iterator)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2017-02-14 19:34:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class PtrType>
|
|
|
|
MWWorld::ContainerStoreIteratorBase<PtrType>::ContainerStoreIteratorBase(
|
|
|
|
ContainerStoreType container, typename Iterator<ESM::Book>::type iterator)
|
|
|
|
: mType(MWWorld::ContainerStore::Type_Book)
|
|
|
|
, mMask(MWWorld::ContainerStore::Type_All)
|
|
|
|
, mContainer(container)
|
|
|
|
, mBook(iterator)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2017-02-14 19:34:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class PtrType>
|
|
|
|
MWWorld::ContainerStoreIteratorBase<PtrType>::ContainerStoreIteratorBase(
|
|
|
|
ContainerStoreType container, typename Iterator<ESM::Clothing>::type iterator)
|
|
|
|
: mType(MWWorld::ContainerStore::Type_Clothing)
|
|
|
|
, mMask(MWWorld::ContainerStore::Type_All)
|
|
|
|
, mContainer(container)
|
|
|
|
, mClothing(iterator)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2017-02-14 19:34:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class PtrType>
|
|
|
|
MWWorld::ContainerStoreIteratorBase<PtrType>::ContainerStoreIteratorBase(
|
|
|
|
ContainerStoreType container, typename Iterator<ESM::Ingredient>::type iterator)
|
|
|
|
: mType(MWWorld::ContainerStore::Type_Ingredient)
|
|
|
|
, mMask(MWWorld::ContainerStore::Type_All)
|
|
|
|
, mContainer(container)
|
|
|
|
, mIngredient(iterator)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2017-02-14 19:34:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class PtrType>
|
|
|
|
MWWorld::ContainerStoreIteratorBase<PtrType>::ContainerStoreIteratorBase(
|
|
|
|
ContainerStoreType container, typename Iterator<ESM::Light>::type iterator)
|
|
|
|
: mType(MWWorld::ContainerStore::Type_Light)
|
|
|
|
, mMask(MWWorld::ContainerStore::Type_All)
|
|
|
|
, mContainer(container)
|
|
|
|
, mLight(iterator)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2017-02-14 19:34:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class PtrType>
|
|
|
|
MWWorld::ContainerStoreIteratorBase<PtrType>::ContainerStoreIteratorBase(
|
|
|
|
ContainerStoreType container, typename Iterator<ESM::Lockpick>::type iterator)
|
|
|
|
: mType(MWWorld::ContainerStore::Type_Lockpick)
|
|
|
|
, mMask(MWWorld::ContainerStore::Type_All)
|
|
|
|
, mContainer(container)
|
|
|
|
, mLockpick(iterator)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2017-02-14 19:34:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class PtrType>
|
|
|
|
MWWorld::ContainerStoreIteratorBase<PtrType>::ContainerStoreIteratorBase(
|
|
|
|
ContainerStoreType container, typename Iterator<ESM::Miscellaneous>::type iterator)
|
|
|
|
: mType(MWWorld::ContainerStore::Type_Miscellaneous)
|
|
|
|
, mMask(MWWorld::ContainerStore::Type_All)
|
|
|
|
, mContainer(container)
|
|
|
|
, mMiscellaneous(iterator)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2017-02-14 19:34:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class PtrType>
|
|
|
|
MWWorld::ContainerStoreIteratorBase<PtrType>::ContainerStoreIteratorBase(
|
|
|
|
ContainerStoreType container, typename Iterator<ESM::Probe>::type iterator)
|
|
|
|
: mType(MWWorld::ContainerStore::Type_Probe)
|
|
|
|
, mMask(MWWorld::ContainerStore::Type_All)
|
|
|
|
, mContainer(container)
|
|
|
|
, mProbe(iterator)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2017-02-14 19:34:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class PtrType>
|
|
|
|
MWWorld::ContainerStoreIteratorBase<PtrType>::ContainerStoreIteratorBase(
|
|
|
|
ContainerStoreType container, typename Iterator<ESM::Repair>::type iterator)
|
|
|
|
: mType(MWWorld::ContainerStore::Type_Repair)
|
|
|
|
, mMask(MWWorld::ContainerStore::Type_All)
|
|
|
|
, mContainer(container)
|
|
|
|
, mRepair(iterator)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
2017-02-14 19:34:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class PtrType>
|
|
|
|
MWWorld::ContainerStoreIteratorBase<PtrType>::ContainerStoreIteratorBase(
|
|
|
|
ContainerStoreType container, typename Iterator<ESM::Weapon>::type iterator)
|
|
|
|
: mType(MWWorld::ContainerStore::Type_Weapon)
|
|
|
|
, mMask(MWWorld::ContainerStore::Type_All)
|
|
|
|
, mContainer(container)
|
|
|
|
, mWeapon(iterator)
|
2022-09-22 21:26:05 +03:00
|
|
|
{
|
|
|
|
}
|
2017-02-14 19:34:54 +00:00
|
|
|
|
|
|
|
template <class T, class U>
|
|
|
|
bool MWWorld::operator==(const ContainerStoreIteratorBase<T>& left, const ContainerStoreIteratorBase<U>& right)
|
2012-02-20 14:14:39 +01:00
|
|
|
{
|
|
|
|
return left.isEqual(right);
|
|
|
|
}
|
|
|
|
|
2017-02-14 19:34:54 +00:00
|
|
|
template <class T, class U>
|
|
|
|
bool MWWorld::operator!=(const ContainerStoreIteratorBase<T>& left, const ContainerStoreIteratorBase<U>& right)
|
2012-02-20 14:14:39 +01:00
|
|
|
{
|
|
|
|
return !(left == right);
|
|
|
|
}
|
2017-02-14 19:34:54 +00:00
|
|
|
|
|
|
|
template class MWWorld::ContainerStoreIteratorBase<MWWorld::Ptr>;
|
|
|
|
template class MWWorld::ContainerStoreIteratorBase<MWWorld::ConstPtr>;
|
|
|
|
|
|
|
|
template bool MWWorld::operator==(
|
|
|
|
const ContainerStoreIteratorBase<Ptr>& left, const ContainerStoreIteratorBase<Ptr>& right);
|
|
|
|
template bool MWWorld::operator!=(
|
|
|
|
const ContainerStoreIteratorBase<Ptr>& left, const ContainerStoreIteratorBase<Ptr>& right);
|
|
|
|
template bool MWWorld::operator==(
|
|
|
|
const ContainerStoreIteratorBase<ConstPtr>& left, const ContainerStoreIteratorBase<ConstPtr>& right);
|
|
|
|
template bool MWWorld::operator!=(
|
|
|
|
const ContainerStoreIteratorBase<ConstPtr>& left, const ContainerStoreIteratorBase<ConstPtr>& right);
|
|
|
|
template bool MWWorld::operator==(
|
|
|
|
const ContainerStoreIteratorBase<ConstPtr>& left, const ContainerStoreIteratorBase<Ptr>& right);
|
|
|
|
template bool MWWorld::operator!=(
|
|
|
|
const ContainerStoreIteratorBase<ConstPtr>& left, const ContainerStoreIteratorBase<Ptr>& right);
|
|
|
|
template bool MWWorld::operator==(
|
|
|
|
const ContainerStoreIteratorBase<Ptr>& left, const ContainerStoreIteratorBase<ConstPtr>& right);
|
|
|
|
template bool MWWorld::operator!=(
|
|
|
|
const ContainerStoreIteratorBase<Ptr>& left, const ContainerStoreIteratorBase<ConstPtr>& right);
|
|
|
|
|
|
|
|
template void MWWorld::ContainerStoreIteratorBase<MWWorld::Ptr>::copy(const ContainerStoreIteratorBase<Ptr>& src);
|
|
|
|
template void MWWorld::ContainerStoreIteratorBase<MWWorld::ConstPtr>::copy(const ContainerStoreIteratorBase<Ptr>& src);
|
|
|
|
template void MWWorld::ContainerStoreIteratorBase<MWWorld::ConstPtr>::copy(
|
|
|
|
const ContainerStoreIteratorBase<ConstPtr>& src);
|