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" 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" 52 #include <format/format.h> 64 return ( *itr ).second;
70 const char* ot_str = str.c_str();
71 if ( isdigit( *ot_str ) )
73 objtype =
static_cast<u32>( strtoul( ot_str,
nullptr, 0 ) );
80 throw std::runtime_error(
"Can't convert " + str +
" to an objtype" );
91 ERROR_PRINT <<
"itemdesc.cfg: Resource '" << rname <<
"' not found\n";
92 throw std::runtime_error(
"Configuration error" );
99 u32 objtype =
static_cast<u32>( strtoul( elem.
rest(),
nullptr, 0 ) );
102 elem.
throw_error(
"Element must have objtype specified" );
108 "Objtype is defined as an OldObjtype of " +
114 if ( elem.
type_is(
"Container" ) )
118 else if ( elem.
type_is(
"Item" ) )
122 else if ( elem.
type_is(
"Door" ) )
124 descriptor =
new DoorDesc( objtype, elem, pkg );
126 else if ( elem.
type_is(
"Weapon" ) )
130 descriptor =
new WeaponDesc( objtype, elem, pkg );
132 else if ( elem.
type_is(
"Armor" ) )
136 descriptor =
new ArmorDesc( objtype, elem, pkg, forceShield );
138 else if ( elem.
type_is(
"Boat" ) )
140 descriptor =
new BoatDesc( objtype, elem, pkg );
142 else if ( elem.
type_is(
"House" ) )
144 descriptor =
new HouseDesc( objtype, elem, pkg );
146 else if ( elem.
type_is(
"Spellbook" ) )
150 else if ( elem.
type_is(
"SpellScroll" ) )
154 else if ( elem.
type_is(
"Map" ) )
156 descriptor =
new MapDesc( objtype, elem, pkg );
160 elem.
throw_error( std::string(
"Unexpected element type: " ) + elem.
type() );
169 graphic( elem.remove_ushort(
"GRAPHIC", 0 ) ),
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 ) ),
187 elem.remove_ulong(
"DECAYTIME", Core::
settingsManager.ssopt.default_decay_time ) ),
189 doubleclick_range( elem.remove_ushort(
190 "DoubleclickRange", Core::
settingsManager.ssopt.default_doubleclick_range ) ),
191 use_requires_los( elem.remove_bool(
"UseRequiresLOS", true ) ),
192 ghosts_can_use( elem.remove_bool(
"GhostsCanUse", false ) ),
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 ) ),
204 method_script( nullptr ),
205 save_on_exit( elem.remove_bool(
"SaveOnExit", true ) )
213 ERROR_PRINT <<
"Itemdesc has no 'multiid' specified for a multi.\n" 214 <<
" Note: read corechanges.txt for the new multi format\n";
228 ERROR_PRINT <<
"Itemdesc has no 'graphic' specified, and no 'objtype' is valid either.\n";
239 ERROR_PRINT.Format(
"itemdesc.cfg, objtype 0x{:X} has no MaxHP specified." ) <<
objtype;
255 unsigned short in_movable;
261 std::string weight_str;
264 const char* s = weight_str.c_str();
267 s =
static_cast<const char*
>( endptr );
268 while ( *s && isspace( *s ) )
276 elem.
throw_error(
"Poorly formed weight directive: " + weight_str );
279 else if ( *s ==
'\0' )
285 elem.
throw_error(
"Poorly formed weight directive: " + weight_str );
300 if ( is >> rname >> amount )
306 ERROR_PRINT.Format(
"itemdesc.cfg, objtype 0x{:X} : Resource '{}' is malformed.\n" )
308 throw std::runtime_error(
"Configuration file error" );
317 "Warning! objtype 0x{:X} : ObjtypeName '{}' is the same as objtype {:#X}\n" )
346 if ( pkg ==
nullptr )
347 throw std::runtime_error(
"MethodScripts can only be specified in a package" );
358 unsigned int old_objtype;
359 while ( elem.
remove_prop(
"OldObjtype", &old_objtype ) )
364 Clib::hexint( old_objtype ) +
" which is already mapped to " +
372 " which is already defined as " +
378 if ( elem.
remove_prop(
"StackingIgnoresCProps", &temp ) )
381 std::string cprop_name;
382 while ( is >> cprop_name )
410 passed = elem.
remove_prop(
"PHYSICALRESIST", &tmp );
418 if ( !dice.
load( tmp.c_str(), &errmsg ) )
420 ERROR_PRINT <<
"Error loading itemdesc.cfg Elemental Resistances for " 422 throw std::runtime_error(
"Error loading Item Elemental Resistances" );
465 passed = elem.
remove_prop(
"PHYSICALDAMAGE", &tmp );
473 if ( !dice.
load( tmp.c_str(), &errmsg ) )
476 <<
" : " << errmsg <<
"\n";
477 throw std::runtime_error(
"Error loading Item Elemental Damages" );
554 using namespace Bscript;
562 typestr =
"Container";
580 typestr =
"Spellbook";
583 typestr =
"Spellscroll";
643 std::set<std::string>::const_iterator set_itr;
644 std::unique_ptr<ObjArray> ignorecp(
new ObjArray );
646 ignorecp->addElement(
new String( *set_itr ) );
648 descriptor->
addMember(
"StackingIgnoresCProps", ignorecp.release() );
651 std::vector<std::string> propnames;
652 std::vector<std::string>::const_iterator vec_itr;
655 for ( vec_itr = propnames.begin(); vec_itr != propnames.end(); ++vec_itr )
661 descriptor->
addMember(
"CProps", cpropdict );
664 std::vector<ResourceComponent>::const_iterator resource_itr;
665 for ( resource_itr =
resources.begin(); resource_itr !=
resources.end(); ++resource_itr )
667 descriptor->
addMember(
"Resource",
new String( resource_itr->rd->name() +
" " +
685 tmp <<
":" <<
pkg->
name() <<
":";
705 size += 3 *
sizeof(
void* );
708 size += ignore.capacity() + 3 *
sizeof(
void* );
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",
722 max_items( elem.remove_ushort(
"MAXITEMS",
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/" )
745 using namespace Bscript;
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 ) )
801 :
ContainerDesc( objtype, elem, pkg ), spelltype( elem.remove_string(
"SPELLTYPE" ) )
819 spelltype( elem.remove_string(
"SPELLTYPE" ) )
835 :
ItemDesc( objtype, elem, type, pkg )
881 :
ItemDesc( objtype, elem,
MAPDESC, pkg ), editable( elem.remove_bool(
"EDITABLE", true ) )
924 throw std::runtime_error(
"Objtype " +
Clib::hexint( objtype ) +
" must define a graphic" );
937 return *( obj->second );
947 " should be defined as container or spellbook, but is not" );
972 Bscript::BStruct::Contents::const_iterator itr;
973 for ( itr = struct_cont.begin(); itr != struct_cont.end(); ++itr )
975 const std::string& key = ( *itr ).first;
978 if ( key ==
"CProps" )
984 Bscript::BDictionary::Contents::const_iterator ditr;
985 for ( ditr = cprop_cont.begin(); ditr != cprop_cont.end(); ++ditr )
987 elem.
add_prop(
"cprop", ( ( *ditr ).first->getStringRep() +
"\t" +
988 ( *ditr ).second->impptr()->pack() ) );
993 throw std::runtime_error(
"CreateItemDescriptor: CProps must be a dictionary, but is: " +
994 std::string( val_imp->
typeOf() ) );
997 else if ( key ==
"StackingIgnoresCProps" )
1005 Bscript::ObjArray::Cont::const_iterator aitr;
1006 for ( aitr = conts.begin(); aitr != conts.end(); ++aitr )
1008 os << ( *aitr ).get()->impptr()->getStringRep() <<
" ";
1014 throw std::runtime_error(
1015 "CreateItemDescriptor: StackingIgnoresCProps must be an array, but is: " +
1016 std::string( val_imp->
typeOf() ) );
1019 else if ( key ==
"Coverage" )
1026 Bscript::ObjArray::Cont::const_iterator aitr;
1027 for ( aitr = conts.begin(); aitr != conts.end(); ++aitr )
1030 os << ( *aitr ).get()->impptr()->getStringRep();
1036 throw std::runtime_error(
"CreateItemDescriptor: Coverage must be an array, but is: " +
1037 std::string( val_imp->
typeOf() ) );
1040 else if ( key ==
"ObjClass" )
1045 else if ( key ==
"ObjType" )
1063 elem.
add_prop( key, std::move(value) );
1067 unsigned int objtype =
static_cast<unsigned int>( strtoul( elem.
rest(),
nullptr, 0 ) );
1087 "CONTAINER ITEM DOOR WEAPON ARMOR BOAT HOUSE SPELLBOOK SPELLSCROLL MAP" );
1090 while ( cf.
read( elem ) )
1105 tmp.Format(
"Error: Objtype 0x{:X} is already defined in" ) << descriptor->
objtype;
1107 tmp <<
"config/itemdesc.cfg\n";
1113 " defined more than once." );
1134 std::ofstream ofs(
"objtypes.txt" );
1135 unsigned int last_objtype = 0;
1138 const ItemDesc* itemdesc = elem.second;
1139 unsigned int i = elem.first;
1141 if ( i != last_objtype + 1 )
1143 unsigned int first = last_objtype + 1;
1144 unsigned int last = i - 1;
1145 if ( first == last )
1162 if ( itemdesc->
pkg )
1163 ofs <<
" " << itemdesc->
pkg->
name();
1177 unsigned int first = last_objtype + 1;
1179 if ( first == last )
1228 rc.rd->consume( rc.amount );
1242 rc.rd->produce( rc.amount );
virtual void PopulateStruct(Bscript::BStruct *descriptor) const POL_OVERRIDE
unsigned short doubleclick_range
unsigned int tile_flags(unsigned short tilenum)
MultiDesc(u32 objtype, Clib::ConfigElem &elem, Type type, const Plib::Package *pkg)
unsigned short stack_limit
virtual std::string getStringRep() const =0
Core::ExportScript * method_script
std::string objtype_description() const
unsigned int get_objtype_byname(const char *str)
virtual size_t estimatedSize() const POL_OVERRIDE
std::vector< Items::ItemDesc * > dynamic_item_descriptors
const std::string & scriptname() const
void return_resources(u32 objtype, u16)
SpellbookDesc(u32 objtype, Clib::ConfigElem &elem, const Plib::Package *pkg)
unsigned short roll(void) const
bool isa(BObjectType type) const
Core::ScriptDef on_remove_script
virtual size_t estimatedSize() const POL_OVERRIDE
std::map< std::string, BObjectRef, Clib::ci_cmp_pred > Contents
std::set< std::string > ignore_cprops
std::string decint(unsigned short v)
unsigned short base_str_req
size_t estimatedSize() const
const Contents & contents() const
virtual size_t estimatedSize() const
unsigned int vendor_sells_for
std::string relativename(const Plib::Package *pkg=nullptr) const
void load_package_itemdesc(Plib::Package *pkg)
size_t estimatedSize() const
unsigned short getcolor(unsigned int objtype)
#define OSTRINGSTREAM_STR(x)
void read_itemdesc_file(const char *filename, Plib::Package *pkg=nullptr)
std::vector< ResourceComponent > resources
bool blocks_casting_if_in_hand
void addMember(const char *name, BObjectRef val)
const std::string & name() const
const ItemDesc & find_itemdesc(unsigned int objtype)
bool can_use_while_frozen
virtual void PopulateStruct(Bscript::BStruct *descriptor) const POL_OVERRIDE
Core::ScriptDef on_insert_script
Core::ElementDamages element_damage
DoorDesc(u32 objtype, Clib::ConfigElem &elem, const Plib::Package *pkg)
#define passert_r(exp, reason)
Core::ScriptDef on_use_script
virtual void PopulateStruct(Bscript::BStruct *descriptor) const POL_OVERRIDE
std::string hexint(unsigned short v)
unsigned short getgraphic(u32 objtype)
std::unique_ptr< Items::ItemDesc > empty_itemdesc
const char * rest() const
#define PKTOUT_B7_MAX_CHARACTERS
Core::ScriptDef destroy_script
virtual void PopulateStruct(Bscript::BStruct *descriptor) const POL_OVERRIDE
POL_NORETURN void throw_error(const std::string &errmsg) const
const Plib::Package * pkg
virtual size_t estimatedSize() const POL_OVERRIDE
unsigned int get_objtype_from_string(const std::string &str)
void set_type(const char *newtype)
boost_utils::script_name_flystring equip_script
Core::ScriptDef walk_on_script
void add_prop(std::string propname, std::string propval)
boost_utils::object_name_flystring desc
Core::ScriptDef can_insert_script
std::map< BObject, BObjectRef > Contents
std::vector< BObjectRef > Cont
ResourceDef * find_resource_def(const std::string &rname)
boost_utils::script_name_flystring unequip_script
void readProperties(Clib::ConfigElem &elem)
static BObjectImp * unpack(const char *pstr)
virtual size_t estimatedSize() const POL_OVERRIDE
void remove_resources(u32 objtype, u16)
void getpropnames(std::vector< std::string > &propnames) const
ContainerDesc(u32 objtype, Clib::ConfigElem &elem, const Plib::Package *pkg)
Core::Resistances element_resist
SettingsManager settingsManager
bool remove_prop(const char *propname, std::string *value)
bool MultiDefByMultiIDExists(u16 multiid)
virtual void PopulateStruct(Bscript::BStruct *descriptor) const
const MultiDesc & find_multidesc(u32 objtype)
virtual size_t estimatedSize() const POL_OVERRIDE
const Contents & contents() const
bool type_is(const char *name) const
ObjtypeByNameMap objtype_byname
const ItemDesc * CreateItemDescriptor(Bscript::BStruct *itemdesc_struct)
Core::ScriptDef can_remove_script
std::string strlower(const std::string &str)
ResourceComponent(const std::string &rname, unsigned amount)
OldObjtypeConversions old_objtype_conversions
unsigned short remove_ushort(const char *propname)
bool getprop(const std::string &propname, std::string &propvalue) const
bool objtype_is_lockable(u32 objtype)
unsigned short tileweight(unsigned short tilenum)
const DoorDesc & fast_find_doordesc(u32 objtype)
std::string GetPackageCfgPath(const Package *pkg, const std::string &filename)
virtual void PopulateStruct(Bscript::BStruct *descriptor) const POL_OVERRIDE
void set_source(const ConfigElem &elem)
std::map< u32, Items::ItemDesc * > desctable
void write_objtypes_txt()
HouseDesc(u32 objtype, Clib::ConfigElem &elem, const Plib::Package *pkg)
bool FileExists(const char *filename)
Core::ScriptDef control_script
bool read(ConfigElem &elem)
const ContainerDesc & find_container_desc(u32 objtype)
bool load(const char *dice, std::string *errormsg)
unsigned int vendor_buys_for
enum Pol::Items::ItemDesc::Movable movable
const char * type() const
void set_rest(const char *newrest)
virtual void PopulateStruct(Bscript::BStruct *descriptor) const POL_OVERRIDE
bool default_movable() const
bool has_itemdesc(u32 objtype)
virtual size_t estimatedSize() const POL_OVERRIDE
MapDesc(u32 objtype, Clib::ConfigElem &elem, const Plib::Package *pkg)
virtual const char * typeOf() const
Core::ScriptDef create_script
virtual void PopulateStruct(Bscript::BStruct *descriptor) const POL_OVERRIDE
std::atomic< bool > exit_signalled
bool can_use_while_paralyzed
BoatDesc(u32 objtype, Clib::ConfigElem &elem, const Plib::Package *pkg)
const std::string & dir() const
ItemDesc(u32 objtype, Clib::ConfigElem &elem, Type type, const Plib::Package *pkg)
virtual size_t estimatedSize() const POL_OVERRIDE
static ItemDesc * create(Clib::ConfigElem &elem, const Plib::Package *pkg)