Skip to content

Commit a8543f5

Browse files
committed
Ported autodump tool
1 parent ff4d545 commit a8543f5

9 files changed

Lines changed: 216 additions & 293 deletions

File tree

plugins/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,4 @@ DFHACK_PLUGIN(mode mode.cpp)
143143
#DFHACK_PLUGIN(tiles tiles.cpp)
144144
DFHACK_PLUGIN(liquids liquids.cpp)
145145
DFHACK_PLUGIN(tubefill tubefill.cpp)
146+
DFHACK_PLUGIN(autodump autodump.cpp)

plugins/autodump.cpp

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
// Quick Dumper : Moves items marked as "dump" to cursor
2+
// FIXME: local item cache in map blocks needs to be fixed after teleporting items
3+
#include <iostream>
4+
#include <iomanip>
5+
#include <sstream>
6+
#include <climits>
7+
#include <vector>
8+
#include <set>
9+
using namespace std;
10+
11+
#include <dfhack/Core.h>
12+
#include <dfhack/Console.h>
13+
#include <dfhack/Export.h>
14+
#include <dfhack/PluginManager.h>
15+
#include <vector>
16+
#include <string>
17+
#include <dfhack/modules/Maps.h>
18+
#include <dfhack/modules/Gui.h>
19+
#include <dfhack/modules/Items.h>
20+
#include <dfhack/modules/Materials.h>
21+
#include <dfhack/extra/MapExtras.h>
22+
23+
using namespace DFHack;
24+
using MapExtras::Block;
25+
using MapExtras::MapCache;
26+
27+
DFhackCExport command_result df_autodump (Core * c, vector <string> & parameters);
28+
29+
DFhackCExport const char * plugin_name ( void )
30+
{
31+
return "autodump";
32+
}
33+
34+
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands)
35+
{
36+
commands.clear();
37+
commands.push_back(PluginCommand("autodump",
38+
"Teleport items marked for dumping to the cursor.",
39+
df_autodump));
40+
return CR_OK;
41+
}
42+
43+
DFhackCExport command_result plugin_shutdown ( Core * c )
44+
{
45+
return CR_OK;
46+
}
47+
48+
typedef std::map <DFCoord, uint32_t> coordmap;
49+
50+
DFhackCExport command_result df_autodump (Core * c, vector <string> & parameters)
51+
{
52+
// Command line options
53+
bool destroy = false;
54+
if(parameters.size() > 0)
55+
{
56+
string & p = parameters[0];
57+
if(p == "destroy")
58+
destroy = true;
59+
else if(p == "?" || p == "help")
60+
{
61+
c->con.print(
62+
"This utility lets you quickly move all items designated to be dumped.\n"
63+
"Items are instantly moved to the cursor position, the dump flag is unset,\n"
64+
"and the forbid flag is set, as if it had been dumped normally.\n"
65+
"Be aware that any active dump item tasks still point at the item.\n\n"
66+
);
67+
return CR_OK;
68+
}
69+
}
70+
c->Suspend();
71+
DFHack::occupancies40d * occupancies;
72+
DFHack::VersionInfo *mem = c->vinfo;
73+
DFHack::Gui * Gui = c->getGui();
74+
DFHack::Items * Items = c->getItems();
75+
DFHack::Maps *Maps = c->getMaps();
76+
77+
vector <t_item*> p_items;
78+
if(!Items->readItemVector(p_items))
79+
{
80+
c->con.printerr("Can't access the item vector.\n");
81+
c->Resume();
82+
return CR_FAILURE;
83+
}
84+
std::size_t numItems = p_items.size();
85+
86+
// init the map
87+
if(!Maps->Start())
88+
{
89+
c->con.printerr("Can't initialize map.\n");
90+
c->Resume();
91+
return CR_FAILURE;
92+
}
93+
MapCache MC (Maps);
94+
int i = 0;
95+
int dumped_total = 0;
96+
97+
int cx, cy, cz;
98+
DFCoord pos_cursor;
99+
if(!destroy)
100+
{
101+
if (!Gui->getCursorCoords(cx,cy,cz))
102+
{
103+
c->con.printerr("Cursor position not found. Please enabled the cursor.\n");
104+
c->Resume();
105+
return CR_FAILURE;
106+
}
107+
pos_cursor = DFCoord(cx,cy,cz);
108+
{
109+
Block * b = MC.BlockAt(pos_cursor / 16);
110+
if(!b)
111+
{
112+
c->con.printerr("Cursor is in an invalid/uninitialized area. Place it over a floor.\n");
113+
c->Resume();
114+
return CR_FAILURE;
115+
}
116+
uint16_t ttype = MC.tiletypeAt(pos_cursor);
117+
if(!DFHack::isFloorTerrain(ttype))
118+
{
119+
c->con.printerr("Cursor should be placed over a floor.\n");
120+
c->Resume();
121+
return CR_FAILURE;
122+
}
123+
}
124+
}
125+
coordmap counts;
126+
// proceed with the dumpification operation
127+
for(std::size_t i=0; i< numItems; i++)
128+
{
129+
t_item * itm = p_items[i];
130+
DFCoord pos_item(itm->x, itm->y, itm->z);
131+
132+
// keep track how many items are at places. all items.
133+
coordmap::iterator it = counts.find(pos_item);
134+
if(it == counts.end())
135+
{
136+
std::pair< coordmap::iterator, bool > inserted = counts.insert(std::make_pair(pos_item,1));
137+
it = inserted.first;
138+
}
139+
else
140+
{
141+
it->second ++;
142+
}
143+
// iterator is valid here, we use it later to decrement the pile counter if the item is moved
144+
145+
// only dump the stuff marked for dumping and laying on the ground
146+
if ( !itm->flags.dump
147+
|| !itm->flags.on_ground
148+
|| itm->flags.construction
149+
|| itm->flags.hidden
150+
|| itm->flags.in_building
151+
|| itm->flags.in_chest
152+
|| itm->flags.in_inventory
153+
|| itm->flags.construction
154+
)
155+
continue;
156+
157+
if(!destroy) // move to cursor
158+
{
159+
// Change flags to indicate the dump was completed, as if by super-dwarfs
160+
itm->flags.dump = false;
161+
itm->flags.forbid = true;
162+
163+
// Don't move items if they're already at the cursor
164+
if (pos_cursor == pos_item)
165+
continue;
166+
167+
// Move the item
168+
itm->x = pos_cursor.x;
169+
itm->y = pos_cursor.y;
170+
itm->z = pos_cursor.z;
171+
}
172+
else // destroy
173+
{
174+
itm->flags.garbage_colect = true;
175+
}
176+
// keeping track of item pile sizes ;)
177+
it->second --;
178+
dumped_total++;
179+
}
180+
if(!destroy) // TODO: do we have to do any of this when destroying items?
181+
{
182+
// for each item pile, see if it reached zero. if so, unset item flag on the tile it's on
183+
coordmap::iterator it = counts.begin();
184+
coordmap::iterator end = counts.end();
185+
while(it != end)
186+
{
187+
if(it->second == 0)
188+
{
189+
t_occupancy occ = MC.occupancyAt(it->first);
190+
occ.bits.item = false;
191+
MC.setOccupancyAt(it->first, occ);
192+
}
193+
it++;
194+
}
195+
// Set "item here" flag on target tile, if we moved any items to the target tile.
196+
if (dumped_total > 0)
197+
{
198+
// assume there is a possibility the cursor points at some weird location with missing block data
199+
Block * b = MC.BlockAt(pos_cursor / 16);
200+
if(b)
201+
{
202+
t_occupancy occ = MC.occupancyAt(pos_cursor);
203+
occ.bits.item = 1;
204+
MC.setOccupancyAt(pos_cursor,occ);
205+
}
206+
}
207+
// write map changes back to DF.
208+
MC.WriteAll();
209+
// Is this necessary? Is "forbid" a dirtyable attribute like "dig" is?
210+
Maps->WriteDirtyBit(cx/16, cy/16, cz, true);
211+
}
212+
c->Resume();
213+
c->con.print("Done. %d items %s.\n", dumped_total, destroy ? "marked for desctruction" : "quickdumped");
214+
return CR_OK;
215+
}

