implements findnameindexes
commit
8d78822f3d
@ -0,0 +1,20 @@
|
||||
# linux backup files
|
||||
*~
|
||||
|
||||
# compiled binaries
|
||||
output/*
|
||||
|
||||
# this one is important, track it
|
||||
!output/Memory.xml
|
||||
|
||||
# a file generated by cmake
|
||||
library/config.h
|
||||
|
||||
# any build folders
|
||||
build*/
|
||||
|
||||
#except for the real one
|
||||
!build/
|
||||
|
||||
#ignore Kdevelop stuff
|
||||
.kdev4
|
@ -0,0 +1 @@
|
||||
build-real
|
@ -1,110 +0,0 @@
|
||||
// digger.cpp
|
||||
|
||||
// Usage: Call with a list of TileClass ids separated by a space,
|
||||
// every (visible) tile on the map with that id will be designated for digging.
|
||||
|
||||
// NOTE currently only works with trees
|
||||
|
||||
// TODO add a sort of "sub-target" to dig() to make it able to designate stone as well
|
||||
// TODO add proper cli
|
||||
// TODO add interactive text based menu
|
||||
|
||||
#include <iostream>
|
||||
#include <integers.h>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <cstdlib>
|
||||
using namespace std;
|
||||
|
||||
#include <DFTypes.h>
|
||||
#include <DFTileTypes.h>
|
||||
#include <DFHackAPI.h>
|
||||
|
||||
int vec_count(vector<uint16_t>& vec, uint16_t t)
|
||||
{
|
||||
int count = 0;
|
||||
for (uint32_t i = 0; i < vec.size(); ++i)
|
||||
{
|
||||
if (vec[i] == t)
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int dig(DFHack::API& DF, vector<uint16_t>& targets)
|
||||
{
|
||||
uint32_t x_max,y_max,z_max;
|
||||
DFHack::t_designation designations[256];
|
||||
uint16_t tiles[256];
|
||||
uint32_t count = 0;
|
||||
DF.getSize(x_max,y_max,z_max);
|
||||
|
||||
// walk the map
|
||||
for(uint32_t x = 0; x< x_max;x++)
|
||||
{
|
||||
for(uint32_t y = 0; y< y_max;y++)
|
||||
{
|
||||
for(uint32_t z = 0; z< z_max;z++)
|
||||
{
|
||||
if(DF.isValidBlock(x,y,z))
|
||||
{
|
||||
// read block designations and tiletype
|
||||
DF.ReadDesignations(x,y,z, (uint32_t *) designations);
|
||||
DF.ReadTileTypes(x,y,z, (uint16_t *) tiles);
|
||||
|
||||
// check all tiles, if type is in target list and its visible: designate for dig
|
||||
for (uint32_t i = 0; i < 256; i++)
|
||||
{
|
||||
if (designations[i].bits.hidden == 0 &&
|
||||
vec_count(targets, DFHack::tileTypeTable[tiles[i]].c) > 0)
|
||||
{
|
||||
//cout << "target found at: ";
|
||||
//cout << x << "," << y << "," << z << "," << i << endl;
|
||||
designations[i].bits.dig = DFHack::designation_default;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
// write the designations back
|
||||
// could probably be optimized in the cases where we dont changed anything
|
||||
DF.WriteDesignations(x,y,z, (uint32_t *) designations);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int main (int argc, const char* argv[])
|
||||
{
|
||||
vector<uint16_t> targets;
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
targets.push_back(atoi(argv[i]));
|
||||
}
|
||||
if (targets.size() == 0)
|
||||
{
|
||||
cout << "Usage: Call with a list of TileClass ids separated by a space,\n";
|
||||
cout << "every (visible) tile on the map with that id will be designated for digging.\n\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
DFHack::API DF("Memory.xml");
|
||||
if(!DF.Attach())
|
||||
{
|
||||
cerr << "DF not found" << endl;
|
||||
return 1;
|
||||
}
|
||||
DF.InitMap();
|
||||
|
||||
int count = dig(DF, targets); // <-- important part
|
||||
cout << count << " targets designated" << endl;
|
||||
|
||||
DF.Detach();
|
||||
}
|
||||
#ifndef LINUX_BUILD
|
||||
cout << "Done. Press any key to continue" << endl;
|
||||
cin.ignore();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,265 @@
|
||||
/* gopt.c version 8.1: tom.viza@gmail.com PUBLIC DOMAIN 2003-8 */
|
||||
/*
|
||||
I, Tom Vajzovic, am the author of this software and its documentation and
|
||||
permanently abandon all copyright and other intellectual property rights in
|
||||
them, including the right to be identified as the author.
|
||||
|
||||
I am fairly certain that this software does what the documentation says it
|
||||
does, but I cannot guarantee that it does, or that it does what you think it
|
||||
should, and I cannot guarantee that it will not have undesirable side effects.
|
||||
|
||||
You are free to use, modify and distribute this software as you please, but
|
||||
you do so at your own risk. If you remove or hide this warning then you are
|
||||
responsible for any problems encountered by people that you make the software
|
||||
available to.
|
||||
|
||||
Before modifying or distributing this software I ask that you would please
|
||||
read http://www.purposeful.co.uk/tfl/
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "gopt.h"
|
||||
|
||||
#ifdef USE_SYSEXITS
|
||||
#include <sysexits.h>
|
||||
#else
|
||||
#define EX_OSERR EXIT_FAILURE
|
||||
#define EX_USAGE EXIT_FAILURE
|
||||
#endif
|
||||
|
||||
struct opt_spec_s {
|
||||
int key;
|
||||
int flags;
|
||||
const char *shorts;
|
||||
const char* const *longs;
|
||||
};
|
||||
typedef struct opt_spec_s opt_spec_t;
|
||||
|
||||
struct opt_s {
|
||||
int key;
|
||||
const char *arg;
|
||||
};
|
||||
typedef struct opt_s opt_t;
|
||||
|
||||
void *gopt_sort( int *argc, const char **argv, const void *opt_specs ){
|
||||
void *opts;
|
||||
{{{
|
||||
const char* const *arg_p= argv + 1;
|
||||
size_t opt_count= 1;
|
||||
for( ; *arg_p; ++arg_p )
|
||||
if( '-' == (*arg_p)[0] && (*arg_p)[1] )
|
||||
if( '-' == (*arg_p)[1] )
|
||||
if( (*arg_p)[2] )
|
||||
++opt_count;
|
||||
else
|
||||
break;
|
||||
else {
|
||||
const opt_spec_t *opt_spec_p= (const opt_spec_t*)opt_specs;
|
||||
for( ; opt_spec_p-> key; ++opt_spec_p )
|
||||
if( strchr( opt_spec_p-> shorts, (*arg_p)[1] )){
|
||||
opt_count+= opt_spec_p-> flags & GOPT_ARG ? 1 : strlen( (*arg_p) + 1 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
opts= malloc( opt_count * sizeof(opt_t) );
|
||||
}}}
|
||||
{
|
||||
const char **arg_p= argv + 1;
|
||||
const char **next_operand= arg_p;
|
||||
opt_t *next_option= (opt_t*)opts;
|
||||
|
||||
if( ! opts ){
|
||||
perror( argv[0] );
|
||||
exit( EX_OSERR );
|
||||
}
|
||||
for( ; *arg_p; ++arg_p )
|
||||
if( '-' == (*arg_p)[0] && (*arg_p)[1] )
|
||||
if( '-' == (*arg_p)[1] )
|
||||
if( (*arg_p)[2] )
|
||||
{{{
|
||||
const opt_spec_t *opt_spec_p= (const opt_spec_t*)opt_specs;
|
||||
const char* const *longs= opt_spec_p-> longs;
|
||||
next_option-> key= 0;
|
||||
while( *longs ){
|
||||
const char *option_cp= (*arg_p) + 2;
|
||||
const char *name_cp= *longs;
|
||||
while( *option_cp && *option_cp == *name_cp ){
|
||||
++option_cp;
|
||||
++name_cp;
|
||||
}
|
||||
if( '=' == *option_cp || !*option_cp ){
|
||||
if( *name_cp ){
|
||||
if( next_option-> key ){
|
||||
fprintf( stderr, "%s: --%.*s: abbreviated option is ambiguous\n", argv[0], (int)( option_cp -( (*arg_p) + 2 )), (*arg_p) + 2 );
|
||||
free( opts );
|
||||
exit( EX_USAGE );
|
||||
}
|
||||
next_option-> key= opt_spec_p-> key;
|
||||
}
|
||||
else {
|
||||
next_option-> key= opt_spec_p-> key;
|
||||
goto found_long;
|
||||
}
|
||||
}
|
||||
if( !*++longs ){
|
||||
++opt_spec_p;
|
||||
if( opt_spec_p-> key )
|
||||
longs= opt_spec_p-> longs;
|
||||
}
|
||||
}
|
||||
if( ! next_option-> key ){
|
||||
fprintf( stderr, "%s: --%.*s: unknown option\n", argv[0], (int)strcspn( (*arg_p) + 2, "=" ), (*arg_p) + 2 );
|
||||
free( opts );
|
||||
exit( EX_USAGE );
|
||||
}
|
||||
for( opt_spec_p= (const opt_spec_t*)opt_specs; opt_spec_p-> key != next_option-> key; ++opt_spec_p );
|
||||
found_long:
|
||||
|
||||
if( !( opt_spec_p-> flags & GOPT_REPEAT )){
|
||||
const opt_t *opt_p= (const opt_t*)opts;
|
||||
for( ; opt_p != next_option; ++opt_p )
|
||||
if( opt_p-> key == opt_spec_p-> key ){
|
||||
fprintf( stderr, "%s: --%.*s: option may not be repeated (in any long or short form)\n", argv[0], (int)strcspn( (*arg_p) + 2, "=" ), (*arg_p) + 2 );
|
||||
free( opts );
|
||||
exit( EX_USAGE );
|
||||
}
|
||||
}
|
||||
if( opt_spec_p-> flags & GOPT_ARG ){
|
||||
next_option-> arg= strchr( (*arg_p) + 2, '=' ) + 1;
|
||||
if( (char*)0 + 1 == next_option-> arg ){
|
||||
++arg_p;
|
||||
if( !*arg_p || '-' == (*arg_p)[0] && (*arg_p)[1] ){
|
||||
fprintf( stderr, "%s: --%s: option requires an option argument\n", argv[0], (*(arg_p-1)) + 2 );
|
||||
free( opts );
|
||||
exit( EX_USAGE );
|
||||
}
|
||||
next_option-> arg= *arg_p;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if( strchr( (*arg_p) + 2, '=' )){
|
||||
fprintf( stderr, "%s: --%.*s: option may not take an option argument\n", argv[0], (int)strcspn( (*arg_p) + 2, "=" ), (*arg_p) + 2 );
|
||||
free( opts );
|
||||
exit( EX_USAGE );
|
||||
}
|
||||
next_option-> arg= NULL;
|
||||
}
|
||||
++next_option;
|
||||
}}}
|
||||
else {
|
||||
for( ++arg_p; *arg_p; ++arg_p )
|
||||
*next_operand++= *arg_p;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{{{
|
||||
const char *short_opt= (*arg_p) + 1;
|
||||
for( ;*short_opt; ++short_opt ){
|
||||
const opt_spec_t *opt_spec_p= (const opt_spec_t*)opt_specs;
|
||||
|
||||
for( ; opt_spec_p-> key; ++opt_spec_p )
|
||||
if( strchr( opt_spec_p-> shorts, *short_opt )){
|
||||
if( !( opt_spec_p-> flags & GOPT_REPEAT )){
|
||||
const opt_t *opt_p= (const opt_t*)opts;
|
||||
for( ; opt_p != next_option; ++opt_p )
|
||||
if( opt_p-> key == opt_spec_p-> key ){
|
||||
fprintf( stderr, "%s: -%c: option may not be repeated (in any long or short form)\n", argv[0], *short_opt );
|
||||
free( opts );
|
||||
exit( EX_USAGE );
|
||||
}
|
||||
}
|
||||
next_option-> key= opt_spec_p-> key;
|
||||
|
||||
if( opt_spec_p-> flags & GOPT_ARG ){
|
||||
if( short_opt[1] )
|
||||
next_option-> arg= short_opt + 1;
|
||||
|
||||
else {
|
||||
++arg_p;
|
||||
if( !*arg_p || '-' == (*arg_p)[0] && (*arg_p)[1] ){
|
||||
fprintf( stderr, "%s: -%c: option requires an option argument\n", argv[0], *short_opt );
|
||||
free( opts );
|
||||
exit( EX_USAGE );
|
||||
}
|
||||
next_option-> arg= *arg_p;
|
||||
}
|
||||
++next_option;
|
||||
goto break_2;
|
||||
}
|
||||
next_option-> arg= NULL;
|
||||
++next_option;
|
||||
goto continue_2;
|
||||
}
|
||||
fprintf( stderr, "%s: -%c: unknown option\n", argv[0], *short_opt );
|
||||
free( opts );
|
||||
exit( EX_USAGE );
|
||||
continue_2: 0;
|
||||
}
|
||||
break_2: 0;
|
||||
}}}
|
||||
else
|
||||
*next_operand++= *arg_p;
|
||||
|
||||
next_option-> key= 0;
|
||||
*next_operand= NULL;
|
||||
*argc= next_operand - argv;
|
||||
}
|
||||
return opts;
|
||||
}
|
||||
|
||||
size_t gopt( const void *vptr_opts, int key ){
|
||||
const opt_t *opts= (const opt_t*)vptr_opts;
|
||||
size_t count= 0;
|
||||
for( ; opts-> key; ++opts )
|
||||
count+= opts-> key == key;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t gopt_arg( const void *vptr_opts, int key, const char **arg ){
|
||||
const opt_t *opts= (const opt_t*)vptr_opts;
|
||||
size_t count= 0;
|
||||
|
||||
for( ; opts-> key; ++opts )
|
||||
if( opts-> key == key ){
|
||||
if( ! count )
|
||||
*arg= opts-> arg;
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
const char *gopt_arg_i( const void *vptr_opts, int key, size_t i ){
|
||||
const opt_t *opts= (const opt_t*)vptr_opts;
|
||||
|
||||
for( ; opts-> key; ++opts )
|
||||
if( opts-> key == key ){
|
||||
if( ! i )
|
||||
return opts-> arg;
|
||||
--i;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t gopt_args( const void *vptr_opts, int key, const char **args, size_t args_len ){
|
||||
const char **args_stop= args + args_len;
|
||||
const char **args_ptr= args;
|
||||
const opt_t *opts= (const opt_t*)vptr_opts;
|
||||
|
||||
for( ; opts-> key; ++opts )
|
||||
if( opts-> key == key ){
|
||||
if( args_stop == args_ptr )
|
||||
return args_len + gopt( opts, key );
|
||||
|
||||
*args_ptr++= opts-> arg;
|
||||
}
|
||||
if( args_stop != args_ptr )
|
||||
*args_ptr= NULL;
|
||||
return args_ptr - args;
|
||||
}
|
||||
|
||||
void gopt_free( void *vptr_opts ){
|
||||
free( vptr_opts );
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/* gopt.h version 8.1: tom.viza@gmail.com PUBLIC DOMAIN 2003-8 */
|
||||
/*
|
||||
I, Tom Vajzovic, am the author of this software and its documentation and
|
||||
permanently abandon all copyright and other intellectual property rights in
|
||||
them, including the right to be identified as the author.
|
||||
|
||||
I am fairly certain that this software does what the documentation says it
|
||||
does, but I cannot guarantee that it does, or that it does what you think it
|
||||
should, and I cannot guarantee that it will not have undesirable side effects.
|
||||
|
||||
You are free to use, modify and distribute this software as you please, but
|
||||
you do so at your own risk. If you remove or hide this warning then you are
|
||||
responsible for any problems encountered by people that you make the software
|
||||
available to.
|
||||
|
||||
Before modifying or distributing this software I ask that you would please
|
||||
read http://www.purposeful.co.uk/tfl/
|
||||
*/
|
||||
|
||||
#ifndef GOPT_H_INCLUDED
|
||||
#define GOPT_H_INCLUDED
|
||||
|
||||
#define GOPT_ONCE 0
|
||||
#define GOPT_REPEAT 1
|
||||
#define GOPT_NOARG 0
|
||||
#define GOPT_ARG 2
|
||||
|
||||
#define gopt_start(...) (const void*)( const struct { int k; int f; const char *s; const char*const*l; }[]){ __VA_ARGS__, {0}}
|
||||
#define gopt_option(k,f,s,l) { k, f, s, l }
|
||||
#define gopt_shorts( ... ) (const char*)(const char[]){ __VA_ARGS__, 0 }
|
||||
#define gopt_longs( ... ) (const char**)(const char*[]){ __VA_ARGS__, NULL }
|
||||
|
||||
|
||||
void *gopt_sort( int *argc, const char **argv, const void *opt_specs );
|
||||
/* returns a pointer for use in the following calls
|
||||
* prints to stderr and call exit() on error
|
||||
*/
|
||||
size_t gopt( const void *opts, int key );
|
||||
/* returns the number of times the option was specified
|
||||
* which will be 0 or 1 unless GOPT_REPEAT was used
|
||||
*/
|
||||
size_t gopt_arg( const void *opts, int key, const char **arg );
|
||||
/* returns the number of times the option was specified
|
||||
* writes a pointer to the option argument from the first (or only) occurance to *arg
|
||||
*/
|
||||
const char *gopt_arg_i( const void *opts, int key, size_t i );
|
||||
/* returns a pointer to the ith (starting at zero) occurance
|
||||
* of the option, or NULL if it was not specified that many times
|
||||
*/
|
||||
size_t gopt_args( const void *opts, int key, const char **args, size_t args_len );
|
||||
/* returns the number of times the option was specified
|
||||
* writes pointers to the option arguments in the order of occurance to args[].
|
||||
* writes at most args_len pointers
|
||||
* if the return value is less than args_len, also writes a null pointer
|
||||
*/
|
||||
void gopt_free( void *opts );
|
||||
/* releases memory allocated in the corresponding call to gopt_sort()
|
||||
* opts can no longer be used
|
||||
*/
|
||||
#endif /* GOPT_H_INCLUDED */
|
@ -0,0 +1,3 @@
|
||||
Debug
|
||||
Release
|
||||
RelWithDebInfo
|
@ -0,0 +1,354 @@
|
||||
// digger.cpp
|
||||
|
||||
// Usage: Call with a list of TileClass ids separated by a space,
|
||||
// every (visible) tile on the map with that id will be designated for digging.
|
||||
|
||||
// NOTE currently only works with trees
|
||||
|
||||
// TODO add a sort of "sub-target" to dig() to make it able to designate stone as well
|
||||
// TODO add proper cli
|
||||
// TODO add interactive text based menu
|
||||
// TODO add ability to mark num closest to cursor
|
||||
|
||||
#include <iostream>
|
||||
#include <integers.h>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
using namespace std;
|
||||
|
||||
#include <DFTypes.h>
|
||||
#include <DFTileTypes.h>
|
||||
#include <DFHackAPI.h>
|
||||
|
||||
int vec_count(vector<uint16_t>& vec, uint16_t t)
|
||||
{
|
||||
int count = 0;
|
||||
for (uint32_t i = 0; i < vec.size(); ++i)
|
||||
{
|
||||
if (vec[i] == t)
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
//// manhattan distance
|
||||
//int source_distance(int sx, int sy, int sz,
|
||||
// int x, int y, int z, int i)
|
||||
//{
|
||||
// // TODO changing x and y seems to be optimized away (?)
|
||||
// cout << x << " " << i << " " << i%16 << " " << x+(i%16) << endl;
|
||||
//
|
||||
// // handle the fact that x,y,z refers to a 16x16 grid
|
||||
// //x += i%16;
|
||||
// //y += i/16;
|
||||
// int dx = i%16;
|
||||
// int dy = i/16;
|
||||
// //x *= 16;
|
||||
// //y *= 16;
|
||||
// //x += dx;
|
||||
// //y += dy;
|
||||
// return abs(sx-(x+(i%16)))+abs(sy-(y+(i/16)))+abs(sz-z);
|
||||
//}
|
||||
|
||||
int manhattan_distance(int x, int y, int z, int xx, int yy, int zz)
|
||||
{
|
||||
return abs(x-xx)+abs(y-yy)+abs(z-zz);
|
||||
}
|
||||
|
||||
struct DigTarget
|
||||
{
|
||||
//public:
|
||||
DigTarget() :
|
||||
source_distance(0),
|
||||
grid_x(0), grid_y(0),
|
||||
local_x(0), local_y(0),
|
||||
real_x(0), real_y(0), z(0)
|
||||
{
|
||||
}
|
||||
|
||||
DigTarget(
|
||||
int realx, int realy, int _z,
|
||||
int sourcex, int sourcey, int sourcez) :
|
||||
//grid_x(realx/16), grid_y(realy/16),
|
||||
//local_x(realx%16), local_y(realy%16),
|
||||
real_x(realx), real_y(realy), z(_z)
|
||||
{
|
||||
grid_x = realx/16;
|
||||
grid_y = realy/16;
|
||||
|
||||
local_x = realx%16;
|
||||
local_y = realy%16;
|
||||
|
||||
source_distance = manhattan_distance(
|
||||
real_x, real_y, z,
|
||||
sourcex, sourcey, sourcez);
|
||||
}
|
||||
|
||||
DigTarget(
|
||||
int gridx, int gridy, int _z,
|
||||
int localx, int localy,
|
||||
int sourcex, int sourcey, int sourcez) :
|
||||
//source_distance(manhattan_distance(
|
||||
// realx, realy, realz,
|
||||
// sourcex, sourcey, sourcez)),
|
||||
grid_x(gridx), grid_y(gridy),
|
||||
local_x(localx), local_y(localy),
|
||||
z(_z)
|
||||
//real_x(realx), real_y(realy), real_z(realz)
|
||||
{
|
||||
real_x = (grid_x*16)+local_x;
|
||||
real_y = (grid_y*16)+local_y;
|
||||
|
||||
source_distance = manhattan_distance(
|
||||
real_x, real_y, z,
|
||||
sourcex, sourcey, sourcez);
|
||||
}
|
||||
|
||||
int source_distance; // the distance to the source coords, used for sorting
|
||||
//int source_distance() const { return _source_distance; }
|
||||
|
||||
int grid_x, grid_y;
|
||||
int local_x, local_y;
|
||||
int real_x, real_y;
|
||||
int z;
|
||||
//int index;
|
||||
|
||||
//const bool valid;
|
||||
|
||||
bool operator<(const DigTarget& o) const { return source_distance < o.source_distance; }
|
||||
|
||||
//private:
|
||||
// int source_x, source_y, source_z;
|
||||
// int _source_distance;
|
||||
};
|
||||
|
||||
int dig(DFHack::API& DF,
|
||||
vector<uint16_t>& targets,
|
||||
int num = -1,
|
||||
const int x_source = 0,
|
||||
const int y_source = 0,
|
||||
const int z_source = 0)
|
||||
{
|
||||
if (num == 0)
|
||||
return 0; // max limit of 0, nothing to do
|
||||
|
||||
uint32_t x_max,y_max,z_max;
|
||||
DFHack::t_designation designations[16][16];
|
||||
uint16_t tiles[16][16];
|
||||
//uint32_t count = 0;
|
||||
DF.getSize(x_max,y_max,z_max);
|
||||
|
||||
// every tile found, will later be sorted by distance to source
|
||||
vector<DigTarget> candidates;
|
||||
|
||||
cout << "============================" << endl;
|
||||
cout << "source is " << x_source << " " << y_source << " " << z_source << endl;
|
||||
|
||||
//int debugmaxx = 0;
|
||||
//int debugmaxy = 0;
|
||||
|
||||
// walk the map
|
||||
for(uint32_t x = 0; x < x_max; x++)
|
||||
{
|
||||
for(uint32_t y = 0; y < y_max; y++)
|
||||
{
|
||||
for(uint32_t z = 0; z < z_max; z++)
|
||||
{
|
||||
if (z != z_source)
|
||||
continue; // hack to cut down on targets
|
||||
|
||||
if(DF.isValidBlock(x,y,z))
|
||||
{
|
||||
// read block designations and tiletype
|
||||
DF.ReadDesignations(x,y,z, (uint32_t *) designations);
|
||||
DF.ReadTileTypes(x,y,z, (uint16_t *) tiles);
|
||||
|
||||
// search all tiles for dig targets:
|
||||
// visible, not yet marked for dig and matching tile type
|
||||
for(uint32_t lx = 0; lx < 16; lx++)
|
||||
{
|
||||
for(uint32_t ly = 0; ly < 16; ly++)
|
||||
{
|
||||
if (designations[lx][ly].bits.hidden == 0 &&
|
||||
designations[lx][ly].bits.dig == 0 &&
|
||||
vec_count(targets, DFHack::tileTypeTable[tiles[lx][ly]].c) > 0)
|
||||
{
|
||||
//cout << "target found at: ";
|
||||
//cout << x << "," << y << "," << z << "," << i << endl;
|
||||
|
||||
//designations[i].bits.dig = DFHack::designation_default;
|
||||
//++count;
|
||||
|
||||
//int realx = (x*16)+lx;
|
||||
//int realy = (y*16)+ly;
|
||||
|
||||
candidates.push_back(DigTarget(
|
||||
x, y, z,
|
||||
lx, ly,
|
||||
x_source, y_source, z_source));
|
||||
|
||||
//cout << "target found at " << world_x << " " << world_y << " " << z;
|
||||
//cout << ", " << dt->source_distance << " tiles to source" << endl;
|
||||
|
||||
//if (world_x > debugmaxx)
|
||||
// debugmaxx = world_x;
|
||||
//if (world_y > debugmaxy)
|
||||
// debugmaxy = world_y;
|
||||
}
|
||||
} // local y
|
||||
} // local x
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO the following routine doesnt check if the tile is already marked for digging
|
||||
|
||||
// if we found more tiles than was requested, sort them by distance to source,
|
||||
// keep the front 'num' elements and drop the rest
|
||||
if (num != -1 && candidates.size() > (unsigned int)num)
|
||||
{
|
||||
sort(candidates.begin(), candidates.end());
|
||||
candidates.resize(num);
|
||||
}
|
||||
num = candidates.size();
|
||||
|
||||
cout << "============================" << endl;
|
||||
cout << "source is " << x_source << " " << y_source << " " << z_source << endl;
|
||||
|
||||
// mark the tiles for actual digging
|
||||
for (vector<DigTarget>::const_iterator i = candidates.begin(); i != candidates.end(); ++i)
|
||||
{
|
||||
//int grid_x = (*i).x/16;
|
||||
//int grid_y = (*i).y/16;
|
||||
//int z = (*i).z;
|
||||
|
||||
//int local_x = (*i).x%grid_x;
|
||||
//int local_y = (*i).y%grid_y;
|
||||
|
||||
cout << "designating at " << (*i).real_x << " " << (*i).real_y << " " << (*i).z;
|
||||
cout << ", " << (*i).source_distance << " tiles to source" << endl;
|
||||
|
||||
// TODO this could probably be made much better, theres a big chance the trees are on the same grid
|
||||
// TODO move into function in DigTarget
|
||||
DF.ReadDesignations((*i).grid_x, (*i).grid_y, (*i).z, (uint32_t *) designations);
|
||||
designations[(*i).local_x][(*i).local_y].bits.dig = DFHack::designation_default;
|
||||
DF.WriteDesignations((*i).grid_x, (*i).grid_y, (*i).z, (uint32_t *) designations);
|
||||
}
|
||||
|
||||
//cout << debugmaxx << " " << debugmaxy << endl;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
void test()
|
||||
{
|
||||
{
|
||||
DigTarget dt;
|
||||
//assert(!dt.valid);
|
||||
}
|
||||
|
||||
{
|
||||
DigTarget dt(
|
||||
20, 35, 16,
|
||||
10, 12, 14);
|
||||
|
||||
assert(dt.grid_x == 1);
|
||||
assert(dt.grid_y == 2);
|
||||
|
||||
assert(dt.local_x == 4);
|
||||
assert(dt.local_y == 3);
|
||||
|
||||
assert(dt.real_x == 20);
|
||||
assert(dt.real_y == 35);
|
||||
|
||||
assert(dt.z == 16);
|
||||
assert(dt.source_distance == 35);
|
||||
//assert(dt.valid);
|
||||
}
|
||||
|
||||
{
|
||||
DigTarget dt(
|
||||
2, 4, 16,
|
||||
5, 10,
|
||||
10, 12, 14);
|
||||
|
||||
assert(dt.grid_x == 2);
|
||||
assert(dt.grid_y == 4);
|
||||
|
||||
assert(dt.local_x == 5);
|
||||
assert(dt.local_y == 10);
|
||||
|
||||
assert(dt.real_x == 37);
|
||||
assert(dt.real_y == 74);
|
||||
|
||||
assert(dt.z == 16);
|
||||
assert(dt.source_distance == 91);
|
||||
//assert(dt.valid);
|
||||
}
|
||||
|
||||
//{ // sorting
|
||||
// DigTarget a(
|
||||
// 20, 35, 16,
|
||||
// 10, 12, 14);
|
||||
|
||||
// DigTarget b(
|
||||
// 2, 4, 16,
|
||||
// 5, 10,
|
||||
// 10, 12, 14);
|
||||
|
||||
// vector<DigTarget> v;
|
||||
// v.push_back(b);
|
||||
// v.push_back(a);
|
||||
// sort(v.begin(), v.end());
|
||||
// assert(*(v.begin()) == a);
|
||||
//}
|
||||
}
|
||||
|
||||
int main (int argc, const char* argv[])
|
||||
{
|
||||
test();
|
||||
|
||||
vector<uint16_t> targets;
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
targets.push_back(atoi(argv[i]));
|
||||
}
|
||||
if (targets.size() == 0)
|
||||
{
|
||||
cout << "Usage: Call with a list of TileClass ids separated by a space,\n";
|
||||
cout << "every (visible) tile on the map with that id will be designated for digging.\n\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
DFHack::API DF("Memory.xml");
|
||||
if(!DF.Attach())
|
||||
{
|
||||
cerr << "DF not found" << endl;
|
||||
return 1;
|
||||
}
|
||||
DF.InitMap();
|
||||
|
||||
// TODO hack until we have a proper cli to specify origin
|
||||
int x_source = 134, y_source = 134, z_source = 16; // my wagon starts here; cut trees close to wagon
|
||||
//DF.InitViewAndCursor();
|
||||
//if (!DF.getViewCoords(x_source, y_source, z_source))
|
||||
//{
|
||||
// cerr << "Enable cursor" << endl;
|
||||
// return 1;
|
||||
//}
|
||||
|
||||
int count = dig(DF, targets, 10, x_source, y_source, z_source); // <-- important part
|
||||
cout << count << " targets designated" << endl;
|
||||
|
||||
DF.Detach();
|
||||
}
|
||||
#ifndef LINUX_BUILD
|
||||
cout << "Done. Press any key to continue" << endl;
|
||||
cin.ignore();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
// Map cleaner. Removes all the snow, mud spills, blood and vomit from map tiles.
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <integers.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
using namespace std;
|
||||
|
||||
#include <DFTypes.h>
|
||||
#include <DFHackAPI.h>
|
||||
|
||||
// returns a lower case version of the string
|
||||
string tolower (const string & s)
|
||||
{
|
||||
string d (s);
|
||||
|
||||
transform (d.begin (), d.end (), d.begin (), (int(*)(int)) tolower);
|
||||
return d;
|
||||
}
|
||||
string groupBy2(const string & s)
|
||||
{
|
||||
string d;
|
||||
for(int i =2;i<s.length();i++){
|
||||
if(i%2==0)
|
||||
{
|
||||
d+= s.substr(i-2,2) + " ";
|
||||
}
|
||||
}
|
||||
d+=s.substr(s.length()-2,2);
|
||||
return(d);
|
||||
}
|
||||
|
||||
uint32_t endian_swap(uint32_t x)
|
||||
{
|
||||
x = (x>>24) |
|
||||
((x<<8) & 0x00FF0000) |
|
||||
((x>>8) & 0x0000FF00) |
|
||||
(x<<24);
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
int main (void)
|
||||
{
|
||||
DFHack::API DF ("Memory.xml");
|
||||
if(!DF.Attach())
|
||||
{
|
||||
cerr << "DF not found" << endl;
|
||||
return 1;
|
||||
}
|
||||
map< string, vector<string> > names;
|
||||
if(!DF.InitReadNameTables(names))
|
||||
{
|
||||
cerr << "Could not get Names" << endl;
|
||||
return 1;
|
||||
}
|
||||
string input;
|
||||
DF.ForceResume();
|
||||
cout << "\nSelect Name to search or q to Quit" << endl;
|
||||
getline (cin, input);
|
||||
while(input != "q"){
|
||||
for( map< string, vector<string> >::iterator it = names.begin();it != names.end(); it++){
|
||||
for(uint32_t i = 0; i < it->second.size(); i++){
|
||||
uint32_t found = input.find(tolower(it->second[i]));
|
||||
if(found != string::npos){
|
||||
stringstream value;
|
||||
value << setfill('0') << setw(8) << hex << endian_swap(i);
|
||||
cout << it->first << " " << it->second[i] << " " << groupBy2(value.str()) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
DF.Resume();
|
||||
getline(cin,input);
|
||||
}
|
||||
DF.Detach();
|
||||
DF.FinishReadNameTables();
|
||||
#ifndef LINUX_BUILD
|
||||
cout << "Done. Press any key to continue" << endl;
|
||||
cin.ignore();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue