mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 06:53:53 +00:00
Merge branch 'underground' into 'master'
Get The Underground 2 running See merge request OpenMW/openmw!608
This commit is contained in:
commit
6a9f2fdb17
10 changed files with 51 additions and 11 deletions
|
@ -1,6 +1,7 @@
|
||||||
0.48.0
|
0.48.0
|
||||||
------
|
------
|
||||||
|
|
||||||
|
Bug #3737: Scripts from The Underground 2 .esp do not play (all patched versions)
|
||||||
Bug #3846: Strings starting with "-" fail to compile if not enclosed in quotes
|
Bug #3846: Strings starting with "-" fail to compile if not enclosed in quotes
|
||||||
|
|
||||||
0.47.0
|
0.47.0
|
||||||
|
|
|
@ -275,10 +275,12 @@ namespace MWScript
|
||||||
MWWorld::Ptr ptr = R()(runtime);
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
if(ptr.getClass().isActor())
|
||||||
|
{
|
||||||
ptr.getClass().getCreatureStats(ptr).setAiSetting(mIndex, value);
|
ptr.getClass().getCreatureStats(ptr).setAiSetting(mIndex, value);
|
||||||
ptr.getClass().setBaseAISetting(ptr.getCellRef().getRefId(), mIndex, value);
|
ptr.getClass().setBaseAISetting(ptr.getCellRef().getRefId(), mIndex, value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class R>
|
template<class R>
|
||||||
|
|
|
@ -308,7 +308,8 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
if (it == invStore.end())
|
if (it == invStore.end())
|
||||||
{
|
{
|
||||||
it = ptr.getClass().getContainerStore (ptr).add (item, 1, ptr);
|
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), item, 1);
|
||||||
|
it = ptr.getClass().getContainerStore (ptr).add (ref.getPtr(), 1, ptr, false);
|
||||||
Log(Debug::Warning) << "Implicitly adding one " << item <<
|
Log(Debug::Warning) << "Implicitly adding one " << item <<
|
||||||
" to the inventory store of " << ptr.getCellRef().getRefId() <<
|
" to the inventory store of " << ptr.getCellRef().getRefId() <<
|
||||||
" to fulfill the requirements of Equip instruction";
|
" to fulfill the requirements of Equip instruction";
|
||||||
|
|
|
@ -92,6 +92,21 @@ namespace
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct IdGettingVisitor : public boost::static_visitor<std::string>
|
||||||
|
{
|
||||||
|
std::string operator()(const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
if(ptr.isEmpty())
|
||||||
|
return {};
|
||||||
|
return ptr.mRef->mRef.getRefId();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string operator()(const std::pair<ESM::RefNum, std::string>& pair) const
|
||||||
|
{
|
||||||
|
return pair.second;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWScript
|
namespace MWScript
|
||||||
|
@ -110,6 +125,11 @@ namespace MWScript
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string GlobalScriptDesc::getId() const
|
||||||
|
{
|
||||||
|
return boost::apply_visitor(IdGettingVisitor(), mTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GlobalScripts::GlobalScripts (const MWWorld::ESMStore& store)
|
GlobalScripts::GlobalScripts (const MWWorld::ESMStore& store)
|
||||||
: mStore (store)
|
: mStore (store)
|
||||||
|
|
|
@ -44,6 +44,8 @@ namespace MWScript
|
||||||
const MWWorld::Ptr* getPtrIfPresent() const; // Returns a Ptr if one has been resolved
|
const MWWorld::Ptr* getPtrIfPresent() const; // Returns a Ptr if one has been resolved
|
||||||
|
|
||||||
MWWorld::Ptr getPtr(); // Resolves mTarget to a Ptr and caches the (potentially empty) result
|
MWWorld::Ptr getPtr(); // Resolves mTarget to a Ptr and caches the (potentially empty) result
|
||||||
|
|
||||||
|
std::string getId() const; // Returns the target's ID -- if any
|
||||||
};
|
};
|
||||||
|
|
||||||
class GlobalScripts
|
class GlobalScripts
|
||||||
|
|
|
@ -129,6 +129,15 @@ namespace MWScript
|
||||||
mGlobalScriptDesc = globalScriptDesc;
|
mGlobalScriptDesc = globalScriptDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string InterpreterContext::getTarget() const
|
||||||
|
{
|
||||||
|
if(!mReference.isEmpty())
|
||||||
|
return mReference.mRef->mRef.getRefId();
|
||||||
|
else if(mGlobalScriptDesc)
|
||||||
|
return mGlobalScriptDesc->getId();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
int InterpreterContext::getLocalShort (int index) const
|
int InterpreterContext::getLocalShort (int index) const
|
||||||
{
|
{
|
||||||
if (!mLocals)
|
if (!mLocals)
|
||||||
|
@ -474,7 +483,7 @@ namespace MWScript
|
||||||
locals.mFloats[findLocalVariableIndex (scriptId, name, 'f')] = value;
|
locals.mFloats[findLocalVariableIndex (scriptId, name, 'f')] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::Ptr InterpreterContext::getReference(bool required)
|
MWWorld::Ptr InterpreterContext::getReference(bool required) const
|
||||||
{
|
{
|
||||||
return getReferenceImp ("", true, required);
|
return getReferenceImp ("", true, required);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,8 @@ namespace MWScript
|
||||||
InterpreterContext (MWScript::Locals *locals, const MWWorld::Ptr& reference);
|
InterpreterContext (MWScript::Locals *locals, const MWWorld::Ptr& reference);
|
||||||
///< The ownership of \a locals is not transferred. 0-pointer allowed.
|
///< The ownership of \a locals is not transferred. 0-pointer allowed.
|
||||||
|
|
||||||
|
std::string getTarget() const override;
|
||||||
|
|
||||||
int getLocalShort (int index) const override;
|
int getLocalShort (int index) const override;
|
||||||
|
|
||||||
int getLocalLong (int index) const override;
|
int getLocalLong (int index) const override;
|
||||||
|
@ -124,7 +126,7 @@ namespace MWScript
|
||||||
|
|
||||||
void setMemberFloat (const std::string& id, const std::string& name, float value, bool global) override;
|
void setMemberFloat (const std::string& id, const std::string& name, float value, bool global) override;
|
||||||
|
|
||||||
MWWorld::Ptr getReference(bool required=true);
|
MWWorld::Ptr getReference(bool required=true) const;
|
||||||
///< Reference, that the script is running from (can be empty)
|
///< Reference, that the script is running from (can be empty)
|
||||||
|
|
||||||
void updatePtr(const MWWorld::Ptr& base, const MWWorld::Ptr& updated);
|
void updatePtr(const MWWorld::Ptr& base, const MWWorld::Ptr& updated);
|
||||||
|
|
|
@ -109,7 +109,8 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
|
|
||||||
// execute script
|
// execute script
|
||||||
if (!iter->second.mByteCode.empty() && iter->second.mActive)
|
std::string target = Misc::StringUtils::lowerCase(interpreterContext.getTarget());
|
||||||
|
if (!iter->second.mByteCode.empty() && iter->second.mInactive.find(target) == iter->second.mInactive.end())
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!mOpcodesInstalled)
|
if (!mOpcodesInstalled)
|
||||||
|
@ -129,7 +130,7 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
Log(Debug::Error) << "Execution of script " << name << " failed: " << e.what();
|
Log(Debug::Error) << "Execution of script " << name << " failed: " << e.what();
|
||||||
|
|
||||||
iter->second.mActive = false; // don't execute again.
|
iter->second.mInactive.insert(target); // don't execute again.
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -138,7 +139,7 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
for (auto& script : mScripts)
|
for (auto& script : mScripts)
|
||||||
{
|
{
|
||||||
script.second.mActive = true;
|
script.second.mInactive.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
mGlobalScripts.clear();
|
mGlobalScripts.clear();
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define GAME_SCRIPT_SCRIPTMANAGER_H
|
#define GAME_SCRIPT_SCRIPTMANAGER_H
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <components/compiler/streamerrorhandler.hpp>
|
#include <components/compiler/streamerrorhandler.hpp>
|
||||||
|
@ -45,13 +46,12 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
std::vector<Interpreter::Type_Code> mByteCode;
|
std::vector<Interpreter::Type_Code> mByteCode;
|
||||||
Compiler::Locals mLocals;
|
Compiler::Locals mLocals;
|
||||||
bool mActive;
|
std::set<std::string> mInactive;
|
||||||
|
|
||||||
CompiledScript(const std::vector<Interpreter::Type_Code>& code, const Compiler::Locals& locals)
|
CompiledScript(const std::vector<Interpreter::Type_Code>& code, const Compiler::Locals& locals)
|
||||||
{
|
{
|
||||||
mByteCode = code;
|
mByteCode = code;
|
||||||
mLocals = locals;
|
mLocals = locals;
|
||||||
mActive = true;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual ~Context() {}
|
virtual ~Context() {}
|
||||||
|
|
||||||
|
virtual std::string getTarget() const = 0;
|
||||||
|
|
||||||
virtual int getLocalShort (int index) const = 0;
|
virtual int getLocalShort (int index) const = 0;
|
||||||
|
|
||||||
virtual int getLocalLong (int index) const = 0;
|
virtual int getLocalLong (int index) const = 0;
|
||||||
|
|
Loading…
Reference in a new issue