2009-09-13 18:02:46 -06:00
/*
www . sourceforge . net / projects / dfhack
Copyright ( c ) 2009 Petr Mr á zek ( peterix ) , Kenneth Ferland ( Impaler [ WrG ] ) , dorf
This software is provided ' as - is ' , without any express or implied
warranty . In no event will the authors be held liable for any
damages arising from the use of this software .
Permission is granted to anyone to use this software for any
purpose , including commercial applications , and to alter it and
redistribute it freely , subject to the following restrictions :
1. The origin of this software must not be misrepresented ; you must
not claim that you wrote the original software . If you use this
software in a product , an acknowledgment in the product documentation
would be appreciated but is not required .
2. Altered source versions must be plainly marked as such , and
must not be misrepresented as being the original software .
3. This notice may not be removed or altered from any source
distribution .
*/
2009-11-10 20:37:28 -07:00
# include "DFCommonInternal.h"
2010-02-27 17:13:34 -07:00
# include "DFError.h"
2009-11-10 20:37:28 -07:00
using namespace DFHack ;
2009-10-04 07:08:20 -06:00
2010-02-27 17:25:04 -07:00
/*
FIXME : memset to 0 ?
*/
2009-11-10 20:37:28 -07:00
class API : : Private
{
2009-12-12 16:56:28 -07:00
public :
Private ( )
: block ( NULL )
2010-02-15 16:04:15 -07:00
, pm ( NULL ) , p ( NULL ) , offset_descriptor ( NULL )
2009-12-12 16:56:28 -07:00
, p_cons ( NULL ) , p_bld ( NULL ) , p_veg ( NULL )
{ }
uint32_t * block ;
uint32_t x_block_count , y_block_count , z_block_count ;
uint32_t regionX , regionY , regionZ ;
uint32_t worldSizeX , worldSizeY ;
uint32_t tile_type_offset ;
uint32_t designation_offset ;
uint32_t occupancy_offset ;
2010-02-20 04:58:52 -07:00
uint32_t block_flags_offset ;
2009-12-12 16:56:28 -07:00
uint32_t biome_stuffs ;
uint32_t veinvector ;
uint32_t veinsize ;
2010-02-20 21:51:29 -07:00
uint32_t vein_mineral_vptr ;
uint32_t vein_ice_vptr ;
2009-12-12 16:56:28 -07:00
uint32_t window_x_offset ;
uint32_t window_y_offset ;
uint32_t window_z_offset ;
uint32_t cursor_xyz_offset ;
uint32_t window_dims_offset ;
uint32_t current_cursor_creature_offset ;
uint32_t pause_state_offset ;
uint32_t view_screen_offset ;
2010-01-18 09:44:24 -07:00
uint32_t current_menu_state_offset ;
2009-12-12 16:56:28 -07:00
uint32_t creature_pos_offset ;
uint32_t creature_type_offset ;
uint32_t creature_flags1_offset ;
uint32_t creature_flags2_offset ;
uint32_t creature_first_name_offset ;
uint32_t creature_nick_name_offset ;
uint32_t creature_last_name_offset ;
uint32_t creature_custom_profession_offset ;
uint32_t creature_profession_offset ;
uint32_t creature_sex_offset ;
uint32_t creature_id_offset ;
uint32_t creature_squad_name_offset ;
uint32_t creature_squad_leader_id_offset ;
uint32_t creature_money_offset ;
uint32_t creature_current_job_offset ;
uint32_t creature_current_job_id_offset ;
uint32_t creature_strength_offset ;
uint32_t creature_agility_offset ;
uint32_t creature_toughness_offset ;
uint32_t creature_skills_offset ;
uint32_t creature_labors_offset ;
uint32_t creature_happiness_offset ;
uint32_t creature_traits_offset ;
2009-12-31 19:14:41 -07:00
uint32_t creature_likes_offset ;
2009-12-12 16:56:28 -07:00
uint32_t item_material_offset ;
2010-02-18 10:06:32 -07:00
uint32_t note_foreground_offset ;
uint32_t note_background_offset ;
uint32_t note_name_offset ;
uint32_t note_xyz_offset ;
uint32_t hotkey_start ;
uint32_t hotkey_mode_offset ;
uint32_t hotkey_xyz_offset ;
uint32_t hotkey_size ;
2010-02-22 19:25:57 -07:00
2010-02-27 17:25:04 -07:00
uint32_t settlement_name_offset ;
uint32_t settlement_world_xy_offset ;
uint32_t settlement_local_xy_offset ;
2010-02-17 19:08:54 -07:00
2009-12-12 16:56:28 -07:00
uint32_t dwarf_lang_table_offset ;
ProcessEnumerator * pm ;
Process * p ;
memory_info * offset_descriptor ;
vector < uint16_t > v_geology [ eBiomeCount ] ;
string xml ;
bool constructionsInited ;
bool buildingsInited ;
bool vegetationInited ;
bool creaturesInited ;
bool cursorWindowInited ;
bool viewSizeInited ;
bool itemsInited ;
2010-02-18 10:06:32 -07:00
bool notesInited ;
bool hotkeyInited ;
2010-02-27 17:25:04 -07:00
bool settlementsInited ;
2009-12-12 16:56:28 -07:00
bool nameTablesInited ;
uint32_t tree_offset ;
DfVector * p_cre ;
DfVector * p_cons ;
DfVector * p_bld ;
DfVector * p_veg ;
DfVector * p_itm ;
2010-02-18 10:06:32 -07:00
DfVector * p_notes ;
2010-02-27 17:25:04 -07:00
DfVector * p_settlements ;
DfVector * p_current_settlement ;
2009-11-10 20:37:28 -07:00
} ;
2009-11-09 16:18:20 -07:00
2009-12-12 16:56:28 -07:00
API : : API ( const string path_to_xml )
: d ( new Private ( ) )
2009-10-04 07:08:20 -06:00
{
2009-12-12 16:56:28 -07:00
d - > xml = QUOT ( MEMXML_DATA_PATH ) ;
2009-11-10 20:37:28 -07:00
d - > xml + = " / " ;
d - > xml + = path_to_xml ;
d - > constructionsInited = false ;
d - > creaturesInited = false ;
d - > buildingsInited = false ;
d - > vegetationInited = false ;
2009-11-11 18:05:07 -07:00
d - > cursorWindowInited = false ;
2009-11-17 20:35:43 -07:00
d - > viewSizeInited = false ;
2009-11-17 07:52:47 -07:00
d - > itemsInited = false ;
2010-02-18 10:06:32 -07:00
d - > notesInited = false ;
d - > hotkeyInited = false ;
2009-11-10 20:37:28 -07:00
d - > pm = NULL ;
2009-10-04 07:08:20 -06:00
}
2009-11-10 20:37:28 -07:00
API : : ~ API ( )
2009-09-13 18:02:46 -06:00
{
2009-11-10 20:37:28 -07:00
delete d ;
2009-09-13 18:02:46 -06:00
}
/*-----------------------------------*
* Init the mapblock pointer array *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2009-11-10 20:37:28 -07:00
bool API : : InitMap ( )
2009-09-13 18:02:46 -06:00
{
2009-12-12 16:56:28 -07:00
uint32_t map_offset = d - > offset_descriptor - > getAddress ( " map_data " ) ;
uint32_t x_count_offset = d - > offset_descriptor - > getAddress ( " x_count " ) ;
uint32_t y_count_offset = d - > offset_descriptor - > getAddress ( " y_count " ) ;
uint32_t z_count_offset = d - > offset_descriptor - > getAddress ( " z_count " ) ;
2009-09-13 18:02:46 -06:00
// get the offsets once here
2009-12-12 16:56:28 -07:00
d - > tile_type_offset = d - > offset_descriptor - > getOffset ( " type " ) ;
d - > designation_offset = d - > offset_descriptor - > getOffset ( " designation " ) ;
d - > occupancy_offset = d - > offset_descriptor - > getOffset ( " occupancy " ) ;
d - > biome_stuffs = d - > offset_descriptor - > getOffset ( " biome_stuffs " ) ;
d - > veinvector = d - > offset_descriptor - > getOffset ( " v_vein " ) ;
d - > veinsize = d - > offset_descriptor - > getHexValue ( " v_vein_size " ) ;
2010-02-20 21:51:29 -07:00
2010-02-25 05:41:57 -07:00
// these can fail and will be found when looking at the actual veins later
// basically a cache
d - > vein_ice_vptr = 0 ;
d - > offset_descriptor - > resolveClassnameToVPtr ( " block_square_event_frozen_liquid " , d - > vein_ice_vptr ) ;
d - > vein_mineral_vptr = 0 ;
d - > offset_descriptor - > resolveClassnameToVPtr ( " block_square_event_mineral " , d - > vein_mineral_vptr ) ;
2009-11-21 03:55:00 -07:00
2009-09-13 18:02:46 -06:00
// get the map pointer
2010-02-27 18:37:05 -07:00
uint32_t x_array_loc = g_pProcess - > readDWord ( map_offset ) ;
2009-11-11 18:05:07 -07:00
//FIXME: very inadequate
2009-11-18 14:27:13 -07:00
if ( ! x_array_loc )
2009-09-13 18:02:46 -06:00
{
2010-02-27 18:37:05 -07:00
throw Error : : NoMapLoaded ( ) ;
2009-09-13 18:02:46 -06:00
// bad stuffz happend
2010-02-27 18:37:05 -07:00
//return false;
2009-09-13 18:02:46 -06:00
}
2009-11-18 14:27:13 -07:00
uint32_t mx , my , mz ;
2009-12-12 16:56:28 -07:00
2009-09-13 18:02:46 -06:00
// get the size
2009-12-22 14:19:39 -07:00
mx = d - > x_block_count = g_pProcess - > readDWord ( x_count_offset ) ;
my = d - > y_block_count = g_pProcess - > readDWord ( y_count_offset ) ;
mz = d - > z_block_count = g_pProcess - > readDWord ( z_count_offset ) ;
2009-09-13 18:02:46 -06:00
2009-11-18 14:27:13 -07:00
// test for wrong map dimensions
2009-12-12 16:56:28 -07:00
if ( mx = = 0 | | mx > 48 | | my = = 0 | | my > 48 | | mz = = 0 )
2009-11-18 14:27:13 -07:00
{
2010-02-27 18:37:05 -07:00
throw Error : : BadMapDimensions ( mx , my ) ;
//return false;
2009-11-18 14:27:13 -07:00
}
2009-12-12 16:56:28 -07:00
2009-11-18 15:56:11 -07:00
// alloc array for pointers to all blocks
2009-11-18 14:27:13 -07:00
d - > block = new uint32_t [ mx * my * mz ] ;
2009-11-18 15:56:11 -07:00
uint32_t * temp_x = new uint32_t [ mx ] ;
uint32_t * temp_y = new uint32_t [ my ] ;
uint32_t * temp_z = new uint32_t [ mz ] ;
2009-11-21 03:55:00 -07:00
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( x_array_loc , mx * sizeof ( uint32_t ) , ( uint8_t * ) temp_x ) ;
2009-12-12 16:56:28 -07:00
for ( uint32_t x = 0 ; x < mx ; x + + )
2009-09-13 18:02:46 -06:00
{
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( temp_x [ x ] , my * sizeof ( uint32_t ) , ( uint8_t * ) temp_y ) ;
2009-09-13 18:02:46 -06:00
// y -> map column
2009-12-12 16:56:28 -07:00
for ( uint32_t y = 0 ; y < my ; y + + )
2009-09-13 18:02:46 -06:00
{
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( temp_y [ y ] ,
2009-12-12 16:56:28 -07:00
mz * sizeof ( uint32_t ) ,
( uint8_t * ) ( d - > block + x * my * mz + y * mz ) ) ;
2009-09-13 18:02:46 -06:00
}
}
2009-11-18 15:56:11 -07:00
delete [ ] temp_x ;
delete [ ] temp_y ;
delete [ ] temp_z ;
2009-09-13 18:02:46 -06:00
return true ;
}
2009-11-10 20:37:28 -07:00
bool API : : DestroyMap ( )
2009-10-04 07:08:20 -06:00
{
2009-11-10 20:37:28 -07:00
if ( d - > block ! = NULL )
{
delete [ ] d - > block ;
d - > block = NULL ;
}
return true ;
2009-10-04 07:08:20 -06:00
}
2009-12-12 16:56:28 -07:00
bool API : : isValidBlock ( uint32_t x , uint32_t y , uint32_t z )
2009-09-13 18:02:46 -06:00
{
2010-02-17 18:10:39 -07:00
if ( x < 0 | | x > = d - > x_block_count | | y < 0 | | y > = d - > y_block_count | | z < 0 | | z > = d - > z_block_count )
return false ;
2009-11-22 07:43:53 -07:00
return d - > block [ x * d - > y_block_count * d - > z_block_count + y * d - > z_block_count + z ] ! = 0 ;
2009-09-13 18:02:46 -06:00
}
2010-02-17 18:10:39 -07:00
uint32_t API : : getBlockPtr ( uint32_t x , uint32_t y , uint32_t z )
{
if ( x < 0 | | x > = d - > x_block_count | | y < 0 | | y > = d - > y_block_count | | z < 0 | | z > = d - > z_block_count )
return 0 ;
return d - > block [ x * d - > y_block_count * d - > z_block_count + y * d - > z_block_count + z ] ;
}
2009-09-13 18:02:46 -06:00
// 256 * sizeof(uint16_t)
2009-12-12 16:56:28 -07:00
bool API : : ReadTileTypes ( uint32_t x , uint32_t y , uint32_t z , uint16_t * buffer )
2009-09-13 18:02:46 -06:00
{
2009-11-10 20:37:28 -07:00
uint32_t addr = d - > block [ x * d - > y_block_count * d - > z_block_count + y * d - > z_block_count + z ] ;
2009-11-22 07:43:53 -07:00
if ( addr )
2009-09-13 18:02:46 -06:00
{
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( addr + d - > tile_type_offset , 256 * sizeof ( uint16_t ) , ( uint8_t * ) buffer ) ;
2009-09-13 18:02:46 -06:00
return true ;
}
return false ;
}
2010-02-20 08:33:30 -07:00
bool API : : ReadDirtyBit ( uint32_t x , uint32_t y , uint32_t z , bool & dirtybit )
2010-02-20 04:58:52 -07:00
{
uint32_t addr = d - > block [ x * d - > y_block_count * d - > z_block_count + y * d - > z_block_count + z ] ;
2010-02-20 08:33:30 -07:00
if ( addr )
2010-02-20 04:58:52 -07:00
{
2010-02-20 08:33:30 -07:00
uint32_t addr_of_struct = g_pProcess - > readDWord ( addr ) ;
dirtybit = g_pProcess - > readDWord ( addr_of_struct ) & 1 ;
2010-02-20 04:58:52 -07:00
return true ;
}
return false ;
}
2010-02-20 08:33:30 -07:00
bool API : : WriteDirtyBit ( uint32_t x , uint32_t y , uint32_t z , bool dirtybit )
2010-02-20 04:58:52 -07:00
{
uint32_t addr = d - > block [ x * d - > y_block_count * d - > z_block_count + y * d - > z_block_count + z ] ;
if ( addr )
{
2010-02-20 08:33:30 -07:00
uint32_t addr_of_struct = g_pProcess - > readDWord ( addr ) ;
uint32_t dirtydword = g_pProcess - > readDWord ( addr_of_struct ) ;
2010-02-27 17:25:04 -07:00
dirtydword & = 0xFFFFFFFE ;
2010-02-21 16:18:44 -07:00
dirtydword | = ( uint32_t ) dirtybit ;
2010-02-20 08:33:30 -07:00
g_pProcess - > writeDWord ( addr_of_struct , dirtydword ) ;
2010-02-20 04:58:52 -07:00
return true ;
}
return false ;
}
2009-09-13 18:02:46 -06:00
// 256 * sizeof(uint32_t)
2009-12-12 16:56:28 -07:00
bool API : : ReadDesignations ( uint32_t x , uint32_t y , uint32_t z , uint32_t * buffer )
2009-09-13 18:02:46 -06:00
{
2009-11-10 20:37:28 -07:00
uint32_t addr = d - > block [ x * d - > y_block_count * d - > z_block_count + y * d - > z_block_count + z ] ;
2009-11-22 07:43:53 -07:00
if ( addr )
2009-09-13 18:02:46 -06:00
{
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( addr + d - > designation_offset , 256 * sizeof ( uint32_t ) , ( uint8_t * ) buffer ) ;
2009-09-13 18:02:46 -06:00
return true ;
}
return false ;
}
// 256 * sizeof(uint32_t)
2009-12-12 16:56:28 -07:00
bool API : : ReadOccupancy ( uint32_t x , uint32_t y , uint32_t z , uint32_t * buffer )
2009-09-13 18:02:46 -06:00
{
2009-11-10 20:37:28 -07:00
uint32_t addr = d - > block [ x * d - > y_block_count * d - > z_block_count + y * d - > z_block_count + z ] ;
2009-11-22 07:43:53 -07:00
if ( addr )
2009-09-13 18:02:46 -06:00
{
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( addr + d - > occupancy_offset , 256 * sizeof ( uint32_t ) , ( uint8_t * ) buffer ) ;
2009-09-13 18:02:46 -06:00
return true ;
}
return false ;
}
// 256 * sizeof(uint16_t)
2009-12-12 16:56:28 -07:00
bool API : : WriteTileTypes ( uint32_t x , uint32_t y , uint32_t z , uint16_t * buffer )
2009-09-13 18:02:46 -06:00
{
2009-11-10 20:37:28 -07:00
uint32_t addr = d - > block [ x * d - > y_block_count * d - > z_block_count + y * d - > z_block_count + z ] ;
2009-11-22 07:43:53 -07:00
if ( addr )
2009-09-13 18:02:46 -06:00
{
2009-12-22 14:19:39 -07:00
g_pProcess - > write ( addr + d - > tile_type_offset , 256 * sizeof ( uint16_t ) , ( uint8_t * ) buffer ) ;
2009-09-13 18:02:46 -06:00
return true ;
}
return false ;
}
2009-12-12 16:56:28 -07:00
bool API : : getCurrentCursorCreatures ( vector < uint32_t > & addresses )
2009-12-12 12:52:30 -07:00
{
2010-02-27 17:25:04 -07:00
if ( d - > cursorWindowInited ) return false ;
2010-02-15 16:04:15 -07:00
DfVector creUnderCursor = d - > p - > readVector ( d - > current_cursor_creature_offset , 4 ) ;
2009-12-12 16:56:28 -07:00
if ( creUnderCursor . getSize ( ) = = 0 )
{
return false ;
2009-12-12 12:52:30 -07:00
}
addresses . clear ( ) ;
2009-12-13 14:03:19 -07:00
for ( uint32_t i = 0 ; i < creUnderCursor . getSize ( ) ; i + + )
2009-12-12 16:56:28 -07:00
{
uint32_t temp = * ( uint32_t * ) creUnderCursor . at ( i ) ;
addresses . push_back ( temp ) ;
2009-12-12 12:52:30 -07:00
}
return true ;
}
2009-09-13 18:02:46 -06:00
// 256 * sizeof(uint32_t)
2009-12-12 16:56:28 -07:00
bool API : : WriteDesignations ( uint32_t x , uint32_t y , uint32_t z , uint32_t * buffer )
2009-09-13 18:02:46 -06:00
{
2009-11-10 20:37:28 -07:00
uint32_t addr = d - > block [ x * d - > y_block_count * d - > z_block_count + y * d - > z_block_count + z ] ;
2009-11-22 07:43:53 -07:00
if ( addr )
2009-09-13 18:02:46 -06:00
{
2009-12-22 14:19:39 -07:00
g_pProcess - > write ( addr + d - > designation_offset , 256 * sizeof ( uint32_t ) , ( uint8_t * ) buffer ) ;
2009-09-13 18:02:46 -06:00
return true ;
}
return false ;
}
// 256 * sizeof(uint32_t)
2009-12-12 16:56:28 -07:00
bool API : : WriteOccupancy ( uint32_t x , uint32_t y , uint32_t z , uint32_t * buffer )
2009-09-13 18:02:46 -06:00
{
2009-11-10 20:37:28 -07:00
uint32_t addr = d - > block [ x * d - > y_block_count * d - > z_block_count + y * d - > z_block_count + z ] ;
2009-11-22 07:43:53 -07:00
if ( addr )
2009-09-13 18:02:46 -06:00
{
2009-12-22 14:19:39 -07:00
g_pProcess - > write ( addr + d - > occupancy_offset , 256 * sizeof ( uint32_t ) , ( uint8_t * ) buffer ) ;
2009-09-13 18:02:46 -06:00
return true ;
}
return false ;
}
2010-02-27 17:25:04 -07:00
// FIXME: this is bad. determine the real size!
2009-09-13 18:02:46 -06:00
//16 of them? IDK... there's probably just 7. Reading more doesn't cause errors as it's an array nested inside a block
// 16 * sizeof(uint8_t)
2009-12-12 16:56:28 -07:00
bool API : : ReadRegionOffsets ( uint32_t x , uint32_t y , uint32_t z , uint8_t * buffer )
2009-09-13 18:02:46 -06:00
{
2009-11-10 20:37:28 -07:00
uint32_t addr = d - > block [ x * d - > y_block_count * d - > z_block_count + y * d - > z_block_count + z ] ;
2009-11-22 07:43:53 -07:00
if ( addr )
2009-09-13 18:02:46 -06:00
{
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( addr + d - > biome_stuffs , 16 * sizeof ( uint8_t ) , buffer ) ;
2009-09-13 18:02:46 -06:00
return true ;
}
return false ;
}
2010-02-20 21:51:29 -07:00
// veins of a block, expects empty vein vectors
bool API : : ReadVeins ( uint32_t x , uint32_t y , uint32_t z , vector < t_vein > & veins , vector < t_frozenliquidvein > & ices )
2009-09-13 18:02:46 -06:00
{
2009-11-10 20:37:28 -07:00
uint32_t addr = d - > block [ x * d - > y_block_count * d - > z_block_count + y * d - > z_block_count + z ] ;
2009-09-13 18:02:46 -06:00
veins . clear ( ) ;
2010-02-20 21:51:29 -07:00
ices . clear ( ) ;
2009-12-12 16:56:28 -07:00
if ( addr & & d - > veinvector & & d - > veinsize )
2009-09-13 18:02:46 -06:00
{
// veins are stored as a vector of pointers to veins
/*pointer is 4 bytes! we work with a 32bit program here, no matter what architecture we compile khazad for*/
2010-02-15 16:04:15 -07:00
DfVector p_veins = d - > p - > readVector ( addr + d - > veinvector , 4 ) ;
2009-11-22 07:43:53 -07:00
uint32_t size = p_veins . getSize ( ) ;
2009-12-12 16:56:28 -07:00
veins . reserve ( size ) ;
2009-09-13 18:02:46 -06:00
// read all veins
2009-12-12 16:56:28 -07:00
for ( uint32_t i = 0 ; i < size ; i + + )
2009-09-13 18:02:46 -06:00
{
t_vein v ;
2010-02-20 21:51:29 -07:00
t_frozenliquidvein fv ;
2009-12-12 16:56:28 -07:00
2009-09-13 18:02:46 -06:00
// read the vein pointer from the vector
2009-12-12 16:56:28 -07:00
uint32_t temp = * ( uint32_t * ) p_veins [ i ] ;
2010-02-20 21:51:29 -07:00
uint32_t type = g_pProcess - > readDWord ( temp ) ;
2010-02-22 15:34:20 -07:00
try_again :
2010-02-20 21:51:29 -07:00
if ( type = = d - > vein_mineral_vptr )
{
// read the vein data (dereference pointer)
g_pProcess - > read ( temp , sizeof ( t_vein ) , ( uint8_t * ) & v ) ;
v . address_of = temp ;
// store it in the vector
veins . push_back ( v ) ;
}
else if ( type = = d - > vein_ice_vptr )
{
// read the ice vein data (dereference pointer)
g_pProcess - > read ( temp , sizeof ( t_frozenliquidvein ) , ( uint8_t * ) & fv ) ;
// store it in the vector
ices . push_back ( fv ) ;
}
2010-02-23 14:29:55 -07:00
//#define ___FIND_THEM
2010-02-22 15:34:20 -07:00
# ifdef ___FIND_THEM
else if ( g_pProcess - > readClassName ( type ) = = " block_square_event_frozen_liquid " )
{
d - > vein_ice_vptr = type ;
cout < < " block_square_event_frozen_liquid : 0x " < < hex < < type < < endl ;
goto try_again ;
}
else if ( g_pProcess - > readClassName ( type ) = = " block_square_event_mineral " )
{
d - > vein_mineral_vptr = type ;
cout < < " block_square_event_mineral : 0x " < < hex < < type < < endl ;
goto try_again ;
}
# endif
2009-09-13 18:02:46 -06:00
}
return true ;
}
return false ;
}
// getter for map size
2009-12-12 16:56:28 -07:00
void API : : getSize ( uint32_t & x , uint32_t & y , uint32_t & z )
2009-09-13 18:02:46 -06:00
{
2009-11-10 20:37:28 -07:00
x = d - > x_block_count ;
y = d - > y_block_count ;
z = d - > z_block_count ;
2009-09-13 18:02:46 -06:00
}
2009-12-12 16:56:28 -07:00
bool API : : ReadWoodMatgloss ( vector < t_matgloss > & woods )
2009-09-18 05:31:56 -06:00
{
2009-12-31 19:14:41 -07:00
2009-12-12 16:56:28 -07:00
int matgloss_address = d - > offset_descriptor - > getAddress ( " matgloss " ) ;
2009-12-31 19:14:41 -07:00
int matgloss_wood_name_offset = d - > offset_descriptor - > getOffset ( " matgloss_wood_name " ) ;
2009-09-18 05:31:56 -06:00
// TODO: find flag for autumnal coloring?
2010-02-15 16:04:15 -07:00
DfVector p_matgloss = d - > p - > readVector ( matgloss_address , 4 ) ;
2009-12-12 16:56:28 -07:00
2009-09-18 05:31:56 -06:00
woods . clear ( ) ;
2009-12-12 16:56:28 -07:00
2009-09-18 05:31:56 -06:00
t_matgloss mat ;
// TODO: use brown?
mat . fore = 7 ;
mat . back = 0 ;
mat . bright = 0 ;
2009-11-16 13:00:14 -07:00
uint32_t size = p_matgloss . getSize ( ) ;
2009-12-12 16:56:28 -07:00
for ( uint32_t i = 0 ; i < size ; i + + )
2009-09-18 05:31:56 -06:00
{
// read the matgloss pointer from the vector into temp
2009-12-12 16:56:28 -07:00
uint32_t temp = * ( uint32_t * ) p_matgloss [ i ] ;
2009-09-18 05:31:56 -06:00
// read the string pointed at by
2009-11-24 03:34:42 -07:00
/*
2010-02-15 16:04:15 -07:00
fill_char_buf ( mat . id , d - > p - > readSTLString ( temp ) ) ; // reads a C string given an address
2009-11-24 03:34:42 -07:00
*/
2010-02-15 16:04:15 -07:00
d - > p - > readSTLString ( temp , mat . id , 128 ) ;
d - > p - > readSTLString ( temp + matgloss_wood_name_offset , mat . name , 128 ) ;
2009-12-12 16:56:28 -07:00
woods . push_back ( mat ) ;
2009-09-18 05:31:56 -06:00
}
return true ;
}
2009-12-12 16:56:28 -07:00
bool API : : ReadStoneMatgloss ( vector < t_matgloss > & stones )
2009-09-13 18:02:46 -06:00
{
2009-11-10 20:37:28 -07:00
memory_info * minfo = d - > offset_descriptor ;
2009-12-12 16:56:28 -07:00
int matgloss_address = minfo - > getAddress ( " matgloss " ) ;
int matgloss_offset = minfo - > getHexValue ( " matgloss_skip " ) ;
int matgloss_colors = minfo - > getOffset ( " matgloss_stone_color " ) ;
2009-12-31 19:14:41 -07:00
int matgloss_stone_name_offset = minfo - > getOffset ( " matgloss_stone_name " ) ;
2010-02-15 16:04:15 -07:00
DfVector p_matgloss = d - > p - > readVector ( matgloss_address + matgloss_offset , 4 ) ;
2009-09-13 18:02:46 -06:00
2009-12-13 14:03:19 -07:00
uint32_t size = p_matgloss . getSize ( ) ;
2009-12-12 16:56:28 -07:00
stones . resize ( 0 ) ;
stones . reserve ( size ) ;
for ( uint32_t i = 0 ; i < size ; i + + )
2009-09-13 18:02:46 -06:00
{
// read the matgloss pointer from the vector into temp
2009-12-12 16:56:28 -07:00
uint32_t temp = * ( uint32_t * ) p_matgloss [ i ] ;
2009-09-13 18:02:46 -06:00
// read the string pointed at by
t_matgloss mat ;
2010-02-15 16:04:15 -07:00
//fill_char_buf(mat.id, d->p->readSTLString(temp)); // reads a C string given an address
d - > p - > readSTLString ( temp , mat . id , 128 ) ;
d - > p - > readSTLString ( temp + matgloss_stone_name_offset , mat . name , 128 ) ;
2009-12-22 14:19:39 -07:00
mat . fore = ( uint8_t ) g_pProcess - > readWord ( temp + matgloss_colors ) ;
mat . back = ( uint8_t ) g_pProcess - > readWord ( temp + matgloss_colors + 2 ) ;
mat . bright = ( uint8_t ) g_pProcess - > readWord ( temp + matgloss_colors + 4 ) ;
2009-12-12 16:56:28 -07:00
stones . push_back ( mat ) ;
2009-09-13 18:02:46 -06:00
}
return true ;
}
2009-12-12 16:56:28 -07:00
bool API : : ReadMetalMatgloss ( vector < t_matgloss > & metals )
2009-09-13 18:02:46 -06:00
{
2009-11-10 20:37:28 -07:00
memory_info * minfo = d - > offset_descriptor ;
2009-12-12 16:56:28 -07:00
int matgloss_address = minfo - > getAddress ( " matgloss " ) ;
int matgloss_offset = minfo - > getHexValue ( " matgloss_skip " ) ;
int matgloss_colors = minfo - > getOffset ( " matgloss_metal_color " ) ;
2009-12-31 19:14:41 -07:00
int matgloss_metal_name_offset = minfo - > getOffset ( " matgloss_metal_name " ) ;
2010-02-15 16:04:15 -07:00
DfVector p_matgloss = d - > p - > readVector ( matgloss_address + matgloss_offset * 3 , 4 ) ;
2009-09-13 18:02:46 -06:00
metals . clear ( ) ;
2009-12-12 16:56:28 -07:00
for ( uint32_t i = 0 ; i < p_matgloss . getSize ( ) ; i + + )
2009-09-13 18:02:46 -06:00
{
// read the matgloss pointer from the vector into temp
2009-12-12 16:56:28 -07:00
uint32_t temp = * ( uint32_t * ) p_matgloss [ i ] ;
2009-09-13 18:02:46 -06:00
// read the string pointed at by
t_matgloss mat ;
2010-02-15 16:04:15 -07:00
//fill_char_buf(mat.id, d->p->readSTLString(temp)); // reads a C string given an address
d - > p - > readSTLString ( temp , mat . id , 128 ) ;
d - > p - > readSTLString ( temp + matgloss_metal_name_offset , mat . name , 128 ) ;
2009-12-22 14:19:39 -07:00
mat . fore = ( uint8_t ) g_pProcess - > readWord ( temp + matgloss_colors ) ;
mat . back = ( uint8_t ) g_pProcess - > readWord ( temp + matgloss_colors + 2 ) ;
mat . bright = ( uint8_t ) g_pProcess - > readWord ( temp + matgloss_colors + 4 ) ;
2009-12-12 16:56:28 -07:00
metals . push_back ( mat ) ;
2009-09-13 18:02:46 -06:00
}
return true ;
}
2009-12-12 16:56:28 -07:00
bool API : : ReadPlantMatgloss ( vector < t_matgloss > & plants )
2009-09-13 18:02:46 -06:00
{
2009-11-10 20:37:28 -07:00
memory_info * minfo = d - > offset_descriptor ;
2009-12-12 16:56:28 -07:00
int matgloss_address = minfo - > getAddress ( " matgloss " ) ;
int matgloss_offset = minfo - > getHexValue ( " matgloss_skip " ) ;
2009-12-31 19:14:41 -07:00
int matgloss_plant_name_offset = minfo - > getOffset ( " matgloss_plant_name " ) ;
2010-02-15 16:04:15 -07:00
DfVector p_matgloss = d - > p - > readVector ( matgloss_address + matgloss_offset * 2 , 4 ) ;
2009-09-13 18:02:46 -06:00
plants . clear ( ) ;
// TODO: use green?
t_matgloss mat ;
mat . fore = 7 ;
mat . back = 0 ;
mat . bright = 0 ;
2009-12-12 16:56:28 -07:00
for ( uint32_t i = 0 ; i < p_matgloss . getSize ( ) ; i + + )
2009-09-13 18:02:46 -06:00
{
// read the matgloss pointer from the vector into temp
2009-12-12 16:56:28 -07:00
uint32_t temp = * ( uint32_t * ) p_matgloss [ i ] ;
2009-09-13 18:02:46 -06:00
// read the string pointed at by
2010-02-15 16:04:15 -07:00
//fill_char_buf(mat.id, d->p->readSTLString(temp)); // reads a C string given an address
d - > p - > readSTLString ( temp , mat . id , 128 ) ;
d - > p - > readSTLString ( temp + matgloss_plant_name_offset , mat . name , 128 ) ;
2009-12-31 19:14:41 -07:00
plants . push_back ( mat ) ;
}
return true ;
}
bool API : : ReadPlantMatgloss ( vector < t_matglossPlant > & plants )
{
memory_info * minfo = d - > offset_descriptor ;
int matgloss_address = minfo - > getAddress ( " matgloss " ) ;
int matgloss_offset = minfo - > getHexValue ( " matgloss_skip " ) ;
int matgloss_plant_name_offset = minfo - > getOffset ( " matgloss_plant_name " ) ;
int matgloss_plant_drink_offset = minfo - > getOffset ( " matgloss_plant_drink " ) ;
int matgloss_plant_food_offset = minfo - > getOffset ( " matgloss_plant_food " ) ;
int matgloss_plant_extract_offset = minfo - > getOffset ( " matgloss_plant_extract " ) ;
2010-02-15 16:04:15 -07:00
DfVector p_matgloss = d - > p - > readVector ( matgloss_address + matgloss_offset * 2 , 4 ) ;
2009-12-31 19:14:41 -07:00
plants . clear ( ) ;
// TODO: use green?
t_matglossPlant mat ;
mat . fore = 7 ;
mat . back = 0 ;
mat . bright = 0 ;
for ( uint32_t i = 0 ; i < p_matgloss . getSize ( ) ; i + + )
{
// read the matgloss pointer from the vector into temp
uint32_t temp = * ( uint32_t * ) p_matgloss [ i ] ;
// read the string pointed at by
2010-02-15 16:04:15 -07:00
//fill_char_buf(mat.id, d->p->readSTLString(temp)); // reads a C string given an address
d - > p - > readSTLString ( temp , mat . id , 128 ) ;
d - > p - > readSTLString ( temp + matgloss_plant_name_offset , mat . name , 128 ) ;
d - > p - > readSTLString ( temp + matgloss_plant_drink_offset , mat . drink_name , 128 ) ;
d - > p - > readSTLString ( temp + matgloss_plant_food_offset , mat . food_name , 128 ) ;
d - > p - > readSTLString ( temp + matgloss_plant_extract_offset , mat . extract_name , 128 ) ;
2009-12-31 19:14:41 -07:00
2010-02-15 16:04:15 -07:00
//d->p->readSTLString (temp
2009-12-12 16:56:28 -07:00
plants . push_back ( mat ) ;
2009-09-13 18:02:46 -06:00
}
return true ;
}
2009-12-12 16:56:28 -07:00
bool API : : ReadCreatureMatgloss ( vector < t_matgloss > & creatures )
2009-10-22 19:39:19 -06:00
{
2009-11-10 20:37:28 -07:00
memory_info * minfo = d - > offset_descriptor ;
2009-12-12 16:56:28 -07:00
int matgloss_address = minfo - > getAddress ( " matgloss " ) ;
int matgloss_offset = minfo - > getHexValue ( " matgloss_skip " ) ;
2009-12-31 19:14:41 -07:00
int matgloss_creature_name_offset = minfo - > getOffset ( " matgloss_creature_name " ) ;
2010-02-15 16:04:15 -07:00
DfVector p_matgloss = d - > p - > readVector ( matgloss_address + matgloss_offset * 6 , 4 ) ;
2009-12-12 16:56:28 -07:00
2009-10-22 19:39:19 -06:00
creatures . clear ( ) ;
2009-12-12 16:56:28 -07:00
2009-10-22 19:39:19 -06:00
// TODO: use green?
t_matgloss mat ;
mat . fore = 7 ;
mat . back = 0 ;
mat . bright = 0 ;
2009-12-12 16:56:28 -07:00
for ( uint32_t i = 0 ; i < p_matgloss . getSize ( ) ; i + + )
2009-10-22 19:39:19 -06:00
{
// read the matgloss pointer from the vector into temp
2009-12-12 16:56:28 -07:00
uint32_t temp = * ( uint32_t * ) p_matgloss [ i ] ;
2009-10-22 19:39:19 -06:00
// read the string pointed at by
2010-02-15 16:04:15 -07:00
//fill_char_buf(mat.id, d->p->readSTLString(temp)); // reads a C string given an address
d - > p - > readSTLString ( temp , mat . id , 128 ) ;
d - > p - > readSTLString ( temp + matgloss_creature_name_offset , mat . name , 128 ) ;
2009-12-12 16:56:28 -07:00
creatures . push_back ( mat ) ;
2009-10-22 19:39:19 -06:00
}
return true ;
}
2009-09-13 18:02:46 -06:00
//vector<uint16_t> v_geology[eBiomeCount];
2009-12-12 16:56:28 -07:00
bool API : : ReadGeology ( vector < vector < uint16_t > > & assign )
2009-09-13 18:02:46 -06:00
{
2009-11-10 20:37:28 -07:00
memory_info * minfo = d - > offset_descriptor ;
2010-02-27 17:25:04 -07:00
// get needed addresses and offsets. Now this is what I call crazy.
2009-12-12 16:56:28 -07:00
int region_x_offset = minfo - > getAddress ( " region_x " ) ;
int region_y_offset = minfo - > getAddress ( " region_y " ) ;
int region_z_offset = minfo - > getAddress ( " region_z " ) ;
int world_offset = minfo - > getAddress ( " world " ) ;
int world_regions_offset = minfo - > getOffset ( " w_regions_arr " ) ;
int region_size = minfo - > getHexValue ( " region_size " ) ;
int region_geo_index_offset = minfo - > getOffset ( " region_geo_index_off " ) ;
int world_geoblocks_offset = minfo - > getOffset ( " w_geoblocks " ) ;
int world_size_x = minfo - > getOffset ( " world_size_x " ) ;
int world_size_y = minfo - > getOffset ( " world_size_y " ) ;
int geolayer_geoblock_offset = minfo - > getOffset ( " geolayer_geoblock_offset " ) ;
2009-09-13 18:02:46 -06:00
uint32_t regionX , regionY , regionZ ;
uint16_t worldSizeX , worldSizeY ;
// check if we have 'em all
2009-12-12 16:56:28 -07:00
if (
! (
region_x_offset & & region_y_offset & & region_z_offset & & world_size_x & & world_size_y
& & world_offset & & world_regions_offset & & world_geoblocks_offset & & region_size
& & region_geo_index_offset & & geolayer_geoblock_offset
2009-09-13 18:02:46 -06:00
)
)
{
// fail if we don't have them
return false ;
}
// read position of the region inside DF world
2009-12-22 14:19:39 -07:00
g_pProcess - > readDWord ( region_x_offset , regionX ) ;
g_pProcess - > readDWord ( region_y_offset , regionY ) ;
g_pProcess - > readDWord ( region_z_offset , regionZ ) ;
2009-09-13 18:02:46 -06:00
// get world size
2009-12-22 14:19:39 -07:00
g_pProcess - > readWord ( world_offset + world_size_x , worldSizeX ) ;
g_pProcess - > readWord ( world_offset + world_size_y , worldSizeY ) ;
2009-09-13 18:02:46 -06:00
// get pointer to first part of 2d array of regions
2009-12-22 14:19:39 -07:00
uint32_t regions = g_pProcess - > readDWord ( world_offset + world_regions_offset ) ;
2009-09-13 18:02:46 -06:00
// read the geoblock vector
2010-02-15 16:04:15 -07:00
DfVector geoblocks = d - > p - > readVector ( world_offset + world_geoblocks_offset , 4 ) ;
2009-09-13 18:02:46 -06:00
// iterate over 8 surrounding regions + local region
2009-12-12 16:56:28 -07:00
for ( int i = eNorthWest ; i < eBiomeCount ; i + + )
2009-09-13 18:02:46 -06:00
{
// check bounds, fix them if needed
2009-12-12 16:56:28 -07:00
int bioRX = regionX / 16 + ( i % 3 ) - 1 ;
if ( bioRX < 0 ) bioRX = 0 ;
if ( bioRX > = worldSizeX ) bioRX = worldSizeX - 1 ;
int bioRY = regionY / 16 + ( i / 3 ) - 1 ;
if ( bioRY < 0 ) bioRY = 0 ;
if ( bioRY > = worldSizeY ) bioRY = worldSizeY - 1 ;
2009-09-13 18:02:46 -06:00
// get pointer to column of regions
uint32_t geoX ;
2009-12-22 14:19:39 -07:00
g_pProcess - > readDWord ( regions + bioRX * 4 , geoX ) ;
2009-09-13 18:02:46 -06:00
// get index into geoblock vector
uint16_t geoindex ;
2009-12-22 14:19:39 -07:00
g_pProcess - > readWord ( geoX + bioRY * region_size + region_geo_index_offset , geoindex ) ;
2009-09-13 18:02:46 -06:00
// get the geoblock from the geoblock vector using the geoindex
2009-11-16 13:00:14 -07:00
// read the matgloss pointer from the vector into temp
2009-12-12 16:56:28 -07:00
uint32_t geoblock_off = * ( uint32_t * ) geoblocks [ geoindex ] ;
2009-09-13 18:02:46 -06:00
// get the vector with pointer to layers
2010-02-15 16:04:15 -07:00
DfVector geolayers = d - > p - > readVector ( geoblock_off + geolayer_geoblock_offset , 4 ) ; // let's hope
2009-09-13 18:02:46 -06:00
// make sure we don't load crap
2009-12-12 16:56:28 -07:00
assert ( geolayers . getSize ( ) > 0 & & geolayers . getSize ( ) < = 16 ) ;
2009-09-13 18:02:46 -06:00
2009-12-12 16:56:28 -07:00
d - > v_geology [ i ] . reserve ( geolayers . getSize ( ) ) ;
2009-09-13 18:02:46 -06:00
// finally, read the layer matgloss
2009-12-12 16:56:28 -07:00
for ( uint32_t j = 0 ; j < geolayers . getSize ( ) ; j + + )
2009-09-13 18:02:46 -06:00
{
// read pointer to a layer
2009-12-12 16:56:28 -07:00
uint32_t geol_offset = * ( uint32_t * ) geolayers [ j ] ;
2009-09-13 18:02:46 -06:00
// read word at pointer + 2, store in our geology vectors
2009-12-22 14:19:39 -07:00
d - > v_geology [ i ] . push_back ( g_pProcess - > readWord ( geol_offset + 2 ) ) ;
2009-09-13 18:02:46 -06:00
}
}
assign . clear ( ) ;
2009-12-12 16:56:28 -07:00
assign . reserve ( eBiomeCount ) ;
2009-09-13 18:02:46 -06:00
// TODO: clean this up
2009-12-12 16:56:28 -07:00
for ( int i = 0 ; i < eBiomeCount ; i + + )
2009-09-13 18:02:46 -06:00
{
2009-12-12 16:56:28 -07:00
assign . push_back ( d - > v_geology [ i ] ) ;
2009-09-13 18:02:46 -06:00
}
return true ;
}
// returns number of buildings, expects v_buildingtypes that will later map t_building.type to its name
2010-02-11 14:08:39 -07:00
bool API : : InitReadBuildings ( uint32_t & numbuildings )
2009-09-13 18:02:46 -06:00
{
2009-12-12 16:56:28 -07:00
int buildings = d - > offset_descriptor - > getAddress ( " buildings " ) ;
2010-02-11 14:08:39 -07:00
if ( buildings )
{
d - > buildingsInited = true ;
2010-02-15 16:04:15 -07:00
d - > p_bld = new DfVector ( d - > p - > readVector ( buildings , 4 ) ) ;
2010-02-25 06:59:29 -07:00
numbuildings = d - > p_bld - > getSize ( ) ;
2010-02-11 14:08:39 -07:00
return true ;
}
else
{
d - > buildingsInited = false ;
numbuildings = 0 ;
return false ;
}
2009-09-13 18:02:46 -06:00
}
// read one building
2010-02-27 17:25:04 -07:00
bool API : : ReadBuilding ( const int32_t index , t_building & building )
2009-09-13 18:02:46 -06:00
{
2010-02-27 17:25:04 -07:00
if ( ! d - > buildingsInited ) return false ;
2009-12-12 16:56:28 -07:00
2009-09-13 18:02:46 -06:00
t_building_df40d bld_40d ;
// read pointer from vector at position
2009-12-12 16:56:28 -07:00
uint32_t temp = * ( uint32_t * ) d - > p_bld - > at ( index ) ;
2009-11-16 13:00:14 -07:00
//d->p_bld->read(index,(uint8_t *)&temp);
2009-09-13 18:02:46 -06:00
//read building from memory
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( temp , sizeof ( t_building_df40d ) , ( uint8_t * ) & bld_40d ) ;
2009-09-13 18:02:46 -06:00
// transform
int32_t type = - 1 ;
2010-02-25 05:41:57 -07:00
d - > offset_descriptor - > resolveObjectToClassID ( temp , type ) ;
2009-11-03 18:01:55 -07:00
building . origin = temp ;
2009-09-13 18:02:46 -06:00
building . vtable = bld_40d . vtable ;
building . x1 = bld_40d . x1 ;
building . x2 = bld_40d . x2 ;
building . y1 = bld_40d . y1 ;
building . y2 = bld_40d . y2 ;
building . z = bld_40d . z ;
building . material = bld_40d . material ;
building . type = type ;
2009-10-04 07:08:20 -06:00
2009-11-10 20:37:28 -07:00
return true ;
2009-09-13 18:02:46 -06:00
}
2009-11-10 20:37:28 -07:00
void API : : FinishReadBuildings ( )
2009-09-13 18:02:46 -06:00
{
2010-02-27 17:25:04 -07:00
if ( d - > p_bld )
{
delete d - > p_bld ;
d - > p_bld = NULL ;
}
2009-11-10 20:37:28 -07:00
d - > buildingsInited = false ;
2009-09-13 18:02:46 -06:00
}
//TODO: maybe do construction reading differently - this could go slow with many of them.
// returns number of constructions, prepares a vector, returns total number of constructions
2010-02-11 14:08:39 -07:00
bool API : : InitReadConstructions ( uint32_t & numconstructions )
2009-09-13 18:02:46 -06:00
{
2009-12-12 16:56:28 -07:00
int constructions = d - > offset_descriptor - > getAddress ( " constructions " ) ;
2010-02-11 14:08:39 -07:00
if ( constructions )
{
2010-02-15 16:04:15 -07:00
d - > p_cons = new DfVector ( d - > p - > readVector ( constructions , 4 ) ) ;
2010-02-11 14:08:39 -07:00
d - > constructionsInited = true ;
numconstructions = d - > p_cons - > getSize ( ) ;
return true ;
}
else
{
d - > constructionsInited = false ;
numconstructions = 0 ;
return false ;
}
2009-09-13 18:02:46 -06:00
}
2010-02-27 17:25:04 -07:00
bool API : : ReadConstruction ( const int32_t index , t_construction & construction )
2009-09-13 18:02:46 -06:00
{
2010-02-27 17:25:04 -07:00
if ( ! d - > constructionsInited ) return false ;
2009-09-13 18:02:46 -06:00
t_construction_df40d c_40d ;
// read pointer from vector at position
2009-12-12 16:56:28 -07:00
uint32_t temp = * ( uint32_t * ) d - > p_cons - > at ( index ) ;
2009-09-13 18:02:46 -06:00
//read construction from memory
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( temp , sizeof ( t_construction_df40d ) , ( uint8_t * ) & c_40d ) ;
2009-09-13 18:02:46 -06:00
// transform
construction . x = c_40d . x ;
construction . y = c_40d . y ;
construction . z = c_40d . z ;
construction . material = c_40d . material ;
2009-10-04 07:08:20 -06:00
2009-12-12 16:56:28 -07:00
return true ;
2009-09-13 18:02:46 -06:00
}
2009-11-10 20:37:28 -07:00
void API : : FinishReadConstructions ( )
2009-09-13 18:02:46 -06:00
{
2010-02-27 17:25:04 -07:00
if ( d - > p_cons )
{
delete d - > p_cons ;
d - > p_cons = NULL ;
}
2009-11-10 20:37:28 -07:00
d - > constructionsInited = false ;
2009-09-13 18:02:46 -06:00
}
2010-02-11 14:08:39 -07:00
bool API : : InitReadVegetation ( uint32_t & numplants )
2009-09-13 18:02:46 -06:00
{
2009-12-12 16:56:28 -07:00
int vegetation = d - > offset_descriptor - > getAddress ( " vegetation " ) ;
d - > tree_offset = d - > offset_descriptor - > getOffset ( " tree_desc_offset " ) ;
2010-02-11 14:08:39 -07:00
if ( vegetation & & d - > tree_offset )
{
d - > vegetationInited = true ;
2010-02-15 16:04:15 -07:00
d - > p_veg = new DfVector ( d - > p - > readVector ( vegetation , 4 ) ) ;
2010-02-11 14:08:39 -07:00
numplants = d - > p_veg - > getSize ( ) ;
return true ;
}
else
{
d - > vegetationInited = false ;
numplants = 0 ;
return false ;
}
2009-09-13 18:02:46 -06:00
}
2010-02-27 17:25:04 -07:00
bool API : : ReadVegetation ( const int32_t index , t_tree_desc & shrubbery )
2009-09-13 18:02:46 -06:00
{
2010-02-27 17:25:04 -07:00
if ( ! d - > vegetationInited )
return false ;
2009-09-13 18:02:46 -06:00
// read pointer from vector at position
2009-12-12 16:56:28 -07:00
uint32_t temp = * ( uint32_t * ) d - > p_veg - > at ( index ) ;
2009-09-13 18:02:46 -06:00
//read construction from memory
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( temp + d - > tree_offset , sizeof ( t_tree_desc ) , ( uint8_t * ) & shrubbery ) ;
2009-09-13 18:02:46 -06:00
// FIXME: this is completely wrong. type isn't just tree/shrub but also different kinds of trees. stuff that grows around ponds has its own type ID
2009-12-12 16:56:28 -07:00
if ( shrubbery . material . type = = 3 ) shrubbery . material . type = 2 ;
2009-10-22 19:39:19 -06:00
return true ;
2009-09-13 18:02:46 -06:00
}
2009-11-10 20:37:28 -07:00
void API : : FinishReadVegetation ( )
{
2010-02-27 17:25:04 -07:00
if ( d - > p_veg )
{
delete d - > p_veg ;
d - > p_veg = 0 ;
}
2009-11-10 20:37:28 -07:00
d - > vegetationInited = false ;
}
2010-02-13 09:19:11 -07:00
bool API : : InitReadCreatures ( uint32_t & numcreatures )
2009-11-10 20:37:28 -07:00
{
memory_info * minfo = d - > offset_descriptor ;
2009-12-12 16:56:28 -07:00
int creatures = d - > offset_descriptor - > getAddress ( " creatures " ) ;
d - > creature_pos_offset = minfo - > getOffset ( " creature_position " ) ;
d - > creature_type_offset = minfo - > getOffset ( " creature_race " ) ;
d - > creature_flags1_offset = minfo - > getOffset ( " creature_flags1 " ) ;
d - > creature_flags2_offset = minfo - > getOffset ( " creature_flags2 " ) ;
d - > creature_first_name_offset = minfo - > getOffset ( " creature_first_name " ) ;
d - > creature_nick_name_offset = minfo - > getOffset ( " creature_nick_name " ) ;
d - > creature_last_name_offset = minfo - > getOffset ( " creature_last_name " ) ;
d - > creature_custom_profession_offset = minfo - > getOffset ( " creature_custom_profession " ) ;
d - > creature_profession_offset = minfo - > getOffset ( " creature_profession " ) ;
d - > creature_sex_offset = minfo - > getOffset ( " creature_sex " ) ;
d - > creature_id_offset = minfo - > getOffset ( " creature_id " ) ;
d - > creature_squad_name_offset = minfo - > getOffset ( " creature_squad_name " ) ;
d - > creature_squad_leader_id_offset = minfo - > getOffset ( " creature_squad_leader_id " ) ;
d - > creature_money_offset = minfo - > getOffset ( " creature_money " ) ;
d - > creature_current_job_offset = minfo - > getOffset ( " creature_current_job " ) ;
d - > creature_current_job_id_offset = minfo - > getOffset ( " current_job_id " ) ;
d - > creature_strength_offset = minfo - > getOffset ( " creature_strength " ) ;
d - > creature_agility_offset = minfo - > getOffset ( " creature_agility " ) ;
d - > creature_toughness_offset = minfo - > getOffset ( " creature_toughness " ) ;
d - > creature_skills_offset = minfo - > getOffset ( " creature_skills " ) ;
d - > creature_labors_offset = minfo - > getOffset ( " creature_labors " ) ;
d - > creature_happiness_offset = minfo - > getOffset ( " creature_happiness " ) ;
d - > creature_traits_offset = minfo - > getOffset ( " creature_traits " ) ;
2009-12-31 19:14:41 -07:00
d - > creature_likes_offset = minfo - > getOffset ( " creature_likes " ) ;
2009-12-12 16:56:28 -07:00
if ( creatures
& & d - > creature_pos_offset
& & d - > creature_type_offset
& & d - > creature_flags1_offset
& & d - > creature_flags2_offset
& & d - > creature_nick_name_offset
& & d - > creature_custom_profession_offset
& & d - > creature_profession_offset
& & d - > creature_sex_offset
& & d - > creature_id_offset
& & d - > creature_squad_name_offset
& & d - > creature_squad_leader_id_offset
& & d - > creature_money_offset
& & d - > creature_current_job_offset
& & d - > creature_strength_offset
& & d - > creature_agility_offset
& & d - > creature_toughness_offset
& & d - > creature_skills_offset
& & d - > creature_labors_offset
& & d - > creature_happiness_offset
& & d - > creature_traits_offset
2010-02-18 10:06:32 -07:00
// && d->creature_likes_offset
2009-12-12 16:56:28 -07:00
)
2009-11-10 20:37:28 -07:00
{
2010-02-15 16:04:15 -07:00
d - > p_cre = new DfVector ( d - > p - > readVector ( creatures , 4 ) ) ;
2009-11-21 03:55:00 -07:00
//InitReadNameTables();
2009-12-12 16:56:28 -07:00
d - > creaturesInited = true ;
2010-02-11 14:08:39 -07:00
numcreatures = d - > p_cre - > getSize ( ) ;
2010-02-13 09:19:11 -07:00
return true ;
2009-11-10 20:37:28 -07:00
}
else
{
2010-02-11 14:08:39 -07:00
d - > creaturesInited = false ;
numcreatures = 0 ;
2009-11-10 20:37:28 -07:00
return false ;
}
2009-10-22 19:39:19 -06:00
}
2010-02-17 16:33:08 -07:00
bool API : : InitReadNotes ( uint32_t & numnotes )
{
memory_info * minfo = d - > offset_descriptor ;
2010-02-22 19:25:57 -07:00
int notes = minfo - > getAddress ( " notes " ) ;
2010-02-17 16:33:08 -07:00
d - > note_foreground_offset = minfo - > getOffset ( " note_foreground " ) ;
2010-02-18 10:06:32 -07:00
d - > note_background_offset = minfo - > getOffset ( " note_background " ) ;
d - > note_name_offset = minfo - > getOffset ( " note_name " ) ;
d - > note_xyz_offset = minfo - > getOffset ( " note_xyz " ) ;
2010-02-17 16:33:08 -07:00
if ( notes
& & d - > note_foreground_offset
& & d - > note_background_offset
& & d - > note_name_offset
& & d - > note_xyz_offset
)
{
d - > p_notes = new DfVector ( d - > p - > readVector ( notes , 4 ) ) ;
d - > notesInited = true ;
numnotes = d - > p_notes - > getSize ( ) ;
return true ;
}
else
{
d - > notesInited = false ;
numnotes = 0 ;
return false ;
}
}
2010-02-27 17:25:04 -07:00
bool API : : ReadNote ( const int32_t index , t_note & note )
2010-02-17 16:33:08 -07:00
{
2010-02-27 17:25:04 -07:00
if ( ! d - > notesInited ) return false ;
2010-02-17 16:33:08 -07:00
// read pointer from vector at position
uint32_t temp = * ( uint32_t * ) d - > p_notes - > at ( index ) ;
2010-02-18 10:06:32 -07:00
note . symbol = g_pProcess - > readByte ( temp ) ;
note . foreground = g_pProcess - > readWord ( temp + d - > note_foreground_offset ) ;
note . background = g_pProcess - > readWord ( temp + d - > note_background_offset ) ;
d - > p - > readSTLString ( temp + d - > note_name_offset , note . name , 128 ) ;
g_pProcess - > read ( temp + d - > note_xyz_offset , 3 * sizeof ( uint16_t ) , ( uint8_t * ) & note . x ) ;
return true ;
2010-02-17 16:33:08 -07:00
}
2010-02-22 19:25:57 -07:00
bool API : : InitReadSettlements ( uint32_t & numsettlements )
{
2010-02-25 09:37:40 -07:00
memory_info * minfo = d - > offset_descriptor ;
2010-02-22 19:25:57 -07:00
int allSettlements = minfo - > getAddress ( " settlements " ) ;
2010-02-25 09:37:40 -07:00
int currentSettlement = minfo - > getAddress ( " settlement_current " ) ;
2010-02-22 19:25:57 -07:00
d - > settlement_name_offset = minfo - > getOffset ( " settlement_name " ) ;
d - > settlement_world_xy_offset = minfo - > getOffset ( " settlement_world_xy " ) ;
d - > settlement_local_xy_offset = minfo - > getOffset ( " settlement_local_xy " ) ;
2010-02-25 09:37:40 -07:00
2010-02-22 19:25:57 -07:00
if ( allSettlements & & currentSettlement
& & d - > settlement_name_offset
2010-02-25 09:37:40 -07:00
& & d - > settlement_world_xy_offset
& & d - > settlement_local_xy_offset
2010-02-22 19:25:57 -07:00
)
{
d - > p_settlements = new DfVector ( d - > p - > readVector ( allSettlements , 4 ) ) ;
2010-02-25 09:37:40 -07:00
d - > p_current_settlement = new DfVector ( d - > p - > readVector ( currentSettlement , 4 ) ) ;
2010-02-22 19:25:57 -07:00
d - > settlementsInited = true ;
numsettlements = d - > p_settlements - > getSize ( ) ;
return true ;
}
else
{
d - > settlementsInited = false ;
numsettlements = 0 ;
return false ;
}
2010-02-25 09:37:40 -07:00
}
2010-02-27 17:25:04 -07:00
bool API : : ReadSettlement ( const int32_t index , t_settlement & settlement )
2010-02-22 19:25:57 -07:00
{
2010-02-27 17:25:04 -07:00
if ( ! d - > settlementsInited ) return false ;
if ( ! d - > p_settlements - > getSize ( ) ) return false ;
2010-02-22 19:25:57 -07:00
// read pointer from vector at position
uint32_t temp = * ( uint32_t * ) d - > p_settlements - > at ( index ) ;
2010-02-25 09:37:40 -07:00
settlement . origin = temp ;
2010-02-22 19:25:57 -07:00
g_pProcess - > read ( temp + d - > settlement_name_offset , 2 * sizeof ( int32_t ) , ( uint8_t * ) & settlement . name ) ;
2010-02-25 09:37:40 -07:00
g_pProcess - > read ( temp + d - > settlement_world_xy_offset , 2 * sizeof ( int16_t ) , ( uint8_t * ) & settlement . world_x ) ;
g_pProcess - > read ( temp + d - > settlement_local_xy_offset , 4 * sizeof ( int16_t ) , ( uint8_t * ) & settlement . local_x1 ) ;
2010-02-22 19:25:57 -07:00
return true ;
}
bool API : : ReadCurrentSettlement ( t_settlement & settlement )
{
2010-02-27 17:25:04 -07:00
if ( ! d - > settlementsInited ) return false ;
if ( ! d - > p_current_settlement - > getSize ( ) ) return false ;
2010-02-22 19:25:57 -07:00
uint32_t temp = * ( uint32_t * ) d - > p_current_settlement - > at ( 0 ) ;
2010-02-25 09:37:40 -07:00
settlement . origin = temp ;
g_pProcess - > read ( temp + d - > settlement_name_offset , 2 * sizeof ( int32_t ) , ( uint8_t * ) & settlement . name ) ;
g_pProcess - > read ( temp + d - > settlement_world_xy_offset , 2 * sizeof ( int16_t ) , ( uint8_t * ) & settlement . world_x ) ;
g_pProcess - > read ( temp + d - > settlement_local_xy_offset , 4 * sizeof ( int16_t ) , ( uint8_t * ) & settlement . local_x1 ) ;
2010-02-22 19:25:57 -07:00
return true ;
}
void API : : FinishReadSettlements ( )
{
2010-02-27 17:25:04 -07:00
if ( d - > p_settlements )
{
delete d - > p_settlements ;
d - > p_settlements = NULL ;
}
if ( d - > p_current_settlement )
{
delete d - > p_current_settlement ;
d - > p_current_settlement = NULL ;
}
2010-02-22 19:25:57 -07:00
d - > settlementsInited = false ;
}
2010-02-17 19:08:54 -07:00
bool API : : InitReadHotkeys ( )
{
memory_info * minfo = d - > offset_descriptor ;
2010-02-18 10:06:32 -07:00
d - > hotkey_start = minfo - > getAddress ( " hotkey_start " ) ;
2010-02-17 19:08:54 -07:00
d - > hotkey_mode_offset = minfo - > getOffset ( " hotkey_mode " ) ;
2010-02-18 10:06:32 -07:00
d - > hotkey_xyz_offset = minfo - > getOffset ( " hotkey_xyz " ) ;
d - > hotkey_size = minfo - > getHexValue ( " hotkey_size " ) ;
2010-02-17 19:08:54 -07:00
if ( d - > hotkey_start & & d - > hotkey_mode_offset & & d - > hotkey_size )
{
2010-02-18 10:06:32 -07:00
d - > hotkeyInited = true ;
return true ;
2010-02-17 19:08:54 -07:00
}
else
{
d - > hotkeyInited = false ;
return false ;
}
}
bool API : : ReadHotkeys ( t_hotkey hotkeys [ ] )
{
2010-02-27 17:25:04 -07:00
if ( ! d - > hotkeyInited ) return false ;
2010-02-18 10:06:32 -07:00
uint32_t currHotkey = d - > hotkey_start ;
for ( uint32_t i = 0 ; i < NUM_HOTKEYS ; i + + )
{
d - > p - > readSTLString ( currHotkey , hotkeys [ i ] . name , 10 ) ;
hotkeys [ i ] . mode = g_pProcess - > readWord ( currHotkey + d - > hotkey_mode_offset ) ;
g_pProcess - > read ( currHotkey + d - > hotkey_xyz_offset , 3 * sizeof ( int32_t ) , ( uint8_t * ) & hotkeys [ i ] . x ) ;
currHotkey + = d - > hotkey_size ;
}
return true ;
2010-02-17 19:08:54 -07:00
}
2009-11-16 09:47:22 -07:00
// returns index of creature actually read or -1 if no creature can be found
2009-12-12 16:56:28 -07:00
int32_t API : : ReadCreatureInBox ( int32_t index , t_creature & furball ,
2010-02-27 18:07:42 -07:00
const uint16_t x1 , const uint16_t y1 , const uint16_t z1 ,
const uint16_t x2 , const uint16_t y2 , const uint16_t z2 )
2009-11-16 09:47:22 -07:00
{
2010-02-27 17:25:04 -07:00
if ( ! d - > creaturesInited ) return - 1 ;
2009-11-16 09:47:22 -07:00
uint16_t coords [ 3 ] ;
uint32_t size = d - > p_cre - > getSize ( ) ;
2009-12-13 14:03:19 -07:00
while ( uint32_t ( index ) < size )
2009-11-16 09:47:22 -07:00
{
// read pointer from vector at position
2009-12-12 16:56:28 -07:00
uint32_t temp = * ( uint32_t * ) d - > p_cre - > at ( index ) ;
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( temp + d - > creature_pos_offset , 3 * sizeof ( uint16_t ) , ( uint8_t * ) & coords ) ;
2009-12-12 16:56:28 -07:00
if ( coords [ 0 ] > = x1 & & coords [ 0 ] < x2 )
2009-11-16 09:47:22 -07:00
{
2009-12-12 16:56:28 -07:00
if ( coords [ 1 ] > = y1 & & coords [ 1 ] < y2 )
2009-11-16 09:47:22 -07:00
{
2009-12-12 16:56:28 -07:00
if ( coords [ 2 ] > = z1 & & coords [ 2 ] < z2 )
2009-11-16 09:47:22 -07:00
{
2009-12-12 16:56:28 -07:00
ReadCreature ( index , furball ) ;
2009-11-16 09:47:22 -07:00
return index ;
}
}
}
index + + ;
}
2009-11-18 17:36:03 -07:00
return - 1 ;
2009-11-16 09:47:22 -07:00
}
2010-02-27 17:25:04 -07:00
bool API : : getItemIndexesInBox ( vector < uint32_t > & indexes ,
const uint16_t x1 , const uint16_t y1 , const uint16_t z1 ,
const uint16_t x2 , const uint16_t y2 , const uint16_t z2 )
2009-12-31 18:49:32 -07:00
{
2010-02-27 17:25:04 -07:00
if ( ! d - > itemsInited ) return false ;
2009-12-31 18:49:32 -07:00
indexes . clear ( ) ;
uint32_t size = d - > p_itm - > getSize ( ) ;
struct temp2 {
uint16_t coords [ 3 ] ;
uint32_t flags ;
} ;
temp2 temp2 ;
2010-02-21 16:18:44 -07:00
for ( uint32_t i = 0 ; i < size ; i + + ) {
2009-12-31 18:49:32 -07:00
uint32_t temp = * ( uint32_t * ) d - > p_itm - > at ( i ) ;
2009-12-31 19:30:35 -07:00
g_pProcess - > read ( temp + sizeof ( uint32_t ) , 5 * sizeof ( uint16_t ) , ( uint8_t * ) & temp2 ) ;
2009-12-31 18:49:32 -07:00
if ( temp2 . flags & ( 1 < < 0 ) ) {
if ( temp2 . coords [ 0 ] > = x1 & & temp2 . coords [ 0 ] < x2 )
{
if ( temp2 . coords [ 1 ] > = y1 & & temp2 . coords [ 1 ] < y2 )
{
if ( temp2 . coords [ 2 ] > = z1 & & temp2 . coords [ 2 ] < z2 )
{
indexes . push_back ( i ) ;
}
}
}
}
}
}
2010-02-27 17:25:04 -07:00
bool API : : ReadCreature ( const int32_t index , t_creature & furball )
2009-10-22 19:39:19 -06:00
{
2010-02-27 17:25:04 -07:00
if ( ! d - > creaturesInited ) return false ;
2009-10-22 19:39:19 -06:00
// read pointer from vector at position
2009-12-12 16:56:28 -07:00
uint32_t temp = * ( uint32_t * ) d - > p_cre - > at ( index ) ;
2009-12-12 12:52:30 -07:00
furball . origin = temp ;
2009-10-22 19:39:19 -06:00
//read creature from memory
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( temp + d - > creature_pos_offset , 3 * sizeof ( uint16_t ) , ( uint8_t * ) & ( furball . x ) ) ; // xyz really
g_pProcess - > readDWord ( temp + d - > creature_type_offset , furball . type ) ;
g_pProcess - > readDWord ( temp + d - > creature_flags1_offset , furball . flags1 . whole ) ;
g_pProcess - > readDWord ( temp + d - > creature_flags2_offset , furball . flags2 . whole ) ;
2009-11-13 06:35:44 -07:00
// normal names
2010-02-15 16:04:15 -07:00
d - > p - > readSTLString ( temp + d - > creature_first_name_offset , furball . first_name , 128 ) ;
d - > p - > readSTLString ( temp + d - > creature_nick_name_offset , furball . nick_name , 128 ) ;
2009-11-24 03:34:42 -07:00
// custom profession
2010-02-15 16:04:15 -07:00
d - > p - > readSTLString ( temp + d - > creature_nick_name_offset , furball . nick_name , 128 ) ;
fill_char_buf ( furball . custom_profession , d - > p - > readSTLString ( temp + d - > creature_custom_profession_offset ) ) ;
2009-11-13 06:35:44 -07:00
// crazy composited names
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( temp + d - > creature_last_name_offset , sizeof ( t_lastname ) , ( uint8_t * ) & furball . last_name ) ;
g_pProcess - > read ( temp + d - > creature_squad_name_offset , sizeof ( t_squadname ) , ( uint8_t * ) & furball . squad_name ) ;
2009-12-12 16:56:28 -07:00
2009-11-13 20:46:56 -07:00
// labors
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( temp + d - > creature_labors_offset , NUM_CREATURE_LABORS , furball . labors ) ;
2009-11-13 20:46:56 -07:00
// traits
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( temp + d - > creature_traits_offset , sizeof ( uint16_t ) * NUM_CREATURE_TRAITS , ( uint8_t * ) & furball . traits ) ;
2009-11-13 20:46:56 -07:00
// learned skills
2010-02-15 16:04:15 -07:00
DfVector skills ( d - > p - > readVector ( temp + d - > creature_skills_offset , 4 ) ) ;
2009-11-13 20:46:56 -07:00
furball . numSkills = skills . getSize ( ) ;
2009-12-12 16:56:28 -07:00
for ( uint32_t i = 0 ; i < furball . numSkills ; i + + )
2009-11-13 20:46:56 -07:00
{
2009-12-12 16:56:28 -07:00
uint32_t temp2 = * ( uint32_t * ) skills [ i ] ;
2009-11-16 13:00:14 -07:00
//skills.read(i, (uint8_t *) &temp2);
2009-11-13 20:46:56 -07:00
// a byte: this gives us 256 skills maximum.
2009-12-22 14:19:39 -07:00
furball . skills [ i ] . id = g_pProcess - > readByte ( temp2 ) ;
furball . skills [ i ] . rating = g_pProcess - > readByte ( temp2 + 4 ) ;
furball . skills [ i ] . experience = g_pProcess - > readWord ( temp2 + 8 ) ;
2009-11-13 20:46:56 -07:00
}
// profession
2009-12-22 14:19:39 -07:00
furball . profession = g_pProcess - > readByte ( temp + d - > creature_profession_offset ) ;
2009-11-13 20:46:56 -07:00
// current job HACK: the job object isn't cleanly represented here
2009-12-22 14:19:39 -07:00
uint32_t jobIdAddr = g_pProcess - > readDWord ( temp + d - > creature_current_job_offset ) ;
2010-02-21 16:18:44 -07:00
2009-12-13 14:03:19 -07:00
if ( jobIdAddr )
2009-11-13 20:46:56 -07:00
{
2010-02-27 17:25:04 -07:00
furball . current_job . active = true ;
2009-12-22 14:19:39 -07:00
furball . current_job . jobId = g_pProcess - > readByte ( jobIdAddr + d - > creature_current_job_id_offset ) ;
2009-11-13 20:46:56 -07:00
}
2010-02-27 17:25:04 -07:00
else
{
furball . current_job . active = false ;
}
2009-12-31 19:14:41 -07:00
//likes
2010-02-15 16:04:15 -07:00
DfVector likes ( d - > p - > readVector ( temp + d - > creature_likes_offset , 4 ) ) ;
2009-12-31 19:14:41 -07:00
furball . numLikes = likes . getSize ( ) ;
for ( uint32_t i = 0 ; i < furball . numLikes ; i + + )
{
uint32_t temp2 = * ( uint32_t * ) likes [ i ] ;
2009-12-31 19:30:35 -07:00
g_pProcess - > read ( temp2 , sizeof ( t_like ) , ( uint8_t * ) & furball . likes [ i ] ) ;
2009-12-31 19:14:41 -07:00
}
2009-12-22 14:19:39 -07:00
g_pProcess - > readDWord ( temp + d - > creature_happiness_offset , furball . happiness ) ;
g_pProcess - > readDWord ( temp + d - > creature_id_offset , furball . id ) ;
g_pProcess - > readDWord ( temp + d - > creature_agility_offset , furball . agility ) ;
g_pProcess - > readDWord ( temp + d - > creature_strength_offset , furball . strength ) ;
g_pProcess - > readDWord ( temp + d - > creature_toughness_offset , furball . toughness ) ;
g_pProcess - > readDWord ( temp + d - > creature_money_offset , furball . money ) ;
furball . squad_leader_id = ( int32_t ) g_pProcess - > readDWord ( temp + d - > creature_squad_leader_id_offset ) ;
g_pProcess - > readByte ( temp + d - > creature_sex_offset , furball . sex ) ;
2009-10-22 19:39:19 -06:00
return true ;
}
2009-11-16 09:47:22 -07:00
2010-02-27 17:25:04 -07:00
void API : : WriteLabors ( const uint32_t index , uint8_t labors [ NUM_CREATURE_LABORS ] )
2009-12-31 19:14:41 -07:00
{
uint32_t temp = * ( uint32_t * ) d - > p_cre - > at ( index ) ;
WriteRaw ( temp + d - > creature_labors_offset , NUM_CREATURE_LABORS , labors ) ;
}
2010-02-11 14:08:39 -07:00
bool API : : InitReadNameTables ( map < string , vector < string > > & nameTable )
2009-12-12 16:56:28 -07:00
{
int genericAddress = d - > offset_descriptor - > getAddress ( " language_vector " ) ;
int transAddress = d - > offset_descriptor - > getAddress ( " translation_vector " ) ;
int word_table_offset = d - > offset_descriptor - > getOffset ( " word_table " ) ;
2010-02-11 14:08:39 -07:00
if ( genericAddress & & transAddress & & word_table_offset )
2009-12-12 16:56:28 -07:00
{
2010-02-15 16:04:15 -07:00
DfVector genericVec ( d - > p - > readVector ( genericAddress , 4 ) ) ;
DfVector transVec ( d - > p - > readVector ( transAddress , 4 ) ) ;
2009-12-12 16:56:28 -07:00
2010-02-11 14:08:39 -07:00
for ( uint32_t i = 0 ; i < genericVec . getSize ( ) ; i + + )
{
uint32_t genericNamePtr = * ( uint32_t * ) genericVec . at ( i ) ;
2010-02-15 16:04:15 -07:00
string genericName = d - > p - > readSTLString ( genericNamePtr ) ;
2010-02-11 14:08:39 -07:00
nameTable [ " GENERIC " ] . push_back ( genericName ) ;
}
for ( uint32_t i = 0 ; i < transVec . getSize ( ) ; i + + )
2009-12-12 16:56:28 -07:00
{
2010-02-11 14:08:39 -07:00
uint32_t transPtr = * ( uint32_t * ) transVec . at ( i ) ;
2010-02-15 16:04:15 -07:00
string transName = d - > p - > readSTLString ( transPtr ) ;
DfVector trans_names_vec ( d - > p - > readVector ( transPtr + word_table_offset , 4 ) ) ;
2010-02-11 14:08:39 -07:00
for ( uint32_t j = 0 ; j < trans_names_vec . getSize ( ) ; j + + )
{
uint32_t transNamePtr = * ( uint32_t * ) trans_names_vec . at ( j ) ;
2010-02-15 16:04:15 -07:00
string name = d - > p - > readSTLString ( transNamePtr ) ;
2010-02-11 14:08:39 -07:00
nameTable [ transName ] . push_back ( name ) ;
}
2009-11-07 14:05:10 -07:00
}
2010-02-11 14:08:39 -07:00
d - > nameTablesInited = true ;
return true ;
}
else
{
d - > nameTablesInited = false ;
return false ;
2009-11-07 14:05:10 -07:00
}
}
2010-02-22 19:25:57 -07:00
string API : : TranslateName ( const int names [ ] , int size , const map < string , vector < string > > & nameTable , const string & language )
{
2010-02-27 17:25:04 -07:00
string trans ;
2010-02-22 19:25:57 -07:00
assert ( d - > nameTablesInited ) ;
map < string , vector < string > > : : const_iterator it ;
it = nameTable . find ( language ) ;
if ( it ! = nameTable . end ( ) )
{
for ( int i = 0 ; i < size ; i + + )
{
if ( names [ i ] = = - 1 )
{
break ;
}
trans . append ( it - > second [ names [ i ] ] ) ;
}
}
return ( trans ) ;
}
2009-12-12 16:56:28 -07:00
string API : : TranslateName ( const t_lastname & last , const map < string , vector < string > > & nameTable , const string & language )
2009-12-12 12:52:30 -07:00
{
string trans_last ;
2009-12-12 16:56:28 -07:00
assert ( d - > nameTablesInited ) ;
2009-12-12 12:52:30 -07:00
map < string , vector < string > > : : const_iterator it ;
2009-12-12 16:56:28 -07:00
it = nameTable . find ( language ) ;
if ( it ! = nameTable . end ( ) )
{
for ( int i = 0 ; i < 7 ; i + + )
{
if ( last . names [ i ] = = - 1 )
{
2009-12-12 12:52:30 -07:00
break ;
}
2009-12-12 16:56:28 -07:00
trans_last . append ( it - > second [ last . names [ i ] ] ) ;
2009-12-12 12:52:30 -07:00
}
}
2009-12-12 16:56:28 -07:00
return ( trans_last ) ;
2009-12-12 12:52:30 -07:00
}
2009-12-12 16:56:28 -07:00
string API : : TranslateName ( const t_squadname & squad , const map < string , vector < string > > & nameTable , const string & language )
2009-12-12 12:52:30 -07:00
{
string trans_squad ;
2009-12-12 16:56:28 -07:00
assert ( d - > nameTablesInited ) ;
2009-12-12 12:52:30 -07:00
map < string , vector < string > > : : const_iterator it ;
2009-12-12 16:56:28 -07:00
it = nameTable . find ( language ) ;
if ( it ! = nameTable . end ( ) )
{
for ( int i = 0 ; i < 7 ; i + + )
{
2009-12-13 14:03:19 -07:00
if ( squad . names [ i ] = = - 1 )
2009-12-12 12:52:30 -07:00
{
continue ;
}
2009-12-12 16:56:28 -07:00
if ( squad . names [ i ] = = 0 )
2009-12-12 12:52:30 -07:00
{
break ;
}
2009-12-12 16:56:28 -07:00
if ( i = = 4 )
{
trans_squad . append ( " " ) ;
}
trans_squad . append ( it - > second [ squad . names [ i ] ] ) ;
2009-12-12 12:52:30 -07:00
}
}
2009-12-12 16:56:28 -07:00
return ( trans_squad ) ;
2009-12-12 12:52:30 -07:00
}
2009-11-11 18:53:49 -07:00
void API : : FinishReadNameTables ( )
2009-11-07 14:05:10 -07:00
{
2009-12-12 16:56:28 -07:00
d - > nameTablesInited = false ;
2009-11-07 14:05:10 -07:00
}
2009-10-22 19:39:19 -06:00
2009-11-10 20:37:28 -07:00
void API : : FinishReadCreatures ( )
2009-10-22 19:39:19 -06:00
{
2010-02-27 17:25:04 -07:00
if ( d - > p_cre )
{
delete d - > p_cre ;
d - > p_cre = 0 ;
}
2009-11-10 20:37:28 -07:00
d - > creaturesInited = false ;
2009-11-21 03:55:00 -07:00
//FinishReadNameTables();
2009-10-22 19:39:19 -06:00
}
2010-02-17 16:33:08 -07:00
void API : : FinishReadNotes ( )
{
2010-02-27 17:25:04 -07:00
if ( d - > p_notes )
{
delete d - > p_notes ;
d - > p_notes = 0 ;
}
2010-02-17 16:33:08 -07:00
d - > notesInited = false ;
}
2009-10-22 19:39:19 -06:00
2009-11-10 20:37:28 -07:00
bool API : : Attach ( )
2009-09-13 18:02:46 -06:00
{
// detach all processes, destroy manager
2010-02-27 17:25:04 -07:00
if ( d - > pm = = 0 )
2009-11-09 16:18:20 -07:00
{
2009-12-12 16:56:28 -07:00
d - > pm = new ProcessEnumerator ( d - > xml ) ; // FIXME: handle bad XML better
2009-11-09 16:18:20 -07:00
}
2009-12-26 20:51:54 -07:00
else
{
d - > pm - > purge ( ) ;
}
2009-12-12 16:56:28 -07:00
2009-09-13 18:02:46 -06:00
// find a process (ProcessManager can find multiple when used properly)
2009-12-12 16:56:28 -07:00
if ( ! d - > pm - > findProcessess ( ) )
2009-11-09 16:18:20 -07:00
{
2010-02-27 17:13:34 -07:00
throw Error : : NoProcess ( ) ;
//cerr << "couldn't find a suitable process" << endl;
//return false;
2009-11-09 16:18:20 -07:00
}
2009-12-12 16:56:28 -07:00
d - > p = ( * d - > pm ) [ 0 ] ;
if ( ! d - > p - > attach ( ) )
2009-11-09 16:18:20 -07:00
{
2010-02-27 17:13:34 -07:00
throw Error : : CantAttach ( ) ;
//cerr << "couldn't attach to process" << endl;
//return false; // couldn't attach to process, no go
2009-11-09 16:18:20 -07:00
}
2009-11-10 20:37:28 -07:00
d - > offset_descriptor = d - > p - > getDescriptor ( ) ;
2009-09-13 18:02:46 -06:00
// process is attached, everything went just fine... hopefully
return true ;
}
2009-11-10 20:37:28 -07:00
bool API : : Detach ( )
2009-09-13 18:02:46 -06:00
{
2009-11-10 20:37:28 -07:00
if ( ! d - > p - > detach ( ) )
2009-11-09 16:18:20 -07:00
{
2009-10-29 12:16:51 -06:00
return false ;
2009-11-09 16:18:20 -07:00
}
2009-12-12 16:56:28 -07:00
if ( d - > pm ! = NULL )
2009-11-09 16:18:20 -07:00
{
2009-11-10 20:37:28 -07:00
delete d - > pm ;
2009-11-09 16:18:20 -07:00
}
2009-11-10 20:37:28 -07:00
d - > pm = NULL ;
d - > p = NULL ;
d - > offset_descriptor = NULL ;
2009-09-13 18:02:46 -06:00
return true ;
}
2009-10-04 07:08:20 -06:00
2009-11-10 20:37:28 -07:00
bool API : : isAttached ( )
2009-10-04 07:08:20 -06:00
{
2010-02-15 16:04:15 -07:00
return d - > p ! = NULL ;
2009-10-04 07:08:20 -06:00
}
2009-11-03 18:01:55 -07:00
2009-11-16 09:47:22 -07:00
bool API : : Suspend ( )
{
return d - > p - > suspend ( ) ;
}
2010-01-01 19:25:21 -07:00
bool API : : AsyncSuspend ( )
{
return d - > p - > asyncSuspend ( ) ;
}
2009-11-16 09:47:22 -07:00
bool API : : Resume ( )
{
return d - > p - > resume ( ) ;
}
2009-11-18 18:48:18 -07:00
bool API : : ForceResume ( )
{
return d - > p - > forceresume ( ) ;
}
2009-11-16 09:47:22 -07:00
bool API : : isSuspended ( )
{
return d - > p - > isSuspended ( ) ;
}
2010-02-27 17:25:04 -07:00
void API : : ReadRaw ( const uint32_t offset , const uint32_t size , uint8_t * target )
2009-11-03 18:01:55 -07:00
{
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( offset , size , target ) ;
2009-11-03 18:01:55 -07:00
}
2009-11-11 18:05:07 -07:00
2010-02-27 17:25:04 -07:00
void API : : WriteRaw ( const uint32_t offset , const uint32_t size , uint8_t * source )
2009-11-11 18:05:07 -07:00
{
2009-12-22 14:19:39 -07:00
g_pProcess - > write ( offset , size , source ) ;
2009-11-11 18:05:07 -07:00
}
bool API : : InitViewAndCursor ( )
{
2009-12-12 16:56:28 -07:00
d - > window_x_offset = d - > offset_descriptor - > getAddress ( " window_x " ) ;
d - > window_y_offset = d - > offset_descriptor - > getAddress ( " window_y " ) ;
d - > window_z_offset = d - > offset_descriptor - > getAddress ( " window_z " ) ;
d - > cursor_xyz_offset = d - > offset_descriptor - > getAddress ( " cursor_xyz " ) ;
d - > current_cursor_creature_offset = d - > offset_descriptor - > getAddress ( " current_cursor_creature " ) ;
2009-12-12 12:52:30 -07:00
2010-01-18 09:44:24 -07:00
d - > current_menu_state_offset = d - > offset_descriptor - > getAddress ( " current_menu_state " ) ;
2009-12-12 16:56:28 -07:00
d - > pause_state_offset = d - > offset_descriptor - > getAddress ( " pause_state " ) ;
d - > view_screen_offset = d - > offset_descriptor - > getAddress ( " view_screen " ) ;
2010-01-18 09:44:24 -07:00
if ( d - > window_x_offset & & d - > window_y_offset & & d - > window_z_offset & &
d - > current_cursor_creature_offset & & d - > current_menu_state_offset & &
d - > pause_state_offset & & d - > view_screen_offset )
2009-11-11 18:05:07 -07:00
{
d - > cursorWindowInited = true ;
return true ;
}
else
{
return false ;
}
}
2009-11-17 20:35:43 -07:00
bool API : : InitViewSize ( )
{
2009-12-12 16:56:28 -07:00
d - > window_dims_offset = d - > offset_descriptor - > getAddress ( " window_dims " ) ;
if ( d - > window_dims_offset )
2009-11-17 20:35:43 -07:00
{
d - > viewSizeInited = true ;
return true ;
}
else
{
return false ;
}
}
2009-11-11 18:39:43 -07:00
bool API : : getViewCoords ( int32_t & x , int32_t & y , int32_t & z )
2009-11-11 18:05:07 -07:00
{
2010-02-27 17:25:04 -07:00
if ( ! d - > cursorWindowInited ) return false ;
2009-12-22 14:19:39 -07:00
g_pProcess - > readDWord ( d - > window_x_offset , ( uint32_t & ) x ) ;
g_pProcess - > readDWord ( d - > window_y_offset , ( uint32_t & ) y ) ;
g_pProcess - > readDWord ( d - > window_z_offset , ( uint32_t & ) z ) ;
2009-11-11 18:39:43 -07:00
return true ;
2009-11-11 18:05:07 -07:00
}
//FIXME: confine writing of coords to map bounds?
2010-02-27 17:25:04 -07:00
bool API : : setViewCoords ( const int32_t x , const int32_t y , const int32_t z )
2009-11-11 18:05:07 -07:00
{
2010-02-27 17:25:04 -07:00
if ( ! d - > cursorWindowInited ) return false ;
g_pProcess - > writeDWord ( d - > window_x_offset , ( uint32_t ) x ) ;
g_pProcess - > writeDWord ( d - > window_y_offset , ( uint32_t ) y ) ;
g_pProcess - > writeDWord ( d - > window_z_offset , ( uint32_t ) z ) ;
2009-11-11 18:39:43 -07:00
return true ;
2009-11-11 18:05:07 -07:00
}
2009-11-11 18:39:43 -07:00
bool API : : getCursorCoords ( int32_t & x , int32_t & y , int32_t & z )
2009-11-11 18:05:07 -07:00
{
2010-02-27 17:25:04 -07:00
if ( ! d - > cursorWindowInited ) return false ;
2009-11-11 18:39:43 -07:00
int32_t coords [ 3 ] ;
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( d - > cursor_xyz_offset , 3 * sizeof ( int32_t ) , ( uint8_t * ) coords ) ;
2009-11-11 18:05:07 -07:00
x = coords [ 0 ] ;
y = coords [ 1 ] ;
z = coords [ 2 ] ;
2009-12-12 16:56:28 -07:00
if ( x = = - 30000 ) return false ;
2009-11-11 18:39:43 -07:00
return true ;
2009-11-11 18:05:07 -07:00
}
//FIXME: confine writing of coords to map bounds?
2010-02-27 17:25:04 -07:00
bool API : : setCursorCoords ( const int32_t x , const int32_t y , const int32_t z )
2009-11-11 18:05:07 -07:00
{
2010-02-27 17:25:04 -07:00
if ( ! d - > cursorWindowInited ) return false ;
2009-12-12 16:56:28 -07:00
int32_t coords [ 3 ] = { x , y , z } ;
2009-12-22 14:19:39 -07:00
g_pProcess - > write ( d - > cursor_xyz_offset , 3 * sizeof ( int32_t ) , ( uint8_t * ) coords ) ;
2009-11-11 18:39:43 -07:00
return true ;
2009-11-13 20:46:56 -07:00
}
2009-12-12 16:56:28 -07:00
bool API : : getWindowSize ( int32_t & width , int32_t & height )
2009-11-17 20:35:43 -07:00
{
2010-02-27 17:25:04 -07:00
if ( ! d - > viewSizeInited ) return false ;
2009-11-17 20:35:43 -07:00
int32_t coords [ 2 ] ;
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( d - > window_dims_offset , 2 * sizeof ( int32_t ) , ( uint8_t * ) coords ) ;
2009-11-17 20:35:43 -07:00
width = coords [ 0 ] ;
height = coords [ 1 ] ;
return true ;
}
2010-02-25 05:41:57 -07:00
/*
2010-02-11 14:08:39 -07:00
bool API : : getClassIDMapping ( vector < string > & objecttypes )
{
if ( isAttached ( ) )
{
d - > offset_descriptor - > getClassIDMapping ( objecttypes ) ;
return true ;
}
return false ;
}
2010-02-25 05:41:57 -07:00
*/
2010-02-22 15:34:20 -07:00
memory_info * API : : getMemoryInfo ( )
2009-11-13 20:46:56 -07:00
{
2010-02-22 15:34:20 -07:00
return d - > offset_descriptor ;
2009-11-14 21:25:00 -07:00
}
Process * API : : getProcess ( )
{
return d - > p ;
2009-11-17 07:52:47 -07:00
}
2009-11-17 20:35:43 -07:00
2009-12-22 14:19:39 -07:00
DFWindow * API : : getWindow ( )
{
return d - > p - > getWindow ( ) ;
}
2010-02-11 14:08:39 -07:00
bool API : : InitReadItems ( uint32_t & numitems )
2009-11-17 07:52:47 -07:00
{
2009-12-12 16:56:28 -07:00
int items = d - > offset_descriptor - > getAddress ( " items " ) ;
d - > item_material_offset = d - > offset_descriptor - > getOffset ( " item_materials " ) ;
2010-02-11 14:08:39 -07:00
if ( items & & d - > item_material_offset )
{
2010-02-15 16:04:15 -07:00
d - > p_itm = new DfVector ( d - > p - > readVector ( items , 4 ) ) ;
2010-02-11 14:08:39 -07:00
d - > itemsInited = true ;
numitems = d - > p_itm - > getSize ( ) ;
return true ;
}
else
{
d - > itemsInited = false ;
numitems = 0 ;
return false ;
}
2009-11-17 07:52:47 -07:00
}
2010-02-27 17:25:04 -07:00
bool API : : ReadItem ( const uint32_t index , t_item & item )
2009-11-17 07:52:47 -07:00
{
2010-02-27 17:25:04 -07:00
if ( ! d - > itemsInited ) return false ;
2009-11-17 07:52:47 -07:00
t_item_df40d item_40d ;
// read pointer from vector at position
2009-12-12 16:56:28 -07:00
uint32_t temp = * ( uint32_t * ) d - > p_itm - > at ( index ) ;
2009-11-17 07:52:47 -07:00
//read building from memory
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( temp , sizeof ( t_item_df40d ) , ( uint8_t * ) & item_40d ) ;
2009-11-17 20:35:43 -07:00
2009-11-17 07:52:47 -07:00
// transform
int32_t type = - 1 ;
2010-02-25 05:41:57 -07:00
d - > offset_descriptor - > resolveObjectToClassID ( temp , type ) ;
2009-11-17 07:52:47 -07:00
item . origin = temp ;
item . vtable = item_40d . vtable ;
item . x = item_40d . x ;
item . y = item_40d . y ;
item . z = item_40d . z ;
item . type = type ;
item . ID = item_40d . ID ;
2010-01-18 09:44:24 -07:00
item . flags . whole = item_40d . flags ;
2009-12-12 16:56:28 -07:00
2009-11-17 20:35:43 -07:00
//TODO certain item types (creature based, threads, seeds, bags do not have the first matType byte, instead they have the material index only located at 0x68
2009-12-22 14:19:39 -07:00
g_pProcess - > read ( temp + d - > item_material_offset , sizeof ( t_matglossPair ) , ( uint8_t * ) & item . material ) ;
2009-11-17 20:35:43 -07:00
//for(int i = 0; i < 0xCC; i++){ // used for item research
// uint8_t byte = MreadByte(temp+i);
// item.bytes.push_back(byte);
2009-12-12 16:56:28 -07:00
//}
2009-11-17 07:52:47 -07:00
return true ;
}
void API : : FinishReadItems ( )
{
2010-02-27 17:25:04 -07:00
if ( d - > p_itm )
{
delete d - > p_itm ;
d - > p_itm = NULL ;
}
2009-11-17 07:52:47 -07:00
d - > itemsInited = false ;
2009-12-12 12:52:30 -07:00
}
bool API : : ReadPauseState ( )
{
2010-02-27 17:25:04 -07:00
// replace with an exception
if ( ! d - > cursorWindowInited ) return false ;
2009-12-12 12:52:30 -07:00
2009-12-22 14:19:39 -07:00
uint32_t pauseState = g_pProcess - > readDWord ( d - > pause_state_offset ) ;
2010-02-21 16:18:44 -07:00
return pauseState & 1 ;
2009-12-12 12:52:30 -07:00
}
2010-01-18 09:44:24 -07:00
uint32_t API : : ReadMenuState ( )
{
2010-02-27 17:25:04 -07:00
if ( d - > cursorWindowInited )
return ( g_pProcess - > readDWord ( d - > current_menu_state_offset ) ) ;
return false ;
2010-01-18 09:44:24 -07:00
}
2009-12-12 16:56:28 -07:00
bool API : : ReadViewScreen ( t_viewscreen & screen )
2009-12-12 12:52:30 -07:00
{
2010-02-27 17:25:04 -07:00
if ( ! d - > cursorWindowInited ) return false ;
2009-12-22 14:19:39 -07:00
uint32_t last = g_pProcess - > readDWord ( d - > view_screen_offset ) ;
uint32_t screenAddr = g_pProcess - > readDWord ( last ) ;
uint32_t nextScreenPtr = g_pProcess - > readDWord ( last + 4 ) ;
2009-12-12 16:56:28 -07:00
while ( nextScreenPtr ! = 0 )
{
2009-12-12 12:52:30 -07:00
last = nextScreenPtr ;
2009-12-22 14:19:39 -07:00
screenAddr = g_pProcess - > readDWord ( nextScreenPtr ) ;
nextScreenPtr = g_pProcess - > readDWord ( nextScreenPtr + 4 ) ;
2009-12-12 12:52:30 -07:00
}
2010-02-25 05:41:57 -07:00
return d - > offset_descriptor - > resolveObjectToClassID ( last , screen . type ) ;
2009-12-12 12:52:30 -07:00
}
2010-02-27 17:25:04 -07:00
2009-12-31 19:14:41 -07:00
bool API : : ReadItemTypes ( vector < vector < t_itemType > > & itemTypes )
{
memory_info * minfo = d - > offset_descriptor ;
int matgloss_address = minfo - > getAddress ( " matgloss " ) ;
int matgloss_skip = minfo - > getHexValue ( " matgloss_skip " ) ;
int item_type_name_offset = minfo - > getOffset ( " item_type_name " ) ;
2010-02-27 17:25:04 -07:00
for ( int i = 8 ; i < 20 ; i + + )
{
2010-02-15 16:04:15 -07:00
DfVector p_temp = d - > p - > readVector ( matgloss_address + i * matgloss_skip , 4 ) ;
2009-12-31 19:14:41 -07:00
vector < t_itemType > typesForVec ;
for ( uint32_t j = 0 ; j < p_temp . getSize ( ) ; j + + )
{
t_itemType currType ;
uint32_t temp = * ( uint32_t * ) p_temp [ j ] ;
// Mread(temp+40,sizeof(name),(uint8_t *) name);
2010-02-15 16:04:15 -07:00
d - > p - > readSTLString ( temp + 4 , currType . id , 128 ) ;
d - > p - > readSTLString ( temp + item_type_name_offset , currType . name , 128 ) ;
2009-12-31 19:14:41 -07:00
//stringsForVec.push_back(string(name));
typesForVec . push_back ( currType ) ;
}
itemTypes . push_back ( typesForVec ) ;
}
return true ;
2010-02-27 17:25:04 -07:00
}