plugins/probe.cpp

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -46,85 +46,7 @@ DFhackCExport command_result plugin_shutdown ( Core * c )
4646
{
4747
return CR_OK;
4848
}
49-
/*
50-
bool parseOptions(vector<string> &params, bool &showBlock, bool &showDesig,
51-
bool &showOccup, bool &showTile, bool &showMisc)
52-
{
53-
// With no options set, show everything.
54-
showBlock = true;
55-
showDesig = true;
56-
showOccup = true;
57-
showTile = true;
58-
showMisc = true;
59-
60-
bool _showBlock = false;
61-
bool _showDesig = false;
62-
bool _showOccup = false;
63-
bool _showTile = false;
64-
bool _showMisc = false;
65-
66-
char c;
67-
xgetopt opt(params, "bdotm");
68-
opt.opterr = 0;
69-
while ((c = opt()) != -1)
70-
{
71-
switch (c)
72-
{
73-
case 'b':
74-
_showBlock = true;
75-
break;
76-
case 'd':
77-
_showDesig = true;
78-
break;
79-
case 'o':
80-
_showOccup = true;
81-
break;
82-
case 't':
83-
_showTile = true;
84-
break;
85-
case 'm':
86-
_showMisc = true;
87-
break;
88-
89-
case '?':
90-
switch (opt.optopt)
91-
{
92-
// For when we take arguments
93-
default:
94-
if (isprint(opt.optopt))
95-
std::cerr << "Unknown option -" << opt.optopt << "!"
96-
<< std::endl;
97-
else
98-
std::cerr << "Unknown option character " << (int) opt.optopt << "!"
99-
<< std::endl;
100-
}
101-
default:
102-
// Um.....
103-
return false;
104-
}
105-
}
106-
107-
// If any options set, show only those requested via options.
108-
if(_showBlock || _showDesig || _showOccup || _showTile || _showMisc)
109-
{
110-
showBlock = false;
111-
showDesig = false;
112-
showOccup = false;
113-
showTile = false;
114-
showMisc = false;
115-
116-
showBlock = _showBlock;
117-
showDesig = _showDesig;
118-
showOccup = _showOccup;
119-
showTile = _showTile;
120-
showMisc = _showMisc;
121-
}
122-
123-
return true;
124-
}
12549

126-
*/
127-
using namespace DFHack;
12850
DFhackCExport command_result df_probe (Core * c, vector <string> & parameters)
12951
{
13052
//bool showBlock, showDesig, showOccup, showTile, showMisc;

0 commit comments

Comments
 (0)