make Class::use method return an equip action for equippable items, add sound for equipping

This commit is contained in:
scrawl 2012-05-16 16:08:55 +02:00
parent 9c4243782e
commit 0f1e09d2c1
10 changed files with 133 additions and 60 deletions

View file

@ -48,6 +48,7 @@ add_openmw_dir (mwworld
refdata world physicssystem scene globals class action nullaction actionteleport refdata world physicssystem scene globals class action nullaction actionteleport
containerstore actiontalk actiontake manualref player cellfunctors containerstore actiontalk actiontake manualref player cellfunctors
cells localscripts customdata weather inventorystore ptr actionopen actionread cells localscripts customdata weather inventorystore ptr actionopen actionread
actionequip
) )
add_openmw_dir (mwclass add_openmw_dir (mwclass

View file

@ -9,6 +9,7 @@
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/actionequip.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "../mwworld/world.hpp" #include "../mwworld/world.hpp"
@ -264,4 +265,11 @@ namespace MWClass
return ref->base->enchant; 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));
}
} }

View file

@ -61,6 +61,11 @@ namespace MWClass
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @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
}; };
} }

View file

@ -9,6 +9,7 @@
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/actionequip.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "../mwworld/world.hpp" #include "../mwworld/world.hpp"
@ -217,4 +218,11 @@ namespace MWClass
return ref->base->enchant; 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));
}
} }

View file

@ -55,6 +55,10 @@ namespace MWClass
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @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
}; };
} }

View file

@ -9,6 +9,7 @@
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/actiontake.hpp" #include "../mwworld/actiontake.hpp"
#include "../mwworld/actionequip.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "../mwworld/world.hpp" #include "../mwworld/world.hpp"
@ -355,4 +356,11 @@ namespace MWClass
return ref->base->enchant; 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));
}
} }

View file

@ -61,6 +61,11 @@ namespace MWClass
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @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
}; };
} }

View file

@ -147,73 +147,32 @@ namespace MWGui
{ {
MWWorld::Ptr ptr = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>(); MWWorld::Ptr ptr = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>();
// can the object be equipped? if (mDragAndDrop->mDraggedFrom != this)
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
{ {
// add item to the player's inventory
MWWorld::InventoryStore& invStore = static_cast<MWWorld::InventoryStore&>(MWWorld::Class::get(mContainer).getContainerStore(mContainer)); MWWorld::InventoryStore& invStore = static_cast<MWWorld::InventoryStore&>(MWWorld::Class::get(mContainer).getContainerStore(mContainer));
MWWorld::ContainerStoreIterator it = invStore.begin(); MWWorld::ContainerStoreIterator it = invStore.begin();
if (mDragAndDrop->mDraggedFrom != this) int origCount = ptr.getRefData().getCount();
{ ptr.getRefData().setCount(origCount - mDragAndDrop->mDraggedCount);
// add item to the player's inventory it = invStore.add(ptr);
int origCount = ptr.getRefData().getCount(); (*it).getRefData().setCount(mDragAndDrop->mDraggedCount);
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;
}
}
}
assert(it != invStore.end()); /// \todo scripts
// equip the item in the first free slot boost::shared_ptr<MWWorld::Action> action = MWWorld::Class::get(ptr).use(ptr);
for (std::vector<int>::const_iterator slot=slots.first.begin();
slot!=slots.first.end(); ++slot) action->execute();
{
// 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()) // this is necessary for books/scrolls: if they are already in the player's inventory,
{ // the "Take" button should not be visible.
// slot is not occupied // NOTE: the take button is "reset" when the window opens, so we can safely do the following
invStore.equip(*slot, it); // without screwing up future book windows
break; if (mDragAndDrop->mWasInInventory)
} {
} mWindowManager.getBookWindow()->setTakeButtonShow(false);
mWindowManager.getScrollWindow()->setTakeButtonShow(false);
} }
mDragAndDrop->mIsOnDragAndDrop = false; mDragAndDrop->mIsOnDragAndDrop = false;

View 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;
}
}
}
}

View 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