2011-10-06 12:29:59 +02:00
|
|
|
#include "localscripts.hpp"
|
|
|
|
|
2018-08-14 23:05:43 +04:00
|
|
|
#include <components/debug/debuglog.hpp>
|
2022-09-08 21:08:59 +02:00
|
|
|
#include <components/esm3/loadcont.hpp>
|
|
|
|
#include <components/esm3/loadcrea.hpp>
|
|
|
|
#include <components/esm3/loadnpc.hpp>
|
2022-09-05 19:35:15 +02:00
|
|
|
#include <components/esm3/loadscpt.hpp>
|
2015-01-25 01:53:20 +01:00
|
|
|
|
2012-06-29 16:48:50 +02:00
|
|
|
#include "cellstore.hpp"
|
2013-01-12 18:31:57 +00:00
|
|
|
#include "class.hpp"
|
|
|
|
#include "containerstore.hpp"
|
2012-10-01 19:17:04 +04:00
|
|
|
#include "esmstore.hpp"
|
2013-01-12 18:31:57 +00:00
|
|
|
|
2011-10-07 09:52:42 +02:00
|
|
|
namespace
|
|
|
|
{
|
2015-12-06 20:30:52 +01:00
|
|
|
|
|
|
|
struct AddScriptsVisitor
|
2011-10-07 09:52:42 +02:00
|
|
|
{
|
2015-12-06 20:30:52 +01:00
|
|
|
AddScriptsVisitor(MWWorld::LocalScripts& scripts)
|
|
|
|
: mScripts(scripts)
|
2011-10-07 09:52:42 +02:00
|
|
|
{
|
|
|
|
}
|
2015-12-06 20:30:52 +01:00
|
|
|
MWWorld::LocalScripts& mScripts;
|
2013-01-12 18:31:57 +00:00
|
|
|
|
2015-12-06 20:30:52 +01:00
|
|
|
bool operator()(const MWWorld::Ptr& ptr)
|
2013-01-12 18:31:57 +00:00
|
|
|
{
|
2015-12-06 20:30:52 +01:00
|
|
|
if (ptr.getRefData().isDeleted())
|
|
|
|
return true;
|
|
|
|
|
2022-08-11 22:51:55 +02:00
|
|
|
std::string_view script = ptr.getClass().getScript(ptr);
|
2015-12-06 20:30:52 +01:00
|
|
|
|
|
|
|
if (!script.empty())
|
|
|
|
mScripts.add(script, ptr);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
2013-12-05 13:21:26 +01:00
|
|
|
|
2015-12-06 20:30:52 +01:00
|
|
|
struct AddContainerItemScriptsVisitor
|
|
|
|
{
|
|
|
|
AddContainerItemScriptsVisitor(MWWorld::LocalScripts& scripts)
|
|
|
|
: mScripts(scripts)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
MWWorld::LocalScripts& mScripts;
|
2013-12-05 13:21:26 +01:00
|
|
|
|
2015-12-06 20:30:52 +01:00
|
|
|
bool operator()(const MWWorld::Ptr& containerPtr)
|
|
|
|
{
|
2018-12-03 20:21:40 +04:00
|
|
|
// Ignore containers without generated content
|
2021-10-11 11:46:21 +00:00
|
|
|
if (containerPtr.getType() == ESM::Container::sRecordId
|
2018-12-03 20:21:40 +04:00
|
|
|
&& containerPtr.getRefData().getCustomData() == nullptr)
|
2020-10-13 17:46:32 +02:00
|
|
|
return true;
|
2018-12-03 20:21:40 +04:00
|
|
|
|
2014-05-22 20:37:22 +02:00
|
|
|
MWWorld::ContainerStore& container = containerPtr.getClass().getContainerStore(containerPtr);
|
2022-08-11 22:51:55 +02:00
|
|
|
for (const auto& ptr : container)
|
2013-01-12 18:31:57 +00:00
|
|
|
{
|
2022-08-11 22:51:55 +02:00
|
|
|
std::string_view script = ptr.getClass().getScript(ptr);
|
|
|
|
if (!script.empty())
|
2013-01-12 18:31:57 +00:00
|
|
|
{
|
2022-08-11 22:51:55 +02:00
|
|
|
MWWorld::Ptr item = ptr;
|
2015-12-06 20:30:52 +01:00
|
|
|
item.mCell = containerPtr.getCell();
|
|
|
|
mScripts.add(script, item);
|
2013-01-12 18:31:57 +00:00
|
|
|
}
|
|
|
|
}
|
2015-12-06 20:30:52 +01:00
|
|
|
return true;
|
2013-01-12 18:31:57 +00:00
|
|
|
}
|
2015-12-06 20:30:52 +01:00
|
|
|
};
|
|
|
|
|
2011-10-07 09:52:42 +02:00
|
|
|
}
|
|
|
|
|
2015-12-29 15:22:19 +01:00
|
|
|
MWWorld::LocalScripts::LocalScripts(const MWWorld::ESMStore& store)
|
|
|
|
: mStore(store)
|
|
|
|
{
|
|
|
|
mIter = mScripts.end();
|
|
|
|
}
|
2011-10-07 09:52:42 +02:00
|
|
|
|
2011-10-06 12:29:59 +02:00
|
|
|
void MWWorld::LocalScripts::startIteration()
|
|
|
|
{
|
|
|
|
mIter = mScripts.begin();
|
|
|
|
}
|
|
|
|
|
2016-02-03 16:09:20 +01:00
|
|
|
bool MWWorld::LocalScripts::getNext(std::pair<std::string, Ptr>& script)
|
2011-10-06 12:29:59 +02:00
|
|
|
{
|
2021-01-09 14:18:38 +04:00
|
|
|
if (mIter != mScripts.end())
|
2011-10-06 12:29:59 +02:00
|
|
|
{
|
2016-02-03 16:09:20 +01:00
|
|
|
std::list<std::pair<std::string, Ptr>>::iterator iter = mIter++;
|
2016-02-26 12:59:35 +01:00
|
|
|
script = *iter;
|
|
|
|
return true;
|
2011-10-06 12:29:59 +02:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-08-11 22:51:55 +02:00
|
|
|
void MWWorld::LocalScripts::add(std::string_view scriptName, const Ptr& ptr)
|
2011-10-06 12:29:59 +02:00
|
|
|
{
|
2015-05-27 19:45:26 +02:00
|
|
|
if (const ESM::Script* script = mStore.get<ESM::Script>().search(scriptName))
|
2011-10-07 09:52:42 +02:00
|
|
|
{
|
2014-09-21 12:43:19 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
ptr.getRefData().setLocals(*script);
|
2011-10-07 09:52:42 +02:00
|
|
|
|
2016-02-03 16:06:25 +01:00
|
|
|
for (std::list<std::pair<std::string, Ptr>>::iterator iter = mScripts.begin(); iter != mScripts.end();
|
|
|
|
++iter)
|
|
|
|
if (iter->second == ptr)
|
|
|
|
{
|
2018-08-14 23:05:43 +04:00
|
|
|
Log(Debug::Warning) << "Error: tried to add local script twice for " << ptr.getCellRef().getRefId();
|
2016-02-03 16:06:25 +01:00
|
|
|
remove(ptr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-10-17 12:26:35 +04:00
|
|
|
mScripts.emplace_back(scriptName, ptr);
|
2014-09-21 12:43:19 +02:00
|
|
|
}
|
|
|
|
catch (const std::exception& exception)
|
|
|
|
{
|
|
|
|
Log(Debug::Error) << "failed to add local script " << scriptName
|
2018-08-14 23:05:43 +04:00
|
|
|
<< " because an exception has been thrown: " << exception.what();
|
2014-09-21 12:43:19 +02:00
|
|
|
}
|
2011-10-07 09:52:42 +02:00
|
|
|
}
|
2015-05-27 19:45:26 +02:00
|
|
|
else
|
|
|
|
Log(Debug::Warning) << "failed to add local script " << scriptName << " because the script does not exist.";
|
2011-10-07 09:52:42 +02:00
|
|
|
}
|
|
|
|
|
2013-12-05 13:21:26 +01:00
|
|
|
void MWWorld::LocalScripts::addCell(CellStore* cell)
|
2011-10-07 09:52:42 +02:00
|
|
|
{
|
2015-12-06 20:30:52 +01:00
|
|
|
AddScriptsVisitor addScriptsVisitor(*this);
|
|
|
|
cell->forEach(addScriptsVisitor);
|
|
|
|
|
|
|
|
AddContainerItemScriptsVisitor addContainerItemScriptsVisitor(*this);
|
|
|
|
cell->forEachType<ESM::NPC>(addContainerItemScriptsVisitor);
|
|
|
|
cell->forEachType<ESM::Creature>(addContainerItemScriptsVisitor);
|
|
|
|
cell->forEachType<ESM::Container>(addContainerItemScriptsVisitor);
|
2011-10-06 12:29:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MWWorld::LocalScripts::clear()
|
|
|
|
{
|
|
|
|
mScripts.clear();
|
|
|
|
}
|
|
|
|
|
2013-12-05 13:21:26 +01:00
|
|
|
void MWWorld::LocalScripts::clearCell(CellStore* cell)
|
2011-10-06 12:29:59 +02:00
|
|
|
{
|
|
|
|
std::list<std::pair<std::string, Ptr>>::iterator iter = mScripts.begin();
|
|
|
|
|
|
|
|
while (iter != mScripts.end())
|
|
|
|
{
|
2013-01-13 19:49:56 +00:00
|
|
|
if (iter->second.mCell == cell)
|
2011-10-06 12:29:59 +02:00
|
|
|
{
|
|
|
|
if (iter == mIter)
|
|
|
|
++mIter;
|
|
|
|
|
|
|
|
mScripts.erase(iter++);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
++iter;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-13 17:05:12 +00:00
|
|
|
void MWWorld::LocalScripts::remove(RefData* ref)
|
|
|
|
{
|
|
|
|
for (std::list<std::pair<std::string, Ptr>>::iterator iter = mScripts.begin(); iter != mScripts.end(); ++iter)
|
|
|
|
if (&(iter->second.getRefData()) == ref)
|
|
|
|
{
|
|
|
|
if (iter == mIter)
|
|
|
|
++mIter;
|
|
|
|
|
|
|
|
mScripts.erase(iter);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-06 12:29:59 +02:00
|
|
|
void MWWorld::LocalScripts::remove(const Ptr& ptr)
|
|
|
|
{
|
|
|
|
for (std::list<std::pair<std::string, Ptr>>::iterator iter = mScripts.begin(); iter != mScripts.end(); ++iter)
|
|
|
|
if (iter->second == ptr)
|
|
|
|
{
|
|
|
|
if (iter == mIter)
|
|
|
|
++mIter;
|
|
|
|
|
|
|
|
mScripts.erase(iter);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|