Don't teleport NPCs to unknown cells

lua_on_mac
Evil Eye 3 years ago committed by psi29a
parent 1b58e10b28
commit ac747f02f3

@ -355,7 +355,8 @@ namespace MWScript
if (ptr.getContainerStore())
return;
if (ptr == MWMechanics::getPlayer())
bool isPlayer = ptr == MWMechanics::getPlayer();
if (isPlayer)
{
MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true);
}
@ -378,17 +379,21 @@ namespace MWScript
}
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);
int cx,cy;
MWBase::Environment::get().getWorld()->positionToIndex(x,y,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";
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;
MWBase::Environment::get().getWorld()->positionToIndex(x,y,cx,cy);
store = MWBase::Environment::get().getWorld()->getExterior(cx,cy);
}
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)
// 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.
if(ptr != MWMechanics::getPlayer())
if(!isPlayer)
zRot = zRot/60.0f;
rot.z() = osg::DegreesToRadians(zRot);
MWBase::Environment::get().getWorld()->rotateObject(ptr,rot);

@ -550,6 +550,14 @@ namespace MWWorld
const ESM::Cell *cell = mStore.get<ESM::Cell>().searchExtByName (cellName);
if (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
for (const ESM::Region &region : mStore.get<ESM::Region>())

@ -12,7 +12,6 @@
#include "generator.hpp"
#include "extensions.hpp"
#include "declarationparser.hpp"
#include "exception.hpp"
namespace Compiler
{
@ -259,33 +258,11 @@ namespace Compiler
mExplicit.clear();
}
try
{
// workaround for broken positioncell instructions.
/// \todo add option to disable this
std::unique_ptr<ErrorDowngrade> errorDowngrade (nullptr);
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;
}
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);
mState = EndState;
return true;

Loading…
Cancel
Save