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-03-28 09:22:15 -06:00
# include <shms.h>
# include <mod-core.h>
# include <mod-maps.h>
# include <mod-creature40d.h>
2009-11-10 20:37:28 -07:00
using namespace DFHack ;
2009-10-04 07:08:20 -06:00
2010-04-02 19:52:46 -06:00
# include "private/APIPrivate.h"
2010-03-08 10:27:19 -07:00
2009-12-12 16:56:28 -07:00
API : : API ( const string path_to_xml )
2010-04-02 19:52:46 -06:00
: d ( new APIPrivate ( ) )
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 - > pm = NULL ;
2010-03-04 16:05:01 -07:00
d - > shm_start = 0 ;
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
{
2010-03-16 15:12:05 -06:00
// FIXME: call all finishread* methods here
Detach ( ) ;
2009-11-10 20:37:28 -07:00
delete d ;
2009-09-13 18:02:46 -06:00
}
2010-04-02 19:52:46 -06:00
bool API : : Attach ( )
2009-09-13 18:02:46 -06:00
{
2010-04-02 19:52:46 -06:00
// detach all processes, destroy manager
if ( d - > pm = = 0 )
2010-03-04 16:05:01 -07:00
{
2010-04-02 19:52:46 -06:00
d - > pm = new ProcessEnumerator ( d - > xml ) ; // FIXME: handle bad XML better
2010-03-04 16:05:01 -07:00
}
2010-04-02 19:52:46 -06:00
else
2009-09-13 18:02:46 -06:00
{
2010-04-02 19:52:46 -06:00
d - > pm - > purge ( ) ;
2009-09-13 18:02:46 -06:00
}
2010-04-02 19:52:46 -06:00
// find a process (ProcessManager can find multiple when used properly)
if ( ! d - > pm - > findProcessess ( ) )
2009-11-18 14:27:13 -07:00
{
2010-04-02 19:52:46 -06:00
throw Error : : NoProcess ( ) ;
//cerr << "couldn't find a suitable process" << endl;
2010-02-27 18:37:05 -07:00
//return false;
2009-11-18 14:27:13 -07:00
}
2010-04-02 19:52:46 -06:00
d - > p = ( * d - > pm ) [ 0 ] ;
if ( ! d - > p - > attach ( ) )
2009-09-13 18:02:46 -06:00
{
2010-04-02 19:52:46 -06:00
throw Error : : CantAttach ( ) ;
//cerr << "couldn't attach to process" << endl;
//return false; // couldn't attach to process, no go
2009-09-13 18:02:46 -06:00
}
2010-04-02 19:52:46 -06:00
d - > shm_start = d - > p - > getSHMStart ( ) ;
d - > offset_descriptor = d - > p - > getDescriptor ( ) ;
// process is attached, everything went just fine... hopefully
2009-09-13 18:02:46 -06:00
return true ;
}
2009-10-04 07:08:20 -06:00
2010-04-02 19:52:46 -06:00
bool API : : Detach ( )
2009-09-13 18:02:46 -06:00
{
2010-04-02 19:52:46 -06:00
if ( ! d - > p )
2010-02-17 18:10:39 -07:00
return false ;
2010-04-02 19:52:46 -06:00
if ( ! d - > p - > detach ( ) )
2010-03-04 16:05:01 -07:00
{
return false ;
}
2010-04-02 19:52:46 -06:00
if ( d - > pm ! = NULL )
2009-09-13 18:02:46 -06:00
{
2010-04-02 19:52:46 -06:00
delete d - > pm ;
2009-09-13 18:02:46 -06:00
}
2010-04-02 19:52:46 -06:00
d - > pm = NULL ;
d - > p = NULL ;
d - > shm_start = 0 ;
d - > offset_descriptor = NULL ;
2009-12-12 12:52:30 -07:00
return true ;
}
2009-09-13 18:02:46 -06:00
2010-04-02 19:52:46 -06:00
bool API : : isAttached ( )
2009-09-13 18:02:46 -06:00
{
2010-04-02 19:52:46 -06:00
return d - > p ! = NULL ;
2009-09-13 18:02:46 -06:00
}
2010-04-02 19:52:46 -06:00
bool API : : Suspend ( )
2009-09-13 18:02:46 -06:00
{
2010-04-02 19:52:46 -06:00
return d - > p - > suspend ( ) ;
2009-09-13 18:02:46 -06:00
}
2010-04-02 19:52:46 -06:00
bool API : : AsyncSuspend ( )
2009-09-13 18:02:46 -06:00
{
2010-04-02 19:52:46 -06:00
return d - > p - > asyncSuspend ( ) ;
2009-09-13 18:02:46 -06:00
}
2010-04-02 19:52:46 -06:00
bool API : : Resume ( )
2009-09-13 18:02:46 -06:00
{
2010-04-02 19:52:46 -06:00
return d - > p - > resume ( ) ;
2009-09-13 18:02:46 -06:00
}
2010-04-02 19:52:46 -06:00
bool API : : ForceResume ( )
2009-09-18 05:31:56 -06:00
{
2010-04-02 19:52:46 -06:00
return d - > p - > forceresume ( ) ;
2009-09-18 05:31:56 -06:00
}
2010-04-02 19:52:46 -06:00
bool API : : isSuspended ( )
2009-09-13 18:02:46 -06:00
{
2010-04-02 19:52:46 -06:00
return d - > p - > isSuspended ( ) ;
2009-09-13 18:02:46 -06:00
}
2010-04-02 19:52:46 -06:00
void API : : ReadRaw ( const uint32_t offset , const uint32_t size , uint8_t * target )
2009-09-13 18:02:46 -06:00
{
2010-04-02 19:52:46 -06:00
g_pProcess - > read ( offset , size , target ) ;
2009-09-13 18:02:46 -06:00
}
2010-04-02 19:52:46 -06:00
void API : : WriteRaw ( const uint32_t offset , const uint32_t size , uint8_t * source )
2009-09-13 18:02:46 -06:00
{
2010-04-02 19:52:46 -06:00
g_pProcess - > write ( offset , size , source ) ;
2009-12-31 19:14:41 -07:00
}
2010-04-02 19:52:46 -06:00
memory_info * API : : getMemoryInfo ( )
2009-12-31 19:14:41 -07:00
{
2010-04-02 19:52:46 -06:00
return d - > offset_descriptor ;
2009-09-13 18:02:46 -06:00
}
2010-04-02 19:52:46 -06:00
Process * API : : getProcess ( )
2009-10-22 19:39:19 -06:00
{
2010-04-02 19:52:46 -06:00
return d - > p ;
2009-10-22 19:39:19 -06:00
}
2010-04-02 19:52:46 -06:00
DFWindow * API : : getWindow ( )
2009-09-13 18:02:46 -06:00
{
2010-04-02 19:52:46 -06:00
return d - > p - > getWindow ( ) ;
2009-09-13 18:02:46 -06:00
}
2010-04-02 19:52:46 -06:00
/*
2009-09-13 18:02:46 -06:00
// 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
{
2010-03-22 17:35:23 -06:00
int buildings = 0 ;
try
{
buildings = d - > offset_descriptor - > getAddress ( " buildings " ) ;
}
catch ( Error : : MissingMemoryDefinition )
{
return false ;
}
2010-02-27 19:34:54 -07:00
d - > buildingsInited = true ;
2010-03-29 18:26:52 -06:00
d - > p_bld = new DfVector ( d - > p , buildings , 4 ) ;
2010-02-27 19:34:54 -07:00
numbuildings = d - > p_bld - > getSize ( ) ;
return true ;
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
}
2010-03-20 10:30:13 -06:00
bool API : : InitReadEffects ( uint32_t & numeffects )
{
if ( d - > effectsInited )
FinishReadEffects ( ) ;
2010-03-22 17:35:23 -06:00
int effects = 0 ;
try
{
effects = d - > offset_descriptor - > getAddress ( " effects_vector " ) ;
}
catch ( Error : : MissingMemoryDefinition )
{
return false ;
}
2010-03-20 10:30:13 -06:00
d - > effectsInited = true ;
2010-03-29 18:26:52 -06:00
d - > p_effect = new DfVector ( d - > p , effects , 4 ) ;
2010-03-20 10:30:13 -06:00
numeffects = d - > p_effect - > getSize ( ) ;
return true ;
}
2010-03-26 06:38:49 -06:00
bool API : : ReadEffect ( const uint32_t index , t_effect_df40d & effect )
2010-03-20 10:30:13 -06:00
{
if ( ! d - > effectsInited )
return false ;
if ( index > = d - > p_effect - > getSize ( ) )
return false ;
// read pointer from vector at position
uint32_t temp = * ( uint32_t * ) d - > p_effect - > at ( index ) ;
//read effect from memory
g_pProcess - > read ( temp , sizeof ( t_effect_df40d ) , ( uint8_t * ) & effect ) ;
return true ;
}
// use with care!
2010-03-26 06:38:49 -06:00
bool API : : WriteEffect ( const uint32_t index , const t_effect_df40d & effect )
2010-03-20 10:30:13 -06:00
{
if ( ! d - > effectsInited )
return false ;
if ( index > = d - > p_effect - > getSize ( ) )
return false ;
// read pointer from vector at position
uint32_t temp = * ( uint32_t * ) d - > p_effect - > at ( index ) ;
// write effect to memory
g_pProcess - > write ( temp , sizeof ( t_effect_df40d ) , ( uint8_t * ) & effect ) ;
return true ;
}
void API : : FinishReadEffects ( )
{
if ( d - > p_effect )
{
delete d - > p_effect ;
d - > p_effect = NULL ;
}
d - > effectsInited = 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
{
2010-03-22 17:35:23 -06:00
int constructions = 0 ;
try
{
constructions = d - > offset_descriptor - > getAddress ( " constructions " ) ;
}
catch ( Error : : MissingMemoryDefinition )
{
return false ;
}
2010-03-29 18:26:52 -06:00
d - > p_cons = new DfVector ( d - > p , constructions , 4 ) ;
2010-02-27 19:34:54 -07:00
d - > constructionsInited = true ;
numconstructions = d - > p_cons - > getSize ( ) ;
return true ;
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
{
2010-02-27 19:34:54 -07:00
try
2010-02-11 14:08:39 -07:00
{
2010-02-27 19:34:54 -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
d - > vegetationInited = true ;
2010-03-29 18:26:52 -06:00
d - > p_veg = new DfVector ( d - > p , vegetation , 4 ) ;
2010-02-11 14:08:39 -07:00
numplants = d - > p_veg - > getSize ( ) ;
return true ;
}
2010-02-27 19:34:54 -07:00
catch ( Error : : MissingMemoryDefinition & )
2010-02-11 14:08:39 -07:00
{
d - > vegetationInited = false ;
numplants = 0 ;
2010-02-27 19:34:54 -07:00
throw ;
2010-02-11 14:08:39 -07:00
}
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-04-02 19:52:46 -06:00
*/
/*
2010-02-17 16:33:08 -07:00
bool API : : InitReadNotes ( uint32_t & numnotes )
{
2010-02-27 19:34:54 -07:00
try
2010-02-17 16:33:08 -07:00
{
2010-02-27 19:34:54 -07:00
memory_info * minfo = d - > offset_descriptor ;
int notes = minfo - > getAddress ( " notes " ) ;
d - > note_foreground_offset = minfo - > getOffset ( " note_foreground " ) ;
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-03-29 18:26:52 -06:00
d - > p_notes = new DfVector ( d - > p , notes , 4 ) ;
2010-02-17 16:33:08 -07:00
d - > notesInited = true ;
numnotes = d - > p_notes - > getSize ( ) ;
return true ;
}
2010-02-27 19:34:54 -07:00
catch ( Error : : MissingMemoryDefinition & )
2010-02-17 16:33:08 -07:00
{
d - > notesInited = false ;
numnotes = 0 ;
2010-02-27 19:34:54 -07:00
throw ;
2010-02-17 16:33:08 -07:00
}
}
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-03-22 17:37:35 -06:00
if ( ! d - > InitReadNames ( ) ) return false ;
2010-02-27 19:34:54 -07:00
try
2010-02-22 19:25:57 -07:00
{
2010-03-22 17:37:35 -06:00
2010-02-27 19:34:54 -07:00
memory_info * minfo = d - > offset_descriptor ;
int allSettlements = minfo - > getAddress ( " settlements " ) ;
int currentSettlement = minfo - > getAddress ( " settlement_current " ) ;
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-03-29 18:26:52 -06:00
d - > p_settlements = new DfVector ( d - > p , allSettlements , 4 ) ;
d - > p_current_settlement = new DfVector ( d - > p , currentSettlement , 4 ) ;
2010-02-22 19:25:57 -07:00
d - > settlementsInited = true ;
numsettlements = d - > p_settlements - > getSize ( ) ;
return true ;
}
2010-02-27 19:34:54 -07:00
catch ( Error : : MissingMemoryDefinition & )
2010-02-22 19:25:57 -07:00
{
d - > settlementsInited = false ;
numsettlements = 0 ;
2010-02-27 19:34:54 -07:00
throw ;
2010-02-22 19:25:57 -07:00
}
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-03-16 15:12:05 -06:00
d - > readName ( settlement . name , temp + d - > settlement_name_offset ) ;
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 ;
}
2010-02-27 19:34:54 -07:00
2010-02-22 19:25:57 -07:00
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 ;
2010-03-16 15:12:05 -06:00
d - > readName ( settlement . name , temp + d - > settlement_name_offset ) ;
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 ;
}
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 ( )
{
2010-02-27 19:34:54 -07:00
try
2010-02-17 19:08:54 -07:00
{
2010-02-27 19:34:54 -07:00
memory_info * minfo = d - > offset_descriptor ;
d - > hotkey_start = minfo - > getAddress ( " hotkey_start " ) ;
d - > hotkey_mode_offset = minfo - > getOffset ( " hotkey_mode " ) ;
d - > hotkey_xyz_offset = minfo - > getOffset ( " hotkey_xyz " ) ;
d - > hotkey_size = minfo - > getHexValue ( " hotkey_size " ) ;
2010-02-18 10:06:32 -07:00
d - > hotkeyInited = true ;
return true ;
2010-02-17 19:08:54 -07:00
}
2010-02-27 19:34:54 -07:00
catch ( Error : : MissingMemoryDefinition & )
2010-02-17 19:08:54 -07:00
{
d - > hotkeyInited = false ;
2010-02-27 19:34:54 -07:00
throw ;
2010-02-17 19:08:54 -07:00
}
}
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 ;
2010-03-28 09:22:15 -06:00
if ( d - > creature_module )
2009-11-16 09:47:22 -07:00
{
2010-03-28 09:22:15 -06:00
// supply the module with offsets so it can work with them
SHMCREATURESHDR - > index = index ;
SHMCREATURESHDR - > x = x1 ;
SHMCREATURESHDR - > y = y1 ;
SHMCREATURESHDR - > z = z1 ;
SHMCREATURESHDR - > x2 = x2 ;
SHMCREATURESHDR - > y2 = y2 ;
SHMCREATURESHDR - > z2 = z2 ;
const uint32_t cmd = Creatures : : CREATURE_FIND_IN_BOX + ( d - > creature_module < < 16 ) ;
g_pProcess - > SetAndWait ( cmd ) ;
if ( SHMCREATURESHDR - > index ! = - 1 )
memcpy ( & furball , SHMDATA ( void ) , sizeof ( t_creature ) ) ;
return SHMCREATURESHDR - > index ;
}
else
{
uint16_t coords [ 3 ] ;
uint32_t size = d - > p_cre - > getSize ( ) ;
while ( uint32_t ( index ) < size )
2009-11-16 09:47:22 -07:00
{
2010-03-28 09:22:15 -06:00
// read pointer from vector at position
uint32_t temp = * ( uint32_t * ) d - > p_cre - > at ( index ) ;
g_pProcess - > read ( temp + d - > creatures . creature_pos_offset , 3 * sizeof ( uint16_t ) , ( uint8_t * ) & coords ) ;
if ( coords [ 0 ] > = x1 & & coords [ 0 ] < x2 )
2009-11-16 09:47:22 -07:00
{
2010-03-28 09:22:15 -06:00
if ( coords [ 1 ] > = y1 & & coords [ 1 ] < y2 )
2009-11-16 09:47:22 -07:00
{
2010-03-28 09:22:15 -06:00
if ( coords [ 2 ] > = z1 & & coords [ 2 ] < z2 )
{
ReadCreature ( index , furball ) ;
return index ;
}
2009-11-16 09:47:22 -07:00
}
}
2010-03-28 09:22:15 -06:00
index + + ;
2009-11-16 09:47:22 -07:00
}
2010-03-28 09:22:15 -06: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 18:50:16 -07:00
return true ;
2009-12-31 18:49:32 -07:00
}
2010-04-02 19:52:46 -06:00
*/
/*
2010-03-08 06:50:32 -07:00
bool API : : InitReadNameTables ( vector < vector < string > > & translations , vector < vector < string > > & foreign_languages ) //(map< string, vector<string> > & nameTable)
2009-12-12 16:56:28 -07:00
{
2010-02-27 19:34:54 -07:00
try
2009-12-12 16:56:28 -07:00
{
2010-02-27 19:34:54 -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-03-08 10:27:19 -07:00
int sizeof_string = d - > offset_descriptor - > getHexValue ( " sizeof_string " ) ;
2010-02-27 19:34:54 -07:00
2010-03-29 18:26:52 -06:00
DfVector genericVec ( d - > p , genericAddress , 4 ) ;
DfVector transVec ( d - > p , transAddress , 4 ) ;
2009-12-12 16:56:28 -07:00
2010-03-08 10:27:19 -07:00
translations . resize ( 10 ) ;
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-03-08 10:27:19 -07:00
for ( int i = 0 ; i < 10 ; i + + )
{
string word = d - > p - > readSTLString ( genericNamePtr + i * sizeof_string ) ;
translations [ i ] . push_back ( word ) ;
}
2010-02-11 14:08:39 -07:00
}
2010-03-08 10:27:19 -07:00
foreign_languages . resize ( transVec . getSize ( ) ) ;
2010-02-11 14:08:39 -07:00
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-03-08 05:56:32 -07:00
//string transName = d->p->readSTLString (transPtr);
2010-03-29 18:26:52 -06:00
DfVector trans_names_vec ( d - > p , 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-03-08 05:56:32 -07:00
foreign_languages [ i ] . push_back ( name ) ;
2010-02-11 14:08:39 -07:00
}
2009-11-07 14:05:10 -07:00
}
2010-02-11 14:08:39 -07:00
d - > nameTablesInited = true ;
return true ;
}
2010-02-27 19:34:54 -07:00
catch ( Error : : MissingMemoryDefinition & )
2010-02-11 14:08:39 -07:00
{
d - > nameTablesInited = false ;
2010-02-27 19:34:54 -07:00
throw ;
2009-11-07 14:05:10 -07:00
}
}
2010-03-08 05:56:32 -07:00
string API : : TranslateName ( const DFHack : : t_name & name , const std : : vector < std : : vector < std : : string > > & translations , const std : : vector < std : : vector < std : : string > > & foreign_languages , bool inEnglish )
2010-02-22 19:25:57 -07:00
{
2010-03-08 10:27:19 -07:00
string out ;
2010-02-22 19:25:57 -07:00
assert ( d - > nameTablesInited ) ;
map < string , vector < string > > : : const_iterator it ;
2010-03-08 10:27:19 -07:00
if ( ! inEnglish )
2010-02-22 19:25:57 -07:00
{
2010-03-08 10:27:19 -07:00
if ( name . words [ 0 ] > = 0 | | name . words [ 1 ] > = 0 )
2010-02-22 19:25:57 -07:00
{
2010-03-08 10:27:19 -07:00
if ( name . words [ 0 ] > = 0 ) out . append ( foreign_languages [ name . language ] [ name . words [ 0 ] ] ) ;
if ( name . words [ 1 ] > = 0 ) out . append ( foreign_languages [ name . language ] [ name . words [ 1 ] ] ) ;
out [ 0 ] = toupper ( out [ 0 ] ) ;
2010-02-22 19:25:57 -07:00
}
2010-03-08 10:27:19 -07:00
if ( name . words [ 5 ] > = 0 )
2009-12-12 16:56:28 -07:00
{
2010-03-08 10:27:19 -07:00
string word ;
for ( int i = 2 ; i < = 5 ; i + + )
if ( name . words [ i ] > = 0 ) word . append ( foreign_languages [ name . language ] [ name . words [ i ] ] ) ;
word [ 0 ] = toupper ( word [ 0 ] ) ;
if ( out . length ( ) > 0 ) out . append ( " " ) ;
out . append ( word ) ;
2009-12-12 12:52:30 -07:00
}
2010-03-08 10:27:19 -07:00
if ( name . words [ 6 ] > = 0 )
{
string word ;
word . append ( foreign_languages [ name . language ] [ name . words [ 6 ] ] ) ;
word [ 0 ] = toupper ( word [ 0 ] ) ;
if ( out . length ( ) > 0 ) out . append ( " " ) ;
out . append ( word ) ;
}
}
else
2009-12-12 16:56:28 -07:00
{
2010-03-08 10:27:19 -07:00
if ( name . words [ 0 ] > = 0 | | name . words [ 1 ] > = 0 )
2009-12-12 16:56:28 -07:00
{
2010-03-08 10:27:19 -07:00
if ( name . words [ 0 ] > = 0 ) out . append ( translations [ name . parts_of_speech [ 0 ] + 1 ] [ name . words [ 0 ] ] ) ;
if ( name . words [ 1 ] > = 0 ) out . append ( translations [ name . parts_of_speech [ 1 ] + 1 ] [ name . words [ 1 ] ] ) ;
out [ 0 ] = toupper ( out [ 0 ] ) ;
}
if ( name . words [ 5 ] > = 0 )
{
if ( out . length ( ) > 0 )
out . append ( " the " ) ;
else
out . append ( " The " ) ;
string word ;
for ( int i = 2 ; i < = 5 ; i + + )
2009-12-12 16:56:28 -07:00
{
2010-03-08 10:27:19 -07:00
if ( name . words [ i ] > = 0 )
{
word = translations [ name . parts_of_speech [ i ] + 1 ] [ name . words [ i ] ] ;
word [ 0 ] = toupper ( word [ 0 ] ) ;
out . append ( " " + word ) ;
}
2009-12-12 16:56:28 -07:00
}
2010-03-08 10:27:19 -07:00
}
if ( name . words [ 6 ] > = 0 )
{
if ( out . length ( ) > 0 )
out . append ( " of " ) ;
else
out . append ( " Of " ) ;
string word ;
word . append ( translations [ name . parts_of_speech [ 6 ] + 1 ] [ name . words [ 6 ] ] ) ;
word [ 0 ] = toupper ( word [ 0 ] ) ;
out . append ( " " + word ) ;
2009-12-12 12:52:30 -07:00
}
}
2010-03-08 10:27:19 -07:00
return out ;
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
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 ;
}
2010-02-25 05:41:57 -07:00
*/
2009-12-22 14:19:39 -07:00
2010-04-02 19:52:46 -06:00
/*
2010-02-11 14:08:39 -07:00
bool API : : InitReadItems ( uint32_t & numitems )
2009-11-17 07:52:47 -07:00
{
2010-02-27 19:34:54 -07:00
try
2010-02-11 14:08:39 -07:00
{
2010-02-27 19:34:54 -07:00
int items = d - > offset_descriptor - > getAddress ( " items " ) ;
d - > item_material_offset = d - > offset_descriptor - > getOffset ( " item_materials " ) ;
2010-03-29 18:26:52 -06:00
d - > p_itm = new DfVector ( d - > p , items , 4 ) ;
2010-02-11 14:08:39 -07:00
d - > itemsInited = true ;
numitems = d - > p_itm - > getSize ( ) ;
return true ;
}
2010-02-27 19:34:54 -07:00
catch ( Error : : MissingMemoryDefinition & )
2010-02-11 14:08:39 -07:00
{
d - > itemsInited = false ;
numitems = 0 ;
2010-02-27 19:34:54 -07:00
throw ;
2010-02-11 14:08:39 -07:00
}
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
}
2010-04-02 19:52:46 -06: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-03-29 18:26:52 -06:00
DfVector p_temp ( d - > p , 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-04-02 19:52:46 -06:00
}
*/