2012-02-20 13:14:39 +00:00
# include "containerstore.hpp"
# include <cassert>
2012-02-23 11:34:25 +00:00
# include <typeinfo>
# include <stdexcept>
2012-02-20 13:14:39 +00:00
2012-06-29 14:48:50 +00:00
# include <boost/algorithm/string.hpp>
2012-05-18 22:36:01 +00:00
2012-03-10 11:11:07 +00:00
# include <components/esm/loadcont.hpp>
2013-02-02 17:36:12 +00:00
# include <components/compiler/locals.hpp>
2012-03-10 11:11:07 +00:00
2012-05-16 15:22:25 +00:00
# include "../mwbase/environment.hpp"
2012-07-03 10:30:50 +00:00
# include "../mwbase/world.hpp"
2013-02-02 17:36:12 +00:00
# include "../mwbase/scriptmanager.hpp"
2012-05-16 15:22:25 +00:00
2013-04-07 19:01:02 +00:00
# include "../mwmechanics/creaturestats.hpp"
2012-03-10 11:11:07 +00:00
# include "manualref.hpp"
2012-03-22 08:45:48 +00:00
# include "refdata.hpp"
2012-05-12 14:17:03 +00:00
# include "class.hpp"
2013-01-13 19:49:56 +00:00
# include "localscripts.hpp"
# include "player.hpp"
2012-03-10 11:11:07 +00:00
2012-03-22 08:45:48 +00:00
namespace
{
template < typename T >
2012-06-29 16:54:23 +00:00
float getTotalWeight ( const MWWorld : : CellRefList < T > & cellRefList )
2012-03-22 08:45:48 +00:00
{
float sum = 0 ;
2012-06-29 16:54:23 +00:00
for ( typename MWWorld : : CellRefList < T > : : List : : const_iterator iter (
2012-11-05 12:07:59 +00:00
cellRefList . mList . begin ( ) ) ;
iter ! = cellRefList . mList . end ( ) ;
2012-03-22 08:45:48 +00:00
+ + iter )
{
if ( iter - > mData . getCount ( ) > 0 )
2012-11-05 12:07:59 +00:00
sum + = iter - > mData . getCount ( ) * iter - > mBase - > mData . mWeight ;
2012-03-22 08:45:48 +00:00
}
return sum ;
}
}
MWWorld : : ContainerStore : : ContainerStore ( ) : mStateId ( 0 ) , mCachedWeight ( 0 ) , mWeightUpToDate ( false ) { }
2012-03-21 11:48:05 +00:00
2012-03-10 11:43:48 +00:00
MWWorld : : ContainerStore : : ~ ContainerStore ( ) { }
2012-02-20 13:14:39 +00:00
MWWorld : : ContainerStoreIterator MWWorld : : ContainerStore : : begin ( int mask )
{
return ContainerStoreIterator ( mask , this ) ;
}
MWWorld : : ContainerStoreIterator MWWorld : : ContainerStore : : end ( )
{
2012-02-23 11:34:25 +00:00
return ContainerStoreIterator ( this ) ;
2012-02-20 13:14:39 +00:00
}
2012-05-13 14:54:18 +00:00
bool MWWorld : : ContainerStore : : stacks ( const Ptr & ptr1 , const Ptr & ptr2 )
2012-05-12 21:09:03 +00:00
{
2013-03-22 13:13:10 +00:00
/// \todo add current enchantment charge here when it is implemented
2012-09-17 07:37:50 +00:00
if ( ptr1 . mCellRef - > mRefID = = ptr2 . mCellRef - > mRefID
2013-05-11 16:38:27 +00:00
& & MWWorld : : Class : : get ( ptr1 ) . getScript ( ptr1 ) = = " " // item with a script never stacks
& & MWWorld : : Class : : get ( ptr1 ) . getEnchantment ( ptr1 ) = = " " // item with enchantment never stacks (we could revisit this later, but for now it makes selecting items in the spell window much easier)
2012-09-17 07:37:50 +00:00
& & ptr1 . mCellRef - > mOwner = = ptr2 . mCellRef - > mOwner
& & ptr1 . mCellRef - > mSoul = = ptr2 . mCellRef - > mSoul
2013-03-23 07:16:46 +00:00
// item that is already partly used up never stacks
& & ( ! MWWorld : : Class : : get ( ptr1 ) . hasItemHealth ( ptr1 ) | | ptr1 . mCellRef - > mCharge = = - 1
| | MWWorld : : Class : : get ( ptr1 ) . getItemMaxHealth ( ptr1 ) = = ptr1 . mCellRef - > mCharge )
& & ( ! MWWorld : : Class : : get ( ptr2 ) . hasItemHealth ( ptr2 ) | | ptr2 . mCellRef - > mCharge = = - 1
| | MWWorld : : Class : : get ( ptr2 ) . getItemMaxHealth ( ptr2 ) = = ptr2 . mCellRef - > mCharge ) )
2012-05-12 21:09:03 +00:00
return true ;
return false ;
}
2012-05-15 18:33:34 +00:00
MWWorld : : ContainerStoreIterator MWWorld : : ContainerStore : : add ( const Ptr & ptr )
2013-01-13 19:49:56 +00:00
{
2013-01-20 14:14:34 +00:00
MWWorld : : ContainerStoreIterator it = addImp ( ptr ) ;
2013-01-13 19:49:56 +00:00
MWWorld : : Ptr item = * it ;
std : : string script = MWWorld : : Class : : get ( item ) . getScript ( item ) ;
if ( script ! = " " )
{
CellStore * cell ;
Ptr player = MWBase : : Environment : : get ( ) . getWorld ( ) - > getPlayer ( ) . getPlayer ( ) ;
2013-02-02 17:36:12 +00:00
2013-01-13 19:49:56 +00:00
if ( & ( MWWorld : : Class : : get ( player ) . getContainerStore ( player ) ) = = this )
2013-02-02 17:36:12 +00:00
{
2013-02-03 13:27:27 +00:00
cell = 0 ; // Items in player's inventory have cell set to 0, so their scripts will never be removed
2013-02-02 17:36:12 +00:00
// Set OnPCAdd special variable, if it is declared
2013-02-03 13:27:27 +00:00
item . mRefData - > getLocals ( ) . setVarByInt ( script , " onpcadd " , 1 ) ;
2013-02-02 17:36:12 +00:00
}
2013-01-13 19:49:56 +00:00
else
cell = player . getCell ( ) ;
item . mCell = cell ;
2013-01-20 14:10:04 +00:00
item . mContainerStore = 0 ;
2013-01-13 19:49:56 +00:00
MWBase : : Environment : : get ( ) . getWorld ( ) - > getLocalScripts ( ) . add ( script , item ) ;
}
return it ;
}
2013-01-20 14:14:34 +00:00
MWWorld : : ContainerStoreIterator MWWorld : : ContainerStore : : addImp ( const Ptr & ptr )
2012-02-23 11:34:25 +00:00
{
2012-05-12 14:30:27 +00:00
int type = getType ( ptr ) ;
2012-11-06 08:36:21 +00:00
const MWWorld : : ESMStore & esmStore =
MWBase : : Environment : : get ( ) . getWorld ( ) - > getStore ( ) ;
2012-05-18 22:36:01 +00:00
// gold needs special handling: when it is inserted into a container, the base object automatically becomes Gold_001
// this ensures that gold piles of different sizes stack with each other (also, several scripts rely on Gold_001 for detecting player gold)
2013-03-30 15:27:06 +00:00
if ( Misc : : StringUtils : : ciEqual ( ptr . getCellRef ( ) . mRefID , " gold_001 " )
| | Misc : : StringUtils : : ciEqual ( ptr . getCellRef ( ) . mRefID , " gold_005 " )
| | Misc : : StringUtils : : ciEqual ( ptr . getCellRef ( ) . mRefID , " gold_010 " )
| | Misc : : StringUtils : : ciEqual ( ptr . getCellRef ( ) . mRefID , " gold_025 " )
| | Misc : : StringUtils : : ciEqual ( ptr . getCellRef ( ) . mRefID , " gold_100 " ) )
2012-05-16 15:22:25 +00:00
{
2013-03-30 15:27:06 +00:00
MWWorld : : ManualRef ref ( esmStore , " Gold_001 " ) ;
2012-05-16 15:22:25 +00:00
2013-03-30 15:27:06 +00:00
int count = MWWorld : : Class : : get ( ptr ) . getValue ( ptr ) * ptr . getRefData ( ) . getCount ( ) ;
2013-03-27 16:27:43 +00:00
2013-03-30 15:27:06 +00:00
ref . getPtr ( ) . getRefData ( ) . setCount ( count ) ;
for ( MWWorld : : ContainerStoreIterator iter ( begin ( type ) ) ; iter ! = end ( ) ; + + iter )
{
if ( Misc : : StringUtils : : ciEqual ( ( * iter ) . get < ESM : : Miscellaneous > ( ) - > mRef . mRefID , " gold_001 " ) )
2012-05-18 22:36:01 +00:00
{
2013-03-30 15:27:06 +00:00
( * iter ) . getRefData ( ) . setCount ( ( * iter ) . getRefData ( ) . getCount ( ) + count ) ;
flagAsModified ( ) ;
return iter ;
2012-05-16 15:22:25 +00:00
}
2012-05-18 22:36:01 +00:00
}
2013-03-30 15:27:06 +00:00
return addImpl ( ref . getPtr ( ) ) ;
2012-05-16 15:22:25 +00:00
}
2012-05-12 14:17:03 +00:00
// determine whether to stack or not
2012-05-12 14:30:27 +00:00
for ( MWWorld : : ContainerStoreIterator iter ( begin ( type ) ) ; iter ! = end ( ) ; + + iter )
2012-05-12 14:17:03 +00:00
{
2012-05-12 21:09:03 +00:00
if ( stacks ( * iter , ptr ) )
2012-05-12 14:17:03 +00:00
{
// stack
iter - > getRefData ( ) . setCount ( iter - > getRefData ( ) . getCount ( ) + ptr . getRefData ( ) . getCount ( ) ) ;
flagAsModified ( ) ;
2012-05-15 18:33:34 +00:00
return iter ;
2012-05-12 14:17:03 +00:00
}
}
2012-05-13 09:52:17 +00:00
// if we got here, this means no stacking
2012-05-15 22:02:05 +00:00
return addImpl ( ptr ) ;
2012-05-13 09:52:17 +00:00
}
2012-05-15 22:02:05 +00:00
MWWorld : : ContainerStoreIterator MWWorld : : ContainerStore : : addImpl ( const Ptr & ptr )
2012-05-13 09:52:17 +00:00
{
2012-05-15 22:02:05 +00:00
ContainerStoreIterator it = begin ( ) ;
2012-05-13 09:52:17 +00:00
switch ( getType ( ptr ) )
2012-02-23 11:34:25 +00:00
{
2012-11-05 12:07:59 +00:00
case Type_Potion : potions . mList . push_back ( * ptr . get < ESM : : Potion > ( ) ) ; it = ContainerStoreIterator ( this , - - potions . mList . end ( ) ) ; break ;
case Type_Apparatus : appas . mList . push_back ( * ptr . get < ESM : : Apparatus > ( ) ) ; it = ContainerStoreIterator ( this , - - appas . mList . end ( ) ) ; break ;
case Type_Armor : armors . mList . push_back ( * ptr . get < ESM : : Armor > ( ) ) ; it = ContainerStoreIterator ( this , - - armors . mList . end ( ) ) ; break ;
case Type_Book : books . mList . push_back ( * ptr . get < ESM : : Book > ( ) ) ; it = ContainerStoreIterator ( this , - - books . mList . end ( ) ) ; break ;
case Type_Clothing : clothes . mList . push_back ( * ptr . get < ESM : : Clothing > ( ) ) ; it = ContainerStoreIterator ( this , - - clothes . mList . end ( ) ) ; break ;
case Type_Ingredient : ingreds . mList . push_back ( * ptr . get < ESM : : Ingredient > ( ) ) ; it = ContainerStoreIterator ( this , - - ingreds . mList . end ( ) ) ; break ;
case Type_Light : lights . mList . push_back ( * ptr . get < ESM : : Light > ( ) ) ; it = ContainerStoreIterator ( this , - - lights . mList . end ( ) ) ; break ;
2013-03-22 04:50:54 +00:00
case Type_Lockpick : lockpicks . mList . push_back ( * ptr . get < ESM : : Lockpick > ( ) ) ; it = ContainerStoreIterator ( this , - - lockpicks . mList . end ( ) ) ; break ;
2012-11-05 12:07:59 +00:00
case Type_Miscellaneous : miscItems . mList . push_back ( * ptr . get < ESM : : Miscellaneous > ( ) ) ; it = ContainerStoreIterator ( this , - - miscItems . mList . end ( ) ) ; break ;
case Type_Probe : probes . mList . push_back ( * ptr . get < ESM : : Probe > ( ) ) ; it = ContainerStoreIterator ( this , - - probes . mList . end ( ) ) ; break ;
case Type_Repair : repairs . mList . push_back ( * ptr . get < ESM : : Repair > ( ) ) ; it = ContainerStoreIterator ( this , - - repairs . mList . end ( ) ) ; break ;
case Type_Weapon : weapons . mList . push_back ( * ptr . get < ESM : : Weapon > ( ) ) ; it = ContainerStoreIterator ( this , - - weapons . mList . end ( ) ) ; break ;
2012-02-23 11:34:25 +00:00
}
2012-03-21 11:48:05 +00:00
flagAsModified ( ) ;
2012-05-15 22:02:05 +00:00
return it ;
2012-02-23 11:34:25 +00:00
}
2013-04-07 20:07:04 +00:00
void MWWorld : : ContainerStore : : fill ( const ESM : : InventoryList & items , const std : : string & owner , const MWWorld : : ESMStore & store )
2012-03-10 11:11:07 +00:00
{
2012-09-17 07:37:50 +00:00
for ( std : : vector < ESM : : ContItem > : : const_iterator iter ( items . mList . begin ( ) ) ; iter ! = items . mList . end ( ) ;
2012-03-10 11:11:07 +00:00
+ + iter )
{
2013-04-07 19:01:02 +00:00
std : : string id = iter - > mItem . toString ( ) ;
2013-04-07 20:07:04 +00:00
addInitialItem ( id , owner , iter - > mCount ) ;
2013-04-07 19:01:02 +00:00
}
flagAsModified ( ) ;
}
2013-04-07 20:07:04 +00:00
void MWWorld : : ContainerStore : : addInitialItem ( const std : : string & id , const std : : string & owner , int count , unsigned char failChance , bool topLevel )
2013-04-07 19:01:02 +00:00
{
count = std : : abs ( count ) ; /// \todo implement item restocking (indicated by negative count)
2013-04-25 02:44:30 +00:00
try
2013-04-07 19:01:02 +00:00
{
2013-04-25 02:44:30 +00:00
ManualRef ref ( MWBase : : Environment : : get ( ) . getWorld ( ) - > getStore ( ) , id ) ;
2013-04-07 19:01:02 +00:00
2013-04-25 02:44:30 +00:00
if ( ref . getPtr ( ) . getTypeName ( ) = = typeid ( ESM : : ItemLevList ) . name ( ) )
{
const ESM : : ItemLevList * levItem = ref . getPtr ( ) . get < ESM : : ItemLevList > ( ) - > mBase ;
const std : : vector < ESM : : LeveledListBase : : LevelItem > & items = levItem - > mList ;
2013-04-07 19:01:02 +00:00
2013-04-25 02:44:30 +00:00
MWWorld : : Ptr player = MWBase : : Environment : : get ( ) . getWorld ( ) - > getPlayer ( ) . getPlayer ( ) ;
int playerLevel = MWWorld : : Class : : get ( player ) . getCreatureStats ( player ) . getLevel ( ) ;
2012-03-10 11:11:07 +00:00
2013-04-25 02:44:30 +00:00
failChance + = levItem - > mChanceNone ;
2012-03-10 11:11:07 +00:00
2013-04-25 02:44:30 +00:00
if ( topLevel & & count > 1 & & levItem - > mFlags & ESM : : ItemLevList : : Each )
2013-04-07 19:01:02 +00:00
{
2013-04-25 02:44:30 +00:00
for ( int i = 0 ; i < count ; + + i )
addInitialItem ( id , owner , 1 , failChance , false ) ;
return ;
2013-04-07 19:01:02 +00:00
}
2013-04-25 02:44:30 +00:00
float random = static_cast < float > ( std : : rand ( ) ) / RAND_MAX ;
if ( random > = failChance / 100.f )
2013-04-07 19:01:02 +00:00
{
2013-04-25 02:44:30 +00:00
std : : vector < std : : string > candidates ;
int highestLevel = 0 ;
for ( std : : vector < ESM : : LeveledListBase : : LevelItem > : : const_iterator it = items . begin ( ) ; it ! = items . end ( ) ; + + it )
2013-04-07 19:01:02 +00:00
{
2013-04-25 02:44:30 +00:00
if ( it - > mLevel > highestLevel )
highestLevel = it - > mLevel ;
2013-04-07 19:01:02 +00:00
}
2013-04-25 02:44:30 +00:00
std : : pair < int , std : : string > highest = std : : make_pair ( - 1 , " " ) ;
for ( std : : vector < ESM : : LeveledListBase : : LevelItem > : : const_iterator it = items . begin ( ) ; it ! = items . end ( ) ; + + it )
{
if ( playerLevel > = it - > mLevel
& & ( levItem - > mFlags & ESM : : ItemLevList : : AllLevels | | it - > mLevel = = highestLevel ) )
{
candidates . push_back ( it - > mId ) ;
if ( it - > mLevel > = highest . first )
highest = std : : make_pair ( it - > mLevel , it - > mId ) ;
}
}
if ( ! candidates . size ( ) )
return ;
std : : string item = candidates [ std : : rand ( ) % candidates . size ( ) ] ;
addInitialItem ( item , owner , count , failChance , false ) ;
2013-04-07 19:01:02 +00:00
}
2013-04-25 02:44:30 +00:00
}
else
{
ref . getPtr ( ) . getRefData ( ) . setCount ( count ) ;
ref . getPtr ( ) . getCellRef ( ) . mOwner = owner ;
addImp ( ref . getPtr ( ) ) ;
2013-04-07 19:01:02 +00:00
}
}
2013-04-25 02:44:30 +00:00
catch ( std : : logic_error & e )
2013-04-07 19:01:02 +00:00
{
2013-04-25 02:44:30 +00:00
// Vanilla doesn't fail on nonexistent items in levelled lists
std : : cerr < < " Warning: ignoring nonexistent item ' " < < id < < " ' " < < std : : endl ;
return ;
2012-03-10 11:11:07 +00:00
}
}
void MWWorld : : ContainerStore : : clear ( )
{
2012-11-01 14:11:13 +00:00
for ( ContainerStoreIterator iter ( begin ( ) ) ; iter ! = end ( ) ; + + iter )
iter - > getRefData ( ) . setCount ( 0 ) ;
2012-03-21 11:48:05 +00:00
flagAsModified ( ) ;
}
void MWWorld : : ContainerStore : : flagAsModified ( )
{
+ + mStateId ;
2012-03-22 08:45:48 +00:00
mWeightUpToDate = false ;
2012-03-21 11:48:05 +00:00
}
int MWWorld : : ContainerStore : : getStateId ( ) const
{
return mStateId ;
2012-03-10 11:11:07 +00:00
}
2012-03-22 08:45:48 +00:00
float MWWorld : : ContainerStore : : getWeight ( ) const
{
if ( ! mWeightUpToDate )
{
mCachedWeight = 0 ;
mCachedWeight + = getTotalWeight ( potions ) ;
mCachedWeight + = getTotalWeight ( appas ) ;
mCachedWeight + = getTotalWeight ( armors ) ;
mCachedWeight + = getTotalWeight ( books ) ;
mCachedWeight + = getTotalWeight ( clothes ) ;
mCachedWeight + = getTotalWeight ( ingreds ) ;
mCachedWeight + = getTotalWeight ( lights ) ;
mCachedWeight + = getTotalWeight ( lockpicks ) ;
mCachedWeight + = getTotalWeight ( miscItems ) ;
mCachedWeight + = getTotalWeight ( probes ) ;
mCachedWeight + = getTotalWeight ( repairs ) ;
mCachedWeight + = getTotalWeight ( weapons ) ;
mWeightUpToDate = true ;
}
return mCachedWeight ;
}
2012-02-23 11:34:25 +00:00
int MWWorld : : ContainerStore : : getType ( const Ptr & ptr )
{
if ( ptr . isEmpty ( ) )
throw std : : runtime_error ( " can't put a non-existent object into a container " ) ;
if ( ptr . getTypeName ( ) = = typeid ( ESM : : Potion ) . name ( ) )
return Type_Potion ;
if ( ptr . getTypeName ( ) = = typeid ( ESM : : Apparatus ) . name ( ) )
return Type_Apparatus ;
if ( ptr . getTypeName ( ) = = typeid ( ESM : : Armor ) . name ( ) )
return Type_Armor ;
if ( ptr . getTypeName ( ) = = typeid ( ESM : : Book ) . name ( ) )
return Type_Book ;
if ( ptr . getTypeName ( ) = = typeid ( ESM : : Clothing ) . name ( ) )
return Type_Clothing ;
if ( ptr . getTypeName ( ) = = typeid ( ESM : : Ingredient ) . name ( ) )
return Type_Ingredient ;
if ( ptr . getTypeName ( ) = = typeid ( ESM : : Light ) . name ( ) )
return Type_Light ;
2013-03-22 04:50:54 +00:00
if ( ptr . getTypeName ( ) = = typeid ( ESM : : Lockpick ) . name ( ) )
2012-02-23 11:34:25 +00:00
return Type_Lockpick ;
if ( ptr . getTypeName ( ) = = typeid ( ESM : : Miscellaneous ) . name ( ) )
return Type_Miscellaneous ;
if ( ptr . getTypeName ( ) = = typeid ( ESM : : Probe ) . name ( ) )
return Type_Probe ;
if ( ptr . getTypeName ( ) = = typeid ( ESM : : Repair ) . name ( ) )
return Type_Repair ;
if ( ptr . getTypeName ( ) = = typeid ( ESM : : Weapon ) . name ( ) )
return Type_Weapon ;
throw std : : runtime_error (
" Object of type " + ptr . getTypeName ( ) + " can not be placed into a container " ) ;
}
2012-02-20 13:14:39 +00:00
2012-02-23 11:34:25 +00:00
MWWorld : : ContainerStoreIterator : : ContainerStoreIterator ( ContainerStore * container )
: mType ( - 1 ) , mMask ( 0 ) , mContainer ( container )
2012-02-20 13:14:39 +00:00
{ }
MWWorld : : ContainerStoreIterator : : ContainerStoreIterator ( int mask , ContainerStore * container )
: mType ( 0 ) , mMask ( mask ) , mContainer ( container )
{
nextType ( ) ;
2012-05-18 20:24:19 +00:00
if ( mType = = - 1 | | ( * * this ) . getRefData ( ) . getCount ( ) )
return ;
+ + * this ;
2012-02-20 13:14:39 +00:00
}
2012-06-29 16:54:23 +00:00
MWWorld : : ContainerStoreIterator : : ContainerStoreIterator ( ContainerStore * container , MWWorld : : CellRefList < ESM : : Potion > : : List : : iterator iterator )
2012-05-15 22:02:05 +00:00
: mType ( MWWorld : : ContainerStore : : Type_Potion ) , mMask ( MWWorld : : ContainerStore : : Type_All ) , mContainer ( container ) , mPotion ( iterator ) { }
2012-06-29 16:54:23 +00:00
MWWorld : : ContainerStoreIterator : : ContainerStoreIterator ( ContainerStore * container , MWWorld : : CellRefList < ESM : : Apparatus > : : List : : iterator iterator )
2012-05-15 22:02:05 +00:00
: mType ( MWWorld : : ContainerStore : : Type_Apparatus ) , mMask ( MWWorld : : ContainerStore : : Type_All ) , mContainer ( container ) , mApparatus ( iterator ) { }
2012-06-29 16:54:23 +00:00
MWWorld : : ContainerStoreIterator : : ContainerStoreIterator ( ContainerStore * container , MWWorld : : CellRefList < ESM : : Armor > : : List : : iterator iterator )
2012-05-15 22:02:05 +00:00
: mType ( MWWorld : : ContainerStore : : Type_Armor ) , mMask ( MWWorld : : ContainerStore : : Type_All ) , mContainer ( container ) , mArmor ( iterator ) { }
2012-06-29 16:54:23 +00:00
MWWorld : : ContainerStoreIterator : : ContainerStoreIterator ( ContainerStore * container , MWWorld : : CellRefList < ESM : : Book > : : List : : iterator iterator )
2012-05-15 22:02:05 +00:00
: mType ( MWWorld : : ContainerStore : : Type_Book ) , mMask ( MWWorld : : ContainerStore : : Type_All ) , mContainer ( container ) , mBook ( iterator ) { }
2012-06-29 16:54:23 +00:00
MWWorld : : ContainerStoreIterator : : ContainerStoreIterator ( ContainerStore * container , MWWorld : : CellRefList < ESM : : Clothing > : : List : : iterator iterator )
2012-05-15 22:02:05 +00:00
: mType ( MWWorld : : ContainerStore : : Type_Clothing ) , mMask ( MWWorld : : ContainerStore : : Type_All ) , mContainer ( container ) , mClothing ( iterator ) { }
2012-06-29 16:54:23 +00:00
MWWorld : : ContainerStoreIterator : : ContainerStoreIterator ( ContainerStore * container , MWWorld : : CellRefList < ESM : : Ingredient > : : List : : iterator iterator )
2012-05-15 22:02:05 +00:00
: mType ( MWWorld : : ContainerStore : : Type_Ingredient ) , mMask ( MWWorld : : ContainerStore : : Type_All ) , mContainer ( container ) , mIngredient ( iterator ) { }
2012-06-29 16:54:23 +00:00
MWWorld : : ContainerStoreIterator : : ContainerStoreIterator ( ContainerStore * container , MWWorld : : CellRefList < ESM : : Light > : : List : : iterator iterator )
2012-05-15 22:02:05 +00:00
: mType ( MWWorld : : ContainerStore : : Type_Light ) , mMask ( MWWorld : : ContainerStore : : Type_All ) , mContainer ( container ) , mLight ( iterator ) { }
2013-03-22 04:50:54 +00:00
MWWorld : : ContainerStoreIterator : : ContainerStoreIterator ( ContainerStore * container , MWWorld : : CellRefList < ESM : : Lockpick > : : List : : iterator iterator )
2012-05-15 22:02:05 +00:00
: mType ( MWWorld : : ContainerStore : : Type_Lockpick ) , mMask ( MWWorld : : ContainerStore : : Type_All ) , mContainer ( container ) , mLockpick ( iterator ) { }
2012-06-29 16:54:23 +00:00
MWWorld : : ContainerStoreIterator : : ContainerStoreIterator ( ContainerStore * container , MWWorld : : CellRefList < ESM : : Miscellaneous > : : List : : iterator iterator )
2012-05-15 22:02:05 +00:00
: mType ( MWWorld : : ContainerStore : : Type_Miscellaneous ) , mMask ( MWWorld : : ContainerStore : : Type_All ) , mContainer ( container ) , mMiscellaneous ( iterator ) { }
2012-06-29 16:54:23 +00:00
MWWorld : : ContainerStoreIterator : : ContainerStoreIterator ( ContainerStore * container , MWWorld : : CellRefList < ESM : : Probe > : : List : : iterator iterator )
2012-05-15 22:02:05 +00:00
: mType ( MWWorld : : ContainerStore : : Type_Probe ) , mMask ( MWWorld : : ContainerStore : : Type_All ) , mContainer ( container ) , mProbe ( iterator ) { }
2012-06-29 16:54:23 +00:00
MWWorld : : ContainerStoreIterator : : ContainerStoreIterator ( ContainerStore * container , MWWorld : : CellRefList < ESM : : Repair > : : List : : iterator iterator )
2012-05-15 22:02:05 +00:00
: mType ( MWWorld : : ContainerStore : : Type_Repair ) , mMask ( MWWorld : : ContainerStore : : Type_All ) , mContainer ( container ) , mRepair ( iterator ) { }
2012-06-29 16:54:23 +00:00
MWWorld : : ContainerStoreIterator : : ContainerStoreIterator ( ContainerStore * container , MWWorld : : CellRefList < ESM : : Weapon > : : List : : iterator iterator )
2012-05-15 22:02:05 +00:00
: mType ( MWWorld : : ContainerStore : : Type_Weapon ) , mMask ( MWWorld : : ContainerStore : : Type_All ) , mContainer ( container ) , mWeapon ( iterator ) { }
2012-02-20 13:14:39 +00:00
void MWWorld : : ContainerStoreIterator : : incType ( )
{
if ( mType = = 0 )
mType = 1 ;
else if ( mType ! = - 1 )
{
mType < < = 1 ;
if ( mType > ContainerStore : : Type_Last )
mType = - 1 ;
}
}
void MWWorld : : ContainerStoreIterator : : nextType ( )
{
while ( mType ! = - 1 )
{
incType ( ) ;
2012-05-18 20:24:19 +00:00
if ( ( mType & mMask ) & & mType > 0 )
2012-02-20 13:14:39 +00:00
if ( resetIterator ( ) )
break ;
}
}
bool MWWorld : : ContainerStoreIterator : : resetIterator ( )
{
switch ( mType )
{
case ContainerStore : : Type_Potion :
2012-11-05 12:07:59 +00:00
mPotion = mContainer - > potions . mList . begin ( ) ;
return mPotion ! = mContainer - > potions . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Apparatus :
2012-11-05 12:07:59 +00:00
mApparatus = mContainer - > appas . mList . begin ( ) ;
return mApparatus ! = mContainer - > appas . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Armor :
2012-11-05 12:07:59 +00:00
mArmor = mContainer - > armors . mList . begin ( ) ;
return mArmor ! = mContainer - > armors . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Book :
2012-11-05 12:07:59 +00:00
mBook = mContainer - > books . mList . begin ( ) ;
return mBook ! = mContainer - > books . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Clothing :
2012-11-05 12:07:59 +00:00
mClothing = mContainer - > clothes . mList . begin ( ) ;
return mClothing ! = mContainer - > clothes . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Ingredient :
2012-11-05 12:07:59 +00:00
mIngredient = mContainer - > ingreds . mList . begin ( ) ;
return mIngredient ! = mContainer - > ingreds . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Light :
2012-11-05 12:07:59 +00:00
mLight = mContainer - > lights . mList . begin ( ) ;
return mLight ! = mContainer - > lights . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Lockpick :
2012-11-05 12:07:59 +00:00
mLockpick = mContainer - > lockpicks . mList . begin ( ) ;
return mLockpick ! = mContainer - > lockpicks . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Miscellaneous :
2012-11-05 12:07:59 +00:00
mMiscellaneous = mContainer - > miscItems . mList . begin ( ) ;
return mMiscellaneous ! = mContainer - > miscItems . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Probe :
2012-11-05 12:07:59 +00:00
mProbe = mContainer - > probes . mList . begin ( ) ;
return mProbe ! = mContainer - > probes . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Repair :
2012-11-05 12:07:59 +00:00
mRepair = mContainer - > repairs . mList . begin ( ) ;
return mRepair ! = mContainer - > repairs . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Weapon :
2012-11-05 12:07:59 +00:00
mWeapon = mContainer - > weapons . mList . begin ( ) ;
return mWeapon ! = mContainer - > weapons . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
}
return false ;
}
bool MWWorld : : ContainerStoreIterator : : incIterator ( )
{
switch ( mType )
{
case ContainerStore : : Type_Potion :
+ + mPotion ;
2012-11-05 12:07:59 +00:00
return mPotion = = mContainer - > potions . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Apparatus :
+ + mApparatus ;
2012-11-05 12:07:59 +00:00
return mApparatus = = mContainer - > appas . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Armor :
+ + mArmor ;
2012-11-05 12:07:59 +00:00
return mArmor = = mContainer - > armors . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Book :
+ + mBook ;
2012-11-05 12:07:59 +00:00
return mBook = = mContainer - > books . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Clothing :
+ + mClothing ;
2012-11-05 12:07:59 +00:00
return mClothing = = mContainer - > clothes . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Ingredient :
+ + mIngredient ;
2012-11-05 12:07:59 +00:00
return mIngredient = = mContainer - > ingreds . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Light :
+ + mLight ;
2012-11-05 12:07:59 +00:00
return mLight = = mContainer - > lights . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Lockpick :
+ + mLockpick ;
2012-11-05 12:07:59 +00:00
return mLockpick = = mContainer - > lockpicks . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Miscellaneous :
+ + mMiscellaneous ;
2012-11-05 12:07:59 +00:00
return mMiscellaneous = = mContainer - > miscItems . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Probe :
+ + mProbe ;
2012-11-05 12:07:59 +00:00
return mProbe = = mContainer - > probes . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Repair :
+ + mRepair ;
2012-11-05 12:07:59 +00:00
return mRepair = = mContainer - > repairs . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
case ContainerStore : : Type_Weapon :
+ + mWeapon ;
2012-11-05 12:07:59 +00:00
return mWeapon = = mContainer - > weapons . mList . end ( ) ;
2012-02-20 13:14:39 +00:00
}
return true ;
}
MWWorld : : Ptr * MWWorld : : ContainerStoreIterator : : operator - > ( ) const
{
mPtr = * * this ;
return & mPtr ;
}
MWWorld : : Ptr MWWorld : : ContainerStoreIterator : : operator * ( ) const
{
2012-03-21 11:20:19 +00:00
Ptr ptr ;
2012-02-20 13:14:39 +00:00
switch ( mType )
{
2012-03-21 11:20:19 +00:00
case ContainerStore : : Type_Potion : ptr = MWWorld : : Ptr ( & * mPotion , 0 ) ; break ;
case ContainerStore : : Type_Apparatus : ptr = MWWorld : : Ptr ( & * mApparatus , 0 ) ; break ;
case ContainerStore : : Type_Armor : ptr = MWWorld : : Ptr ( & * mArmor , 0 ) ; break ;
case ContainerStore : : Type_Book : ptr = MWWorld : : Ptr ( & * mBook , 0 ) ; break ;
case ContainerStore : : Type_Clothing : ptr = MWWorld : : Ptr ( & * mClothing , 0 ) ; break ;
case ContainerStore : : Type_Ingredient : ptr = MWWorld : : Ptr ( & * mIngredient , 0 ) ; break ;
case ContainerStore : : Type_Light : ptr = MWWorld : : Ptr ( & * mLight , 0 ) ; break ;
case ContainerStore : : Type_Lockpick : ptr = MWWorld : : Ptr ( & * mLockpick , 0 ) ; break ;
case ContainerStore : : Type_Miscellaneous : ptr = MWWorld : : Ptr ( & * mMiscellaneous , 0 ) ; break ;
case ContainerStore : : Type_Probe : ptr = MWWorld : : Ptr ( & * mProbe , 0 ) ; break ;
case ContainerStore : : Type_Repair : ptr = MWWorld : : Ptr ( & * mRepair , 0 ) ; break ;
case ContainerStore : : Type_Weapon : ptr = MWWorld : : Ptr ( & * mWeapon , 0 ) ; break ;
2012-02-20 13:14:39 +00:00
}
2012-03-21 11:20:19 +00:00
if ( ptr . isEmpty ( ) )
throw std : : runtime_error ( " invalid iterator " ) ;
ptr . setContainerStore ( mContainer ) ;
return ptr ;
2012-02-20 13:14:39 +00:00
}
MWWorld : : ContainerStoreIterator & MWWorld : : ContainerStoreIterator : : operator + + ( )
{
do
{
if ( incIterator ( ) )
nextType ( ) ;
}
while ( mType ! = - 1 & & ! ( * * this ) . getRefData ( ) . getCount ( ) ) ;
return * this ;
}
MWWorld : : ContainerStoreIterator MWWorld : : ContainerStoreIterator : : operator + + ( int )
{
ContainerStoreIterator iter ( * this ) ;
+ + * this ;
return iter ;
}
bool MWWorld : : ContainerStoreIterator : : isEqual ( const ContainerStoreIterator & iter ) const
{
2013-03-03 15:50:10 +00:00
if ( mContainer ! = iter . mContainer )
return false ;
2012-02-20 13:14:39 +00:00
if ( mType ! = iter . mType )
return false ;
switch ( mType )
{
case ContainerStore : : Type_Potion : return mPotion = = iter . mPotion ;
case ContainerStore : : Type_Apparatus : return mApparatus = = iter . mApparatus ;
case ContainerStore : : Type_Armor : return mArmor = = iter . mArmor ;
case ContainerStore : : Type_Book : return mBook = = iter . mBook ;
case ContainerStore : : Type_Clothing : return mClothing = = iter . mClothing ;
case ContainerStore : : Type_Ingredient : return mIngredient = = iter . mIngredient ;
case ContainerStore : : Type_Light : return mLight = = iter . mLight ;
case ContainerStore : : Type_Lockpick : return mLockpick = = iter . mLockpick ;
case ContainerStore : : Type_Miscellaneous : return mMiscellaneous = = iter . mMiscellaneous ;
case ContainerStore : : Type_Probe : return mProbe = = iter . mProbe ;
case ContainerStore : : Type_Repair : return mRepair = = iter . mRepair ;
case ContainerStore : : Type_Weapon : return mWeapon = = iter . mWeapon ;
2012-02-23 11:34:25 +00:00
case - 1 : return true ;
2012-02-20 13:14:39 +00:00
}
return false ;
}
int MWWorld : : ContainerStoreIterator : : getType ( ) const
{
return mType ;
}
2012-03-13 13:04:19 +00:00
const MWWorld : : ContainerStore * MWWorld : : ContainerStoreIterator : : getContainerStore ( ) const
{
return mContainer ;
}
2012-02-20 13:14:39 +00:00
bool MWWorld : : operator = = ( const ContainerStoreIterator & left , const ContainerStoreIterator & right )
{
return left . isEqual ( right ) ;
}
bool MWWorld : : operator ! = ( const ContainerStoreIterator & left , const ContainerStoreIterator & right )
{
return ! ( left = = right ) ;
}