1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-05 06:40:09 +00:00

Don't teleport NPCs to unknown cells

This commit is contained in:
Evil Eye 2021-12-26 15:27:25 +00:00 committed by psi29a
parent 1b58e10b28
commit ac747f02f3
3 changed files with 27 additions and 37 deletions

View File

@ -355,7 +355,8 @@ namespace MWScript
if (ptr.getContainerStore()) if (ptr.getContainerStore())
return; return;
if (ptr == MWMechanics::getPlayer()) bool isPlayer = ptr == MWMechanics::getPlayer();
if (isPlayer)
{ {
MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true);
} }
@ -378,17 +379,21 @@ namespace MWScript
} }
catch(std::exception&) catch(std::exception&)
{ {
// cell not found, move to exterior instead (vanilla PositionCell compatibility) // cell not found, move to exterior instead if moving the player (vanilla PositionCell compatibility)
const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getExterior(cellID); const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getExterior(cellID);
if(!cell)
{
std::string error = "Warning: PositionCell: unknown interior cell (" + cellID + ")";
if(isPlayer)
error += ", moving to exterior instead";
runtime.getContext().report (error);
Log(Debug::Warning) << error;
if(!isPlayer)
return;
}
int cx,cy; int cx,cy;
MWBase::Environment::get().getWorld()->positionToIndex(x,y,cx,cy); MWBase::Environment::get().getWorld()->positionToIndex(x,y,cx,cy);
store = MWBase::Environment::get().getWorld()->getExterior(cx,cy); store = MWBase::Environment::get().getWorld()->getExterior(cx,cy);
if(!cell)
{
std::string error = "Warning: PositionCell: unknown interior cell (" + cellID + "), moving to exterior instead";
runtime.getContext().report (error);
Log(Debug::Warning) << error;
}
} }
if(store) if(store)
{ {
@ -400,7 +405,7 @@ namespace MWScript
// Note that you must specify ZRot in minutes (1 degree = 60 minutes; north = 0, east = 5400, south = 10800, west = 16200) // Note that you must specify ZRot in minutes (1 degree = 60 minutes; north = 0, east = 5400, south = 10800, west = 16200)
// except for when you position the player, then degrees must be used. // except for when you position the player, then degrees must be used.
// See "Morrowind Scripting for Dummies (9th Edition)" pages 50 and 54 for reference. // See "Morrowind Scripting for Dummies (9th Edition)" pages 50 and 54 for reference.
if(ptr != MWMechanics::getPlayer()) if(!isPlayer)
zRot = zRot/60.0f; zRot = zRot/60.0f;
rot.z() = osg::DegreesToRadians(zRot); rot.z() = osg::DegreesToRadians(zRot);
MWBase::Environment::get().getWorld()->rotateObject(ptr,rot); MWBase::Environment::get().getWorld()->rotateObject(ptr,rot);

View File

@ -550,6 +550,14 @@ namespace MWWorld
const ESM::Cell *cell = mStore.get<ESM::Cell>().searchExtByName (cellName); const ESM::Cell *cell = mStore.get<ESM::Cell>().searchExtByName (cellName);
if (cell) if (cell)
return cell; return cell;
// treat "Wilderness" like an empty string
static const std::string defaultName = mStore.get<ESM::GameSetting>().find("sDefaultCellname")->mValue.getString();
if (Misc::StringUtils::ciEqual(cellName, defaultName))
{
cell = mStore.get<ESM::Cell>().searchExtByName("");
if (cell)
return cell;
}
// didn't work -> now check for regions // didn't work -> now check for regions
for (const ESM::Region &region : mStore.get<ESM::Region>()) for (const ESM::Region &region : mStore.get<ESM::Region>())

View File

@ -12,7 +12,6 @@
#include "generator.hpp" #include "generator.hpp"
#include "extensions.hpp" #include "extensions.hpp"
#include "declarationparser.hpp" #include "declarationparser.hpp"
#include "exception.hpp"
namespace Compiler namespace Compiler
{ {
@ -259,33 +258,11 @@ namespace Compiler
mExplicit.clear(); mExplicit.clear();
} }
try std::vector<Interpreter::Type_Code> code;
{ int optionals = mExprParser.parseArguments (argumentType, scanner, code, keyword);
// workaround for broken positioncell instructions. mCode.insert (mCode.end(), code.begin(), code.end());
/// \todo add option to disable this extensions->generateInstructionCode (keyword, mCode, mLiterals,
std::unique_ptr<ErrorDowngrade> errorDowngrade (nullptr); mExplicit, optionals);
if (Misc::StringUtils::lowerCase (loc.mLiteral)=="positioncell")
errorDowngrade = std::make_unique<ErrorDowngrade> (getErrorHandler());
std::vector<Interpreter::Type_Code> code;
int optionals = mExprParser.parseArguments (argumentType, scanner, code, keyword);
mCode.insert (mCode.end(), code.begin(), code.end());
extensions->generateInstructionCode (keyword, mCode, mLiterals,
mExplicit, optionals);
}
catch (const SourceException&)
{
// Ignore argument exceptions for positioncell.
/// \todo add option to disable this
if (Misc::StringUtils::lowerCase (loc.mLiteral)=="positioncell")
{
SkipParser skip (getErrorHandler(), getContext());
scanner.scan (skip);
return false;
}
throw;
}
mState = EndState; mState = EndState;
return true; return true;