Pol  Revision:cb584c9
itemcr.cpp
Go to the documentation of this file.
1 
12 #include <stddef.h>
13 #include <string>
14 
15 #include <format/format.h>
16 #include "../../clib/clib_endian.h"
17 #include "../../clib/logfacility.h"
18 #include "../../clib/passert.h"
19 #include "../../clib/rawtypes.h"
20 #include "../../plib/systemstate.h"
21 #include "../baseobject.h"
22 #include "../clidata.h"
23 #include "../containr.h"
24 #include "../door.h"
25 #include "../extobj.h"
26 #include "../globals/object_storage.h"
27 #include "../globals/settings.h"
28 #include "../globals/uvars.h"
29 #include "../lockable.h"
30 #include "../mobile/corpse.h"
31 #include "../module/uomod.h"
32 #include "../multi/boatcomp.h"
33 #include "../objtype.h"
34 #include "../polcfg.h"
35 #include "../resource.h"
36 #include "../scrdef.h"
37 #include "../scrsched.h"
38 #include "../spelbook.h"
39 #include "../ufunc.h"
40 #include "../umap.h"
41 #include "../uobject.h"
42 #include "armor.h"
43 #include "armrtmpl.h"
44 #include "item.h"
45 #include "itemdesc.h"
46 #include "weapon.h"
47 #include "wepntmpl.h"
48 
49 namespace Pol
50 {
51 namespace Items
52 {
53 Item* Item::create( u32 objtype, u32 serial )
54 {
55  const ItemDesc& id = find_itemdesc( objtype );
56  if ( &id != Core::gamestate.empty_itemdesc.get() )
57  {
58  return create( id, serial );
59  }
60  else if ( objtype <= Plib::systemstate.config.max_tile_id )
61  {
62  Core::gamestate.temp_itemdesc->objtype = objtype;
63  Core::gamestate.temp_itemdesc->graphic = static_cast<u16>( objtype );
64  return create( *( Core::gamestate.temp_itemdesc.get() ), serial );
65  }
66  else
67  {
68  fmt::Writer message;
69  message.Format( "Objtype not defined : 0x{:X}" ) << objtype;
70 
71  if ( !Plib::systemstate.config.ignore_load_errors )
72  throw std::runtime_error( message.str() );
73  else
74  {
75  ERROR_PRINT << message.str() << "\n";
76  return nullptr;
77  }
78  }
79 }
80 
82 {
83  u32 objtype = id.objtype;
84  unsigned short graphic = id.graphic;
85 
86  Item* item;
87  // FIXME looks like a place for a bunch of function pointers if I ever saw one.
88  if ( id.type == ItemDesc::DOORDESC )
89  {
90  item = new Core::UDoor( static_cast<const DoorDesc&>( id ) );
91  }
92  else if ( id.type == ItemDesc::BOATDESC )
93  {
94  // still created with create_multi
95  return nullptr;
96  }
97  else if ( id.type == ItemDesc::HOUSEDESC )
98  {
99  // still created with create_multi
100  return nullptr;
101  }
102  else if ( ( objtype >= Core::gamestate.spell_scroll_objtype_limits[0][0] &&
103  objtype <= Core::gamestate.spell_scroll_objtype_limits[0][1] ) ||
104  ( objtype >= Core::gamestate.spell_scroll_objtype_limits[1][0] &&
105  objtype <= Core::gamestate.spell_scroll_objtype_limits[1][1] ) ||
106  ( objtype >= Core::gamestate.spell_scroll_objtype_limits[2][0] &&
107  objtype <= Core::gamestate.spell_scroll_objtype_limits[2][1] ) )
108  {
109  item = new Core::USpellScroll( id );
110  }
111  else if ( objtype == UOBJ_CORPSE ) // ITEMDESCTODO make new ItemDesc type
112  {
113  item = new Core::UCorpse( static_cast<const ContainerDesc&>( id ) );
114  }
115  else if ( id.type == ItemDesc::SPELLBOOKDESC ) // ITEMDESCTODO make new ItemDesc type
116  {
117  item = new Core::Spellbook( static_cast<const SpellbookDesc&>( id ) );
118  }
119  else if ( id.type == ItemDesc::CONTAINERDESC )
120  {
121  item = new Core::UContainer( static_cast<const ContainerDesc&>( id ) );
122  }
123  else if ( id.type == ItemDesc::WEAPONDESC )
124  {
125  // we call find_itemdesc here because the item descriptor passed in may not
126  // be the "real" one - it may be a temporary descriptor.
127  const WeaponDesc* permanent_descriptor =
128  static_cast<const WeaponDesc*>( &find_itemdesc( objtype ) );
129  item = new UWeapon( static_cast<const WeaponDesc&>( id ), permanent_descriptor );
130  }
131  else if ( id.type == ItemDesc::ARMORDESC )
132  {
133  const ArmorDesc* permanent_descriptor =
134  static_cast<const ArmorDesc*>( &find_itemdesc( objtype ) );
135  item = new UArmor( static_cast<const ArmorDesc&>( id ), permanent_descriptor );
136  }
137  else if ( id.type == ItemDesc::MAPDESC ) // (graphic >= UOBJ_MAP1 && graphic <= UOBJ_ROLLED_MAP2)
138  {
139  item = new Core::Map( static_cast<const MapDesc&>( id ) );
140  }
141  else if ( objtype == Core::settingsManager.extobj.port_plank ||
142  objtype == Core::settingsManager.extobj
143  .starboard_plank ) // ITEMDESCTODO make new ItemDesc type
144  {
145  item = new Multi::UPlank( id );
146  }
147  else if ( objtype_is_lockable( objtype ) )
148  {
150  }
151  else
152  {
153  item = new Item( id, Core::UOBJ_CLASS::CLASS_ITEM );
154  }
155 
156  // 12-17-2008 MuadDib added for reading the tilelayer at all times while retaining item.layer
157  // useage.
158  item->tile_layer = Core::tilelayer( graphic );
159 
160  // Have to be set after the item is created, because item graphic changes
161  // Because items can have facing 0 as the lightsource we use as default 127 to check
162  if ( item->facing == 127 )
163  item->facing = item->tile_layer;
164 
165  if ( serial )
166  {
167  item->serial = Core::UseItemSerialNumber( serial );
168  item->clear_dirty();
169  }
170  else if ( !find_itemdesc( objtype ).save_on_exit ) // get the real itemdesc
171  {
172  item->set_dirty();
173 
175  }
176  else // creating something new
177  {
178  item->set_dirty();
179  remove_resources( objtype, 1 );
181  }
182 
186 
187  item->serial_ext = ctBEu32( item->serial );
188 
189  item->restart_decay_timer();
190 
191  item->graphic = graphic;
192 
193  // If item already has a serial (eg. an existing item loaded from a save),
194  // then do not assign CProps from descriptor
195  if ( !serial )
196  item->copyprops( id.props );
197 
198 #ifdef PERGON
199  std::string value_self;
200  if ( !item->getprop( "ct", value_self ) ) // Pergon: Check if Prop still exist - prevents
201  // Overwrite on Server-Restart
202  item->setprop(
203  "ct",
204  "i" + Clib::decint(
205  Core::read_gameclock() ) ); // Pergon: Init Property CreateTime for a new Item
206 #endif
207 
208  if ( !id.control_script.empty() )
209  {
210  passert( item->process() == nullptr );
211 
212  Module::UOExecutorModule* uoemod = start_script( id.control_script, item->make_ref() );
213  if ( uoemod )
214  {
215  uoemod->attached_item_ = item;
216  item->process( uoemod );
217  }
218  else
219  {
220  POLLOG << "Unable to start control script " << id.control_script.name() << " for "
221  << id.objtype_description() << "\n";
222  }
223  }
224 
225  for ( unsigned element = 0; element <= Core::ELEMENTAL_TYPE_MAX; ++element )
226  {
227  switch ( element )
228  {
230  item->fire_resist( item->fire_resist().addToValue( id.element_resist.fire ) );
231  item->fire_damage( item->fire_damage().addToValue( id.element_damage.fire ) );
232  break;
234  item->cold_resist( item->cold_resist().addToValue( id.element_resist.cold ) );
235  item->cold_damage( item->cold_damage().addToValue( id.element_damage.cold ) );
236  break;
238  item->energy_resist( item->energy_resist().addToValue( id.element_resist.energy ) );
239  item->energy_damage( item->energy_damage().addToValue( id.element_damage.energy ) );
240  break;
242  item->poison_resist( item->poison_resist().addToValue( id.element_resist.poison ) );
243  item->poison_damage( item->poison_damage().addToValue( id.element_damage.poison ) );
244  break;
246  item->physical_resist( item->physical_resist().addToValue( id.element_resist.physical ) );
247  item->physical_damage( item->physical_damage().addToValue( id.element_damage.physical ) );
248  break;
249  }
250  }
251 
252  // if ItemDesc is a dynamic one desc could differ and would be lost
253  const ItemDesc& origid = find_itemdesc( item->objtype_ );
254  if ( id.desc != origid.desc )
255  item->setname( id.desc );
256 
257  return item;
258 }
259 }
260 }
static Item * create(u32 objtype, u32 serial=0)
Definition: itemcr.cpp:53
virtual Bscript::BObjectImp * make_ref() POL_OVERRIDE
Definition: uoscrobj.cpp:1628
ExternalObject extobj
Definition: settings.h:30
SystemState systemstate
Definition: systemstate.cpp:12
void setprop(const std::string &propname, const std::string &propvalue)
Definition: uobject.cpp:160
unsigned char tilelayer(unsigned short tilenum)
Definition: polfile2.cpp:22
std::string decint(unsigned short v)
Definition: strutil.cpp:64
const ItemDesc & find_itemdesc(unsigned int objtype)
Definition: itemdesc.cpp:933
std::unique_ptr< Items::ItemDesc > temp_itemdesc
Definition: uvars.h:209
void set_dirty()
Definition: uobject.h:291
unsigned short u16
Definition: rawtypes.h:26
unsigned int u32
Definition: rawtypes.h:27
bool getprop(const std::string &propname, std::string &propvalue) const
Definition: uobject.cpp:155
unsigned int starboard_plank
Definition: extobj.h:20
Item(const ItemDesc &itemdesc, Core::UOBJ_CLASS uobj_class)
Definition: item00.cpp:25
u32 GetNewItemSerialNumber(void)
Definition: ufunc.cpp:142
boost_utils::object_name_flystring desc
Definition: itemdesc.h:94
#define UOBJ_CORPSE
Definition: objtype.h:218
u32 UseItemSerialNumber(u32 serial)
Definition: ufunc.cpp:134
#define passert(exp)
Definition: passert.h:62
#define POLLOG
Definition: logfacility.h:219
gameclock_t read_gameclock()
Reads the current value of the game clock.
Definition: gameclck.cpp:57
const u32 objtype_
Definition: uobject.h:249
void setname(const std::string &)
Definition: uobject.cpp:206
GameState gamestate
Definition: uvars.cpp:74
void remove_resources(u32 objtype, u16)
Definition: itemdesc.cpp:1223
#define ctBEu32(x)
Definition: clib_endian.h:45
SettingsManager settingsManager
Definition: settings.cpp:14
bool Insert(UObject *obj)
Definition: objecthash.cpp:30
void restart_decay_timer()
Definition: item.cpp:974
void clear_dirty() const
Definition: uobject.cpp:146
ObjectStorageManager objStorageManager
bool objtype_is_lockable(u32 objtype)
Definition: itemdesc.cpp:900
#define ERROR_PRINT
Definition: logfacility.h:230
void start_script(const char *filename, Bscript::BObjectImp *param0, Bscript::BObjectImp *param1)
Definition: scrsched.cpp:150
Definition: berror.cpp:12
void copyprops(const UObject &obj)
Definition: uobject.cpp:174