2013-05-11 16:38:27 +00:00
# include "inventoryitemmodel.hpp"
2017-09-11 10:49:55 +00:00
# include <sstream>
# include "../mwmechanics/actorutil.hpp"
# include "../mwmechanics/npcstats.hpp"
2013-05-11 16:38:27 +00:00
# include "../mwworld/containerstore.hpp"
# include "../mwworld/class.hpp"
# include "../mwworld/inventorystore.hpp"
2017-10-04 17:25:22 +00:00
# include "../mwbase/environment.hpp"
# include "../mwbase/mechanicsmanager.hpp"
2013-05-11 16:38:27 +00:00
namespace MWGui
{
InventoryItemModel : : InventoryItemModel ( const MWWorld : : Ptr & actor )
: mActor ( actor )
{
}
ItemStack InventoryItemModel : : getItem ( ModelIndex index )
{
if ( index < 0 )
throw std : : runtime_error ( " Invalid index supplied " ) ;
if ( mItems . size ( ) < = static_cast < size_t > ( index ) )
throw std : : runtime_error ( " Item index out of range " ) ;
return mItems [ index ] ;
}
size_t InventoryItemModel : : getItemCount ( )
{
return mItems . size ( ) ;
}
ItemModel : : ModelIndex InventoryItemModel : : getIndex ( ItemStack item )
{
size_t i = 0 ;
for ( std : : vector < ItemStack > : : iterator it = mItems . begin ( ) ; it ! = mItems . end ( ) ; + + it )
{
if ( * it = = item )
return i ;
+ + i ;
}
return - 1 ;
}
2014-05-15 02:41:31 +00:00
MWWorld : : Ptr InventoryItemModel : : copyItem ( const ItemStack & item , size_t count , bool setNewOwner )
2013-05-11 16:38:27 +00:00
{
2013-08-25 15:40:08 +00:00
if ( item . mBase . getContainerStore ( ) = = & mActor . getClass ( ) . getContainerStore ( mActor ) )
throw std : : runtime_error ( " Item to copy needs to be from a different container! " ) ;
2014-05-15 02:41:31 +00:00
return * mActor . getClass ( ) . getContainerStore ( mActor ) . add ( item . mBase , count , mActor , setNewOwner ) ;
2013-05-11 16:38:27 +00:00
}
void InventoryItemModel : : removeItem ( const ItemStack & item , size_t count )
{
2017-09-11 10:49:55 +00:00
int removed = 0 ;
// Re-equipping makes sense only if a target has inventory
if ( mActor . getClass ( ) . hasInventoryStore ( mActor ) )
{
MWWorld : : InventoryStore & store = mActor . getClass ( ) . getInventoryStore ( mActor ) ;
removed = store . remove ( item . mBase , count , mActor , true ) ;
}
else
{
MWWorld : : ContainerStore & store = mActor . getClass ( ) . getContainerStore ( mActor ) ;
removed = store . remove ( item . mBase , count , mActor ) ;
}
std : : stringstream error ;
2013-05-11 16:38:27 +00:00
2013-08-12 23:19:33 +00:00
if ( removed = = 0 )
2017-09-11 10:49:55 +00:00
{
error < < " Item ' " < < item . mBase . getCellRef ( ) . getRefId ( ) < < " ' was not found in container store to remove " ;
throw std : : runtime_error ( error . str ( ) ) ;
}
2013-11-12 21:58:56 +00:00
else if ( removed < static_cast < int > ( count ) )
2017-09-11 10:49:55 +00:00
{
error < < " Not enough items ' " < < item . mBase . getCellRef ( ) . getRefId ( ) < < " ' in the stack to remove ( " < < static_cast < int > ( count ) < < " requested, " < < removed < < " found) " ;
throw std : : runtime_error ( error . str ( ) ) ;
}
2013-05-11 16:38:27 +00:00
}
2014-05-15 02:41:31 +00:00
MWWorld : : Ptr InventoryItemModel : : moveItem ( const ItemStack & item , size_t count , ItemModel * otherModel )
2014-04-27 03:40:07 +00:00
{
2014-09-11 03:38:38 +00:00
// Can't move conjured items: This is a general fix that also takes care of issues with taking conjured items via the 'Take All' button.
2014-09-13 22:59:13 +00:00
if ( item . mFlags & ItemStack : : Flag_Bound )
2014-09-11 03:38:38 +00:00
return MWWorld : : Ptr ( ) ;
2015-02-04 20:18:43 +00:00
MWWorld : : Ptr ret = otherModel - > copyItem ( item , count , false ) ;
2014-04-27 03:40:07 +00:00
removeItem ( item , count ) ;
2014-05-15 02:41:31 +00:00
return ret ;
2014-04-27 03:40:07 +00:00
}
2013-05-11 16:38:27 +00:00
void InventoryItemModel : : update ( )
{
2014-05-22 18:37:22 +00:00
MWWorld : : ContainerStore & store = mActor . getClass ( ) . getContainerStore ( mActor ) ;
2013-05-11 16:38:27 +00:00
mItems . clear ( ) ;
for ( MWWorld : : ContainerStoreIterator it = store . begin ( ) ; it ! = store . end ( ) ; + + it )
{
2013-08-08 23:05:26 +00:00
MWWorld : : Ptr item = * it ;
2016-09-24 16:01:31 +00:00
if ( ! item . getClass ( ) . showsInInventory ( item ) )
2013-08-08 23:05:26 +00:00
continue ;
ItemStack newItem ( item , this , item . getRefData ( ) . getCount ( ) ) ;
2013-05-11 16:38:27 +00:00
2014-01-19 10:42:58 +00:00
if ( mActor . getClass ( ) . hasInventoryStore ( mActor ) )
2013-05-11 16:38:27 +00:00
{
2016-10-30 15:23:51 +00:00
MWWorld : : InventoryStore & invStore = mActor . getClass ( ) . getInventoryStore ( mActor ) ;
if ( invStore . isEquipped ( newItem . mBase ) )
2014-12-15 12:47:34 +00:00
newItem . mType = ItemStack : : Type_Equipped ;
2013-05-11 16:38:27 +00:00
}
mItems . push_back ( newItem ) ;
}
}
2017-10-04 19:26:06 +00:00
bool InventoryItemModel : : onTakeItem ( const MWWorld : : Ptr & item , int count )
2017-10-04 17:25:22 +00:00
{
// Looting a dead corpse is considered OK
if ( mActor . getClass ( ) . isActor ( ) & & mActor . getClass ( ) . getCreatureStats ( mActor ) . isDead ( ) )
return true ;
2017-10-04 18:37:08 +00:00
2017-10-04 17:25:22 +00:00
MWWorld : : Ptr player = MWMechanics : : getPlayer ( ) ;
MWBase : : Environment : : get ( ) . getMechanicsManager ( ) - > itemTaken ( player , item , mActor , count ) ;
return true ;
}
2013-05-11 16:38:27 +00:00
}