forked from mirror/openmw-tes3mp
make Class::use method return an equip action for equippable items, add sound for equipping
This commit is contained in:
parent
9c4243782e
commit
0f1e09d2c1
10 changed files with 133 additions and 60 deletions
|
@ -48,6 +48,7 @@ add_openmw_dir (mwworld
|
|||
refdata world physicssystem scene globals class action nullaction actionteleport
|
||||
containerstore actiontalk actiontake manualref player cellfunctors
|
||||
cells localscripts customdata weather inventorystore ptr actionopen actionread
|
||||
actionequip
|
||||
)
|
||||
|
||||
add_openmw_dir (mwclass
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/actionequip.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
|
@ -264,4 +265,11 @@ namespace MWClass
|
|||
|
||||
return ref->base->enchant;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Armor::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0);
|
||||
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,11 @@ namespace MWClass
|
|||
|
||||
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/actionequip.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
|
@ -217,4 +218,11 @@ namespace MWClass
|
|||
|
||||
return ref->base->enchant;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Clothing::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0);
|
||||
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,10 @@ namespace MWClass
|
|||
|
||||
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/actionequip.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
|
@ -355,4 +356,11 @@ namespace MWClass
|
|||
|
||||
return ref->base->enchant;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Weapon::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0);
|
||||
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,11 @@ namespace MWClass
|
|||
|
||||
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -147,73 +147,32 @@ namespace MWGui
|
|||
{
|
||||
MWWorld::Ptr ptr = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
|
||||
|
||||
// can the object be equipped?
|
||||
std::pair<std::vector<int>, bool> slots = MWWorld::Class::get(ptr).getEquipmentSlots(ptr);
|
||||
if (slots.first.empty())
|
||||
{
|
||||
// can't be equipped, try to use instead
|
||||
boost::shared_ptr<MWWorld::Action> action = MWWorld::Class::get(ptr).use(ptr);
|
||||
|
||||
action->execute();
|
||||
|
||||
/// \todo scripts
|
||||
|
||||
// this is necessary for books/scrolls: if they are already in the player's inventory,
|
||||
// the "Take" button should not be visible.
|
||||
// NOTE: the take button is "reset" when the window opens, so we can safely do the following
|
||||
// without screwing up future book windows
|
||||
if (mDragAndDrop->mWasInInventory)
|
||||
{
|
||||
mWindowManager.getBookWindow()->setTakeButtonShow(false);
|
||||
mWindowManager.getScrollWindow()->setTakeButtonShow(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (mDragAndDrop->mDraggedFrom != this)
|
||||
{
|
||||
// add item to the player's inventory
|
||||
MWWorld::InventoryStore& invStore = static_cast<MWWorld::InventoryStore&>(MWWorld::Class::get(mContainer).getContainerStore(mContainer));
|
||||
|
||||
MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||
|
||||
if (mDragAndDrop->mDraggedFrom != this)
|
||||
{
|
||||
// add item to the player's inventory
|
||||
int origCount = ptr.getRefData().getCount();
|
||||
ptr.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
|
||||
it = invStore.add(ptr);
|
||||
(*it).getRefData().setCount(mDragAndDrop->mDraggedCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
// retrieve iterator to the item
|
||||
for (; it != invStore.end(); ++it)
|
||||
{
|
||||
if (*it == ptr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
int origCount = ptr.getRefData().getCount();
|
||||
ptr.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
|
||||
it = invStore.add(ptr);
|
||||
(*it).getRefData().setCount(mDragAndDrop->mDraggedCount);
|
||||
}
|
||||
|
||||
assert(it != invStore.end());
|
||||
/// \todo scripts
|
||||
|
||||
// equip the item in the first free slot
|
||||
for (std::vector<int>::const_iterator slot=slots.first.begin();
|
||||
slot!=slots.first.end(); ++slot)
|
||||
{
|
||||
// if all slots are occupied, replace the last slot
|
||||
if (slot == --slots.first.end())
|
||||
{
|
||||
invStore.equip(*slot, it);
|
||||
break;
|
||||
}
|
||||
boost::shared_ptr<MWWorld::Action> action = MWWorld::Class::get(ptr).use(ptr);
|
||||
|
||||
action->execute();
|
||||
|
||||
if (invStore.getSlot(*slot) == invStore.end())
|
||||
{
|
||||
// slot is not occupied
|
||||
invStore.equip(*slot, it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// this is necessary for books/scrolls: if they are already in the player's inventory,
|
||||
// the "Take" button should not be visible.
|
||||
// NOTE: the take button is "reset" when the window opens, so we can safely do the following
|
||||
// without screwing up future book windows
|
||||
if (mDragAndDrop->mWasInInventory)
|
||||
{
|
||||
mWindowManager.getBookWindow()->setTakeButtonShow(false);
|
||||
mWindowManager.getScrollWindow()->setTakeButtonShow(false);
|
||||
}
|
||||
|
||||
mDragAndDrop->mIsOnDragAndDrop = false;
|
||||
|
|
54
apps/openmw/mwworld/actionequip.cpp
Normal file
54
apps/openmw/mwworld/actionequip.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
#include "actionequip.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
ActionEquip::ActionEquip (const MWWorld::Ptr& object) : mObject (object)
|
||||
{
|
||||
}
|
||||
|
||||
void ActionEquip::execute ()
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::InventoryStore& invStore = static_cast<MWWorld::InventoryStore&>(MWWorld::Class::get(player).getContainerStore(player));
|
||||
|
||||
// slots that this item can be equipped in
|
||||
std::pair<std::vector<int>, bool> slots = MWWorld::Class::get(mObject).getEquipmentSlots(mObject);
|
||||
|
||||
// retrieve ContainerStoreIterator to the item
|
||||
MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||
for (; it != invStore.end(); ++it)
|
||||
{
|
||||
if (*it == mObject)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(it != invStore.end());
|
||||
|
||||
// equip the item in the first free slot
|
||||
for (std::vector<int>::const_iterator slot=slots.first.begin();
|
||||
slot!=slots.first.end(); ++slot)
|
||||
{
|
||||
// if all slots are occupied, replace the last slot
|
||||
if (slot == --slots.first.end())
|
||||
{
|
||||
invStore.equip(*slot, it);
|
||||
break;
|
||||
}
|
||||
|
||||
if (invStore.getSlot(*slot) == invStore.end())
|
||||
{
|
||||
// slot is not occupied
|
||||
invStore.equip(*slot, it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
21
apps/openmw/mwworld/actionequip.hpp
Normal file
21
apps/openmw/mwworld/actionequip.hpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef GAME_MWWORLD_ACTIONEQUIP_H
|
||||
#define GAME_MWWORLD_ACTIONEQUIP_H
|
||||
|
||||
#include "action.hpp"
|
||||
#include "ptr.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class ActionEquip : public Action
|
||||
{
|
||||
Ptr mObject;
|
||||
|
||||
public:
|
||||
/// @param item to equip
|
||||
ActionEquip (const Ptr& object);
|
||||
|
||||
virtual void execute ();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue