Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0378bbb

Browse files
committed
diggingInvaders: proper user interface.
1 parent 07a4839 commit 0378bbb

1 file changed

Lines changed: 53 additions & 148 deletions

File tree

plugins/diggingInvaders/diggingInvaders.cpp

Lines changed: 53 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,16 @@ using namespace df::enums;
7171
command_result diggingInvadersCommand(color_ostream &out, std::vector <std::string> & parameters);
7272
void watchForJobComplete(color_ostream& out, void* ptr);
7373
void newInvasionHandler(color_ostream& out, void* ptr);
74+
void clearDijkstra();
75+
void findAndAssignInvasionJob(color_ostream& out, void*);
7476
//int32_t manageInvasion(color_ostream& out);
7577

7678
DFHACK_PLUGIN("diggingInvaders");
7779

7880
//TODO: when world unloads
7981
static int32_t lastInvasionJob=-1;
8082
static int32_t lastInvasionDigger = -1;
83+
static int32_t edgesPerTick = 100;
8184
//static EventManager::EventHandler jobCompleteHandler(watchForJobComplete, 5);
8285
static bool enabled=false;
8386
static bool activeDigging=false;
@@ -87,17 +90,24 @@ static df::coord lastDebugEdgeCostPoint;
8790

8891
DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands)
8992
{
90-
EventManager::EventHandler handler(newInvasionHandler, 1000);
91-
EventManager::registerListener(EventManager::EventType::INVASION, handler, plugin_self);
92-
9393
commands.push_back(PluginCommand(
9494
"diggingInvaders", "Makes invaders dig to your dwarves.",
9595
diggingInvadersCommand, false, /* true means that the command can't be used from non-interactive user interface */
96+
"example usage:\n"
97+
" diggingInvaders 0\n disables the plugin\n"
98+
" diggingInvaders 1\n enables the plugin\n"
9699
" diggingInvaders enable\n enables the plugin\n"
97100
" diggingInvaders disable\n disables the plugin\n"
98-
" diggingInvaders add GOBLIN\n registers the race GOBLIN as a digging invader\n"
99-
" diggingInvaders remove GOBLIN\n unregisters the race GOBLIN as a digging invader\n"
100-
" diggingInvaders\n Makes invaders try to dig now.\n"
101+
" diggingInvaders add GOBLIN\n registers the race GOBLIN as a digging invader. Case-sensitive.\n"
102+
" diggingInvaders remove GOBLIN\n unregisters the race GOBLIN as a digging invader. Case-sensitive.\n"
103+
" diggingInvaders setCost walk n\n sets the walk cost in the path algorithm\n"
104+
" diggingInvaders setCost destroyBuilding n\n"
105+
" diggingInvaders setCost dig n\n"
106+
" diggingInvaders setCost destroyConstruction n\n"
107+
" diggingInvaders now\n makes invaders try to dig now, if plugin is enabled\n"
108+
" diggingInvaders clear\n clears all digging invader races\n"
109+
" diggingInvaders edgesPerTick n\n makes the pathfinding algorithm work on at most n edges per tick. Set to 0 or lower to make it unlimited."
110+
// " diggingInvaders\n Makes invaders try to dig now.\n"
101111
));
102112

103113
*df::global::debug_showambush = true;
@@ -111,16 +121,20 @@ DFhackCExport command_result plugin_shutdown ( color_ostream &out )
111121

112122
DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event)
113123
{
114-
EventManager::EventHandler invasionHandler(newInvasionHandler, 1000);
115124
switch (event) {
116125
case DFHack::SC_WORLD_LOADED:
117126
//TODO: check game mode
118-
lastInvasionJob = -1;
119-
//in case there are invaders when the game is loaded, we should check
120-
EventManager::registerTick(invasionHandler, 10, plugin_self);
127+
//in case there are invaders when the game is loaded, we check if there's work to be done
128+
activeDigging = enabled;
129+
clearDijkstra();
130+
findAndAssignInvasionJob(out, (void*)0);
121131
break;
122132
case DFHack::SC_WORLD_UNLOADED:
123133
// cleanup
134+
lastInvasionJob = lastInvasionDigger = -1;
135+
activeDigging = false;
136+
clearDijkstra();
137+
invaderJobs.clear();
124138
break;
125139
default:
126140
break;
@@ -156,105 +170,19 @@ class PointComp {
156170
};
157171

158172
//bool important(df::coord pos, map<df::coord, set<Edge> >& edges, df::coord prev, set<df::coord>& importantPoints, set<Edge>& importantEdges);
159-
void findAndAssignInvasionJob(color_ostream& out, void*);
160173

161174
void newInvasionHandler(color_ostream& out, void* ptr) {
162175
if ( activeDigging )
163176
return;
164177
activeDigging = true;
165-
EventManager::EventHandler handler(findAndAssignInvasionJob, 1);
166-
EventManager::registerTick(handler, 1, plugin_self);
167-
#if 0
168-
//called when there's a new invasion
169-
//TODO: check if invaders can dig
170-
if ( manageInvasion(out) == -2 )
171-
return;
172-
173-
//schedule the next thing
174-
uint32_t tick = World::ReadCurrentTick();
175-
tick = tick % 1000;
176-
tick = 1000 - tick;
177-
178-
EventManager::EventHandler handle(newInvasionHandler, 1000);
179-
EventManager::registerTick(handle, tick, plugin_self);
180-
#endif
181-
}
182-
183-
#if 0
184-
void watchForJobComplete(color_ostream& out, void* ptr) {
185-
/*
186-
df::job* job = (df::job*)ptr;
187-
188-
if ( job->id != lastInvasionJob )
189-
return;
190-
191-
EventManager::unregister(EventManager::EventType::JOB_COMPLETED, jobCompleteHandler, plugin_self);
192-
*/
193-
194-
manageInvasion(out);
195-
}
196-
#endif
197-
198-
#if 0
199-
int32_t manageInvasion(color_ostream& out) {
200-
//EventManager::unregisterAll(plugin_self);
201-
if ( !enabled ) {
202-
return -1;
203-
}
204-
int32_t lastInvasion = df::global::ui->invasions.next_id-1;
205-
if ( lastInvasion < 0 || df::global::ui->invasions.list[lastInvasion]->flags.bits.active == 0 ) {
206-
//if the invasion is over, we're done
207-
//out.print("Invasion is over. Stopping diggingInvaders.\n");
208-
return -2;
209-
}
210-
EventManager::registerTick(jobCompleteHandler, 1, plugin_self);
211-
if ( lastInvasionJob != -1 ) {
212-
//check if he's still doing it
213-
df::unit* worker = df::unit::find(lastInvasionDigger);
214-
//int32_t index = df::unit::binsearch_index(df::global::world->units.all, lastInvasionDigger);
215-
if ( !worker ) {
216-
out.print("Error %s line %d.\n", __FILE__, __LINE__);
217-
return -1;
218-
}
219-
df::job* job = worker->job.current_job;
220-
//out.print("job id: old = %d, new = %d\n", lastInvasionJob, job == NULL ? -1 : job->id);
221-
if ( job != NULL && lastInvasionJob == job->id ) {
222-
//out.print("Still working on the previous job.\n");
223-
return -1;
224-
}
225-
226-
//return 1; //still invading, but nothing new done
227-
}
228-
229-
int32_t unitId = findAndAssignInvasionJob(out);
230-
if ( unitId == -1 ) {
231-
//might need to do more digging later, after we've killed off a few locals
232-
//out.print("DiggingInvaders is waiting.\n");
233-
return -1;
234-
}
235-
236-
lastInvasionDigger = unitId;
237-
{
238-
df::unit* unit = df::unit::find(unitId);
239-
if ( !unit ) {
240-
//out.print("Error %s line %d: unitId = %d, index = %d.\n", __FILE__, __LINE__, unitId, index);
241-
return -1;
242-
}
243-
lastInvasionJob = unit->job.current_job->id;
244-
}
245-
246-
//EventManager::registerListener(EventManager::EventType::JOB_COMPLETED, jobCompleteHandler, plugin_self);
247-
//out.print("DiggingInvaders: job assigned.\n");
248-
*df::global::pause_state = true;
249-
return 0; //did something
178+
findAndAssignInvasionJob(out, (void*)0);
250179
}
251-
#endif
252180

253181
command_result diggingInvadersCommand(color_ostream& out, std::vector<std::string>& parameters) {
254182
for ( size_t a = 0; a < parameters.size(); a++ ) {
255-
if ( parameters[a] == "enable" ) {
183+
if ( parameters[a] == "1" || parameters[a] == "enable" ) {
256184
enabled = true;
257-
} else if ( parameters[a] == "disable" ) {
185+
} else if ( parameters[a] == "0" || parameters[a] == "disable" ) {
258186
enabled = false;
259187
} else if ( parameters[a] == "add" || parameters[a] == "remove" ) {
260188
if ( a+1 >= parameters.size() )
@@ -265,24 +193,6 @@ command_result diggingInvadersCommand(color_ostream& out, std::vector<std::strin
265193
} else {
266194
diggingRaces.erase(race);
267195
}
268-
/*bool foundIt = false;
269-
for ( size_t b = 0; b < df::global::world->raws.creatures.all.size(); b++ ) {
270-
df::creature_raw* raw = df::global::world->raws.creatures.all[b];
271-
if ( race == raw->creature_id ) {
272-
//out.print("%s = %s\n", race.c_str(), raw->creature_id.c_str());
273-
if ( parameters[a] == "add" ) {
274-
diggingRaces.insert(b);
275-
} else {
276-
diggingRaces.erase(b);
277-
}
278-
foundIt = true;
279-
break;
280-
}
281-
}
282-
if ( !foundIt ) {
283-
out.print("Couldn't find \"%s\"\n", race.c_str());
284-
return CR_WRONG_USAGE;
285-
}*/
286196
a++;
287197
} else if ( parameters[a] == "setCost" ) {
288198
if ( a+2 >= parameters.size() )
@@ -311,16 +221,35 @@ command_result diggingInvadersCommand(color_ostream& out, std::vector<std::strin
311221
df::coord bob = Gui::getCursorPos();
312222
out.print("(%d,%d,%d), (%d,%d,%d): cost = %lld\n", lastDebugEdgeCostPoint.x, lastDebugEdgeCostPoint.y, lastDebugEdgeCostPoint.z, bob.x, bob.y, bob.z, getEdgeCost(out, lastDebugEdgeCostPoint, bob));
313223
lastDebugEdgeCostPoint = bob;
224+
} else if ( parameters[a] == "now" ) {
225+
activeDigging = true;
226+
findAndAssignInvasionJob(out, (void*)0);
227+
} else if ( parameters[a] == "clear" ) {
228+
diggingRaces.clear();
229+
} else if ( parameters[a] == "edgesPerTick" ) {
230+
if ( a+1 >= parameters.size() )
231+
return CR_WRONG_USAGE;
232+
stringstream asdf(parameters[a+1]);
233+
int32_t edgeCount = 100;
234+
asdf >> edgeCount;
235+
edgesPerTick = edgeCount;
236+
a++;
314237
}
315238
else {
316239
return CR_WRONG_USAGE;
317240
}
318241
}
242+
activeDigging = enabled;
243+
out.print("diggingInvaders: enabled = %d, activeDigging = %d, edgesPerTick = %d\n", enabled, activeDigging, edgesPerTick);
319244

320-
if ( parameters.size() == 0 ) {
321-
//manageInvasion(out);
322-
newInvasionHandler(out, (void*)0);
245+
EventManager::unregisterAll(plugin_self);
246+
if ( enabled ) {
247+
EventManager::EventHandler handler(newInvasionHandler, 1000);
248+
EventManager::registerListener(EventManager::EventType::INVASION, handler, plugin_self);
249+
clearDijkstra();
250+
findAndAssignInvasionJob(out, (void*)0);
323251
}
252+
324253
return CR_OK;
325254
}
326255

@@ -335,7 +264,6 @@ unordered_map<df::coord,cost_t,PointHash> costMap;
335264
PointComp comp(&costMap);
336265
set<df::coord, PointComp> fringe(comp);
337266
EventManager::EventHandler findJobTickHandler(findAndAssignInvasionJob, 1);
338-
const int32_t edgesPerFrame = 10000000;
339267

340268
int32_t localPtsFound = 0;
341269
unordered_set<df::coord,PointHash> closedSet;
@@ -363,7 +291,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
363291
//returns the worker id of the job created //used to
364292
//out.print("%s, %d: %d\n", __FILE__, __LINE__, (int32_t)tickTime);
365293

366-
if ( !activeDigging ) {
294+
if ( !enabled || !activeDigging ) {
367295
clearDijkstra();
368296
return;
369297
}
@@ -454,12 +382,12 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
454382
xMax *= 16;
455383
yMax *= 16;
456384
MapExtras::MapCache cache;
457-
385+
458386
clock_t t0 = clock();
459387
clock_t totalEdgeTime = 0;
460388
int32_t edgesExpanded = 0;
461389
while(!fringe.empty()) {
462-
if ( edgesExpanded++ >= edgesPerFrame ) {
390+
if ( edgesPerTick > 0 && edgesExpanded++ >= edgesPerTick ) {
463391
return;
464392
}
465393
df::coord pt = *(fringe.begin());
@@ -513,7 +441,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
513441
delete myEdges;
514442
}
515443
clock_t time = clock() - t0;
516-
out.print("tickTime = %d, time = %d, totalEdgeTime = %d, total points = %d, total edges = %d, time per point = %.3f, time per edge = %.3f, clocks/sec = %d\n", (int32_t)tickTime, time, totalEdgeTime, closedSet.size(), edgeCount, (float)time / closedSet.size(), (float)time / edgeCount, CLOCKS_PER_SEC);
444+
//out.print("tickTime = %d, time = %d, totalEdgeTime = %d, total points = %d, total edges = %d, time per point = %.3f, time per edge = %.3f, clocks/sec = %d\n", (int32_t)tickTime, time, totalEdgeTime, closedSet.size(), edgeCount, (float)time / closedSet.size(), (float)time / edgeCount, CLOCKS_PER_SEC);
517445
fringe.clear();
518446

519447
if ( !foundTarget )
@@ -570,29 +498,6 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
570498
out.print("%s,%d: closest = (%d,%d,%d), estimate = %lld != actual = %lld\n", __FILE__, __LINE__, closest.x,closest.y,closest.z, closestCostEstimate, closestCostActual);
571499
return;
572500
}
573-
#if 0
574-
unordered_set<df::coord,PointHash> toDelete;
575-
for ( auto a = requiresZNeg.begin(); a != requiresZNeg.end(); a++ ) {
576-
df::coord pos = *a;
577-
df::tiletype* type = Maps::getTileType(pos);
578-
df::tiletype_shape shape = ENUM_ATTR(tiletype, shape, *type);
579-
if ( ENUM_ATTR(tiletype_shape, passable_low, shape) ) {
580-
toDelete.insert(pos);
581-
}
582-
}
583-
requiresZNeg.erase(toDelete.begin(), toDelete.end());
584-
toDelete.clear();
585-
for ( auto a = requiresZPos.begin(); a != requiresZPos.end(); a++ ) {
586-
df::coord pos = *a;
587-
df::tiletype* type = Maps::getTileType(pos);
588-
df::tiletype_shape shape = ENUM_ATTR(tiletype, shape, *type);
589-
if ( ENUM_ATTR(tiletype_shape, passable_high, shape) ) {
590-
toDelete.insert(pos);
591-
}
592-
}
593-
requiresZPos.erase(toDelete.begin(), toDelete.end());
594-
toDelete.clear();
595-
#endif
596501

597502
assignJob(out, firstImportantEdge, parentMap, costMap, invaders, requiresZNeg, requiresZPos, cache);
598503
lastInvasionDigger = firstInvader->id;

0 commit comments

Comments
 (0)