develop
Mike Stewart 2012-02-03 23:29:05 -08:00
commit 4b3a2bfe05
10 changed files with 211 additions and 41 deletions

@ -64,8 +64,8 @@ OPTION(BUILD_PLUGINS "Build the plugins." ON)
IF(UNIX)
add_definitions(-DLINUX_BUILD)
SET(CMAKE_CXX_FLAGS_DEBUG "-g -Wall")
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -m32 -march=i686 -std=c++0x")
SET(CMAKE_C_FLAGS "-fvisibility=hidden -m32 -march=i686")
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -m32 -march=i686 -mtune=generic -std=c++0x")
SET(CMAKE_C_FLAGS "-fvisibility=hidden -m32 -march=i686 -mtune=generic")
ENDIF()
#add depends to include path

@ -15,7 +15,9 @@ include_directories (depends/tinyxml)
include_directories (depends/tthread)
add_subdirectory (depends/protobuf)
execute_process(COMMAND perl xml/list.pl xml include/df ";"
SET(PERL_EXECUTABLE "perl" CACHE FILEPATH "This is the perl executable to run in the codegen step. Tweak it if you need to run a specific one.")
execute_process(COMMAND ${PERL_EXECUTABLE} xml/list.pl xml include/df ";"
WORKING_DIRECTORY ${dfapi_SOURCE_DIR}
OUTPUT_VARIABLE GENERATED_HDRS)
@ -142,7 +144,7 @@ FILE(GLOB GENERATE_INPUT_XMLS ${dfapi_SOURCE_DIR}/xml/*.xml)
ADD_CUSTOM_COMMAND(
OUTPUT ${dfapi_SOURCE_DIR}/include/df/static.inc
COMMAND perl xml/codegen.pl xml include/df
COMMAND ${PERL_EXECUTABLE} xml/codegen.pl xml include/df
WORKING_DIRECTORY ${dfapi_SOURCE_DIR}
MAIN_DEPENDENCY ${dfapi_SOURCE_DIR}/xml/codegen.pl
DEPENDS ${GENERATE_INPUT_XMLS} ${GENERATE_INPUT_SCRIPTS}
@ -164,7 +166,7 @@ IF(UNIX)
ENDIF()
IF(UNIX)
SET(PROJECT_LIBS rt )
SET(PROJECT_LIBS rt dl)
ELSE(WIN32)
#FIXME: do we really need this?
SET(PROJECT_LIBS psapi ${dfhack_SOURCE_DIR}/library/depends/ntdll/ntdll.lib)

@ -262,6 +262,13 @@ inline bool bits_match(unsigned required, unsigned ok, unsigned mask)
return (required & mask) == (required & mask & ok);
}
template<typename T, typename T1, typename T2>
inline T clip_range(T a, T1 minv, T2 maxv) {
if (a < minv) return minv;
if (a > maxv) return maxv;
return a;
}
/**
* Returns the amount of milliseconds elapsed since the UNIX epoch.
* Works on both windows and linux.

@ -22,6 +22,15 @@ bool operator<(const coord &other) const
return z < other.z;
}
coord operator+(const coord &other) const
{
return coord(x + other.x, y + other.y, z + other.z);
}
coord operator-(const coord &other) const
{
return coord(x - other.x, y - other.y, z - other.z);
}
coord operator/(int number) const
{
return coord(x/number, y/number, z);

@ -18,6 +18,15 @@ bool operator<(const coord2d &other) const
return y < other.y;
}
coord2d operator+(const coord2d &other) const
{
return coord2d(x + other.x, y + other.y);
}
coord2d operator-(const coord2d &other) const
{
return coord2d(x - other.x, y - other.y);
}
coord2d operator/(int number) const
{
return coord2d(x/number, y/number);

@ -1 +1 @@
Subproject commit 7aa928ebe466a4a6036e6bb9e72b12416f0168e4
Subproject commit 64a7aeb6a87b7b5067ace8f6a869b7b4fe6561a4

@ -65,19 +65,27 @@ DFhackCExport command_result df_fixveins (Core * c, vector <string> & parameters
for (int k = 0; k < 16; k++)
has_mineral[k] |= mineral->tile_bitmask[k];
}
t_feature local, global;
Maps::GetGlobalFeature(global, block->global_feature);
Maps::GetLocalFeature(local, df::coord2d(block->map_pos.x / 16, block->map_pos.y / 16), block->local_feature);
for (int x = 0; x < 16; x++)
{
for (int y = 0; y < 16; y++)
{
bool has_feature = ((block->designation[x][y].bits.feature_global) && (global.main_material != -1) && (global.sub_material != -1)) ||
((block->designation[x][y].bits.feature_local) && (local.main_material != -1) && (local.sub_material != -1));
bool has_vein = has_mineral[y] & (1 << x);
if (has_feature)
has_vein = false;
int16_t oldT = block->tiletype[x][y];
TileMaterial mat = tileMaterial(oldT);
if ((mat == VEIN) && !(has_mineral[y] & (1 << x)))
if ((mat == VEIN) && !has_vein)
mineral_removed += setTileMaterial(block->tiletype[x][y], STONE);
if ((mat == STONE) && (has_mineral[y] & (1 << x)))
if ((mat == STONE) && has_vein)
mineral_added += setTileMaterial(block->tiletype[x][y], VEIN);
if ((mat == FEATSTONE) && !(block->designation[x][y].bits.feature_local || block->designation[x][y].bits.feature_global))
if ((mat == FEATSTONE) && !has_feature)
feature_removed += setTileMaterial(block->tiletype[x][y], STONE);
if ((mat == STONE) && (block->designation[x][y].bits.feature_local || block->designation[x][y].bits.feature_global))
if ((mat == STONE) && has_feature)
feature_added += setTileMaterial(block->tiletype[x][y], FEATSTONE);
}
}

@ -113,7 +113,7 @@ DFhackCExport command_result mode (Core * c, vector <string> & parameters)
printCurrentModes(gm, c->con);
if(set)
{
if(gm.g_mode == GAMEMODE_NONE || gm.g_type == GAMETYPE_VIEW_LEGENDS || gm.g_type == GAMETYPE_DWARF_RECLAIM)
if( gm.g_mode == GAMEMODE_NONE || gm.g_type == GAMETYPE_VIEW_LEGENDS )
{
c->con.printerr("It is not safe to set modes in menus.\n");
return CR_FAILURE;
@ -123,6 +123,7 @@ DFhackCExport command_result mode (Core * c, vector <string> & parameters)
<< "1 = Adventurer Mode" << endl
<< "2 = Arena Mode" << endl
<< "3 = Arena, controlling creature" << endl
<< "4 = Reclaim Fortress Mode" << endl
<< "c = cancel/do nothing" << endl;
uint32_t select=99;
@ -135,7 +136,7 @@ DFhackCExport command_result mode (Core * c, vector <string> & parameters)
const char * start = selected.c_str();
char * end = 0;
select = strtol(start, &end, 10);
if(!end || end==start || select > 3)
if(!end || end==start || select > 4)
{
c->con.printerr("This is not a valid selection.\n");
goto input_again;
@ -159,6 +160,10 @@ DFhackCExport command_result mode (Core * c, vector <string> & parameters)
gm.g_mode = GAMEMODE_ADVENTURE;
gm.g_type = GAMETYPE_ADVENTURE_ARENA;
break;
case 4:
gm.g_mode = GAMEMODE_DWARF;
gm.g_type = GAMETYPE_DWARF_RECLAIM;
break;
}
c->Suspend();
world->WriteGameMode(gm);

@ -19,12 +19,21 @@ using namespace std;
#include "PluginManager.h"
#include "modules/MapCache.h"
#include "MiscUtils.h"
#include "DataDefs.h"
#include "df/world.h"
#include "df/world_data.h"
#include "df/world_region_details.h"
#include "df/world_geo_biome.h"
#include "df/world_geo_layer.h"
#include "df/inclusion_type.h"
#include "df/viewscreen_choose_start_sitest.h"
using namespace DFHack;
using namespace df::enums;
using df::global::world;
using df::coord2d;
struct matdata
{
@ -41,9 +50,9 @@ struct matdata
lower_z = copyme.lower_z;
upper_z = copyme.upper_z;
}
unsigned int add( int z_level = invalid_z )
unsigned int add( int z_level = invalid_z, int delta = 1 )
{
count ++;
count += delta;
if(z_level != invalid_z)
{
if(lower_z == invalid_z || z_level < lower_z)
@ -187,6 +196,12 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand>
" all - Scan the whole map, as if it was revealed.\n"
" value - Show material value in the output. Most useful for gems.\n"
" hell - Show the Z range of HFS tubes. Implies 'all'.\n"
"Pre-embark estimate:\n"
" If called during the embark selection screen, displays\n"
" an estimate of layer stone availability. If the 'all'\n"
" option is specified, also estimates veins.\n"
" The estimate is computed either for 1 embark tile of the\n"
" blinking biome, or for all tiles of the embark rectangle.\n"
));
return CR_OK;
}
@ -196,6 +211,120 @@ DFhackCExport command_result plugin_shutdown ( Core * c )
return CR_OK;
}
static coord2d biome_delta[] = {
coord2d(-1,1), coord2d(0,1), coord2d(1,1),
coord2d(-1,0), coord2d(0,0), coord2d(1,0),
coord2d(-1,-1), coord2d(0,-1), coord2d(1,-1)
};
static command_result embark_prospector(DFHack::Core *c, df::viewscreen_choose_start_sitest *screen,
bool showHidden, bool showValue)
{
if (!world || !world->world_data)
{
c->con.printerr("World data is not available.\n");
return CR_FAILURE;
}
df::world_data *data = world->world_data;
coord2d cur_region = screen->region_pos;
int d_idx = linear_index(data->region_details, &df::world_region_details::pos, cur_region);
auto cur_details = vector_get(data->region_details, d_idx);
if (!cur_details)
{
c->con.printerr("Current region details are not available.\n");
return CR_FAILURE;
}
// Compute biomes
std::map<coord2d, int> biomes;
if (screen->biome_highlighted)
{
c->con.print("Processing one embark tile of biome F%d.\n\n", screen->biome_idx+1);
biomes[screen->biome_rgn[screen->biome_idx]]++;
}
else
{
for (int x = screen->embark_pos_min.x; x <= screen->embark_pos_max.x; x++)
{
for (int y = screen->embark_pos_min.y; y <= screen->embark_pos_max.y; y++)
{
int bv = clip_range(cur_details->biome[x][y], 1, 9);
biomes[cur_region + biome_delta[bv-1]]++;
}
}
}
// Compute material maps
MatMap layerMats;
MatMap veinMats;
for (auto biome_it = biomes.begin(); biome_it != biomes.end(); ++biome_it)
{
int bx = clip_range(biome_it->first.x, 0, data->world_width-1);
int by = clip_range(biome_it->first.y, 0, data->world_height-1);
auto &region = data->region_map[bx][by];
df::world_geo_biome *geo_biome = df::world_geo_biome::find(region.geo_index);
if (!geo_biome)
{
c->con.printerr("Region geo-biome not found: (%d,%d)\n", bx, by);
return CR_FAILURE;
}
int cnt = biome_it->second;
for (unsigned i = 0; i < geo_biome->layers.size(); i++)
{
auto layer = geo_biome->layers[i];
for (int z = layer->bottom_height; z <= layer->top_height; z++)
{
layerMats[layer->mat_index].add(z, 48*48*cnt);
for (unsigned j = 0; j < layer->vein_mat.size(); j++)
{
// TODO: find out how to estimate the real density
int bias = 100;
switch (layer->vein_type[j])
{
case inclusion_type::VEIN:
bias = 360;
break;
case inclusion_type::CLUSTER:
bias = 1800;
break;
case inclusion_type::CLUSTER_SMALL:
bias = 18;
break;
case inclusion_type::CLUSTER_ONE:
bias = 3;
break;
}
veinMats[layer->vein_mat[j]].add(z, layer->vein_unk_38[j]*bias*cnt/100);
}
}
}
}
// Print the report
c->con << "Layer materials:" << std::endl;
printMats(c->con, layerMats, world->raws.inorganics, showValue);
if (showHidden) {
DFHack::Materials *mats = c->getMaterials();
printVeins(c->con, veinMats, mats, showValue);
mats->Finish();
}
c->con << "Warning: the above data is only a very rough estimate." << std::endl;
return CR_OK;
}
DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & parameters)
{
bool showHidden = false;
@ -222,13 +351,19 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector <string> & par
else
return CR_WRONG_USAGE;
}
uint32_t x_max = 0, y_max = 0, z_max = 0;
CoreSuspender suspend(c);
// Embark screen active: estimate using world geology data
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_choose_start_sitest, c->getTopViewscreen()))
return embark_prospector(c, screen, showHidden, showValue);
if (!Maps::IsValid())
{
c->con.printerr("Map is not available!\n");
return CR_FAILURE;
}
uint32_t x_max = 0, y_max = 0, z_max = 0;
Maps::getSize(x_max, y_max, z_max);
MapExtras::MapCache map;

@ -14,7 +14,9 @@
#include "df/world.h"
#include "df/plant_raw.h"
#include "df/item_flags.h"
#include "df/items_other_id.h"
using namespace std;
using namespace DFHack;
using namespace DFHack::Simple;
using namespace df::enums;
@ -24,7 +26,7 @@ const int buffer = 20; // seed number buffer - 20 is reasonable
bool running = false; // whether seedwatch is counting the seeds or not
// abbreviations for the standard plants
std::map<std::string, std::string> abbreviations;
map<string, string> abbreviations;
bool ignoreSeeds(df::item_flags& f) // seeds with the following flags should not be counted
{
@ -64,7 +66,7 @@ void printHelp(Core& core) // prints help
if(!abbreviations.empty())
{
core.con.print("You can use these abbreviations for the plant tokens:\n");
for(std::map<std::string, std::string>::const_iterator i = abbreviations.begin(); i != abbreviations.end(); ++i)
for(map<string, string>::const_iterator i = abbreviations.begin(); i != abbreviations.end(); ++i)
{
core.con.print("%s -> %s\n", i->first.c_str(), i->second.c_str());
}
@ -83,7 +85,7 @@ void printHelp(Core& core) // prints help
};
// searches abbreviations, returns expansion if so, returns original if not
std::string searchAbbreviations(std::string in)
string searchAbbreviations(string in)
{
if(abbreviations.count(in) > 0)
{
@ -95,7 +97,7 @@ std::string searchAbbreviations(std::string in)
}
};
DFhackCExport command_result df_seedwatch(Core* pCore, std::vector<std::string>& parameters)
DFhackCExport command_result df_seedwatch(Core* pCore, vector<string>& parameters)
{
Core& core = *pCore;
if(!core.isValid())
@ -104,8 +106,8 @@ DFhackCExport command_result df_seedwatch(Core* pCore, std::vector<std::string>&
}
CoreSuspender suspend(pCore);
std::map<std::string, t_materialIndex> materialsReverser;
for(std::size_t i = 0; i < world->raws.plants.all.size(); ++i)
map<string, t_materialIndex> materialsReverser;
for(size_t i = 0; i < world->raws.plants.all.size(); ++i)
{
materialsReverser[world->raws.plants.all[i]->id] = i;
}
@ -122,7 +124,7 @@ DFhackCExport command_result df_seedwatch(Core* pCore, std::vector<std::string>&
return CR_OK;
}
std::string par;
string par;
int limit;
switch(parameters.size())
{
@ -159,7 +161,7 @@ DFhackCExport command_result df_seedwatch(Core* pCore, std::vector<std::string>&
{
core.con.print("seedwatch is not supervising. Use 'seedwatch start' to start supervision.\n");
}
std::map<t_materialIndex, unsigned int> watchMap;
map<t_materialIndex, unsigned int> watchMap;
Kitchen::fillWatchMap(watchMap);
if(watchMap.empty())
{
@ -168,7 +170,7 @@ DFhackCExport command_result df_seedwatch(Core* pCore, std::vector<std::string>&
else
{
core.con.print("The watch list is:\n");
for(std::map<t_materialIndex, unsigned int>::const_iterator i = watchMap.begin(); i != watchMap.end(); ++i)
for(map<t_materialIndex, unsigned int>::const_iterator i = watchMap.begin(); i != watchMap.end(); ++i)
{
core.con.print("%s : %u\n", world->raws.plants.all[i->first]->id.c_str(), i->second);
}
@ -176,7 +178,7 @@ DFhackCExport command_result df_seedwatch(Core* pCore, std::vector<std::string>&
}
else if(par == "debug")
{
std::map<t_materialIndex, unsigned int> watchMap;
map<t_materialIndex, unsigned int> watchMap;
Kitchen::fillWatchMap(watchMap);
Kitchen::debug_print(core);
}
@ -199,7 +201,7 @@ DFhackCExport command_result df_seedwatch(Core* pCore, std::vector<std::string>&
*/
else
{
std::string token = searchAbbreviations(par);
string token = searchAbbreviations(par);
if(materialsReverser.count(token) > 0)
{
Kitchen::removeLimit(materialsReverser[token]);
@ -216,14 +218,14 @@ DFhackCExport command_result df_seedwatch(Core* pCore, std::vector<std::string>&
if(limit < 0) limit = 0;
if(parameters[0] == "all")
{
for(std::map<std::string, std::string>::const_iterator i = abbreviations.begin(); i != abbreviations.end(); ++i)
for(map<string, string>::const_iterator i = abbreviations.begin(); i != abbreviations.end(); ++i)
{
if(materialsReverser.count(i->second) > 0) Kitchen::setLimit(materialsReverser[i->second], limit);
}
}
else
{
std::string token = searchAbbreviations(parameters[0]);
string token = searchAbbreviations(parameters[0]);
if(materialsReverser.count(token) > 0)
{
Kitchen::setLimit(materialsReverser[token], limit);
@ -248,7 +250,7 @@ DFhackCExport const char* plugin_name(void)
return "seedwatch";
}
DFhackCExport command_result plugin_init(Core* pCore, std::vector<PluginCommand>& commands)
DFhackCExport command_result plugin_init(Core* pCore, vector<PluginCommand>& commands)
{
commands.clear();
commands.push_back(PluginCommand("seedwatch", "Switches cookery based on quantity of seeds, to keep reserves", df_seedwatch));
@ -316,24 +318,17 @@ DFhackCExport command_result plugin_onupdate(Core* pCore)
return CR_OK;
}
// this is dwarf mode, continue
std::map<t_materialIndex, unsigned int> seedCount; // the number of seeds
map<t_materialIndex, unsigned int> seedCount; // the number of seeds
// count all seeds and plants by RAW material
for(std::size_t i = 0; i < world->items.all.size(); ++i)
for(size_t i = 0; i < world->items.other[items_other_id::SEEDS].size(); ++i)
{
df::item * item = world->items.all[i];
df::item * item = world->items.other[items_other_id::SEEDS][i];
t_materialIndex materialIndex = item->getMaterialIndex();
switch(item->getType())
{
case item_type::SEEDS:
if(!ignoreSeeds(item->flags)) ++seedCount[materialIndex];
break;
case item_type::PLANT:
break;
}
if(!ignoreSeeds(item->flags)) ++seedCount[materialIndex];
}
std::map<t_materialIndex, unsigned int> watchMap;
map<t_materialIndex, unsigned int> watchMap;
Kitchen::fillWatchMap(watchMap);
for(auto i = watchMap.begin(); i != watchMap.end(); ++i)
{