Merge branch 'dfapi' of github.com:peterix/dfhack into dfapi

develop
Petr Mrázek 2011-07-21 11:30:21 +02:00
commit 26dfa7ab39
14 changed files with 503 additions and 31 deletions

@ -928,6 +928,15 @@
</Group>
<Group name="Materials" description="Offsets used by the Materials module.">
<Address name="inorganics" description="Soil, stone, gems and metal."/>
<Group name="inorganic_extras">
<Offset name="ore_types" description="Vector of indexes of metals produced when ore is smelted"/>
<Offset name="ore_chances" description="Vector of percent chance of each type of metal being produced on smelting"/>
<Offset name="strand_types" description="Vector of indexes of metals produced when ore undergoes strand extraction"/>
<Offset name="strand_chances" description="Vector of percent chance of each type of metal being produced on strand extraction"/>
<Offset name="value" description="Meterial value"/>
<Offset name="wall_tile" description="Tile when material is a natural wall"/>
<Offset name="boulder_tile" description="Tile when material is a dug out stone"/>
</Group>
<Address name="organics_all" description="Wood and plant matter, mixed" />
<Address name="organics_plants" description="plant matter" />
<Address name="organics_trees" description="just wood" />
@ -1064,6 +1073,9 @@
</Group>
</Group>
</Group>
<Group name="Notes" description="In-game notes">
<Address name="vector"/>
</Group>
</Offsets>
</Base>
@ -2254,6 +2266,17 @@
<Offset name="flags3" value="0xE8"/>
</Group>
</Group>
<Group name="Materials">
<Group name="inorganic_extras">
<Offset name="ore_types" value="0x18"/>
<Offset name="ore_chances" value="0x24"/>
<Offset name="strand_types" value="0x3c"/>
<Offset name="strand_chances" value="0x48"/>
<Offset name="value" value="0x17c"/>
<Offset name="wall_tile" value="0x20c"/>
<Offset name="boulder_tile" value="0x21e"/>
</Group>
</Group>
<Group name="Items" valid="true">
<Address name="items_vector" value="0x16c4540"/>
<Offset name="id" value="0x14"/>
@ -3027,6 +3050,7 @@
<MD5 value="fc15065c4d1977ca019c6dad220413d1" />
<Offsets>
WORLD: 0x93f77a0
<Group name="GUI">
<Address name="hotkeys" value="0x93f740c" />
<Address name="interface" value="0x8C3E900" />
@ -3041,6 +3065,17 @@
<Offset name="flags3" value="0x94"/>
</Group>
</Group>
<Group name="Materials">
<Group name="inorganic_extras">
<Offset name="ore_types" value="0x18"/>
<Offset name="ore_chances" value="0x24"/>
<Offset name="strand_types" value="0x3c"/>
<Offset name="strand_chances" value="0x48"/>
<Offset name="value" value="0x17c"/>
<Offset name="wall_tile" value="0x20c"/>
<Offset name="boulder_tile" value="0x21e"/>
</Group>
</Group>
<Group name="Vermin" valid="true">
<Group name="Spawn Points">
<Address name="vector" value="0x93f77c4"/>
@ -3110,6 +3145,9 @@
<Group name="Vegetation">
<Address name="vector" value="0x940bd70" />
</Group>
<Group name="Notes">
<Address name="vector" value="0x93f635c"/>
</Group>
</Offsets>
</Version>
</DFHack>

@ -45,6 +45,7 @@ include/dfhack/modules/Gui.h
include/dfhack/modules/Items.h
include/dfhack/modules/Maps.h
include/dfhack/modules/Materials.h
include/dfhack/modules/Notes.h
include/dfhack/modules/Translation.h
include/dfhack/modules/Vegetation.h
include/dfhack/modules/Vermin.h
@ -75,6 +76,7 @@ modules/Gui.cpp
modules/Items.cpp
modules/Maps.cpp
modules/Materials.cpp
modules/Notes.cpp
modules/Translation.cpp
modules/Vegetation.cpp
modules/Vermin.cpp

@ -596,3 +596,4 @@ MODULE_GETTER(Vegetation);
MODULE_GETTER(Buildings);
MODULE_GETTER(Constructions);
MODULE_GETTER(Vermin);
MODULE_GETTER(Notes);

