cleaning up in needs_porting
Removed obsolete plugins. Started hotkeys port. Mostly-finished position port. Corrected dwarfmonitor date display. Documented putontable.lua in readme.develop
parent
8e6fcac92e
commit
f3826abc0c
@ -1,543 +0,0 @@
|
||||
#ifndef SEGMENTED_FINDER_H
|
||||
#define SEGMENTED_FINDER_H
|
||||
#include <malloc.h>
|
||||
#include <iosfwd>
|
||||
#include <iterator>
|
||||
|
||||
class SegmentedFinder;
|
||||
class SegmentFinder
|
||||
{
|
||||
public:
|
||||
SegmentFinder(DFHack::t_memrange & mr, DFHack::Context * DF, SegmentedFinder * SF)
|
||||
{
|
||||
_DF = DF;
|
||||
mr_ = mr;
|
||||
valid=false;
|
||||
if(mr.valid)
|
||||
{
|
||||
mr_.buffer = (uint8_t *)malloc (mr_.end - mr_.start);
|
||||
_SF = SF;
|
||||
try
|
||||
{
|
||||
DF->ReadRaw(mr_.start,(mr_.end - mr_.start),mr_.buffer);
|
||||
valid = true;
|
||||
}
|
||||
catch (DFHack::Error::MemoryAccessDenied &)
|
||||
{
|
||||
free(mr_.buffer);
|
||||
valid = false;
|
||||
mr.valid = false; // mark the range passed in as bad
|
||||
cout << "Range 0x" << hex << mr_.start << " - 0x" << mr_.end;
|
||||
|
||||
if (strlen(mr_.name) != 0)
|
||||
cout << " (" << mr_.name << ")";
|
||||
|
||||
cout << dec << " not readable." << endl;
|
||||
cout << "Skipping this range on future scans." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
~SegmentFinder()
|
||||
{
|
||||
if(valid)
|
||||
free(mr_.buffer);
|
||||
}
|
||||
bool isValid()
|
||||
{
|
||||
return valid;
|
||||
}
|
||||
template <class needleType, class hayType, typename comparator >
|
||||
bool Find (needleType needle, const uint8_t increment , vector <uint64_t> &newfound, comparator oper)
|
||||
{
|
||||
if(!valid) return !newfound.empty();
|
||||
//loop
|
||||
for(uint64_t offset = 0; offset < (mr_.end - mr_.start) - sizeof(hayType); offset += increment)
|
||||
{
|
||||
if( oper(_SF,(hayType *)(mr_.buffer + offset), needle) )
|
||||
newfound.push_back(mr_.start + offset);
|
||||
}
|
||||
return !newfound.empty();
|
||||
}
|
||||
|
||||
template < class needleType, class hayType, typename comparator >
|
||||
uint64_t FindInRange (needleType needle, comparator oper, uint64_t start, uint64_t length)
|
||||
{
|
||||
if(!valid) return 0;
|
||||
uint64_t stopper = min((mr_.end - mr_.start) - sizeof(hayType), (start - mr_.start) - sizeof(hayType) + length);
|
||||
//loop
|
||||
for(uint64_t offset = start - mr_.start; offset < stopper; offset +=1)
|
||||
{
|
||||
if( oper(_SF,(hayType *)(mr_.buffer + offset), needle) )
|
||||
return mr_.start + offset;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class needleType, class hayType, typename comparator >
|
||||
bool Filter (needleType needle, vector <uint64_t> &found, vector <uint64_t> &newfound, comparator oper)
|
||||
{
|
||||
if(!valid) return !newfound.empty();
|
||||
for( uint64_t i = 0; i < found.size(); i++)
|
||||
{
|
||||
if(mr_.isInRange(found[i]))
|
||||
{
|
||||
uint64_t corrected = found[i] - mr_.start;
|
||||
if( oper(_SF,(hayType *)(mr_.buffer + corrected), needle) )
|
||||
newfound.push_back(found[i]);
|
||||
}
|
||||
}
|
||||
return !newfound.empty();
|
||||
}
|
||||
private:
|
||||
friend class SegmentedFinder;
|
||||
SegmentedFinder * _SF;
|
||||
DFHack::Context * _DF;
|
||||
DFHack::t_memrange mr_;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
class SegmentedFinder
|
||||
{
|
||||
public:
|
||||
SegmentedFinder(vector <DFHack::t_memrange>& ranges, DFHack::Context * DF)
|
||||
{
|
||||
_DF = DF;
|
||||
for(size_t i = 0; i < ranges.size(); i++)
|
||||
{
|
||||
segments.push_back(new SegmentFinder(ranges[i], DF, this));
|
||||
}
|
||||
}
|
||||
~SegmentedFinder()
|
||||
{
|
||||
for(size_t i = 0; i < segments.size(); i++)
|
||||
{
|
||||
delete segments[i];
|
||||
}
|
||||
}
|
||||
SegmentFinder * getSegmentForAddress (uint64_t addr)
|
||||
{
|
||||
for(size_t i = 0; i < segments.size(); i++)
|
||||
{
|
||||
if(segments[i]->mr_.isInRange(addr))
|
||||
{
|
||||
return segments[i];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
template <class needleType, class hayType, typename comparator >
|
||||
bool Find (const needleType needle, const uint8_t increment, vector <uint64_t> &found, comparator oper)
|
||||
{
|
||||
found.clear();
|
||||
for(size_t i = 0; i < segments.size(); i++)
|
||||
{
|
||||
segments[i]->Find<needleType,hayType,comparator>(needle, increment, found, oper);
|
||||
}
|
||||
return !(found.empty());
|
||||
}
|
||||
|
||||
template < class needleType, class hayType, typename comparator >
|
||||
uint64_t FindInRange (needleType needle, comparator oper, uint64_t start, uint64_t length)
|
||||
{
|
||||
SegmentFinder * sf = getSegmentForAddress(start);
|
||||
if(sf)
|
||||
{
|
||||
return sf->FindInRange<needleType,hayType,comparator>(needle, oper, start, length);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class needleType, class hayType, typename comparator >
|
||||
bool Filter (const needleType needle, vector <uint64_t> &found, comparator oper)
|
||||
{
|
||||
vector <uint64_t> newfound;
|
||||
for(size_t i = 0; i < segments.size(); i++)
|
||||
{
|
||||
segments[i]->Filter<needleType,hayType,comparator>(needle, found, newfound, oper);
|
||||
}
|
||||
found.clear();
|
||||
found = newfound;
|
||||
return !(found.empty());
|
||||
}
|
||||
|
||||
template <class needleType, class hayType, typename comparator >
|
||||
bool Incremental (needleType needle, const uint8_t increment ,vector <uint64_t> &found, comparator oper)
|
||||
{
|
||||
if(found.empty())
|
||||
{
|
||||
return Find <needleType, hayType, comparator>(needle,increment,found,oper);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Filter <needleType, hayType, comparator>(needle,found,oper);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T * Translate(uint64_t address)
|
||||
{
|
||||
for(size_t i = 0; i < segments.size(); i++)
|
||||
{
|
||||
if(segments[i]->mr_.isInRange(address))
|
||||
{
|
||||
return (T *) (segments[i]->mr_.buffer + address - segments[i]->mr_.start);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T Read(uint64_t address)
|
||||
{
|
||||
return *Translate<T>(address);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Read(uint64_t address, T& target)
|
||||
{
|
||||
T * test = Translate<T>(address);
|
||||
if(test)
|
||||
{
|
||||
target = *test;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private:
|
||||
DFHack::Context * _DF;
|
||||
vector <SegmentFinder *> segments;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
bool equalityP (SegmentedFinder* s, T *x, T y)
|
||||
{
|
||||
return (*x) == y;
|
||||
}
|
||||
|
||||
struct vecTriplet
|
||||
{
|
||||
uint32_t start;
|
||||
uint32_t finish;
|
||||
uint32_t alloc_finish;
|
||||
};
|
||||
|
||||
template <typename Needle>
|
||||
bool vectorLength (SegmentedFinder* s, vecTriplet *x, Needle &y)
|
||||
{
|
||||
if(x->start <= x->finish && x->finish <= x->alloc_finish)
|
||||
if((x->finish - x->start) == y)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// find a vector of 32bit pointers, where an object pointed to has a string 'y' as the first member
|
||||
bool vectorString (SegmentedFinder* s, vecTriplet *x, const char *y)
|
||||
{
|
||||
uint32_t object_ptr;
|
||||
// iterate over vector of pointers
|
||||
for(uint32_t idx = x->start; idx < x->finish; idx += sizeof(uint32_t))
|
||||
{
|
||||
// deref ptr idx, get ptr to object
|
||||
if(!s->Read(idx,object_ptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// deref ptr to first object, get ptr to string
|
||||
uint32_t string_ptr;
|
||||
if(!s->Read(object_ptr,string_ptr))
|
||||
return false;
|
||||
// get string location in our local cache
|
||||
char * str = s->Translate<char>(string_ptr);
|
||||
if(!str)
|
||||
return false;
|
||||
if(strcmp(y, str) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// find a vector of 32bit pointers, where the first object pointed to has a string 'y' as the first member
|
||||
bool vectorStringFirst (SegmentedFinder* s, vecTriplet *x, const char *y)
|
||||
{
|
||||
uint32_t object_ptr;
|
||||
uint32_t idx = x->start;
|
||||
// deref ptr idx, get ptr to object
|
||||
if(!s->Read(idx,object_ptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// deref ptr to first object, get ptr to string
|
||||
uint32_t string_ptr;
|
||||
if(!s->Read(object_ptr,string_ptr))
|
||||
return false;
|
||||
// get string location in our local cache
|
||||
char * str = s->Translate<char>(string_ptr);
|
||||
if(!str)
|
||||
return false;
|
||||
if(strcmp(y, str) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// test if the address is between vector.start and vector.finish
|
||||
// not very useful alone, but could be a good step to filter some things
|
||||
bool vectorAddrWithin (SegmentedFinder* s, vecTriplet *x, uint32_t address)
|
||||
{
|
||||
if(address < x->finish && address >= x->start)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// test if an object address is within the vector of pointers
|
||||
//
|
||||
bool vectorOfPtrWithin (SegmentedFinder* s, vecTriplet *x, uint32_t address)
|
||||
{
|
||||
uint32_t object_ptr;
|
||||
for(uint32_t idx = x->start; idx < x->finish; idx += sizeof(uint32_t))
|
||||
{
|
||||
if(!s->Read(idx,object_ptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(object_ptr == address)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool vectorAll (SegmentedFinder* s, vecTriplet *x, int )
|
||||
{
|
||||
if(x->start <= x->finish && x->finish <= x->alloc_finish)
|
||||
{
|
||||
if(s->getSegmentForAddress(x->start) == s->getSegmentForAddress(x->finish)
|
||||
&& s->getSegmentForAddress(x->finish) == s->getSegmentForAddress(x->alloc_finish))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class Bytestreamdata
|
||||
{
|
||||
public:
|
||||
void * object;
|
||||
uint32_t length;
|
||||
uint32_t allocated;
|
||||
uint32_t n_used;
|
||||
};
|
||||
|
||||
class Bytestream
|
||||
{
|
||||
public:
|
||||
Bytestream(void * obj, uint32_t len, bool alloc = false)
|
||||
{
|
||||
d = new Bytestreamdata();
|
||||
d->allocated = alloc;
|
||||
d->object = obj;
|
||||
d->length = len;
|
||||
d->n_used = 1;
|
||||
constant = false;
|
||||
}
|
||||
Bytestream()
|
||||
{
|
||||
d = new Bytestreamdata();
|
||||
d->allocated = false;
|
||||
d->object = 0;
|
||||
d->length = 0;
|
||||
d->n_used = 1;
|
||||
constant = false;
|
||||
}
|
||||
Bytestream( Bytestream & bs)
|
||||
{
|
||||
d =bs.d;
|
||||
d->n_used++;
|
||||
constant = false;
|
||||
}
|
||||
Bytestream( const Bytestream & bs)
|
||||
{
|
||||
d =bs.d;
|
||||
d->n_used++;
|
||||
constant = true;
|
||||
}
|
||||
~Bytestream()
|
||||
{
|
||||
d->n_used --;
|
||||
if(d->allocated && d->object && d->n_used == 0)
|
||||
{
|
||||
free (d->object);
|
||||
free (d);
|
||||
}
|
||||
}
|
||||
bool Allocate(size_t bytes)
|
||||
{
|
||||
if(constant)
|
||||
return false;
|
||||
if(d->allocated)
|
||||
{
|
||||
d->object = realloc(d->object, bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
d->object = malloc( bytes );
|
||||
}
|
||||
|
||||
if(d->object)
|
||||
{
|
||||
d->allocated = bytes;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
d->allocated = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
template < class T >
|
||||
bool insert( T what )
|
||||
{
|
||||
if(constant)
|
||||
return false;
|
||||
if(d->length+sizeof(T) >= d->allocated)
|
||||
Allocate((d->length+sizeof(T)) * 2);
|
||||
(*(T *)( (uint64_t)d->object + d->length)) = what;
|
||||
d->length += sizeof(T);
|
||||
return true;
|
||||
}
|
||||
Bytestreamdata * d;
|
||||
bool constant;
|
||||
};
|
||||
std::ostream& operator<< ( std::ostream& out, Bytestream& bs )
|
||||
{
|
||||
if(bs.d->object)
|
||||
{
|
||||
out << "bytestream " << dec << bs.d->length << "/" << bs.d->allocated << " bytes" << endl;
|
||||
for(size_t i = 0; i < bs.d->length; i++)
|
||||
{
|
||||
out << hex << (int) ((uint8_t *) bs.d->object)[i] << " ";
|
||||
}
|
||||
out << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "empty bytestresm" << endl;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::istream& operator>> ( std::istream& out, Bytestream& bs )
|
||||
{
|
||||
string read;
|
||||
while(!out.eof())
|
||||
{
|
||||
string tmp;
|
||||
out >> tmp;
|
||||
read.append(tmp);
|
||||
}
|
||||
cout << read << endl;
|
||||
bs.d->length = 0;
|
||||
size_t first = read.find_first_of("\"");
|
||||
size_t last = read.find_last_of("\"");
|
||||
size_t start = first + 1;
|
||||
if(first == read.npos)
|
||||
{
|
||||
std::transform(read.begin(), read.end(), read.begin(), (int(*)(int)) tolower);
|
||||
bs.Allocate(read.size()); // overkill. size / 2 should be good, but this is safe
|
||||
int state = 0;
|
||||
char big = 0;
|
||||
char small = 0;
|
||||
string::iterator it = read.begin();
|
||||
// iterate through string, construct a bytestream out of 00-FF bytes
|
||||
while(it != read.end())
|
||||
{
|
||||
char reads = *it;
|
||||
if((reads >='0' && reads <= '9'))
|
||||
{
|
||||
if(state == 0)
|
||||
{
|
||||
big = reads - '0';
|
||||
state = 1;
|
||||
}
|
||||
else if(state == 1)
|
||||
{
|
||||
small = reads - '0';
|
||||
state = 0;
|
||||
bs.insert<char>(big*16 + small);
|
||||
}
|
||||
}
|
||||
if((reads >= 'a' && reads <= 'f'))
|
||||
{
|
||||
if(state == 0)
|
||||
{
|
||||
big = reads - 'a' + 10;
|
||||
state = 1;
|
||||
}
|
||||
else if(state == 1)
|
||||
{
|
||||
small = reads - 'a' + 10;
|
||||
state = 0;
|
||||
bs.insert<char>(big*16 + small);
|
||||
}
|
||||
}
|
||||
it++;
|
||||
}
|
||||
// we end in state= 1. should we add or should we trim... or throw errors?
|
||||
// I decided on adding
|
||||
if (state == 1)
|
||||
{
|
||||
small = 0;
|
||||
bs.insert<char>(big*16 + small);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(last == first)
|
||||
{
|
||||
// only one "
|
||||
last = read.size();
|
||||
}
|
||||
size_t length = last - start;
|
||||
// construct bytestream out of stuff between ""
|
||||
bs.d->length = length;
|
||||
if(length)
|
||||
{
|
||||
// todo: Bytestream should be able to handle this without external code
|
||||
bs.Allocate(length);
|
||||
bs.d->length = length;
|
||||
const char* strstart = read.c_str();
|
||||
memcpy(bs.d->object, strstart + start, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
bs.d->object = 0;
|
||||
}
|
||||
}
|
||||
cout << bs;
|
||||
return out;
|
||||
}
|
||||
|
||||
bool findBytestream (SegmentedFinder* s, void *addr, Bytestream compare )
|
||||
{
|
||||
if(memcmp(addr, compare.d->object, compare.d->length) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool findString (SegmentedFinder* s, uint32_t *addr, const char * compare )
|
||||
{
|
||||
// read string pointer, translate to local scheme
|
||||
char *str = s->Translate<char>(*addr);
|
||||
// verify
|
||||
if(!str)
|
||||
return false;
|
||||
if(strcmp(str, compare) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool findStrBuffer (SegmentedFinder* s, uint32_t *addr, const char * compare )
|
||||
{
|
||||
if(memcmp((const char *)addr, compare, strlen(compare)) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // SEGMENTED_FINDER_H
|
@ -1,30 +1,13 @@
|
||||
Notes by PeridexisErrant, on the needs_porting scripts and plugins:
|
||||
|
||||
I deleted:
|
||||
attachtest.py obsolete
|
||||
digger.cpp less useful than digger2, replaced by autochop
|
||||
digger2.cpp replaced by digfort
|
||||
dfstatus.cpp replaced by dfstatus.lua
|
||||
drawtile.cpp replaced by tiletypes
|
||||
fix-3708.cpp obsolete, bug fixed in vanilla
|
||||
lair.cpp replaced by lair
|
||||
reveal.py replaced by reveal
|
||||
treedump.py replaced by prospect & autochop
|
||||
veinlook.cpp replaced by prospect
|
||||
veinswap.cpp replaced by changevein
|
||||
|
||||
|
||||
To investigate further:
|
||||
creaturemanager.cpp modify skills and labors of creatures, kill creatures, etc; impressive but I suspect most functions implemented elsewhere
|
||||
digpattern.cpp allows multi-Z designations. Obsolete, or is there more here?
|
||||
incrementalsearch.cpp linux-only memory stuff; unqualified to judge
|
||||
SegementedFinder.h more memory stuff
|
||||
|
||||
|
||||
To port:
|
||||
copypaste.cpp high value target - a proof of concept plugin to allow copy-pasting in DF; does both terrain and buildings/constructions
|
||||
dfbauxtite.cpp changes material of mechanisms to bauxtite (ie magma-safe)
|
||||
hellhole.cpp instantly creates a hole to the HFS
|
||||
hotkeynotedump.py outputs a list of hotkeys and names; most useful before keybindings were possible. Trival to port but low value.
|
||||
itemdesignator.cpp mostly replaced by Falconne's enhanced stocks, but could port the interesting 'set fire to things' function
|
||||
position.py outputs very detailed time& place info
|
||||
TODO:
|
||||
copypaste.cpp
|
||||
high value target - a proof of concept plugin to allow copy-pasting in DF; does both terrain and buildings/constructions
|
||||
creaturemanager.cpp
|
||||
modify skills and labors of creatures, kill creatures, etc; impressive but I suspect most functions implemented elsewhere
|
||||
dfbauxtite.cpp
|
||||
changes material of mechanisms to bauxtite (ie magma-safe)
|
||||
hellhole.cpp
|
||||
instantly creates a hole to the HFS
|
||||
|
||||
In progress:
|
||||
hotkey-notes.lua
|
||||
prints list of hotkeys with name and jump position
|
||||
|
@ -1,259 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <string.h> // for memset
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
#include <map>
|
||||
#include <stdio.h>
|
||||
#include <cstdlib>
|
||||
using namespace std;
|
||||
|
||||
#include <DFHack.h>
|
||||
#include <extra/MapExtras.h>
|
||||
using namespace MapExtras;
|
||||
//#include <argstream.h>
|
||||
|
||||
void usage(int argc, const char * argv[])
|
||||
{
|
||||
cout
|
||||
<< "Usage:" << endl
|
||||
<< argv[0] << " [option 1] [option 2] [...]" << endl
|
||||
<< "-q : Suppress \"Press any key to continue\" at program termination" << endl
|
||||
<< "-u <n> : Dig upwards <n> times (default 5)" << endl
|
||||
<< "-d <n> : Dig downwards <n> times (default 5)" << endl
|
||||
;
|
||||
}
|
||||
|
||||
void digat(MapCache * MCache, DFHack::DFCoord xy)
|
||||
{
|
||||
int16_t tt;
|
||||
tt = MCache->tiletypeAt(xy);
|
||||
if(!DFHack::isWallTerrain(tt))
|
||||
return;
|
||||
|
||||
// found a good tile, dig+unset material
|
||||
DFHack::t_designation des = MCache->designationAt(xy);
|
||||
|
||||
if(MCache->testCoord(xy))
|
||||
{
|
||||
MCache->clearMaterialAt(xy);
|
||||
|
||||
if(des.bits.dig == DFHack::designation_no)
|
||||
des.bits.dig = DFHack::designation_default;
|
||||
MCache->setDesignationAt(xy,des);
|
||||
}
|
||||
}
|
||||
|
||||
int strtoint(const string &str)
|
||||
{
|
||||
stringstream ss(str);
|
||||
int result;
|
||||
return ss >> result ? result : -1;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
} pos;
|
||||
|
||||
int main (int argc, const char* argv[])
|
||||
{
|
||||
// Command line options
|
||||
bool updown = false;
|
||||
bool quiet = true;
|
||||
// let's be more useful when double-clicked on windows
|
||||
#ifndef LINUX_BUILD
|
||||
quiet = false;
|
||||
#endif
|
||||
int dig_up_n = 5;
|
||||
int dig_down_n = 5;
|
||||
|
||||
for(int i = 1; i < argc; i++)
|
||||
{
|
||||
string arg_cur = argv[i];
|
||||
string arg_next = "";
|
||||
int arg_next_int = -99999;
|
||||
/* Check if argv[i+1] is a number >= 0 */
|
||||
if (i < argc-1) {
|
||||
arg_next = argv[i+1];
|
||||
arg_next_int = strtoint(arg_next);
|
||||
if (arg_next != "0" && arg_next_int == 0) {
|
||||
arg_next_int = -99999;
|
||||
}
|
||||
}
|
||||
if (arg_cur == "-x")
|
||||
{
|
||||
updown = true;
|
||||
}
|
||||
else if (arg_cur == "-q")
|
||||
{
|
||||
quiet = true;
|
||||
}
|
||||
else if(arg_cur == "-u" && i < argc-1)
|
||||
{
|
||||
if (arg_next_int < 0 || arg_next_int >= 99999) {
|
||||
usage(argc, argv);
|
||||
return 1;
|
||||
}
|
||||
dig_up_n = arg_next_int;
|
||||
i++;
|
||||
}
|
||||
else if(arg_cur == "-d" && i < argc-1)
|
||||
{
|
||||
if (arg_next_int < 0 || arg_next_int >= 99999) {
|
||||
usage(argc, argv);
|
||||
return 1;
|
||||
}
|
||||
dig_down_n = arg_next_int;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
usage(argc, argv);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
DFHack::ContextManager DFMgr("Memory.xml");
|
||||
DFHack::Context * DF;
|
||||
try
|
||||
{
|
||||
DF = DFMgr.getSingleContext();
|
||||
DF->Attach();
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
cerr << "Error getting context: " << e.what() << endl;
|
||||
if (!quiet)
|
||||
cin.ignore();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t x_max,y_max,z_max;
|
||||
DFHack::Maps * Maps = DF->getMaps();
|
||||
DFHack::Gui * Gui = DF->getGui();
|
||||
|
||||
// init the map
|
||||
if(!Maps->Start())
|
||||
{
|
||||
cerr << "Can't init map. Make sure you have a map loaded in DF." << endl;
|
||||
DF->Detach();
|
||||
if (!quiet)
|
||||
cin.ignore();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t cx, cy, cz;
|
||||
Maps->getSize(x_max,y_max,z_max);
|
||||
uint32_t tx_max = x_max * 16;
|
||||
uint32_t ty_max = y_max * 16;
|
||||
|
||||
Gui->getCursorCoords(cx,cy,cz);
|
||||
if (cx == -30000)
|
||||
{
|
||||
cerr << "Cursor is not active. Point the cursor at the position to dig at." << endl;
|
||||
DF->Detach();
|
||||
if (!quiet)
|
||||
{
|
||||
cin.ignore();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
DFHack::DFCoord xy ((uint32_t)cx,(uint32_t)cy,cz);
|
||||
if(xy.x == 0 || xy.x == tx_max - 1 || xy.y == 0 || xy.y == ty_max - 1)
|
||||
{
|
||||
cerr << "I won't dig the borders. That would be cheating!" << endl;
|
||||
DF->Detach();
|
||||
if (!quiet)
|
||||
{
|
||||
cin.ignore();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
MapCache * MCache = new MapCache(Maps);
|
||||
|
||||
DFHack::t_designation des = MCache->designationAt(xy);
|
||||
int16_t tt = MCache->tiletypeAt(xy);
|
||||
int16_t veinmat = MCache->veinMaterialAt(xy);
|
||||
|
||||
/*
|
||||
if( veinmat == -1 )
|
||||
{
|
||||
cerr << "This tile is non-vein. Bye :)" << endl;
|
||||
delete MCache;
|
||||
DF->Detach();
|
||||
if (!quiet) {
|
||||
cin.ignore();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
printf("Digging at (%d/%d/%d), tiletype: %d, veinmat: %d, designation: 0x%x ... DIGGING!\n", cx,cy,cz, tt, veinmat, des.whole);
|
||||
|
||||
// 1 < xy.x < tx_max - 1
|
||||
// 1 < xy.y < ty_max - 1
|
||||
// xy.z
|
||||
|
||||
// X____
|
||||
// X_XXX
|
||||
// XXXXX
|
||||
// __XXX
|
||||
// __XXX
|
||||
// _____
|
||||
pos map[] =
|
||||
{
|
||||
{ 0,0 }
|
||||
, { 0,1 }
|
||||
, { 0,2 } , { 2,2 }, { 3,2 }, { 4,2 }
|
||||
, { 0,3 }, { 1,3 }, { 2,3 }, { 3,3 }, { 4,3 }
|
||||
, { 2,4 }, { 3,4 }, { 4,4 }
|
||||
// this is mirrored, goes left instead of right
|
||||
, {-2,2 }, {-3,2 }, {-4,2 }
|
||||
, {-1,3 }, {-2,3 }, {-3,3 }, {-4,3 }
|
||||
, {-2,4 }, {-3,4 }, {-4,4 }
|
||||
};
|
||||
|
||||
DFHack::DFCoord npos = xy;
|
||||
|
||||
if (dig_up_n > 0)
|
||||
{
|
||||
for (int j = 0; j < dig_up_n; j++)
|
||||
{
|
||||
for (int i = 0; i < sizeof(map)/sizeof(map[0]); i++)
|
||||
{
|
||||
npos=xy;
|
||||
npos.x += map[i].x;
|
||||
npos.y -= 4*j + map[i].y;
|
||||
printf("Digging at (%d/%d/%d)\n", npos.x, npos.y, npos.z);
|
||||
digat(MCache, npos);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dig_down_n > 0)
|
||||
{
|
||||
for (int j = 0; j < dig_down_n; j++)
|
||||
{
|
||||
for (int i = 0; i < sizeof(map)/sizeof(map[0]); i++)
|
||||
{
|
||||
npos=xy;
|
||||
npos.x += map[i].x;
|
||||
npos.y += 4*j + map[i].y;
|
||||
printf("Digging at (%d/%d/%d)\n", npos.x, npos.y, npos.z);
|
||||
digat(MCache, npos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MCache->WriteAll();
|
||||
delete MCache;
|
||||
DF->Detach();
|
||||
if (!quiet) {
|
||||
cout << "Done. Press any key to continue" << endl;
|
||||
cin.ignore();
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
-- prints info on assigned hotkeys to the console
|
||||
|
||||
local hotkeys = {'F1 ', 'F2 ', 'F3 ', 'F4 ', 'F5 ', 'F6 ',
|
||||
'F7 ', 'F8 ', 'F9 ', 'F10', 'F11', 'F12'}
|
||||
|
||||
for i=1, #hotkeys do
|
||||
local hk = hotkeys[i]
|
||||
hk = {id=hk}
|
||||
-- PLACEHOLDER PROPERTIES ONLY!
|
||||
hk.name = '_name'
|
||||
hk.x = df.global.window_x
|
||||
hk.y = df.global.window_y
|
||||
hk.z = df.global.window_z
|
||||
|
||||
print(hk.id..' '..hk.name..' X= '..hk.x..', Y= '..hk.y..', Z= '..hk.z)
|
||||
end
|
||||
|
||||
--[[
|
||||
# the (very) old Python version...
|
||||
from context import Context, ContextManager
|
||||
|
||||
cm = ContextManager("Memory.xml")
|
||||
df = cm.get_single_context()
|
||||
|
||||
df.attach()
|
||||
|
||||
gui = df.gui
|
||||
|
||||
print "Hotkeys"
|
||||
|
||||
hotkeys = gui.read_hotkeys()
|
||||
|
||||
for key in hotkeys:
|
||||
print "x: %d\ny: %d\tz: %d\ttext: %s" % (key.x, key.y, key.z, key.name)
|
||||
|
||||
df.detach()
|
||||
|
||||
print "Done. Press any key to continue"
|
||||
raw_input()
|
||||
]]--
|
@ -1,20 +0,0 @@
|
||||
from context import Context, ContextManager
|
||||
|
||||
cm = ContextManager("Memory.xml")
|
||||
df = cm.get_single_context()
|
||||
|
||||
df.attach()
|
||||
|
||||
gui = df.gui
|
||||
|
||||
print "Hotkeys"
|
||||
|
||||
hotkeys = gui.read_hotkeys()
|
||||
|
||||
for key in hotkeys:
|
||||
print "x: %d\ny: %d\tz: %d\ttext: %s" % (key.x, key.y, key.z, key.name)
|
||||
|
||||
df.detach()
|
||||
|
||||
print "Done. Press any key to continue"
|
||||
raw_input()
|
File diff suppressed because it is too large
Load Diff
@ -1,71 +0,0 @@
|
||||
import sys
|
||||
from pydfhack import ContextManager
|
||||
|
||||
df_cm = ContextManager("Memory.xml")
|
||||
df = df_cm.get_single_context()
|
||||
|
||||
if not df.attach():
|
||||
print "Unable to attach!"
|
||||
print "Press any key to continue"
|
||||
|
||||
raw_input()
|
||||
sys.exit(1)
|
||||
|
||||
gui = df.gui
|
||||
|
||||
if gui is not None:
|
||||
maps = df.maps
|
||||
world = df.world
|
||||
|
||||
have_maps = maps.start()
|
||||
world.start()
|
||||
|
||||
gm = world.read_game_mode()
|
||||
|
||||
if gm is not None:
|
||||
print gm
|
||||
|
||||
date_tuple = (world.read_current_year(), world.read_current_month(), world.read_current_day(), world.read_current_tick())
|
||||
|
||||
print "Year: %d Month: %d Day: %d Tick: %d" % date_tuple
|
||||
|
||||
v_coords = gui.get_view_coords()
|
||||
c_coords = gui.get_cursor_coords()
|
||||
w_coords = (-1, -1, -1)
|
||||
world_pos_string = ""
|
||||
|
||||
if have_maps is True:
|
||||
w_coords = maps.getPosition()
|
||||
|
||||
x = (v_coords[0] + w_coords[0]) * 48
|
||||
y = (v_coords[1] + w_coords[1]) * 48
|
||||
z = (v_coords[2] + w_coords[2])
|
||||
|
||||
world_pos_string = " world: %d/%d/%d" % (x, y, z)
|
||||
|
||||
print "Map world offset: %d/%d/%d embark squares" % w_coords
|
||||
|
||||
if v_coords != (-1, -1, -1):
|
||||
print "view coords: %d/%d/%d" % v_coords
|
||||
|
||||
if have_maps is True:
|
||||
print world_pos_string
|
||||
|
||||
if c_coords != (-1, -1, -1):
|
||||
print "cursor coords: %d/%d/%d" % c_coords
|
||||
|
||||
if have_maps is True:
|
||||
print world_pos_string
|
||||
|
||||
window_size = gui.get_window_size()
|
||||
|
||||
if window_size != (-1, -1):
|
||||
print "window size : %d %d" % window_size
|
||||
else:
|
||||
print "cursor and window parameters are unsupported on your version of DF"
|
||||
|
||||
if not df.detach():
|
||||
print "Unable to detach!"
|
||||
|
||||
print "Done. Press any key to continue"
|
||||
raw_input()
|
@ -0,0 +1,40 @@
|
||||
--prints current time and position
|
||||
|
||||
local months = {
|
||||
'Granite, in early Spring.',
|
||||
'Slate, in mid Spring.',
|
||||
'Felsite, in late Spring.',
|
||||
'Hematite, in early Summer.',
|
||||
'Malachite, in mid Summer.',
|
||||
'Galena, in late Summer.',
|
||||
'Limestone, in early Autumn.',
|
||||
'Sandstone, in mid Autumn.',
|
||||
'Timber, in late Autumn.',
|
||||
'Moonstone, in early Winter.',
|
||||
'Opal, in mid Winter.',
|
||||
'Obsidian, in late Winter.',
|
||||
}
|
||||
|
||||
--Fortress mode counts 1200 ticks per day and 403200 per year
|
||||
--Adventurer mode counts 86400 ticks to a day and 29030400 ticks per year
|
||||
--Twelve months per year, 28 days to every month, 336 days per year
|
||||
|
||||
local julian_day = math.floor(df.global.cur_year_tick / 1200) + 1
|
||||
local month = math.floor(julian_day / 28) + 1 --days and months are 1-indexed
|
||||
local day = julian_day % 28
|
||||
|
||||
local time_of_day = math.floor(df.global.cur_year_tick_advmode / 336)
|
||||
local second = time_of_day % 60
|
||||
local minute = (time_of_day / 60) % 60
|
||||
local hour = math.floor(time_of_day / 3600) % 24
|
||||
|
||||
print('Time:')
|
||||
print(' The time is '..string.format('%02d:%02d:%02d', hour, minute, second))
|
||||
print(' The date is '..string.format('%05d-%02d-%02d', df.global.cur_year, month, day))
|
||||
print(' It is the month of '..months[month])
|
||||
|
||||
print('Place:')
|
||||
print(' Local window is at x='..df.global.window_x
|
||||
..' y='..df.global.window_y..' z='..df.global.window_z)
|
||||
|
||||
--TODO: add cursor, regional/embark square co-ords, window size?
|
Loading…
Reference in New Issue