mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 23:23:52 +00:00
Merge branch 'autoequip'
This commit is contained in:
commit
f52b9cc162
9 changed files with 216 additions and 32 deletions
|
@ -55,7 +55,7 @@ add_openmw_dir (mwclass
|
|||
)
|
||||
|
||||
add_openmw_dir (mwmechanics
|
||||
mechanicsmanager stat creaturestats magiceffects movement
|
||||
mechanicsmanager stat creaturestats magiceffects movement actors
|
||||
)
|
||||
|
||||
# Main executable
|
||||
|
|
|
@ -160,7 +160,8 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
|||
|
||||
// update actors
|
||||
std::vector<std::pair<std::string, Ogre::Vector3> > movement;
|
||||
mEnvironment.mMechanicsManager->update (movement);
|
||||
mEnvironment.mMechanicsManager->update (movement, mEnvironment.mFrameDuration,
|
||||
mEnvironment.mWindowManager->getMode()!=MWGui::GM_Game);
|
||||
|
||||
if (mEnvironment.mWindowManager->getMode()==MWGui::GM_Game)
|
||||
mEnvironment.mWorld->doPhysics (movement, mEnvironment.mFrameDuration);
|
||||
|
|
77
apps/openmw/mwmechanics/actors.cpp
Normal file
77
apps/openmw/mwmechanics/actors.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
|
||||
#include "actors.hpp"
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
#include <components/esm/loadnpc.hpp>
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
void Actors::updateActor (const MWWorld::Ptr& ptr, float duration)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused)
|
||||
{
|
||||
if (!paused)
|
||||
MWWorld::Class::get (ptr).getInventoryStore (ptr).autoEquip (
|
||||
MWWorld::Class::get (ptr).getNpcStats (ptr));
|
||||
}
|
||||
|
||||
Actors::Actors (MWWorld::Environment& environment) : mEnvironment (environment), mDuration (0) {}
|
||||
|
||||
void Actors::addActor (const MWWorld::Ptr& ptr)
|
||||
{
|
||||
mActors.insert (ptr);
|
||||
}
|
||||
|
||||
void Actors::removeActor (const MWWorld::Ptr& ptr)
|
||||
{
|
||||
mActors.erase (ptr);
|
||||
}
|
||||
|
||||
void Actors::dropActors (const MWWorld::Ptr::CellStore *cellStore)
|
||||
{
|
||||
std::set<MWWorld::Ptr>::iterator iter = mActors.begin();
|
||||
|
||||
while (iter!=mActors.end())
|
||||
if (iter->getCell()==cellStore)
|
||||
{
|
||||
mActors.erase (iter++);
|
||||
}
|
||||
else
|
||||
++iter;
|
||||
}
|
||||
|
||||
void Actors::update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement, float duration,
|
||||
bool paused)
|
||||
{
|
||||
mDuration += duration;
|
||||
|
||||
if (mDuration>=0.25)
|
||||
{
|
||||
for (std::set<MWWorld::Ptr>::iterator iter (mActors.begin()); iter!=mActors.end(); ++iter)
|
||||
{
|
||||
updateActor (*iter, mDuration);
|
||||
|
||||
if (iter->getTypeName()==typeid (ESM::NPC).name())
|
||||
updateNpc (*iter, mDuration, paused);
|
||||
}
|
||||
|
||||
mDuration = 0;
|
||||
}
|
||||
|
||||
for (std::set<MWWorld::Ptr>::iterator iter (mActors.begin()); iter!=mActors.end();
|
||||
++iter)
|
||||
{
|
||||
Ogre::Vector3 vector = MWWorld::Class::get (*iter).getMovementVector (*iter);
|
||||
|
||||
if (vector!=Ogre::Vector3::ZERO)
|
||||
movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector));
|
||||
}
|
||||
}
|
||||
}
|
51
apps/openmw/mwmechanics/actors.hpp
Normal file
51
apps/openmw/mwmechanics/actors.hpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
#ifndef GAME_MWMECHANICS_ACTORS_H
|
||||
#define GAME_MWMECHANICS_ACTORS_H
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Vector3;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class Environment;
|
||||
}
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
class Actors
|
||||
{
|
||||
MWWorld::Environment& mEnvironment;
|
||||
std::set<MWWorld::Ptr> mActors;
|
||||
float mDuration;
|
||||
|
||||
void updateActor (const MWWorld::Ptr& ptr, float duration);
|
||||
|
||||
void updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused);
|
||||
|
||||
public:
|
||||
|
||||
Actors (MWWorld::Environment& environment);
|
||||
|
||||
void addActor (const MWWorld::Ptr& ptr);
|
||||
///< Register an actor for stats management
|
||||
|
||||
void removeActor (const MWWorld::Ptr& ptr);
|
||||
///< Deregister an actor for stats management
|
||||
|
||||
void dropActors (const MWWorld::Ptr::CellStore *cellStore);
|
||||
///< Deregister all actors in the given cell.
|
||||
|
||||
void update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement,
|
||||
float duration, bool paused);
|
||||
///< Update actor stats and store desired velocity vectors in \a movement
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -222,14 +222,14 @@ namespace MWMechanics
|
|||
|
||||
MechanicsManager::MechanicsManager (MWWorld::Environment& environment)
|
||||
: mEnvironment (environment), mUpdatePlayer (true), mClassSelected (false),
|
||||
mRaceSelected (false)
|
||||
mRaceSelected (false), mActors (environment)
|
||||
{
|
||||
buildPlayer();
|
||||
}
|
||||
|
||||
void MechanicsManager::addActor (const MWWorld::Ptr& ptr)
|
||||
{
|
||||
mActors.insert (ptr);
|
||||
mActors.addActor (ptr);
|
||||
}
|
||||
|
||||
void MechanicsManager::removeActor (const MWWorld::Ptr& ptr)
|
||||
|
@ -237,7 +237,7 @@ namespace MWMechanics
|
|||
if (ptr==mWatched)
|
||||
mWatched = MWWorld::Ptr();
|
||||
|
||||
mActors.erase (ptr);
|
||||
mActors.removeActor (ptr);
|
||||
}
|
||||
|
||||
void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore)
|
||||
|
@ -245,16 +245,7 @@ namespace MWMechanics
|
|||
if (!mWatched.isEmpty() && mWatched.getCell()==cellStore)
|
||||
mWatched = MWWorld::Ptr();
|
||||
|
||||
std::set<MWWorld::Ptr>::iterator iter = mActors.begin();
|
||||
|
||||
while (iter!=mActors.end())
|
||||
if (iter->getCell()==cellStore)
|
||||
{
|
||||
//std::cout << "Erasing an actor";
|
||||
mActors.erase (iter++);
|
||||
}
|
||||
else
|
||||
++iter;
|
||||
mActors.dropActors (cellStore);
|
||||
}
|
||||
|
||||
void MechanicsManager::watchActor (const MWWorld::Ptr& ptr)
|
||||
|
@ -262,7 +253,8 @@ namespace MWMechanics
|
|||
mWatched = ptr;
|
||||
}
|
||||
|
||||
void MechanicsManager::update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement)
|
||||
void MechanicsManager::update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement,
|
||||
float duration, bool paused)
|
||||
{
|
||||
if (!mWatched.isEmpty())
|
||||
{
|
||||
|
@ -345,14 +337,7 @@ namespace MWMechanics
|
|||
mEnvironment.mWindowManager->configureSkills (majorSkills, minorSkills);
|
||||
}
|
||||
|
||||
for (std::set<MWWorld::Ptr>::iterator iter (mActors.begin()); iter!=mActors.end();
|
||||
++iter)
|
||||
{
|
||||
Ogre::Vector3 vector = MWWorld::Class::get (*iter).getMovementVector (*iter);
|
||||
|
||||
if (vector!=Ogre::Vector3::ZERO)
|
||||
movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector));
|
||||
}
|
||||
mActors.update (movement, duration, paused);
|
||||
}
|
||||
|
||||
void MechanicsManager::setPlayerName (const std::string& name)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef GAME_MWMECHANICS_MECHANICSMANAGER_H
|
||||
#define GAME_MWMECHANICS_MECHANICSMANAGER_H
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
@ -9,6 +8,7 @@
|
|||
|
||||
#include "creaturestats.hpp"
|
||||
#include "npcstats.hpp"
|
||||
#include "actors.hpp"
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
|
@ -25,13 +25,13 @@ namespace MWMechanics
|
|||
class MechanicsManager
|
||||
{
|
||||
MWWorld::Environment& mEnvironment;
|
||||
std::set<MWWorld::Ptr> mActors;
|
||||
MWWorld::Ptr mWatched;
|
||||
CreatureStats mWatchedCreature;
|
||||
NpcStats mWatchedNpc;
|
||||
bool mUpdatePlayer;
|
||||
bool mClassSelected;
|
||||
bool mRaceSelected;
|
||||
Actors mActors;
|
||||
|
||||
void buildPlayer();
|
||||
///< build player according to stored class/race/birthsign information. Will
|
||||
|
@ -60,8 +60,12 @@ namespace MWMechanics
|
|||
///< On each update look for changes in a previously registered actor and update the
|
||||
/// GUI accordingly.
|
||||
|
||||
void update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement);
|
||||
void update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement, float duration,
|
||||
bool paused);
|
||||
///< Update actor stats and store desired velocity vectors in \a movement
|
||||
///
|
||||
/// \param paused In game type does not currently advance (this usually means some GUI
|
||||
/// component is up).
|
||||
|
||||
void setPlayerName (const std::string& name);
|
||||
///< Set player name.
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "class.hpp"
|
||||
|
||||
#include <iostream> /// \todo remove after rendering is implemented
|
||||
|
||||
void MWWorld::InventoryStore::copySlots (const InventoryStore& store)
|
||||
{
|
||||
// some const-trickery, required because of a flaw in the handling of MW-references and the
|
||||
|
@ -24,10 +26,15 @@ void MWWorld::InventoryStore::copySlots (const InventoryStore& store)
|
|||
}
|
||||
}
|
||||
|
||||
MWWorld::InventoryStore::InventoryStore()
|
||||
void MWWorld::InventoryStore::initSlots (TSlots& slots)
|
||||
{
|
||||
for (int i=0; i<Slots; ++i)
|
||||
mSlots.push_back (end());
|
||||
slots.push_back (end());
|
||||
}
|
||||
|
||||
MWWorld::InventoryStore::InventoryStore()
|
||||
{
|
||||
initSlots (mSlots);
|
||||
}
|
||||
|
||||
MWWorld::InventoryStore::InventoryStore (const InventoryStore& store)
|
||||
|
@ -86,3 +93,50 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot)
|
|||
|
||||
return mSlots[slot];
|
||||
}
|
||||
|
||||
void MWWorld::InventoryStore::autoEquip (const MWMechanics::NpcStats& stats)
|
||||
{
|
||||
TSlots slots;
|
||||
initSlots (slots);
|
||||
|
||||
for (ContainerStoreIterator iter (begin()); iter!=end(); ++iter)
|
||||
{
|
||||
std::pair<std::vector<int>, bool> itemsSlots =
|
||||
MWWorld::Class::get (*iter).getEquipmentSlots (*iter);
|
||||
|
||||
for (std::vector<int>::const_iterator iter2 (itemsSlots.first.begin());
|
||||
iter2!=itemsSlots.first.end(); ++iter2)
|
||||
{
|
||||
/// \todo comapre item with item in slot
|
||||
if (slots.at (*iter2)==end())
|
||||
{
|
||||
/// \todo unstack, if reqquired (itemsSlots.second)
|
||||
|
||||
slots[*iter2] = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
|
||||
for (std::size_t i=0; i<slots.size(); ++i)
|
||||
if (slots[i]!=mSlots[i])
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
mSlots.swap (slots);
|
||||
flagAsModified();
|
||||
|
||||
/// \todo remove the following line after rendering is implemented
|
||||
for (std::size_t i=0; i<mSlots.size(); ++i)
|
||||
if (mSlots[i]!=end())
|
||||
{
|
||||
std::cout<<"NPC is equipping " << MWWorld::Class::get (*mSlots[i]).getName (*mSlots[i])
|
||||
<< " in slot " << i << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
|
||||
#include "containerstore.hpp"
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
struct NpcStats;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
///< \brief Variant of the ContainerStore for NPCs
|
||||
|
@ -36,10 +41,14 @@ namespace MWWorld
|
|||
|
||||
private:
|
||||
|
||||
mutable std::vector<ContainerStoreIterator> mSlots;
|
||||
typedef std::vector<ContainerStoreIterator> TSlots;
|
||||
|
||||
mutable TSlots mSlots;
|
||||
|
||||
void copySlots (const InventoryStore& store);
|
||||
|
||||
void initSlots (TSlots& slots);
|
||||
|
||||
public:
|
||||
|
||||
InventoryStore();
|
||||
|
@ -52,6 +61,9 @@ namespace MWWorld
|
|||
///< \note \a iteartor can be an end-iterator
|
||||
|
||||
ContainerStoreIterator getSlot (int slot);
|
||||
|
||||
void autoEquip (const MWMechanics::NpcStats& stats);
|
||||
///< Auto equip items according to stats and item value.
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace MWWorld
|
|||
return mPtr.empty();
|
||||
}
|
||||
|
||||
const std::type_info& getType()
|
||||
const std::type_info& getType() const
|
||||
{
|
||||
assert (!mPtr.empty());
|
||||
return mPtr.type();
|
||||
|
|
Loading…
Reference in a new issue