diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 43e526ecb..10e25b376 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -451,6 +451,9 @@ namespace MWBase /// Update the value of some globals according to the world state, which may be used by dialogue entries. /// This should be called when initiating a dialogue. virtual void updateDialogueGlobals() = 0; + + /// Moves all stolen items from \a ptr to the closest evidence chest. + virtual void confiscateStolenItems(const MWWorld::Ptr& ptr) = 0; }; } diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index a403d76ed..f69f2e7cb 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -769,8 +769,8 @@ namespace MWScript MWWorld::Ptr player = world->getPlayerPtr(); world->teleportToClosestMarker(player, "prisonmarker"); player.getClass().getNpcStats(player).setBounty(0); + world->confiscateStolenItems(player); // TODO: pass time, change skills, show messagebox - // TODO: move stolen items to closest evidence chest // iDaysinPrisonMod } }; @@ -782,8 +782,7 @@ namespace MWScript { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); player.getClass().getNpcStats(player).setBounty(0); - - // TODO: move stolen items to closest evidence chest + MWBase::Environment::get().getWorld()->confiscateStolenItems(player); } }; diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index 621ff3b31..575e10f04 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -271,3 +271,15 @@ void MWWorld::Cells::getExteriorPtrs(const std::string &name, std::vector &out) +{ + for (std::map::iterator iter = mInteriors.begin(); + iter!=mInteriors.end(); ++iter) + { + Ptr ptr = getPtrAndCache (name, iter->second); + if (!ptr.isEmpty()) + out.push_back(ptr); + } + +} diff --git a/apps/openmw/mwworld/cells.hpp b/apps/openmw/mwworld/cells.hpp index 31de2f60e..afa7c03f2 100644 --- a/apps/openmw/mwworld/cells.hpp +++ b/apps/openmw/mwworld/cells.hpp @@ -56,6 +56,12 @@ namespace MWWorld /// @note Due to the current implementation of getPtr this only supports one Ptr per cell. /// @note name must be lower case void getExteriorPtrs (const std::string& name, std::vector& out); + + /// Get all Ptrs referencing \a name in interior cells + /// @note Due to the current implementation of getPtr this only supports one Ptr per cell. + /// @note name must be lower case + void getInteriorPtrs (const std::string& name, std::vector& out); + }; } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 738c71a7d..c5315afe6 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2446,4 +2446,44 @@ namespace MWWorld mGlobalVariables->setInt("crimegoldturnin", turnIn); mGlobalVariables->setInt("pchasturnin", (turnIn <= playerGold) ? 1 : 0); } + + void World::confiscateStolenItems(const Ptr &ptr) + { + Ogre::Vector3 playerPos; + if (!findInteriorPositionInWorldSpace(ptr.getCell(), playerPos)) + playerPos = mPlayer->getLastKnownExteriorPosition(); + + MWWorld::Ptr closestChest; + float closestDistance = FLT_MAX; + + std::vector chests; + mCells.getInteriorPtrs("stolen_goods", chests); + + Ogre::Vector3 chestPos; + for (std::vector::iterator it = chests.begin(); it != chests.end(); ++it) + { + if (!findInteriorPositionInWorldSpace(it->getCell(), chestPos)) + continue; + + float distance = playerPos.squaredDistance(chestPos); + if (distance < closestDistance) + { + closestDistance = distance; + closestChest = *it; + } + } + + if (!closestChest.isEmpty()) + { + ContainerStore& store = ptr.getClass().getContainerStore(ptr); + for (ContainerStoreIterator it = store.begin(); it != store.end(); ++it) + { + if (!it->getCellRef().mOwner.empty() && it->getCellRef().mOwner != "player") + { + closestChest.getClass().getContainerStore(closestChest).add(*it, it->getRefData().getCount(), closestChest); + store.remove(*it, it->getRefData().getCount(), ptr); + } + } + } + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index cc087a89f..8c091de50 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -536,6 +536,9 @@ namespace MWWorld /// Update the value of some globals according to the world state, which may be used by dialogue entries. /// This should be called when initiating a dialogue. virtual void updateDialogueGlobals(); + + /// Moves all stolen items from \a ptr to the closest evidence chest. + virtual void confiscateStolenItems(const MWWorld::Ptr& ptr); }; }