Pol  Revision:cb584c9
itemdesc.cpp
Go to the documentation of this file.
1 
16 #include "itemdesc.h"
17 
18 #include <ctype.h>
19 #include <iosfwd>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include "../../bscript/bobject.h"
24 #include "../../bscript/bstruct.h"
25 #include "../../bscript/dict.h"
26 #include "../../bscript/impstr.h"
27 #include "../../clib/cfgelem.h"
28 #include "../../clib/cfgfile.h"
29 #include "../../clib/esignal.h"
30 #include "../../clib/fileutil.h"
31 #include "../../clib/logfacility.h"
32 #include "../../clib/passert.h"
33 #include "../../clib/stlutil.h"
34 #include "../../clib/strutil.h"
35 #include "../../plib/mapcell.h"
36 #include "../../plib/pkg.h"
37 #include "../../plib/systemstate.h"
38 #include "../clidata.h"
39 #include "../dice.h"
40 #include "../extobj.h"
41 #include "../globals/settings.h"
42 #include "../globals/uvars.h"
43 #include "../multi/multidef.h"
44 #include "../pktdef.h"
45 #include "../proplist.h"
46 #include "../resource.h"
47 #include "../syshookscript.h"
48 #include "../uconst.h"
49 #include "../uobject.h"
50 #include "armrtmpl.h"
51 #include "wepntmpl.h"
52 #include <format/format.h>
53 
54 namespace Pol
55 {
56 namespace Items
57 {
58 unsigned int get_objtype_byname( const char* str )
59 {
60  auto itr = Core::gamestate.objtype_byname.find( str );
61  if ( itr == Core::gamestate.objtype_byname.end() )
62  return 0;
63  else
64  return ( *itr ).second;
65 }
66 
67 unsigned int get_objtype_from_string( const std::string& str )
68 {
69  unsigned int objtype;
70  const char* ot_str = str.c_str();
71  if ( isdigit( *ot_str ) )
72  {
73  objtype = static_cast<u32>( strtoul( ot_str, nullptr, 0 ) );
74  }
75  else
76  {
77  objtype = get_objtype_byname( ot_str );
78  if ( !objtype )
79  {
80  throw std::runtime_error( "Can't convert " + str + " to an objtype" );
81  }
82  }
83  return objtype;
84 }
85 
86 ResourceComponent::ResourceComponent( const std::string& rname, unsigned amount )
87  : rd( Core::find_resource_def( rname ) ), amount( amount )
88 {
89  if ( rd == nullptr )
90  {
91  ERROR_PRINT << "itemdesc.cfg: Resource '" << rname << "' not found\n";
92  throw std::runtime_error( "Configuration error" );
93  }
94 }
95 
96 
98 {
99  u32 objtype = static_cast<u32>( strtoul( elem.rest(), nullptr, 0 ) );
100  if ( !objtype )
101  {
102  elem.throw_error( "Element must have objtype specified" );
103  }
104 
105  if ( Core::gamestate.old_objtype_conversions.count( objtype ) )
106  {
107  elem.throw_error(
108  "Objtype is defined as an OldObjtype of " +
109  find_itemdesc( Core::gamestate.old_objtype_conversions[objtype] ).objtype_description() );
110  }
111 
112  ItemDesc* descriptor = nullptr;
113 
114  if ( elem.type_is( "Container" ) )
115  {
116  descriptor = new ContainerDesc( objtype, elem, pkg );
117  }
118  else if ( elem.type_is( "Item" ) )
119  {
120  descriptor = new ItemDesc( objtype, elem, ItemDesc::ITEMDESC, pkg );
121  }
122  else if ( elem.type_is( "Door" ) )
123  {
124  descriptor = new DoorDesc( objtype, elem, pkg );
125  }
126  else if ( elem.type_is( "Weapon" ) )
127  {
128  // This one is making leaks when the descriptor is not given to a UWeapon object...
129  // I really can't figure a good way to avoid this leak everytime
130  descriptor = new WeaponDesc( objtype, elem, pkg );
131  }
132  else if ( elem.type_is( "Armor" ) )
133  {
134  // Ugly but effective workaround, needed to avoid coverage error
135  bool forceShield = ( objtype == Core::settingsManager.extobj.shield );
136  descriptor = new ArmorDesc( objtype, elem, pkg, forceShield );
137  }
138  else if ( elem.type_is( "Boat" ) )
139  {
140  descriptor = new BoatDesc( objtype, elem, pkg );
141  }
142  else if ( elem.type_is( "House" ) )
143  {
144  descriptor = new HouseDesc( objtype, elem, pkg );
145  }
146  else if ( elem.type_is( "Spellbook" ) )
147  {
148  descriptor = new SpellbookDesc( objtype, elem, pkg );
149  }
150  else if ( elem.type_is( "SpellScroll" ) )
151  {
152  descriptor = new SpellScrollDesc( objtype, elem, pkg );
153  }
154  else if ( elem.type_is( "Map" ) )
155  {
156  descriptor = new MapDesc( objtype, elem, pkg );
157  }
158  else
159  {
160  elem.throw_error( std::string( "Unexpected element type: " ) + elem.type() );
161  }
162  return descriptor;
163 }
164 
165 ItemDesc::ItemDesc( u32 objtype, Clib::ConfigElem& elem, Type type, const Plib::Package* pkg )
166  : type( type ),
167  pkg( pkg ),
168  objtype( objtype ),
169  graphic( elem.remove_ushort( "GRAPHIC", 0 ) ),
170  // Changed from Valid Color Mask to cfg mask in ssopt.
171  color( elem.remove_ushort( "COLOR", 0 ) & Core::settingsManager.ssopt.item_color_mask ),
172  facing( static_cast<unsigned char>( elem.remove_ushort( "FACING", 127 ) ) ),
173  desc( elem.remove_string( "DESC", "" ) ),
174  tooltip( elem.remove_string( "TOOLTIP", "" ) ),
175  walk_on_script( elem.remove_string( "WALKONSCRIPT", "" ), pkg, "scripts/items/" ),
176  on_use_script( elem.remove_string( "SCRIPT", "" ), pkg, "scripts/items/" ),
177  equip_script( elem.remove_string( "EQUIPSCRIPT", "" ) ),
178  unequip_script( elem.remove_string( "UNEQUIPSCRIPT", "" ) ),
179  control_script( elem.remove_string( "CONTROLSCRIPT", "" ), pkg, "scripts/control/" ),
180  create_script( elem.remove_string( "CREATESCRIPT", "" ), pkg, "scripts/control/" ),
181  destroy_script( elem.remove_string( "DESTROYSCRIPT", "" ), pkg, "scripts/control/" ),
182  requires_attention( elem.remove_bool( "REQUIRESATTENTION", true ) ),
183  lockable( elem.remove_bool( "LOCKABLE", false ) ),
184  vendor_sells_for( elem.remove_ulong( "VENDORSELLSFOR", 0 ) ),
185  vendor_buys_for( elem.remove_ulong( "VENDORBUYSFOR", 0 ) ),
186  decay_time(
187  elem.remove_ulong( "DECAYTIME", Core::settingsManager.ssopt.default_decay_time ) ),
188  movable( DEFAULT ),
189  doubleclick_range( elem.remove_ushort(
190  "DoubleclickRange", Core::settingsManager.ssopt.default_doubleclick_range ) ),
191  use_requires_los( elem.remove_bool( "UseRequiresLOS", true ) ), // Dave 11/24
192  ghosts_can_use( elem.remove_bool( "GhostsCanUse", false ) ), // Dave 11/24
193  can_use_while_paralyzed( elem.remove_bool( "CanUseWhileParalyzed", false ) ),
194  can_use_while_frozen( elem.remove_bool( "CanUseWhileFrozen", false ) ),
195  newbie( elem.remove_bool( "NEWBIE", false ) ),
196  insured( elem.remove_bool( "INSURED", false ) ),
197  invisible( elem.remove_bool( "INVISIBLE", false ) ),
198  decays_on_multis( elem.remove_bool( "DecaysOnMultis", 0 ) ),
199  blocks_casting_if_in_hand( elem.remove_bool( "BlocksCastingIfInHand", true ) ),
200  no_drop( elem.remove_bool( "NoDrop", false ) ),
201  base_str_req( elem.remove_ushort( "StrRequired", 0 ) * 10 ),
202  quality( elem.remove_double( "QUALITY", 1.0 ) ),
203  props( Core::CPropProfiler::Type::ITEM ),
204  method_script( nullptr ),
205  save_on_exit( elem.remove_bool( "SaveOnExit", true ) )
206 {
207  if ( type == BOATDESC || type == HOUSEDESC )
208  {
209  multiid = elem.remove_ushort( "MultiID", 0xFFFF );
210 
211  if ( multiid == 0xFFFF )
212  {
213  ERROR_PRINT << "Itemdesc has no 'multiid' specified for a multi.\n"
214  << " Note: read corechanges.txt for the new multi format\n";
215  elem.throw_error( "Configuration error" );
216  }
217  }
218  else
219  {
220  if ( graphic == 0 )
221  {
222  if ( objtype <= Plib::systemstate.config.max_tile_id )
223  {
224  graphic = static_cast<u16>( objtype );
225  }
226  else
227  {
228  ERROR_PRINT << "Itemdesc has no 'graphic' specified, and no 'objtype' is valid either.\n";
229  elem.throw_error( "Configuration error" );
230  }
231  }
232  }
233 
234  maxhp = elem.remove_ushort( "MAXHP", 0 );
235 
236  // Make sure Weapons and Armors ALL have this value defined to not break the core combat system
237  if ( maxhp == 0 && ( type == WEAPONDESC || type == ARMORDESC ) )
238  {
239  ERROR_PRINT.Format( "itemdesc.cfg, objtype 0x{:X} has no MaxHP specified." ) << objtype;
240  elem.throw_error( "Configuration error" );
241  }
242 
243  unsigned short stacklimit = elem.remove_ushort( "StackLimit", MAX_STACK_ITEMS );
244 
245  if ( stacklimit > MAX_STACK_ITEMS )
247  else
248  stack_limit = stacklimit;
249 
250  if ( tooltip.length() > PKTOUT_B7_MAX_CHARACTERS )
251  {
252  tooltip.erase( PKTOUT_B7_MAX_CHARACTERS, std::string::npos );
253  }
254 
255  unsigned short in_movable;
256  if ( elem.remove_prop( "MOVABLE", &in_movable ) )
257  {
258  movable = in_movable ? MOVABLE : UNMOVABLE;
259  }
260 
261  std::string weight_str;
262  if ( elem.remove_prop( "WEIGHT", &weight_str ) )
263  {
264  const char* s = weight_str.c_str();
265  char* endptr;
266  weightmult = strtoul( s, &endptr, 0 );
267  s = static_cast<const char*>( endptr );
268  while ( *s && isspace( *s ) )
269  ++s;
270  if ( *s == '/' )
271  {
272  ++s;
273  weightdiv = strtoul( s, &endptr, 0 );
274  if ( !weightdiv )
275  {
276  elem.throw_error( "Poorly formed weight directive: " + weight_str );
277  }
278  }
279  else if ( *s == '\0' )
280  {
281  weightdiv = 1;
282  }
283  else
284  {
285  elem.throw_error( "Poorly formed weight directive: " + weight_str );
286  }
287  }
288  else
289  {
291  weightdiv = 1;
292  }
293 
294  std::string temp;
295  while ( elem.remove_prop( "Resource", &temp ) )
296  {
297  ISTRINGSTREAM is( temp );
298  std::string rname;
299  unsigned amount;
300  if ( is >> rname >> amount )
301  {
302  resources.push_back( ResourceComponent( rname, amount ) );
303  }
304  else
305  {
306  ERROR_PRINT.Format( "itemdesc.cfg, objtype 0x{:X} : Resource '{}' is malformed.\n" )
307  << objtype << temp;
308  throw std::runtime_error( "Configuration file error" );
309  }
310  }
311 
312  while ( elem.remove_prop( "Name", &temp ) || elem.remove_prop( "ObjtypeName", &temp ) )
313  {
314  if ( Core::gamestate.objtype_byname.count( temp.c_str() ) )
315  {
316  ERROR_PRINT.Format(
317  "Warning! objtype 0x{:X} : ObjtypeName '{}' is the same as objtype {:#X}\n" )
318  << objtype << temp << Core::gamestate.objtype_byname[temp.c_str()];
319  // throw runtime_error( "Configuration file error" );
320  }
321  else
322  {
323  Core::gamestate.objtype_byname[temp.c_str()] = objtype;
324  }
325 
326  if ( objtypename.empty() )
327  objtypename = temp;
328 
329  /*
330  if (objtype_byname.count( temp.c_str() ))
331  {
332  cerr << "itemdesc.cfg, objtype 0x" << hex << objtype << dec
333  << ": Name '" << temp << "' has already been specified for objtype 0x"
334  << hex << objtype_byname[ temp.c_str() ] << dec << endl;
335  throw runtime_error( "Configuration file error" );
336  }
337  */
338  // if (!objtype_byname.count( temp.c_str() ))
339  // objtype_byname[ temp.c_str() ] = objtype;
340  }
341 
342  props.readProperties( elem );
343 
344  if ( elem.remove_prop( "MethodScript", &temp ) )
345  {
346  if ( pkg == nullptr )
347  throw std::runtime_error( "MethodScripts can only be specified in a package" );
348  if ( !temp.empty() )
349  {
350  Core::ExportScript* shs = new Core::ExportScript( pkg, temp );
351  if ( shs->Initialize() )
352  method_script = shs;
353  else
354  delete shs;
355  }
356  }
357 
358  unsigned int old_objtype;
359  while ( elem.remove_prop( "OldObjtype", &old_objtype ) )
360  {
361  if ( Core::gamestate.old_objtype_conversions.count( old_objtype ) )
362  {
363  elem.throw_error( objtype_description() + " specifies OldObjtype " +
364  Clib::hexint( old_objtype ) + " which is already mapped to " +
365  find_itemdesc( Core::gamestate.old_objtype_conversions[old_objtype] )
366  .objtype_description() );
367  }
368  if ( has_itemdesc( old_objtype ) )
369  {
370  elem.throw_error(
371  objtype_description() + " specifies OldObjtype " + Clib::hexint( old_objtype ) +
372  " which is already defined as " +
373  find_itemdesc( Core::gamestate.old_objtype_conversions[objtype] ).objtype_description() );
374  }
376  }
377 
378  if ( elem.remove_prop( "StackingIgnoresCProps", &temp ) )
379  {
380  ISTRINGSTREAM is( temp );
381  std::string cprop_name;
382  while ( is >> cprop_name )
383  {
384  ignore_cprops.insert( cprop_name );
385  }
386  }
387 
388  memset( &element_resist, 0, sizeof( element_resist ) );
389  memset( &element_damage, 0, sizeof( element_damage ) );
390  for ( unsigned resist = 0; resist <= Core::ELEMENTAL_TYPE_MAX; ++resist )
391  {
392  std::string tmp;
393  bool passed = false;
394 
395  switch ( resist )
396  {
398  passed = elem.remove_prop( "FIRERESIST", &tmp );
399  break;
401  passed = elem.remove_prop( "COLDRESIST", &tmp );
402  break;
404  passed = elem.remove_prop( "ENERGYRESIST", &tmp );
405  break;
407  passed = elem.remove_prop( "POISONRESIST", &tmp );
408  break;
410  passed = elem.remove_prop( "PHYSICALRESIST", &tmp );
411  break;
412  }
413 
414  if ( passed )
415  {
416  Core::Dice dice;
417  std::string errmsg;
418  if ( !dice.load( tmp.c_str(), &errmsg ) )
419  {
420  ERROR_PRINT << "Error loading itemdesc.cfg Elemental Resistances for "
421  << objtype_description() << " : " << errmsg << "\n";
422  throw std::runtime_error( "Error loading Item Elemental Resistances" );
423  }
424  switch ( resist )
425  {
427  element_resist.fire = dice.roll();
428  break;
430  element_resist.cold = dice.roll();
431  break;
433  element_resist.energy = dice.roll();
434  break;
436  element_resist.poison = dice.roll();
437  break;
439  element_resist.physical = dice.roll();
440  break;
441  }
442  }
443  }
444 
445  for ( unsigned edamage = 0; edamage <= Core::ELEMENTAL_TYPE_MAX; ++edamage )
446  {
447  std::string tmp;
448  bool passed = false;
449 
450  switch ( edamage )
451  {
453  passed = elem.remove_prop( "FIREDAMAGE", &tmp );
454  break;
456  passed = elem.remove_prop( "COLDDAMAGE", &tmp );
457  break;
459  passed = elem.remove_prop( "ENERGYDAMAGE", &tmp );
460  break;
462  passed = elem.remove_prop( "POISONDAMAGE", &tmp );
463  break;
465  passed = elem.remove_prop( "PHYSICALDAMAGE", &tmp );
466  break;
467  }
468 
469  if ( passed )
470  {
471  Core::Dice dice;
472  std::string errmsg;
473  if ( !dice.load( tmp.c_str(), &errmsg ) )
474  {
475  ERROR_PRINT << "Error loading itemdesc.cfg elemental damages for " << objtype_description()
476  << " : " << errmsg << "\n";
477  throw std::runtime_error( "Error loading Item Elemental Damages" );
478  }
479  switch ( edamage )
480  {
482  element_damage.fire = dice.roll();
483  break;
485  element_damage.cold = dice.roll();
486  break;
488  element_damage.energy = dice.roll();
489  break;
491  element_damage.poison = dice.roll();
492  break;
494  element_damage.physical = dice.roll();
495  break;
496  }
497  }
498  }
499 }
500 
502  : type( type ),
503  pkg( nullptr ),
504  objtype( 0 ),
505  graphic( 0 ),
506  color( 0 ),
507  facing( 127 ),
508  weightmult( 1 ),
509  weightdiv( 1 ),
510  desc( "" ),
511  tooltip( "" ),
512  // walk_on_script2(""),
513  // on_use_script2(""),
514  // control_script2(""),
515  // create_script2(""),
516  // destroy_script2(""),
517  requires_attention( false ),
518  lockable( false ),
519  vendor_sells_for( 0 ),
520  vendor_buys_for( 0 ),
521  decay_time( Core::settingsManager.ssopt.default_decay_time ),
522  movable( DEFAULT ),
523  doubleclick_range( Core::settingsManager.ssopt.default_doubleclick_range ),
524  use_requires_los( true ),
525  ghosts_can_use( false ),
526  can_use_while_paralyzed( false ),
527  can_use_while_frozen( false ),
528  newbie( false ),
529  insured( false ),
530  invisible( false ),
531  decays_on_multis( false ),
533  no_drop( false ),
534  base_str_req( 0 ),
536  quality( 1.0 ),
537  multiid( 0xFFFF ),
538  maxhp( 0 ),
539  props( Core::CPropProfiler::Type::ITEM ),
540  method_script( nullptr ),
541  save_on_exit( true )
542 {
543  memset( &element_resist, 0, sizeof( element_resist ) );
544  memset( &element_damage, 0, sizeof( element_damage ) );
545 }
546 
548 {
549  unload_scripts();
550 }
551 
553 {
554  using namespace Bscript;
555  std::string typestr;
556  switch ( type )
557  {
558  case ITEMDESC:
559  typestr = "Item";
560  break;
561  case CONTAINERDESC:
562  typestr = "Container";
563  break;
564  case DOORDESC:
565  typestr = "Door";
566  break;
567  case WEAPONDESC:
568  typestr = "Weapon";
569  break;
570  case ARMORDESC:
571  typestr = "Armor";
572  break;
573  case BOATDESC:
574  typestr = "Boat";
575  break;
576  case HOUSEDESC:
577  typestr = "House";
578  break;
579  case SPELLBOOKDESC:
580  typestr = "Spellbook";
581  break;
582  case SPELLSCROLLDESC:
583  typestr = "Spellscroll";
584  break;
585  case MAPDESC:
586  typestr = "Map";
587  break;
588  default:
589  typestr = "Unknown";
590  break;
591  }
592  descriptor->addMember( "ObjClass", new String( typestr ) );
593  descriptor->addMember( "ObjType", new BLong( objtype ) );
594  descriptor->addMember( "Graphic", new BLong( graphic ) );
595  descriptor->addMember( "Name", new String( objtypename ) );
596  descriptor->addMember( "Color", new BLong( color ) );
597  descriptor->addMember( "Facing", new BLong( facing ) );
598  descriptor->addMember( "Desc", new String( desc ) );
599  descriptor->addMember( "Tooltip", new String( tooltip ) );
600  descriptor->addMember( "WalkOnScript", new String( walk_on_script.relativename( pkg ) ) );
601  descriptor->addMember( "Script", new String( on_use_script.relativename( pkg ) ) );
602  descriptor->addMember( "EquipScript", new String( equip_script ) );
603  descriptor->addMember( "UnequipScript", new String( unequip_script ) );
604  descriptor->addMember( "ControlScript", new String( control_script.relativename( pkg ) ) );
605  descriptor->addMember( "CreateScript", new String( create_script.relativename( pkg ) ) );
606  descriptor->addMember( "DestroyScript", new String( destroy_script.relativename( pkg ) ) );
607  descriptor->addMember( "MethodScript",
608  new String( method_script ? method_script->scriptname() : "" ) );
609  descriptor->addMember( "RequiresAttention", new BLong( requires_attention ) );
610  descriptor->addMember( "Lockable", new BLong( lockable ) );
611  descriptor->addMember( "VendorSellsFor", new BLong( vendor_sells_for ) );
612  descriptor->addMember( "VendorBuysFor", new BLong( vendor_buys_for ) );
613  descriptor->addMember( "DecayTime", new BLong( decay_time ) );
614  descriptor->addMember( "Movable", new BLong( default_movable() ) );
615  descriptor->addMember( "DoubleClickRange", new BLong( doubleclick_range ) );
616  descriptor->addMember( "UseRequiresLOS", new BLong( use_requires_los ) );
617  descriptor->addMember( "GhostsCanUse", new BLong( ghosts_can_use ) );
618  descriptor->addMember( "CanUseWhileFrozen", new BLong( can_use_while_frozen ) );
619  descriptor->addMember( "CanUseWhileParalyzed", new BLong( can_use_while_paralyzed ) );
620  descriptor->addMember( "Newbie", new BLong( newbie ) );
621  descriptor->addMember( "Insured", new BLong( insured ) );
622  descriptor->addMember( "Invisible", new BLong( invisible ) );
623  descriptor->addMember( "DecaysOnMultis", new BLong( decays_on_multis ) );
624  descriptor->addMember( "BlocksCastingIfInHand", new BLong( blocks_casting_if_in_hand ) );
625  descriptor->addMember( "NoDrop", new BLong( no_drop ) );
626  descriptor->addMember( "StrRequired", new BLong( base_str_req ) );
627  descriptor->addMember( "StackLimit", new BLong( stack_limit ) );
628  descriptor->addMember( "Weight", new Double( static_cast<double>( weightmult ) / weightdiv ) );
629  descriptor->addMember( "FireResist", new BLong( element_resist.fire ) );
630  descriptor->addMember( "ColdResist", new BLong( element_resist.cold ) );
631  descriptor->addMember( "EnergyResist", new BLong( element_resist.energy ) );
632  descriptor->addMember( "PoisonResist", new BLong( element_resist.poison ) );
633  descriptor->addMember( "PhysicalResist", new BLong( element_resist.physical ) );
634  descriptor->addMember( "FireDamage", new BLong( element_damage.fire ) );
635  descriptor->addMember( "ColdDamage", new BLong( element_damage.cold ) );
636  descriptor->addMember( "EnergyDamage", new BLong( element_damage.energy ) );
637  descriptor->addMember( "PoisonDamage", new BLong( element_damage.poison ) );
638  descriptor->addMember( "PhysicalDamage", new BLong( element_damage.physical ) );
639  descriptor->addMember( "Quality", new Double( quality ) );
640  descriptor->addMember( "MultiID", new BLong( multiid ) );
641  descriptor->addMember( "MaxHp", new BLong( maxhp ) );
642 
643  std::set<std::string>::const_iterator set_itr;
644  std::unique_ptr<ObjArray> ignorecp( new ObjArray );
645  for ( set_itr = ignore_cprops.begin(); set_itr != ignore_cprops.end(); ++set_itr )
646  ignorecp->addElement( new String( *set_itr ) );
647 
648  descriptor->addMember( "StackingIgnoresCProps", ignorecp.release() );
649 
650  auto cpropdict = new BDictionary();
651  std::vector<std::string> propnames;
652  std::vector<std::string>::const_iterator vec_itr;
653  std::string tempval;
654  props.getpropnames( propnames );
655  for ( vec_itr = propnames.begin(); vec_itr != propnames.end(); ++vec_itr )
656  {
657  props.getprop( *vec_itr, tempval );
658  cpropdict->addMember( vec_itr->c_str(), BObjectImp::unpack( tempval.c_str() ) );
659  }
660 
661  descriptor->addMember( "CProps", cpropdict );
662 
663  // FIXME: this should be a single member similar to CProps, called Resources
664  std::vector<ResourceComponent>::const_iterator resource_itr;
665  for ( resource_itr = resources.begin(); resource_itr != resources.end(); ++resource_itr )
666  {
667  descriptor->addMember( "Resource", new String( resource_itr->rd->name() + " " +
668  Clib::decint( resource_itr->amount ) ) );
669  }
670 }
671 
673 {
674  if ( method_script != nullptr )
675  {
676  delete method_script;
677  method_script = nullptr;
678  }
679 }
680 
681 std::string ItemDesc::objtype_description() const
682 {
683  fmt::Writer tmp;
684  if ( pkg )
685  tmp << ":" << pkg->name() << ":";
686  tmp << objtypename << " (0x" << fmt::hexu( objtype ) << ")";
687  return tmp.str();
688 }
689 
691 {
692  if ( movable == DEFAULT )
693  return ( ( Core::tile_flags( graphic ) & Plib::FLAG::MOVABLE ) != 0 );
694  else
695  return movable ? true : false;
696 }
697 
699 {
700  size_t size = sizeof( ItemDesc ) + objtypename.capacity() + tooltip.capacity() +
703  destroy_script.estimatedSize() + 3 * sizeof( ResourceComponent* ) +
704  resources.capacity() * sizeof( ResourceComponent ) + props.estimatedSize();
705  size += 3 * sizeof( void* );
706  for ( const auto& ignore : ignore_cprops )
707  {
708  size += ignore.capacity() + 3 * sizeof( void* );
709  }
710  return size;
711 }
712 
714  : ItemDesc( objtype, elem, CONTAINERDESC, pkg ),
715  gump( elem.remove_ushort( "GUMP" ) ),
716  minx( elem.remove_ushort( "MINX" ) ),
717  maxx( elem.remove_ushort( "MAXX" ) ),
718  miny( elem.remove_ushort( "MINY" ) ),
719  maxy( elem.remove_ushort( "MAXY" ) ),
720  max_weight( elem.remove_ushort( "MAXWEIGHT",
721  Core::settingsManager.ssopt.default_container_max_weight ) ),
722  max_items( elem.remove_ushort( "MAXITEMS",
723  Core::settingsManager.ssopt.default_container_max_items ) ),
724  max_slots( static_cast<u8>(
725  elem.remove_ushort( "MAXSLOTS", Core::settingsManager.ssopt.default_max_slots ) ) ),
726  no_drop_exception( elem.remove_bool( "NoDropException", false ) ),
727  can_insert_script( elem.remove_string( "CANINSERTSCRIPT", "" ), pkg, "scripts/control/" ),
728  on_insert_script( elem.remove_string( "ONINSERTSCRIPT", "" ), pkg, "scripts/control/" ),
729  can_remove_script( elem.remove_string( "CANREMOVESCRIPT", "" ), pkg, "scripts/control/" ),
730  on_remove_script( elem.remove_string( "ONREMOVESCRIPT", "" ), pkg, "scripts/control/" )
731 {
732  // FIXME: in theory, should never happen due to conversion to u8. Maybe here as note during
733  // rewrite. Add a remove_uchar/remove_char for allowing
734  // use of max 0-255 integers control due to packet limits, in configuration files. Yay.
735  // if ( max_slots > 255 )
736  // {
737  // cerr << "Warning! Container " << hexint( objtype ) << ": Invalid MaxSlots defined.
738  // MaxSlots max value is 255. Setting to 255." << endl;
739  // max_slots = 255;
740  // }
741 }
742 
744 {
745  using namespace Bscript;
746  base::PopulateStruct( descriptor );
747  descriptor->addMember( "Gump", new BLong( gump ) );
748  descriptor->addMember( "MinX", new BLong( minx ) );
749  descriptor->addMember( "MinY", new BLong( miny ) );
750  descriptor->addMember( "MaxX", new BLong( maxx ) );
751  descriptor->addMember( "MaxY", new BLong( maxy ) );
752  descriptor->addMember( "MaxWeight", new BLong( max_weight ) );
753  descriptor->addMember( "MaxItems", new BLong( max_items ) );
754  descriptor->addMember( "MaxSlots", new BLong( max_slots ) );
755  descriptor->addMember( "NoDropException", new BLong( no_drop_exception ) );
756  descriptor->addMember( "CanInsertScript", new String( can_insert_script.relativename( pkg ) ) );
757  descriptor->addMember( "CanRemoveScript", new String( can_remove_script.relativename( pkg ) ) );
758  descriptor->addMember( "OnInsertScript", new String( on_insert_script.relativename( pkg ) ) );
759  descriptor->addMember( "OnRemoveScript", new String( on_remove_script.relativename( pkg ) ) );
760 }
761 
763 {
764  return base::estimatedSize() + sizeof( u16 ) /*gump*/
765  + sizeof( u16 ) /*minx*/
766  + sizeof( u16 ) /*maxx*/
767  + sizeof( u16 ) /*miny*/
768  + sizeof( u16 ) /*maxy*/
769  + sizeof( u16 ) /*max_weight*/
770  + sizeof( u16 ) /*max_items*/
771  + sizeof( u8 ) /*max_slots*/
772  + sizeof( bool ) /*no_drop_exception*/
775 }
776 
778  : ItemDesc( objtype, elem, DOORDESC, pkg ),
779  xmod( static_cast<s16>( elem.remove_int( "XMOD" ) ) ),
780  ymod( static_cast<s16>( elem.remove_int( "YMOD" ) ) ),
781  open_graphic( elem.remove_ushort( "OPENGRAPHIC", 0 ) )
782 {
783 }
784 
786 {
787  base::PopulateStruct( descriptor );
788  descriptor->addMember( "XMod", new Bscript::BLong( xmod ) );
789  descriptor->addMember( "YMod", new Bscript::BLong( ymod ) );
790  descriptor->addMember( "OpenGraphic", new Bscript::BLong( open_graphic ) );
791 }
793 {
794  return base::estimatedSize() + sizeof( s16 ) /*xmod*/
795  + sizeof( s16 ) /*ymod*/
796  + sizeof( u16 ) /*open_graphic*/
797  ;
798 }
799 
801  : ContainerDesc( objtype, elem, pkg ), spelltype( elem.remove_string( "SPELLTYPE" ) )
802 {
804 }
805 
807 {
808  base::PopulateStruct( descriptor );
809  descriptor->addMember( "Spelltype", new Bscript::String( spelltype ) );
810 }
811 
813 {
814  return base::estimatedSize() + spelltype.capacity();
815 }
816 
818  : ItemDesc( objtype, elem, SPELLSCROLLDESC, pkg ),
819  spelltype( elem.remove_string( "SPELLTYPE" ) )
820 {
821 }
822 
824 {
825  base::PopulateStruct( descriptor );
826  descriptor->addMember( "Spelltype", new Bscript::String( spelltype ) );
827 }
828 
830 {
831  return base::estimatedSize() + spelltype.capacity();
832 }
833 
835  : ItemDesc( objtype, elem, type, pkg )
836 {
838  {
839  elem.throw_error( "Multi definition not found. Objtype=" + Clib::hexint( objtype ) +
840  ", multiid=" + Clib::hexint( multiid ) );
841  }
842 }
844 {
845  base::PopulateStruct( descriptor );
846 }
848 {
849  return base::estimatedSize();
850 }
851 
853  : MultiDesc( objtype, elem, BOATDESC, pkg )
854 {
855 }
856 
858 {
859  base::PopulateStruct( descriptor );
860 }
862 {
863  return base::estimatedSize();
864 }
865 
867  : MultiDesc( objtype, elem, HOUSEDESC, pkg )
868 {
869 }
870 
872 {
873  base::PopulateStruct( descriptor );
874 }
876 {
877  return base::estimatedSize();
878 }
879 
881  : ItemDesc( objtype, elem, MAPDESC, pkg ), editable( elem.remove_bool( "EDITABLE", true ) )
882 {
883 }
884 
885 void MapDesc::PopulateStruct( Bscript::BStruct* descriptor ) const
886 {
887  base::PopulateStruct( descriptor );
888  descriptor->addMember( "Editable", new Bscript::BLong( editable ) );
889 }
891 {
892  return sizeof( bool ) /*editable*/ + base::estimatedSize();
893 }
894 
896 {
897  return Core::gamestate.desctable.count( objtype ) > 0;
898 }
899 
901 {
902  const ItemDesc& id = find_itemdesc( objtype );
903  return id.lockable;
904 }
905 
906 unsigned short getgraphic( u32 objtype )
907 {
908  const ItemDesc& id = find_itemdesc( objtype );
909 
910  // Check here to make sure multis are created without a graphic entry in itemdesc.
911  if ( id.type == id.BOATDESC || id.type == id.HOUSEDESC )
912  return 0;
913 
914  if ( id.graphic )
915  {
916  return id.graphic;
917  }
918  else if ( objtype <= Plib::systemstate.config.max_tile_id )
919  {
920  return static_cast<u16>( objtype );
921  }
922  else
923  {
924  throw std::runtime_error( "Objtype " + Clib::hexint( objtype ) + " must define a graphic" );
925  }
926 }
927 unsigned short getcolor( unsigned int objtype )
928 {
929  const ItemDesc& id = find_itemdesc( objtype );
930  return id.color;
931 }
932 
933 const ItemDesc& find_itemdesc( unsigned int objtype )
934 {
935  const auto& obj = Core::gamestate.desctable.find( objtype );
936  if ( obj != Core::gamestate.desctable.end() )
937  return *( obj->second );
938  else
939  return *( Core::gamestate.empty_itemdesc.get() );
940 }
941 
943 {
944  const ContainerDesc* cd = static_cast<const ContainerDesc*>( &find_itemdesc( objtype ) );
946  "ObjType " + Clib::hexint( objtype ) +
947  " should be defined as container or spellbook, but is not" );
948  return *cd;
949 }
950 
952 {
953  const DoorDesc* dd = static_cast<const DoorDesc*>( &find_itemdesc( objtype ) );
954  passert( dd->type == ItemDesc::DOORDESC );
955  return *dd;
956 }
957 
959 {
960  const MultiDesc* md = static_cast<const MultiDesc*>( &find_itemdesc( objtype ) );
962  return *md;
963 }
964 
966 {
967  Clib::ConfigElem elem;
968  Clib::StubConfigSource stub_source;
969  elem.set_source( &stub_source );
970 
971  const Bscript::BStruct::Contents& struct_cont = itemdesc_struct->contents();
972  Bscript::BStruct::Contents::const_iterator itr;
973  for ( itr = struct_cont.begin(); itr != struct_cont.end(); ++itr )
974  {
975  const std::string& key = ( *itr ).first;
976  Bscript::BObjectImp* val_imp = ( *itr ).second->impptr();
977 
978  if ( key == "CProps" )
979  {
980  if ( val_imp->isa( Bscript::BObjectImp::OTDictionary ) )
981  {
982  Bscript::BDictionary* cpropdict = static_cast<Bscript::BDictionary*>( val_imp );
983  const Bscript::BDictionary::Contents& cprop_cont = cpropdict->contents();
984  Bscript::BDictionary::Contents::const_iterator ditr;
985  for ( ditr = cprop_cont.begin(); ditr != cprop_cont.end(); ++ditr )
986  {
987  elem.add_prop( "cprop", ( ( *ditr ).first->getStringRep() + "\t" +
988  ( *ditr ).second->impptr()->pack() ) );
989  }
990  }
991  else
992  {
993  throw std::runtime_error( "CreateItemDescriptor: CProps must be a dictionary, but is: " +
994  std::string( val_imp->typeOf() ) );
995  }
996  }
997  else if ( key == "StackingIgnoresCProps" )
998  {
999  if ( val_imp->isa( Bscript::BObjectImp::OTArray ) )
1000  {
1001  OSTRINGSTREAM os;
1002  // FIXME verify that it's an ObjArray...
1003  Bscript::ObjArray* ignorecp = static_cast<Bscript::ObjArray*>( itr->second->impptr() );
1004  const Bscript::ObjArray::Cont& conts = ignorecp->ref_arr;
1005  Bscript::ObjArray::Cont::const_iterator aitr;
1006  for ( aitr = conts.begin(); aitr != conts.end(); ++aitr )
1007  {
1008  os << ( *aitr ).get()->impptr()->getStringRep() << " ";
1009  }
1010  elem.add_prop( key, OSTRINGSTREAM_STR( os ));
1011  }
1012  else
1013  {
1014  throw std::runtime_error(
1015  "CreateItemDescriptor: StackingIgnoresCProps must be an array, but is: " +
1016  std::string( val_imp->typeOf() ) );
1017  }
1018  }
1019  else if ( key == "Coverage" ) // Dave 7/13 needs to be parsed out into individual lines
1020  {
1021  if ( val_imp->isa( Bscript::BObjectImp::OTArray ) )
1022  {
1023  // FIXME verify that it's an ObjArray...
1024  Bscript::ObjArray* coverage = static_cast<Bscript::ObjArray*>( itr->second->impptr() );
1025  const Bscript::ObjArray::Cont& conts = coverage->ref_arr;
1026  Bscript::ObjArray::Cont::const_iterator aitr;
1027  for ( aitr = conts.begin(); aitr != conts.end(); ++aitr )
1028  {
1029  OSTRINGSTREAM os;
1030  os << ( *aitr ).get()->impptr()->getStringRep();
1031  elem.add_prop( key.c_str(), OSTRINGSTREAM_STR( os ) );
1032  }
1033  }
1034  else
1035  {
1036  throw std::runtime_error( "CreateItemDescriptor: Coverage must be an array, but is: " +
1037  std::string( val_imp->typeOf() ) );
1038  }
1039  }
1040  else if ( key == "ObjClass" )
1041  {
1042  std::string value = val_imp->getStringRep();
1043  elem.set_type( value.c_str() );
1044  }
1045  else if ( key == "ObjType" )
1046  {
1047  std::string value = val_imp->getStringRep();
1048  elem.set_rest( value.c_str() );
1049  }
1050  else if ( Clib::strlower( key ) == "name" || Clib::strlower( key ) == "objtypename" ||
1051  Clib::strlower( key ) == "oldobjtype" || Clib::strlower( key ) == "methodscript" ||
1052  Clib::strlower( key ) == "weight" )
1053  {
1054  // all of these only affect the main descriptor, so they're left out.
1055  // name, objtypename, and oldobjtype would try to insert aliases
1056  // methodscript would create scripts and such.
1057  // weight, for values like 0.1 (came in as 1/10), won't parse correctly.
1058  continue;
1059  }
1060  else
1061  {
1062  std::string value = val_imp->getStringRep();
1063  elem.add_prop( key, std::move(value) );
1064  }
1065  }
1066 
1067  unsigned int objtype = static_cast<unsigned int>( strtoul( elem.rest(), nullptr, 0 ) );
1068  ItemDesc* id = ItemDesc::create( elem, find_itemdesc( objtype ).pkg );
1069 
1070  Core::gamestate.dynamic_item_descriptors.push_back( id );
1071 
1072  return id;
1073 }
1074 
1075 
1076 void read_itemdesc_file( const char* filename, Plib::Package* pkg = nullptr )
1077 {
1078  /*
1079  if (1)
1080  {
1081  ref_ptr<StoredConfigFile> scfg = FindConfigFile( "config/itemdesc.cfg" );
1082  ConfigFile cf( filename );
1083  scfg->load( cf );
1084  }
1085  */
1086  Clib::ConfigFile cf( filename,
1087  "CONTAINER ITEM DOOR WEAPON ARMOR BOAT HOUSE SPELLBOOK SPELLSCROLL MAP" );
1088 
1089  Clib::ConfigElem elem;
1090  while ( cf.read( elem ) )
1091  {
1092  ItemDesc* descriptor = ItemDesc::create( elem, pkg );
1093 
1094 
1095  // string unused_name, unused_value;
1096  // while (elem.remove_first_prop( &unused_name, &unused_value ))
1097  //{
1098  // elem.warn_with_line( "Property '" + unused_name + "' (value '" + unused_value + "') is
1099  // unused." );
1100  //}
1101 
1102  if ( has_itemdesc( descriptor->objtype ) )
1103  {
1104  fmt::Writer tmp;
1105  tmp.Format( "Error: Objtype 0x{:X} is already defined in" ) << descriptor->objtype;
1106  if ( find_itemdesc( descriptor->objtype ).pkg == nullptr )
1107  tmp << "config/itemdesc.cfg\n";
1108  else
1109  tmp << find_itemdesc( descriptor->objtype ).pkg->dir() << "itemdesc.cfg\n";
1110  ERROR_PRINT << tmp.str();
1111 
1112  elem.throw_error( "ObjType " + Clib::hexint( descriptor->objtype ) +
1113  " defined more than once." );
1114  }
1115  Core::gamestate.desctable[descriptor->objtype] = descriptor;
1116 
1117  // just make sure this will work later.
1118  getgraphic( descriptor->objtype );
1119  }
1120 }
1121 
1123 {
1124  // string filename = pkg->dir() + "itemdesc.cfg";
1125  std::string filename = GetPackageCfgPath( pkg, "itemdesc.cfg" );
1126  if ( Clib::FileExists( filename.c_str() ) )
1127  {
1128  read_itemdesc_file( filename.c_str(), pkg );
1129  }
1130 }
1131 
1133 {
1134  std::ofstream ofs( "objtypes.txt" );
1135  unsigned int last_objtype = 0;
1136  for ( const auto& elem : Core::gamestate.desctable )
1137  {
1138  const ItemDesc* itemdesc = elem.second;
1139  unsigned int i = elem.first;
1140 
1141  if ( i != last_objtype + 1 )
1142  {
1143  unsigned int first = last_objtype + 1;
1144  unsigned int last = i - 1;
1145  if ( first == last )
1146  {
1147  ofs << "# " << Clib::hexint( first ) << " unused\n";
1148  }
1149  else
1150  {
1151  ofs << "# " << Clib::hexint( first ) << " - " << Clib::hexint( last ) << " unused\n";
1152  }
1153  }
1154 
1155  if ( !Core::gamestate.old_objtype_conversions.count( i ) )
1156  {
1157  ofs << Clib::hexint( i ) << " ";
1158  if ( itemdesc->objtypename.empty() == false )
1159  ofs << itemdesc->objtypename;
1160  else
1161  ofs << "[n/a]";
1162  if ( itemdesc->pkg )
1163  ofs << " " << itemdesc->pkg->name();
1164  ofs << '\n';
1165  }
1166  else // it's converted
1167  {
1168  ofs << "# " << Clib::hexint( i ) << " converts to "
1169  << Clib::hexint( (int)Core::gamestate.old_objtype_conversions[i] ) << '\n';
1170  }
1171 
1172  last_objtype = i;
1173  }
1174 
1175  if ( last_objtype != Plib::systemstate.config.max_objtype )
1176  {
1177  unsigned int first = last_objtype + 1;
1178  unsigned int last = Plib::systemstate.config.max_objtype;
1179  if ( first == last )
1180  {
1181  ofs << "# " << Clib::hexint( first ) << " unused\n";
1182  }
1183  else
1184  {
1185  ofs << "# " << Clib::hexint( first ) << " - " << Clib::hexint( last ) << " unused\n";
1186  }
1187  }
1188 }
1189 
1191 {
1192  // CreateEmptyStoredConfigFile( "config/itemdesc.cfg" );
1193  if ( Clib::FileExists( "config/itemdesc.cfg" ) )
1194  read_itemdesc_file( "config/itemdesc.cfg" );
1195  // read_itemdesc_file( "config/wepndesc.cfg" );
1196  // read_itemdesc_file( "config/armrdesc.cfg" );
1197  for ( auto& pkg : Plib::systemstate.packages )
1199 
1201 }
1202 
1204 {
1205  for ( auto& elem : Core::gamestate.desctable )
1206  {
1207  if ( elem.second != Core::gamestate.empty_itemdesc.get() )
1208  {
1209  delete elem.second;
1210  elem.second = Core::gamestate.empty_itemdesc.get();
1211  }
1212  }
1213 
1216  for ( auto& item : Core::gamestate.dynamic_item_descriptors )
1217  {
1218  delete item;
1219  }
1221 }
1222 
1223 void remove_resources( u32 objtype, u16 /*amount*/ )
1224 {
1225  const ItemDesc& id = find_itemdesc( objtype );
1226  for ( const auto& rc : id.resources )
1227  {
1228  rc.rd->consume( rc.amount );
1229  }
1230 }
1231 
1232 void return_resources( u32 objtype, u16 /*amount*/ )
1233 {
1234  // MuadDib Added 03/22/09. This can cause a crash in shutdown with orphaned/leaked items
1235  // after saving of data files, and clearing all objects. At this stage, there is no need
1236  // to free and replenish ore/wood/etc resources in the world. o_O
1237  if ( !Clib::exit_signalled )
1238  {
1239  const ItemDesc& id = find_itemdesc( objtype );
1240  for ( const auto& rc : id.resources )
1241  {
1242  rc.rd->produce( rc.amount );
1243  }
1244  }
1245 }
1246 } // namespace Items
1247 } // namespace Pol
virtual void PopulateStruct(Bscript::BStruct *descriptor) const POL_OVERRIDE
Definition: itemdesc.cpp:843
unsigned short doubleclick_range
Definition: itemdesc.h:114
unsigned char u8
Definition: rawtypes.h:25
SpellScrollDesc(u32 objtype, Clib::ConfigElem &elem, const Plib::Package *pkg)
Definition: itemdesc.cpp:817
unsigned int tile_flags(unsigned short tilenum)
Definition: polfile2.cpp:49
MultiDesc(u32 objtype, Clib::ConfigElem &elem, Type type, const Plib::Package *pkg)
Definition: itemdesc.cpp:834
unsigned short stack_limit
Definition: itemdesc.h:126
Core::PropertyList props
Definition: itemdesc.h:138
virtual std::string getStringRep() const =0
Core::ExportScript * method_script
Definition: itemdesc.h:141
std::string objtype_description() const
Definition: itemdesc.cpp:681
unsigned decay_time
Definition: itemdesc.h:107
unsigned int get_objtype_byname(const char *str)
Definition: itemdesc.cpp:58
virtual size_t estimatedSize() const POL_OVERRIDE
Definition: itemdesc.cpp:890
std::vector< Items::ItemDesc * > dynamic_item_descriptors
Definition: uvars.h:206
const std::string & scriptname() const
void return_resources(u32 objtype, u16)
Definition: itemdesc.cpp:1232
SpellbookDesc(u32 objtype, Clib::ConfigElem &elem, const Plib::Package *pkg)
Definition: itemdesc.cpp:800
unsigned short roll(void) const
Definition: dice.cpp:26
ExternalObject extobj
Definition: settings.h:30
std::string objtypename
Definition: itemdesc.h:85
SystemState systemstate
Definition: systemstate.cpp:12
bool isa(BObjectType type) const
Definition: bobject.h:353
Core::PolConfig config
Definition: systemstate.h:43
Core::ScriptDef on_remove_script
Definition: itemdesc.h:174
virtual size_t estimatedSize() const POL_OVERRIDE
Definition: itemdesc.cpp:861
std::map< std::string, BObjectRef, Clib::ci_cmp_pred > Contents
Definition: bstruct.h:51
std::set< std::string > ignore_cprops
Definition: itemdesc.h:139
std::string tooltip
Definition: itemdesc.h:95
std::string decint(unsigned short v)
Definition: strutil.cpp:64
unsigned short base_str_req
Definition: itemdesc.h:125
#define MAX_STACK_ITEMS
Definition: uconst.h:93
size_t estimatedSize() const
Definition: scrdef.cpp:140
const Contents & contents() const
Definition: bstruct.cpp:466
virtual size_t estimatedSize() const
Definition: itemdesc.cpp:698
void load_itemdesc()
Definition: itemdesc.cpp:1190
unsigned int vendor_sells_for
Definition: itemdesc.h:105
std::string relativename(const Plib::Package *pkg=nullptr) const
Definition: scrdef.cpp:102
void load_package_itemdesc(Plib::Package *pkg)
Definition: itemdesc.cpp:1122
size_t estimatedSize() const
Definition: proplist.cpp:362
unsigned short getcolor(unsigned int objtype)
Definition: itemdesc.cpp:927
#define OSTRINGSTREAM_STR(x)
Definition: stlutil.h:76
void read_itemdesc_file(const char *filename, Plib::Package *pkg=nullptr)
Definition: itemdesc.cpp:1076
std::vector< ResourceComponent > resources
Definition: itemdesc.h:136
bool blocks_casting_if_in_hand
Definition: itemdesc.h:123
void addMember(const char *name, BObjectRef val)
Definition: bstruct.cpp:305
const std::string & name() const
Definition: pkg.h:83
const ItemDesc & find_itemdesc(unsigned int objtype)
Definition: itemdesc.cpp:933
virtual void PopulateStruct(Bscript::BStruct *descriptor) const POL_OVERRIDE
Definition: itemdesc.cpp:806
unsigned short multiid
Definition: itemdesc.h:128
Core::ScriptDef on_insert_script
Definition: itemdesc.h:172
Core::ElementDamages element_damage
Definition: itemdesc.h:134
DoorDesc(u32 objtype, Clib::ConfigElem &elem, const Plib::Package *pkg)
Definition: itemdesc.cpp:777
#define passert_r(exp, reason)
Definition: passert.h:66
Core::ScriptDef on_use_script
Definition: itemdesc.h:97
virtual void PopulateStruct(Bscript::BStruct *descriptor) const POL_OVERRIDE
Definition: itemdesc.cpp:885
std::string hexint(unsigned short v)
Definition: strutil.cpp:23
unsigned short getgraphic(u32 objtype)
Definition: itemdesc.cpp:906
std::unique_ptr< Items::ItemDesc > empty_itemdesc
Definition: uvars.h:208
unsigned short u16
Definition: rawtypes.h:26
const char * rest() const
Definition: cfgfile.cpp:71
#define PKTOUT_B7_MAX_CHARACTERS
Definition: pktdef.h:152
Core::ScriptDef destroy_script
Definition: itemdesc.h:102
virtual void PopulateStruct(Bscript::BStruct *descriptor) const POL_OVERRIDE
Definition: itemdesc.cpp:871
unsigned int u32
Definition: rawtypes.h:27
unsigned short maxhp
Definition: itemdesc.h:129
POL_NORETURN void throw_error(const std::string &errmsg) const
Definition: cfgfile.cpp:285
const Plib::Package * pkg
Definition: itemdesc.h:84
virtual size_t estimatedSize() const POL_OVERRIDE
Definition: itemdesc.cpp:762
unsigned int get_objtype_from_string(const std::string &str)
Definition: itemdesc.cpp:67
signed short s16
Definition: rawtypes.h:30
void set_type(const char *newtype)
Definition: cfgfile.cpp:81
boost_utils::script_name_flystring equip_script
Definition: itemdesc.h:98
Core::ScriptDef walk_on_script
Definition: itemdesc.h:96
void add_prop(std::string propname, std::string propval)
Definition: cfgfile.cpp:490
boost_utils::object_name_flystring desc
Definition: itemdesc.h:94
Core::ScriptDef can_insert_script
Definition: itemdesc.h:171
virtual void PopulateStruct(Bscript::BStruct *descriptor) const POL_OVERRIDE
Definition: itemdesc.cpp:823
std::map< BObject, BObjectRef > Contents
Definition: dict.h:47
#define OSTRINGSTREAM
Definition: stlutil.h:75
std::vector< BObjectRef > Cont
Definition: bobject.h:507
void unload_itemdesc()
Definition: itemdesc.cpp:1203
ResourceDef * find_resource_def(const std::string &rname)
Definition: resource.cpp:315
#define passert(exp)
Definition: passert.h:62
boost_utils::script_name_flystring unequip_script
Definition: itemdesc.h:99
void readProperties(Clib::ConfigElem &elem)
Definition: proplist.cpp:464
static BObjectImp * unpack(const char *pstr)
Definition: object.cpp:120
GameState gamestate
Definition: uvars.cpp:74
virtual size_t estimatedSize() const POL_OVERRIDE
Definition: itemdesc.cpp:847
void remove_resources(u32 objtype, u16)
Definition: itemdesc.cpp:1223
void getpropnames(std::vector< std::string > &propnames) const
Definition: proplist.cpp:421
ContainerDesc(u32 objtype, Clib::ConfigElem &elem, const Plib::Package *pkg)
Definition: itemdesc.cpp:713
Core::Resistances element_resist
Definition: itemdesc.h:133
SettingsManager settingsManager
Definition: settings.cpp:14
virtual size_t estimatedSize() const POL_OVERRIDE
Definition: itemdesc.cpp:829
bool remove_prop(const char *propname, std::string *value)
Definition: cfgfile.cpp:128
bool MultiDefByMultiIDExists(u16 multiid)
Definition: multidef.cpp:293
virtual void PopulateStruct(Bscript::BStruct *descriptor) const
Definition: itemdesc.cpp:552
unsigned int shield
Definition: extobj.h:33
const MultiDesc & find_multidesc(u32 objtype)
Definition: itemdesc.cpp:958
virtual size_t estimatedSize() const POL_OVERRIDE
Definition: itemdesc.cpp:792
#define ISTRINGSTREAM
Definition: stlutil.h:73
const Contents & contents() const
Definition: dict.cpp:435
bool type_is(const char *name) const
Definition: cfgfile.cpp:95
ObjtypeByNameMap objtype_byname
Definition: uvars.h:207
const ItemDesc * CreateItemDescriptor(Bscript::BStruct *itemdesc_struct)
Definition: itemdesc.cpp:965
Core::ScriptDef can_remove_script
Definition: itemdesc.h:173
std::string strlower(const std::string &str)
Definition: strutil.cpp:276
Core::ResourceDef * rd
Definition: itemdesc.h:49
ResourceComponent(const std::string &rname, unsigned amount)
Definition: itemdesc.cpp:86
OldObjtypeConversions old_objtype_conversions
Definition: uvars.h:205
unsigned short remove_ushort(const char *propname)
Definition: cfgfile.cpp:318
bool getprop(const std::string &propname, std::string &propvalue) const
Definition: proplist.cpp:371
bool objtype_is_lockable(u32 objtype)
Definition: itemdesc.cpp:900
unsigned short tileweight(unsigned short tilenum)
Definition: polfile2.cpp:85
const DoorDesc & fast_find_doordesc(u32 objtype)
Definition: itemdesc.cpp:951
std::string GetPackageCfgPath(const Package *pkg, const std::string &filename)
Definition: pkg.cpp:491
virtual void PopulateStruct(Bscript::BStruct *descriptor) const POL_OVERRIDE
Definition: itemdesc.cpp:743
void set_source(const ConfigElem &elem)
Definition: cfgfile.cpp:86
#define ERROR_PRINT
Definition: logfacility.h:230
std::map< u32, Items::ItemDesc * > desctable
Definition: uvars.h:204
void write_objtypes_txt()
Definition: itemdesc.cpp:1132
HouseDesc(u32 objtype, Clib::ConfigElem &elem, const Plib::Package *pkg)
Definition: itemdesc.cpp:866
bool FileExists(const char *filename)
Definition: fileutil.cpp:118
Core::ScriptDef control_script
Definition: itemdesc.h:100
bool read(ConfigElem &elem)
Definition: cfgfile.cpp:1015
const ContainerDesc & find_container_desc(u32 objtype)
Definition: itemdesc.cpp:942
bool load(const char *dice, std::string *errormsg)
Definition: dice.cpp:42
unsigned int vendor_buys_for
Definition: itemdesc.h:106
enum Pol::Items::ItemDesc::Movable movable
const char * type() const
Definition: cfgfile.cpp:66
void set_rest(const char *newrest)
Definition: cfgfile.cpp:76
virtual void PopulateStruct(Bscript::BStruct *descriptor) const POL_OVERRIDE
Definition: itemdesc.cpp:785
bool default_movable() const
Definition: itemdesc.cpp:690
bool has_itemdesc(u32 objtype)
Definition: itemdesc.cpp:895
virtual size_t estimatedSize() const POL_OVERRIDE
Definition: itemdesc.cpp:875
Definition: berror.cpp:12
MapDesc(u32 objtype, Clib::ConfigElem &elem, const Plib::Package *pkg)
Definition: itemdesc.cpp:880
virtual const char * typeOf() const
Definition: object.cpp:257
Core::ScriptDef create_script
Definition: itemdesc.h:101
virtual void PopulateStruct(Bscript::BStruct *descriptor) const POL_OVERRIDE
Definition: itemdesc.cpp:857
std::atomic< bool > exit_signalled
bool can_use_while_paralyzed
Definition: itemdesc.h:117
BoatDesc(u32 objtype, Clib::ConfigElem &elem, const Plib::Package *pkg)
Definition: itemdesc.cpp:852
const std::string & dir() const
Definition: pkg.h:79
ItemDesc(u32 objtype, Clib::ConfigElem &elem, Type type, const Plib::Package *pkg)
Definition: itemdesc.cpp:165
unsigned int max_objtype
Definition: polcfg.h:62
virtual size_t estimatedSize() const POL_OVERRIDE
Definition: itemdesc.cpp:812
static ItemDesc * create(Clib::ConfigElem &elem, const Plib::Package *pkg)
Definition: itemdesc.cpp:97