|
|
|
@ -78,6 +78,7 @@
|
|
|
|
|
|
|
|
|
|
#include "contentloader.hpp"
|
|
|
|
|
#include "esmloader.hpp"
|
|
|
|
|
#include "cellutils.hpp"
|
|
|
|
|
|
|
|
|
|
namespace MWWorld
|
|
|
|
|
{
|
|
|
|
@ -1276,11 +1277,10 @@ namespace MWWorld
|
|
|
|
|
|
|
|
|
|
MWWorld::Ptr World::moveObject(const Ptr& ptr, const osg::Vec3f& position, bool movePhysics, bool moveToActive)
|
|
|
|
|
{
|
|
|
|
|
int cellX, cellY;
|
|
|
|
|
positionToIndex(position.x(), position.y(), cellX, cellY);
|
|
|
|
|
const auto index = MWWorld::positionToIndex(position.x(), position.y());
|
|
|
|
|
|
|
|
|
|
CellStore* cell = ptr.getCell();
|
|
|
|
|
CellStore* newCell = getExterior(cellX, cellY);
|
|
|
|
|
CellStore* newCell = getExterior(index.mX, index.mY);
|
|
|
|
|
bool isCellActive = getPlayerPtr().isInCell() && getPlayerPtr().getCell()->isExterior() && mWorldScene->isCellActive(*newCell);
|
|
|
|
|
|
|
|
|
|
if (cell->isExterior() || (moveToActive && isCellActive && ptr.getClass().isActor()))
|
|
|
|
@ -1518,8 +1518,9 @@ namespace MWWorld
|
|
|
|
|
|
|
|
|
|
void World::positionToIndex (float x, float y, int &cellX, int &cellY) const
|
|
|
|
|
{
|
|
|
|
|
cellX = static_cast<int>(std::floor(x / Constants::CellSizeInUnits));
|
|
|
|
|
cellY = static_cast<int>(std::floor(y / Constants::CellSizeInUnits));
|
|
|
|
|
const auto index = MWWorld::positionToIndex(x, y);
|
|
|
|
|
cellX = index.mX;
|
|
|
|
|
cellY = index.mY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void World::queueMovement(const Ptr &ptr, const osg::Vec3f &velocity)
|
|
|
|
@ -2074,11 +2075,6 @@ namespace MWWorld
|
|
|
|
|
|
|
|
|
|
struct GetDoorMarkerVisitor
|
|
|
|
|
{
|
|
|
|
|
GetDoorMarkerVisitor(std::vector<World::DoorMarker>& out)
|
|
|
|
|
: mOut(out)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<World::DoorMarker>& mOut;
|
|
|
|
|
|
|
|
|
|
bool operator()(const MWWorld::Ptr& ptr)
|
|
|
|
@ -2104,11 +2100,7 @@ namespace MWWorld
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
cellid.mPaged = true;
|
|
|
|
|
MWBase::Environment::get().getWorld()->positionToIndex(
|
|
|
|
|
ref.mRef.getDoorDest().pos[0],
|
|
|
|
|
ref.mRef.getDoorDest().pos[1],
|
|
|
|
|
cellid.mIndex.mX,
|
|
|
|
|
cellid.mIndex.mY);
|
|
|
|
|
cellid.mIndex = MWWorld::positionToIndex(ref.mRef.getDoorDest().pos[0], ref.mRef.getDoorDest().pos[1]);
|
|
|
|
|
}
|
|
|
|
|
newMarker.dest = cellid;
|
|
|
|
|
|
|
|
|
@ -2124,7 +2116,7 @@ namespace MWWorld
|
|
|
|
|
|
|
|
|
|
void World::getDoorMarkers (CellStore* cell, std::vector<World::DoorMarker>& out)
|
|
|
|
|
{
|
|
|
|
|
GetDoorMarkerVisitor visitor(out);
|
|
|
|
|
GetDoorMarkerVisitor visitor {out};
|
|
|
|
|
cell->forEachType<ESM::Door>(visitor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -2210,9 +2202,8 @@ namespace MWWorld
|
|
|
|
|
throw std::runtime_error("copyObjectToCell(): cannot copy object to null cell");
|
|
|
|
|
if (cell->isExterior())
|
|
|
|
|
{
|
|
|
|
|
int cellX, cellY;
|
|
|
|
|
positionToIndex(pos.pos[0], pos.pos[1], cellX, cellY);
|
|
|
|
|
cell = mCells.getExterior(cellX, cellY);
|
|
|
|
|
const auto index = MWWorld::positionToIndex(pos.pos[0], pos.pos[1]);
|
|
|
|
|
cell = mCells.getExterior(index.mX, index.mY);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MWWorld::Ptr dropped =
|
|
|
|
@ -2819,10 +2810,9 @@ namespace MWWorld
|
|
|
|
|
// door to exterior
|
|
|
|
|
if (door->getDestCell().empty())
|
|
|
|
|
{
|
|
|
|
|
int x, y;
|
|
|
|
|
ESM::Position doorDest = door->getDoorDest();
|
|
|
|
|
positionToIndex(doorDest.pos[0], doorDest.pos[1], x, y);
|
|
|
|
|
source = getExterior(x, y);
|
|
|
|
|
const auto index = MWWorld::positionToIndex(doorDest.pos[0], doorDest.pos[1]);
|
|
|
|
|
source = getExterior(index.mX, index.mY);
|
|
|
|
|
}
|
|
|
|
|
// door to interior
|
|
|
|
|
else
|
|
|
|
@ -3154,7 +3144,7 @@ namespace MWWorld
|
|
|
|
|
const osg::Vec3f sourcePos = worldPos + orient * osg::Vec3f(0,-1,0) * 64.f;
|
|
|
|
|
|
|
|
|
|
// Early out if the launch position is underwater
|
|
|
|
|
bool underwater = MWBase::Environment::get().getWorld()->isUnderwater(MWMechanics::getPlayer().getCell(), worldPos);
|
|
|
|
|
bool underwater = isUnderwater(MWMechanics::getPlayer().getCell(), worldPos);
|
|
|
|
|
if (underwater)
|
|
|
|
|
{
|
|
|
|
|
MWMechanics::projectileHit(actor, Ptr(), bow, projectile, worldPos, attackStrength);
|
|
|
|
@ -3415,15 +3405,12 @@ namespace MWWorld
|
|
|
|
|
|
|
|
|
|
struct AddDetectedReferenceVisitor
|
|
|
|
|
{
|
|
|
|
|
AddDetectedReferenceVisitor(std::vector<Ptr>& out, const Ptr& detector, World::DetectionType type, float squaredDist)
|
|
|
|
|
: mOut(out), mDetector(detector), mSquaredDist(squaredDist), mType(type)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<Ptr>& mOut;
|
|
|
|
|
Ptr mDetector;
|
|
|
|
|
float mSquaredDist;
|
|
|
|
|
World::DetectionType mType;
|
|
|
|
|
const MWWorld::ESMStore& mStore;
|
|
|
|
|
|
|
|
|
|
bool operator() (const MWWorld::Ptr& ptr)
|
|
|
|
|
{
|
|
|
|
|
if ((ptr.getRefData().getPosition().asVec3() - mDetector.getRefData().getPosition().asVec3()).length2() >= mSquaredDist)
|
|
|
|
@ -3439,14 +3426,13 @@ namespace MWWorld
|
|
|
|
|
// but ignore containers without resolved content
|
|
|
|
|
if (isContainer && ptr.getRefData().getCustomData() == nullptr)
|
|
|
|
|
{
|
|
|
|
|
const auto& store = MWBase::Environment::get().getWorld()->getStore();
|
|
|
|
|
for(const auto& containerItem : ptr.get<ESM::Container>()->mBase->mInventory.mList)
|
|
|
|
|
{
|
|
|
|
|
if(containerItem.mCount)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
ManualRef ref(store, containerItem.mItem, containerItem.mCount);
|
|
|
|
|
ManualRef ref(mStore, containerItem.mItem, containerItem.mCount);
|
|
|
|
|
if(needToAdd(ref.getPtr(), mDetector))
|
|
|
|
|
{
|
|
|
|
|
mOut.push_back(ptr);
|
|
|
|
@ -3521,7 +3507,7 @@ namespace MWWorld
|
|
|
|
|
|
|
|
|
|
dist = feetToGameUnits(dist);
|
|
|
|
|
|
|
|
|
|
AddDetectedReferenceVisitor visitor (out, ptr, type, dist*dist);
|
|
|
|
|
AddDetectedReferenceVisitor visitor {out, ptr, dist * dist, type, mStore};
|
|
|
|
|
|
|
|
|
|
for (CellStore* cellStore : mWorldScene->getActiveCells())
|
|
|
|
|
{
|
|
|
|
@ -3701,10 +3687,9 @@ namespace MWWorld
|
|
|
|
|
static int iNumberCreatures = mStore.get<ESM::GameSetting>().find("iNumberCreatures")->mValue.getInteger();
|
|
|
|
|
int numCreatures = 1 + Misc::Rng::rollDice(iNumberCreatures); // [1, iNumberCreatures]
|
|
|
|
|
|
|
|
|
|
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
|
|
|
|
for (int i=0; i<numCreatures; ++i)
|
|
|
|
|
{
|
|
|
|
|
std::string selectedCreature = MWMechanics::getLevelledItem(list, true, prng);
|
|
|
|
|
std::string selectedCreature = MWMechanics::getLevelledItem(list, true, mPrng);
|
|
|
|
|
if (selectedCreature.empty())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
@ -3833,6 +3818,8 @@ namespace MWWorld
|
|
|
|
|
|
|
|
|
|
struct ResetActorsVisitor
|
|
|
|
|
{
|
|
|
|
|
World& mWorld;
|
|
|
|
|
|
|
|
|
|
bool operator() (const Ptr& ptr)
|
|
|
|
|
{
|
|
|
|
|
if (ptr.getClass().isActor() && ptr.getCellRef().hasContentFile())
|
|
|
|
@ -3841,18 +3828,19 @@ namespace MWWorld
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
const ESM::Position& origPos = ptr.getCellRef().getPosition();
|
|
|
|
|
MWBase::Environment::get().getWorld()->moveObject(ptr, origPos.asVec3());
|
|
|
|
|
MWBase::Environment::get().getWorld()->rotateObject(ptr, origPos.asRotationVec3());
|
|
|
|
|
mWorld.moveObject(ptr, origPos.asVec3());
|
|
|
|
|
mWorld.rotateObject(ptr, origPos.asRotationVec3());
|
|
|
|
|
ptr.getClass().adjustPosition(ptr, true);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void World::resetActors()
|
|
|
|
|
{
|
|
|
|
|
for (CellStore* cellstore : mWorldScene->getActiveCells())
|
|
|
|
|
{
|
|
|
|
|
ResetActorsVisitor visitor;
|
|
|
|
|
ResetActorsVisitor visitor {*this};
|
|
|
|
|
cellstore->forEach(visitor);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|