@ -49,6 +49,7 @@ namespace DFHack
class Buildings;
class Constructions;
class Vermin;
class Notes;
class VersionInfo;
class VersionInfoFactory;
class PluginManager;
@ -107,6 +108,8 @@ namespace DFHack
Constructions * getConstructions();
/// get the vermin module
Vermin * getVermin();
/// get the notes module
Notes * getNotes();
/// sets the current hotkey command
bool setHotkeyCmd( std::string cmd );
/// removes the hotkey command and gives it to the caller thread
@ -147,6 +150,7 @@ namespace DFHack
Buildings * pBuildings;
Constructions * pConstructions;
Vermin * pVermin;
Notes * pNotes;
} s_mods;
std::vector <Module *> allModules;
DFHack::PluginManager * plug_mgr;

@ -109,17 +109,6 @@ struct t_effect_df40d //size 40
//#pragma pack(push,4)
struct t_note
{
char symbol;
uint16_t foreground;
uint16_t background;
char name[128];
uint16_t x;
uint16_t y;
uint16_t z;
};
struct t_name
{
char first_name[128];

@ -32,20 +32,58 @@ distribution.
#include "dfhack/Export.h"
#include "dfhack/Module.h"
#include "dfhack/Types.h"
#include <vector>
namespace DFHack
{
class DFContextShared;
/**
* \ingroup grp_materials
*/
struct t_matgloss
class DFHACK_EXPORT t_matgloss
{
public:
char id[128]; //the id in the raws
uint8_t fore; // Annoyingly the offset for this differs between types
uint8_t back;
uint8_t bright;
char name[128]; //this is the name displayed ingame
int32_t value; // Material value
uint16_t wall_tile; // Tile when a natural wall
uint16_t boulder_tile; // Tile when a dug-out stone;
public:
t_matgloss();
};
class DFHACK_EXPORT t_matglossInorganic : public t_matgloss
{
public:
// Types of metals the ore will produce when smelted. Each number
// is an index into the inorganic matglass vector.
std::vector<uint16_t>* ore_types;
// Percent chance that the ore will produce each type of metal
// when smelted.
std::vector<uint16_t>* ore_chances;
// Types of metals the ore will produce from strand extraction.
// Each number is an index into the inorganic matglass vector.
std::vector<uint16_t>* strand_types;
// Percent chance that the ore will produce each type of metal
// fram strand extraction.
std::vector<uint16_t>* strand_chances;
public:
t_matglossInorganic();
bool isOre();
bool isGem();
};
/**
* \ingroup grp_materials
*/
@ -178,7 +216,7 @@ namespace DFHack
~Materials();
bool Finish();
std::vector<t_matgloss> inorganic;
std::vector<t_matglossInorganic> inorganic;
std::vector<t_matgloss> organic;
std::vector<t_matgloss> tree;
std::vector<t_matgloss> plant;

@ -0,0 +1,71 @@
#pragma once
#ifndef CL_MOD_NOTES
#define CL_MOD_NOTES
/**
* \defgroup grp_notes In game notes (and routes)
* @ingroup grp_notes
*/
#include "dfhack/Export.h"
#include "dfhack/Module.h"
#include <vector>
#include <string>
#ifdef __cplusplus
namespace DFHack
{
#endif
/**
* Game's structure for a note.
* \ingroup grp_notes
*/
struct t_note
{
// First note created has id 0, second has id 1, etc. Not affected
// by lower id notes being deleted.
uint32_t id;
uint8_t symbol;
uint8_t unk1;
uint16_t foreground;
uint16_t background;
uint16_t unk2;
std::string name;
std::string text;
uint16_t x;
uint16_t y;
uint16_t z;
// Is there more?
};
#ifdef __cplusplus
/**
* The notes module - allows reading DF in-game notes
* \ingroup grp_modules
* \ingroup grp_notes
*/
class DFHACK_EXPORT Notes : public Module
{
public:
Notes();
~Notes();
bool Finish();
// Returns NULL if there's no notes yet.
std::vector<t_note*>* getNotes();
private:
struct Private;
Private *d;
};
}
#endif // __cplusplus
#endif

@ -58,6 +58,20 @@ class Materials::Private
uint32_t vector_organic_trees;
uint32_t vector_races;
uint32_t vector_other;
class t_inorganic_extras
{
public:
uint32_t offset_ore_types;
uint32_t offset_ore_chances;
uint32_t offset_strand_types;
uint32_t offset_strand_chances;
uint32_t offset_value;
uint32_t offset_wall_tile;
uint32_t offset_boulder_tile;
};
t_inorganic_extras i_ex;
};
Materials::Materials()
@ -73,7 +87,18 @@ Materials::Materials()
d->vector_organic_trees = OG_Materials->getAddress ("organics_trees");
d->vector_races = OG_Materials->getAddress("creature_type_vector");
}
OffsetGroup *OG_Offsets = OG_Materials->getGroup("inorganic_extras");
{
d->i_ex.offset_ore_types = OG_Offsets->getOffset("ore_types");
d->i_ex.offset_ore_chances = OG_Offsets->getOffset("ore_chances");
d->i_ex.offset_strand_types = OG_Offsets->getOffset("strand_types");
d->i_ex.offset_strand_chances = OG_Offsets->getOffset("strand_chances");
d->i_ex.offset_value = OG_Offsets->getOffset("value");
d->i_ex.offset_wall_tile = OG_Offsets->getOffset("wall_tile");
d->i_ex.offset_boulder_tile = OG_Offsets->getOffset("boulder_tile");
}
}
Materials::~Materials()
{
delete d;
@ -119,6 +144,48 @@ bool API::ReadInorganicMaterials (vector<t_matgloss> & inorganic)
}
*/
t_matgloss::t_matgloss()
{
name[0] = 0;
fore = 0;
back = 0;
bright = 0;
value = 0;
wall_tile = 0;
boulder_tile = 0;
}
t_matglossInorganic::t_matglossInorganic()
{
ore_types = NULL;
ore_chances = NULL;
strand_types = NULL;
strand_chances = NULL;
}
bool t_matglossInorganic::isOre()
{
if (ore_chances != NULL && !ore_chances->empty())
{
if ( (*ore_chances)[0] > 0)
return true;
}
if (strand_chances != NULL && !strand_chances->empty())
{
if ( (*strand_chances)[0] > 0)
return true;
}
return false;
}
bool t_matglossInorganic::isGem()
{
return (wall_tile == 15 && boulder_tile == 7);
}
// good for now
inline bool ReadNamesOnly(Process* p, uint32_t address, vector<t_matgloss> & names)
{
@ -144,14 +211,36 @@ bool Materials::ReadInorganicMaterials (void)
inorganic.reserve (size);
for (uint32_t i = 0; i < size;i++)
{
t_matgloss mat;
t_matglossInorganic mat;
p->readSTLString (p_matgloss[i], mat.id, 128);
//p->readSTLString (p_matgloss[i] + mat_name, mat.name, 128);
mat.name[0] = 0;
mat.fore = 0;
mat.back = 0;
mat.bright = 0;
uint32_t ptr = p_matgloss[i] + d->i_ex.offset_ore_types;
if ( *( (uint32_t*) ptr) != 0)
mat.ore_types = (std::vector<uint16_t>*) ptr;
ptr = p_matgloss[i] + d->i_ex.offset_ore_chances;
if ( *( (uint32_t*) ptr) != 0)
mat.ore_chances = (std::vector<uint16_t>*) ptr;
ptr = p_matgloss[i] + d->i_ex.offset_strand_types;
if ( *( (uint32_t*) ptr) != 0)
mat.strand_types = (std::vector<uint16_t>*) ptr;
ptr = p_matgloss[i] + d->i_ex.offset_strand_chances;
if ( *( (uint32_t*) ptr) != 0)
mat.strand_chances = (std::vector<uint16_t>*) ptr;
ptr = p_matgloss[i] + d->i_ex.offset_value;
mat.value = *( (int32_t*) ptr);
ptr = p_matgloss[i] + d->i_ex.offset_wall_tile;
mat.wall_tile = *( (uint8_t*) ptr);
ptr = p_matgloss[i] + d->i_ex.offset_boulder_tile;
mat.boulder_tile = *( (uint8_t*) ptr);
inorganic.push_back(mat);
}
return true;

@ -0,0 +1,102 @@
/*
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.
*/
#include "Internal.h"
#include <string>
#include <vector>
#include <map>
using namespace std;
#include "dfhack/VersionInfo.h"
#include "dfhack/Types.h"
#include "dfhack/Error.h"
#include "dfhack/Process.h"
#include "ModuleFactory.h"
#include "dfhack/Core.h"
#include "dfhack/modules/Notes.h"
using namespace DFHack;
struct Notes::Private
{
uint32_t notes_vector;
Process * owner;
bool Inited;
bool Started;
};
Module* DFHack::createNotes()
{
return new Notes();
}
Notes::Notes()
{
Core & c = Core::getInstance();
d = new Private;
d->owner = c.p;
d->Inited = d->Started = false;
VersionInfo * mem = c.vinfo;
d->Inited = true;
try
{
OffsetGroup * OG_Notes = mem->getGroup("Notes");
d->notes_vector = OG_Notes->getAddress("vector");
}
catch(DFHack::Error::AllMemdef &e)
{
c.con << "Notes not available... " << e.what() << endl;
d->Inited = false;
}
}
Notes::~Notes()
{
delete d;
}
std::vector<t_note*>* Notes::getNotes()
{
if (!d->Inited)
{
Core & c = Core::getInstance();
c.con << "Notes not available... " << endl;
return NULL;
}
uint32_t ptr = d->notes_vector;
if ( *( (uint32_t*) ptr) == 0)
// Notes vector not set up yet.
return NULL;
return (std::vector<t_note*>*) ptr;
}
bool Notes::Finish()
{
return true;
}

@ -42,5 +42,6 @@ namespace DFHack
Module* createConstructions();
Module* createMaps();
Module* createVermin();
Module* createNotes();
}
#endif

