forked from teamnwah/openmw-tes3coop
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
|
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
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
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