Pol  Revision:cb584c9
loaddata.cpp
Go to the documentation of this file.
1 
11 #include <stddef.h>
12 #include <string>
13 
14 #include "../clib/cfgelem.h"
15 #include "../clib/cfgfile.h"
16 #include "../clib/fileutil.h"
17 #include "../clib/logfacility.h"
18 #include "../clib/rawtypes.h"
19 #include "../clib/strutil.h"
20 #include "../clib/timer.h"
21 #include "../plib/systemstate.h"
22 #include "clidata.h"
23 #include "containr.h"
24 #include "fnsearch.h"
25 #include "globals/object_storage.h"
26 #include "globals/state.h"
27 #include "item/item.h"
28 #include "loaddata.h"
29 #include "mobile/charactr.h"
30 #include "objecthash.h"
31 #include "polclass.h"
32 #include "spelbook.h"
33 #include "uobject.h"
34 
35 namespace Pol
36 {
37 namespace Core
38 {
39 void load_incremental_indexes() // indices is such a stupid word
40 {
41  for ( ;; )
42  {
43  unsigned next_incremental_counter = objStorageManager.incremental_save_count + 1;
44  std::string filename = Plib::systemstate.config.world_data_path + "incr-index-" +
45  Clib::decint( next_incremental_counter ) + ".txt";
46  if ( !Clib::FileExists( filename ) )
47  break;
48 
50  Clib::ConfigFile cf( filename, "MODIFIED DELETED" );
51  Clib::ConfigElem elem;
52  while ( cf.read( elem ) )
53  {
54  unsigned index;
55  if ( elem.type_is( "Modified" ) )
57  else
58  index = UINT_MAX;
59 
60  std::string name, value;
61  while ( elem.remove_first_prop( &name, &value ) )
62  {
63  pol_serial_t serial = strtoul( name.c_str(), nullptr, 0 );
65  }
66  }
67  }
68 }
69 
70 unsigned get_save_index( pol_serial_t serial )
71 {
72  SerialIndexMap::iterator itr = objStorageManager.incremental_serial_index.find( serial );
74  return ( *itr ).second;
75  else
76  return 0;
77 }
78 
80 {
81  for ( unsigned i = 1; i <= objStorageManager.incremental_save_count; ++i )
82  {
83  std::string filename =
84  Plib::systemstate.config.world_data_path + "incr-data-" + Clib::decint( i ) + ".txt";
86 
87  slurp( filename.c_str(), "CHARACTER NPC ITEM GLOBALPROPERTIES SYSTEM MULTI STORAGEAREA" );
88  }
89 }
90 
92 {
93  // we have to store the deleted serials as 'clean deletes' so that we don't start
94  // creating objects with the same serials.
95  // after a full save, these will be cleared.
96  for ( SerialIndexMap::const_iterator citr = objStorageManager.incremental_serial_index.begin();
97  citr != objStorageManager.incremental_serial_index.end(); ++citr )
98  {
99  pol_serial_t serial = ( *citr ).first;
100  unsigned index = ( *citr ).second;
101  if ( index == UINT_MAX )
103  }
104 }
105 
107 {
109 }
110 
111 
112 void defer_item_insertion( Items::Item* item, pol_serial_t container_serial )
113 {
114  objStorageManager.deferred_insertions.insert( std::make_pair( container_serial, item ) );
115 }
116 
118 {
120  return;
121 
122  int num_until_dot = 1000;
123  unsigned int nobjects = 0;
124  Tools::Timer<> timer;
125 
126  INFO_PRINT << " deferred inserts:";
127 
128  for ( DeferList::iterator itr = objStorageManager.deferred_insertions.begin();
129  itr != objStorageManager.deferred_insertions.end(); ++itr )
130  {
131  if ( --num_until_dot == 0 )
132  {
133  INFO_PRINT << ".";
134  num_until_dot = 1000;
135  }
136 
137  pol_serial_t container_serial = ( *itr ).first;
138  UObject* obj = ( *itr ).second;
139 
140  if ( IsCharacter( container_serial ) )
141  {
142  Mobile::Character* chr = system_find_mobile( container_serial );
143  Items::Item* item = static_cast<Items::Item*>( obj );
144  if ( chr != nullptr )
145  {
146  equip_loaded_item( chr, item );
147  }
148  else
149  {
150  ERROR_PRINT.Format(
151  "Item 0x{:X} is supposed to be on Character 0x{:X}, but that character cannot be "
152  "found.\n" )
153  << item->serial << container_serial;
154 
155  // Austin - Aug. 10, 2006
156  // Removes the object if ignore_load_errors is enabled and the character can't be found.
157  if ( !Plib::systemstate.config.ignore_load_errors )
158  throw std::runtime_error( "Data file integrity error" );
159  else
160  {
161  ERROR_PRINT << "Ignore load errors enabled. Removing object.\n";
162  obj->destroy();
163  }
164  }
165  }
166  else
167  {
168  Items::Item* cont_item = system_find_item( container_serial );
169  Items::Item* item = static_cast<Items::Item*>( obj );
170  if ( cont_item != nullptr )
171  {
172  add_loaded_item( cont_item, item );
173  }
174  else
175  {
176  ERROR_PRINT << "Item 0x" << fmt::hexu( item->serial )
177  << " is supposed to be in container 0x" << fmt::hexu( container_serial )
178  << ", but that container cannot be found.\n";
179 
180  // Austin - Aug. 10, 2006
181  // Removes the object if ignore_load_errors is enabled and the character can't be found.
182  if ( !Plib::systemstate.config.ignore_load_errors )
183  throw std::runtime_error( "Data file integrity error" );
184  else
185  {
186  ERROR_PRINT << "Ignore load errors enabled. Removing object.\n";
187  obj->destroy();
188  }
189  }
190  }
191  ++nobjects;
192  }
193  timer.stop();
194  INFO_PRINT << " " << nobjects << " elements in " << timer.ellapsed() << " ms.\n";
195 
197 }
198 
200 {
201  item->layer = tilelayer( item->graphic ); // adjust for tiledata changes
202  item->tile_layer = item->layer; // adjust for tiledata changes
203 
204  if ( chr->equippable( item ) && item->check_equiptest_scripts( chr, true ) &&
205  item->check_equip_script( chr, true ) &&
206  !item->orphan() ) // dave added 1/28/3, item might be destroyed in RTC script
207  {
208  chr->equip( item );
209  item->clear_dirty(); // equipping sets dirty
210  return;
211  }
212  else
213  {
214  ERROR_PRINT << "Item 0x" << fmt::hexu( item->serial )
215  << " is supposed to be equipped on Character " << fmt::hexu( chr->serial )
216  << ", but is not 'equippable' on that character.\n";
217  UContainer* bp = chr->backpack();
218  if ( bp )
219  {
221  bool canadd = bp->can_add( *item );
222  u8 slotIndex = item->slot_index();
223  bool add_to_slot = bp->can_add_to_slot( slotIndex );
224  if ( canadd && add_to_slot && item->slot_index( slotIndex ) )
225  {
226  bp->add_at_random_location( item );
227  // leaving dirty
229  ERROR_PRINT << "I'm so cool, I put it in the character's backpack!\n";
230  return;
231  }
232  else
233  {
235  ERROR_PRINT << "Tried to put it in the character's backpack, "
236  << "but it wouldn't fit.\n";
237  }
238  }
239  else
240  {
241  ERROR_PRINT << "Tried to put it in the character's backpack, "
242  << "but there isn't one. That's naughty...\n";
243  }
244  throw std::runtime_error( "Data file integrity error" );
245  }
246 }
247 
248 void add_loaded_item( Items::Item* cont_item, Items::Item* item )
249 {
250  if ( cont_item->isa( UOBJ_CLASS::CLASS_CONTAINER ) )
251  {
252  UContainer* cont = static_cast<UContainer*>( cont_item );
253 
254  // Convert spellbook to use bitwise system, not scrolls.
255  if ( cont->script_isa( POLCLASS_SPELLBOOK ) )
256  {
257  // if can't add, means spell already there.
258  if ( !cont->can_add( *item ) )
259  {
260  item->destroy();
261  return;
262  }
263  // this is an oldschool book, oldschool contents. We need to create the bitwise
264  // and handle for the first time before destroying the scrolls.
265  Spellbook* book = static_cast<Spellbook*>( cont );
266 
267  u16 spellnum =
269  u8 spellslot = spellnum & 7;
270  if ( spellslot == 0 )
271  spellslot = 8;
272  book->bitwise_contents[( spellnum - 1 ) >> 3] |= 1 << ( spellslot - 1 );
273  item->destroy();
274  return;
275  }
276 
278  bool canadd = cont->can_add( *item );
279  u8 slotIndex = item->slot_index();
280  bool add_to_slot = cont->can_add_to_slot( slotIndex );
281  if ( !canadd )
282  {
283  ERROR_PRINT << "Can't add Item 0x" << fmt::hexu( item->serial ) << " to container 0x"
284  << fmt::hexu( cont->serial ) << "\n";
285  throw std::runtime_error( "Data file error" );
286  }
287 
288  if ( !add_to_slot || !item->slot_index( slotIndex ) )
289  {
290  ERROR_PRINT << "Can't add Item 0x" << fmt::hexu( item->serial ) << " to container 0x"
291  << fmt::hexu( cont->serial ) << " at slot 0x" << fmt::hexu( slotIndex ) << "\n";
292  throw std::runtime_error( "Data file error" );
293  }
294 
295  cont->add( item );
296  item->clear_dirty(); // adding sets dirty
297 
299 
300  // if (new_parent_cont)
301  // parent_conts.push( cont );
302  // if (item->isa( UObject::CLASS_CONTAINER ))
303  // parent_conts.push( static_cast<UContainer*>(item) );
304  }
305  else
306  {
307  INFO_PRINT << "Container type 0x" << fmt::hexu( cont_item->objtype_ )
308  << " contains items, but is not a container class\n";
309  throw std::runtime_error( "Config file error" );
310  }
311 }
312 }
313 }
unsigned char u8
Definition: rawtypes.h:25
bool remove_first_prop(std::string *propname, std::string *value)
Definition: cfgfile.cpp:100
bool can_add_to_slot(u8 &slotIndex)
Definition: containr.cpp:178
u8 bitwise_contents[8]
Definition: spelbook.h:61
virtual bool can_add(const Items::Item &item) const
Definition: containr.cpp:168
void add_loaded_item(Items::Item *cont_item, Items::Item *item)
Definition: loaddata.cpp:248
SystemState systemstate
Definition: systemstate.cpp:12
Core::PolConfig config
Definition: systemstate.h:43
std::string world_data_path
Definition: polcfg.h:28
unsigned char tilelayer(unsigned short tilenum)
Definition: polfile2.cpp:22
std::string decint(unsigned short v)
Definition: strutil.cpp:64
void insert_deferred_items()
Definition: loaddata.cpp:117
void RegisterCleanDeletedSerial(u32 serial)
Definition: objecthash.cpp:271
void load_incremental_indexes()
Definition: loaddata.cpp:39
virtual void add(Items::Item *item)
Definition: containr.cpp:194
virtual bool script_isa(unsigned isatype) const POL_OVERRIDE
Definition: uoscrobj.cpp:4576
void read_incremental_saves()
Definition: loaddata.cpp:79
void clear_save_index()
Definition: loaddata.cpp:106
unsigned short u16
Definition: rawtypes.h:26
virtual void destroy()
Definition: uobject.cpp:122
bool check_equip_script(Mobile::Character *chr, bool startup)
Definition: item.cpp:1051
bool orphan() const
Definition: baseobject.h:119
void add_at_random_location(Items::Item *item)
Definition: containr.cpp:291
void equip_loaded_item(Mobile::Character *chr, Items::Item *item)
Definition: loaddata.cpp:199
const u32 objtype_
Definition: uobject.h:249
void equip(Items::Item *item)
Definition: charactr.cpp:1433
SerialIndexMap incremental_serial_index
const unsigned POLCLASS_SPELLBOOK
Definition: polclass.h:21
StateManager stateManager
Definition: state.cpp:8
Mobile::Character * system_find_mobile(u32 serial)
Definition: fnsearch.cpp:32
bool IsCharacter(u32 serial)
Definition: uobject.h:311
Items::Item * system_find_item(u32 serial)
Definition: fnsearch.cpp:41
u8 slot_index() const
Definition: item.h:358
Core::UContainer * backpack() const
Definition: charactr.cpp:1276
bool type_is(const char *name) const
Definition: cfgfile.cpp:95
void clear_dirty() const
Definition: uobject.cpp:146
u32 pol_serial_t
Definition: poltype.h:23
ObjectStorageManager objStorageManager
long long ellapsed() const
Definition: timer.cpp:46
std::string name
Definition: osmod.cpp:943
bool gflag_enforce_container_limits
Definition: state.h:38
bool isa(UOBJ_CLASS uobj_class) const
Definition: baseobject.h:99
bool check_equiptest_scripts(Mobile::Character *chr, bool startup=false)
Definition: item.cpp:1137
#define ERROR_PRINT
Definition: logfacility.h:230
void defer_item_insertion(Items::Item *item, pol_serial_t container_serial)
Definition: loaddata.cpp:112
bool FileExists(const char *filename)
Definition: fileutil.cpp:118
bool read(ConfigElem &elem)
Definition: cfgfile.cpp:1015
bool equippable(const Items::Item *item) const
Definition: charactr.cpp:1356
#define INFO_PRINT
Definition: logfacility.h:223
void slurp(const char *filename, const char *tags, int sysfind_flags=0)
Definition: uimport.cpp:363
unsigned get_save_index(pol_serial_t serial)
Definition: loaddata.cpp:70
Definition: berror.cpp:12
static u16 convert_objtype_to_spellnum(u32 objtype, u8 school)
Definition: spelbook.cpp:335
void register_deleted_serials()
Definition: loaddata.cpp:91