@ -128,3 +128,4 @@ DFHACK_PLUGIN(weather weather.cpp)
DFHACK_PLUGIN(vdig vdig.cpp)
DFHACK_PLUGIN(colonies colonies.cpp)
DFHACK_PLUGIN(itemhacks itemhacks.cpp)
DFHACK_PLUGIN(notes notes.cpp)

@ -0,0 +1,80 @@
#include <dfhack/Core.h>
#include <dfhack/Console.h>
#include <dfhack/Export.h>
#include <dfhack/PluginManager.h>
#include <vector>
#include <string>
#include <dfhack/modules/Notes.h>
using std::vector;
using std::string;
using namespace DFHack;
DFhackCExport command_result df_notes (Core * c, vector <string> & parameters);
DFhackCExport const char * plugin_name ( void )
{
return "notes";
}
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands)
{
commands.clear();
commands.push_back(PluginCommand("dumpnotes",
"Dumps in-game notes",
df_notes));
return CR_OK;
}
DFhackCExport command_result plugin_shutdown ( Core * c )
{
return CR_OK;
}
DFhackCExport command_result df_notes (Core * c, vector <string> & parameters)
{
Console & con = c->con;
c->Suspend();
DFHack::Notes * note_mod = c->getNotes();
std::vector<t_note*>* note_list = note_mod->getNotes();
if (note_list == NULL)
{
con << "No notes yet." << std::endl;
c->Resume();
return CR_OK;
}
if (note_list->empty())
{
con << "All notes deleted." << std::endl;
c->Resume();
return CR_OK;
}
for (size_t i = 0; i < note_list->size(); i++)
{
t_note* note = (*note_list)[i];
con.print("Note at: %d/%d/%d\n", note->x, note->y, note->z);
con.print("Note id: %d\n", note->id);
con.print("Note symbol: '%c'\n", note->symbol);
if (note->name.length() > 0)
con << "Note name: " << (note->name) << std::endl;
if (note->text.length() > 0)
con << "Note text: " << (note->text) << std::endl;
if (note->unk1 != 0)
con.print("unk1: %x\n", note->unk1);
if (note->unk2 != 0)
con.print("unk2: %x\n", note->unk2);
con << std::endl;
}
c->Resume();
return CR_OK;
}

@ -30,6 +30,11 @@ typedef std::vector<DFHack::t_feature*> FeatureListPointer;
typedef std::map<DFHack::DFCoord, FeatureListPointer> FeatureMap;
typedef std::vector<DFHack::df_plant *> PlantList;
#define TO_PTR_VEC(obj_vec, ptr_vec) \
ptr_vec.clear(); \
for (size_t i = 0; i < obj_vec.size(); i++) \
ptr_vec.push_back(&obj_vec[i])
template<template <typename> class P = std::greater >
struct compare_pair_second
{
@ -40,8 +45,10 @@ struct compare_pair_second
}
};
void printMats(DFHack::Console & con, MatMap &mat, std::vector<DFHack::t_matgloss> &materials)
// printMats() accepts a vector of pointers to t_matgloss so that it can
// deal t_matgloss and all subclasses.
void printMats(DFHack::Console & con, MatMap &mat,
std::vector<DFHack::t_matgloss*> &materials)
{
unsigned int total = 0;
MatSorter sorting_vector;
@ -49,21 +56,65 @@ void printMats(DFHack::Console & con, MatMap &mat, std::vector<DFHack::t_matglos
{
sorting_vector.push_back(*it);
}
std::sort(sorting_vector.begin(), sorting_vector.end(), compare_pair_second<>());
for (MatSorter::const_iterator it = sorting_vector.begin(); it != sorting_vector.end(); ++it)
std::sort(sorting_vector.begin(), sorting_vector.end(),
compare_pair_second<>());
for (MatSorter::const_iterator it = sorting_vector.begin();
it != sorting_vector.end(); ++it)
{
if(it->first >= materials.size())
{
con << "Bad index: " << it->first << " out of " << materials.size() << endl;
con << "Bad index: " << it->first << " out of "
<< materials.size() << endl;
continue;
}
DFHack::t_matgloss mat = materials[it->first];
con << std::setw(25) << mat.id << " : " << it->second << std::endl;
DFHack::t_matgloss* mat = materials[it->first];
con << std::setw(25) << mat->id << " : " << it->second << std::endl;
total += it->second;
}
con << ">>> TOTAL = " << total << std::endl << std::endl;
}
void printMats(DFHack::Console & con, MatMap &mat,
std::vector<DFHack::t_matgloss> &materials)
{
std::vector<DFHack::t_matgloss*> ptr_vec;
TO_PTR_VEC(materials, ptr_vec);
printMats(con, mat, ptr_vec);
}
void printVeins(DFHack::Console & con, MatMap &mat_map,
DFHack::Materials* mats)
{
MatMap ores;
MatMap gems;
MatMap rest;
for (MatMap::const_iterator it = mat_map.begin(); it != mat_map.end(); ++it)
{
DFHack::t_matglossInorganic &gloss = mats->inorganic[it->first];
if (gloss.isOre())
ores[it->first] = it->second;
else if (gloss.isGem())
gems[it->first] = it->second;
else
rest[it->first] = it->second;
}
std::vector<DFHack::t_matgloss*> ptr_vec;
TO_PTR_VEC(mats->inorganic, ptr_vec);
con << "Ores:" << std::endl;
printMats(con, ores, ptr_vec);
con << "Gems:" << std::endl;
printMats(con, gems, ptr_vec);
con << "Other vein stone:" << std::endl;
printMats(con, rest, ptr_vec);
}
DFhackCExport command_result prospector (Core * c, vector <string> & parameters);
DFhackCExport const char * plugin_name ( void )
@ -313,11 +364,13 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
con << std::setw(25) << DFHack::TileMaterialString[it->first] << " : " << it->second << std::endl;
}
std::vector<t_matgloss*> ptr_vec;
TO_PTR_VEC(mats->inorganic, ptr_vec);
con << std::endl << "Layer materials:" << std::endl;
printMats(con, layerMats, mats->inorganic);
printMats(con, layerMats, ptr_vec);
con << "Vein materials:" << std::endl;
printMats(con, veinMats, mats->inorganic);
printVeins(con, veinMats, mats);
if (showPlants)
{

@ -71,7 +71,10 @@ static bool mightBeVec(vector<t_memrange> &heap_ranges,
if ((vec->start > vec->end) || (vec->end > vec->alloc_end))
return false;
if ((vec->end - vec->start) % 4 != 0)
// Vector length might not be a multiple of 4 if, for example,
// it's a vector of uint8_t or uint16_t. However, the actual memory
// allocated to the vector should be 4 byte aligned.
if ((vec->start % 4 != 0) || (vec->alloc_end % 4 != 0))
return false;
for (size_t i = 0; i < heap_ranges.size(); i++)