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

Skip to content

Commit f459bfc

Browse files
committed
diggingInvaders: added per-creature dig times and differentiated between smooth and rough constructions.
1 parent 776d088 commit f459bfc

5 files changed

Lines changed: 191 additions & 54 deletions

File tree

plugins/diggingInvaders/assignJob.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "modules/Materials.h"
77

88
#include "df/building.h"
9+
#include "df/construction.h"
910
#include "df/coord.h"
1011
#include "df/general_ref.h"
1112
#include "df/general_ref_building_holderst.h"
@@ -47,7 +48,7 @@ void getRidOfOldJob(df::unit* unit) {
4748
//delete job;
4849
}
4950

50-
int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df::coord,df::coord,PointHash> parentMap, unordered_map<df::coord,cost_t,PointHash>& costMap, vector<int32_t>& invaders, unordered_set<df::coord,PointHash>& requiresZNeg, unordered_set<df::coord,PointHash>& requiresZPos, MapExtras::MapCache& cache) {
51+
int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df::coord,df::coord,PointHash> parentMap, unordered_map<df::coord,cost_t,PointHash>& costMap, vector<int32_t>& invaders, unordered_set<df::coord,PointHash>& requiresZNeg, unordered_set<df::coord,PointHash>& requiresZPos, MapExtras::MapCache& cache, DigAbilities& abilities ) {
5152
df::unit* firstInvader = df::unit::find(invaders[0]);
5253
if ( !firstInvader ) {
5354
return -1;
@@ -69,7 +70,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
6970
df::map_block* block2 = Maps::getTileBlock(pt2);
7071
bool passable1 = block1->walkable[pt1.x&0xF][pt1.y&0xF];
7172
bool passable2 = block2->walkable[pt2.x&0xF][pt2.y&0xF];
72-
73+
7374
df::coord location;
7475
df::building* building = Buildings::findAtTile(pt2);
7576
df::coord buildingPos = pt2;
@@ -107,7 +108,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
107108
building->jobs.push_back(job);
108109
Job::linkIntoWorld(job);
109110
jobId = job->id;
110-
job->completion_timer = jobDelay[DestroyBuilding];
111+
job->completion_timer = abilities.jobDelay[CostDimension::DestroyBuilding];
111112
} else {
112113
df::tiletype* type1 = Maps::getTileType(pt1);
113114
df::tiletype* type2 = Maps::getTileType(pt2);
@@ -132,7 +133,12 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
132133
firstInvader->job.destroy_target = NULL;
133134
Job::linkIntoWorld(job);
134135
jobId = job->id;
135-
job->completion_timer = jobDelay[DestroyConstruction];
136+
df::construction* constr = df::construction::find(pt2);
137+
bool smooth = constr != NULL && constr->item_type != df::enums::item_type::BOULDER;
138+
if ( smooth )
139+
job->completion_timer = abilities.jobDelay[CostDimension::DestroySmoothConstruction];
140+
else
141+
job->completion_timer = abilities.jobDelay[CostDimension::DestroyRoughConstruction];
136142
} else {
137143
bool walkable_low1 = shape1 == df::tiletype_shape::STAIR_DOWN || shape1 == df::tiletype_shape::STAIR_UPDOWN;
138144
bool walkable_low2 = shape2 == df::tiletype_shape::STAIR_DOWN || shape2 == df::tiletype_shape::STAIR_UPDOWN;
@@ -195,7 +201,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
195201
firstInvader->path.path.z.clear();
196202
Job::linkIntoWorld(job);
197203
jobId = job->id;
198-
job->completion_timer = jobDelay[Dig];
204+
job->completion_timer = abilities.jobDelay[CostDimension::Dig];
199205

200206
//TODO: test if he already has a pick
201207
bool hasPick = false;

plugins/diggingInvaders/assignJob.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99

1010
using namespace std;
1111

12-
int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df::coord,df::coord,PointHash> parentMap, unordered_map<df::coord,cost_t,PointHash>& costMap, vector<int32_t>& invaders, unordered_set<df::coord,PointHash>& requiresZNeg, unordered_set<df::coord,PointHash>& requiresZPos, MapExtras::MapCache& cache);
12+
int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df::coord,df::coord,PointHash> parentMap, unordered_map<df::coord,cost_t,PointHash>& costMap, vector<int32_t>& invaders, unordered_set<df::coord,PointHash>& requiresZNeg, unordered_set<df::coord,PointHash>& requiresZPos, MapExtras::MapCache& cache, DigAbilities& abilities);
1313

plugins/diggingInvaders/diggingInvaders.cpp

Lines changed: 97 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -87,33 +87,61 @@ static bool activeDigging=false;
8787
static unordered_set<string> diggingRaces;
8888
static unordered_set<int32_t> invaderJobs;
8989
static df::coord lastDebugEdgeCostPoint;
90+
unordered_map<string, DigAbilities> digAbilities;
91+
92+
static cost_t costWeightDefault[] = {
93+
//Distance
94+
1,
95+
//Destroy Building
96+
2,
97+
//Dig
98+
10000,
99+
//DestroyRoughConstruction
100+
1000,
101+
//DestroySmoothConstruction
102+
100,
103+
};
104+
105+
static int32_t jobDelayDefault[] = {
106+
//Distance
107+
-1,
108+
//Destroy Building
109+
1000,
110+
//Dig
111+
1000,
112+
//DestroyRoughConstruction
113+
1000,
114+
//DestroySmoothConstruction
115+
100,
116+
};
90117

91118
DFhackCExport command_result plugin_init (color_ostream &out, std::vector <PluginCommand> &commands)
92119
{
93120
commands.push_back(PluginCommand(
94121
"diggingInvaders", "Makes invaders dig to your dwarves.",
95122
diggingInvadersCommand, false, /* true means that the command can't be used from non-interactive user interface */
96-
"example usage:\n"
97123
" diggingInvaders 0\n disables the plugin\n"
98124
" diggingInvaders 1\n enables the plugin\n"
99125
" diggingInvaders enable\n enables the plugin\n"
100126
" diggingInvaders disable\n disables the plugin\n"
101127
" diggingInvaders add GOBLIN\n registers the race GOBLIN as a digging invader. Case-sensitive.\n"
102128
" 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 setDelay destroyBuilding n\n adds to the job_completion_timer of destroy building jobs that are assigned to invaders\n"
108-
" diggingInvaders setDelay dig n\n"
109-
" diggingInvaders setDelay destroyConstruction n\n"
129+
" diggingInvaders setCost GOBLIN walk n\n sets the walk cost in the path algorithm for the race GOBLIN\n"
130+
" diggingInvaders setCost GOBLIN destroyBuilding n\n"
131+
" diggingInvaders setCost GOBLIN dig n\n"
132+
" diggingInvaders setCost GOBLIN destroyRoughConstruction n\n rough constructions are made from boulders\n"
133+
" diggingInvaders setCost GOBLIN destroySmoothConstruction n\n smooth constructions are made from blocks or bars instead of boulders\n"
134+
" diggingInvaders setDelay GOBLIN destroyBuilding n\n adds to the job_completion_timer of destroy building jobs that are assigned to invaders\n"
135+
" diggingInvaders setDelay GOBLIN dig n\n"
136+
" diggingInvaders setDelay GOBLIN destroyRoughConstruction n\n"
137+
" diggingInvaders setDelay GOBLIN destroySmoothConstruction n\n"
110138
" diggingInvaders now\n makes invaders try to dig now, if plugin is enabled\n"
111139
" diggingInvaders clear\n clears all digging invader races\n"
112140
" 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."
113141
// " diggingInvaders\n Makes invaders try to dig now.\n"
114142
));
115143

116-
*df::global::debug_showambush = true;
144+
//*df::global::debug_showambush = true;
117145
return CR_OK;
118146
}
119147

@@ -135,6 +163,7 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan
135163
case DFHack::SC_WORLD_UNLOADED:
136164
// cleanup
137165
lastInvasionJob = lastInvasionDigger = -1;
166+
enabled = false;
138167
activeDigging = false;
139168
clearDijkstra();
140169
invaderJobs.clear();
@@ -193,14 +222,28 @@ command_result diggingInvadersCommand(color_ostream& out, std::vector<std::strin
193222
string race = parameters[a+1];
194223
if ( parameters[a] == "add" ) {
195224
diggingRaces.insert(race);
225+
DigAbilities& abilities = digAbilities[race];
226+
memcpy(abilities.costWeight, costWeightDefault, costDim*sizeof(cost_t));
227+
memcpy(abilities.jobDelay, jobDelayDefault, costDim*sizeof(int32_t));
196228
} else {
197229
diggingRaces.erase(race);
230+
digAbilities.erase(race);
198231
}
199232
a++;
233+
200234
} else if ( parameters[a] == "setCost" || parameters[a] == "setDelay" ) {
201-
if ( a+2 >= parameters.size() )
235+
if ( a+3 >= parameters.size() )
202236
return CR_WRONG_USAGE;
203-
string costStr = parameters[a+1];
237+
238+
string raceString = parameters[a+1];
239+
if ( digAbilities.find(raceString) == digAbilities.end() ) {
240+
DigAbilities bob;
241+
memset(&bob, 0xFF, sizeof(bob));
242+
digAbilities[raceString] = bob;
243+
}
244+
DigAbilities& abilities = digAbilities[raceString];
245+
246+
string costStr = parameters[a+2];
204247
int32_t costDim = -1;
205248
if ( costStr == "walk" ) {
206249
costDim = CostDimension::Walk;
@@ -210,30 +253,47 @@ command_result diggingInvadersCommand(color_ostream& out, std::vector<std::strin
210253
costDim = CostDimension::DestroyBuilding;
211254
} else if ( costStr == "dig" ) {
212255
costDim = CostDimension::Dig;
213-
} else if ( costStr == "destroyConstruction" ) {
214-
costDim = CostDimension::DestroyConstruction;
256+
} else if ( costStr == "destroyRoughConstruction" ) {
257+
costDim = CostDimension::DestroyRoughConstruction;
258+
} else if ( costStr == "destroySmoothConstruction" ) {
259+
costDim = CostDimension::DestroySmoothConstruction;
215260
} else {
216261
return CR_WRONG_USAGE;
217262
}
263+
218264
cost_t value;
219-
stringstream asdf(parameters[a+2]);
265+
stringstream asdf(parameters[a+3]);
220266
asdf >> value;
221-
if ( parameters[a] == "setCost" && value <= 0 )
222-
return CR_WRONG_USAGE;
223-
if ( parameters[a] == "setCost" )
224-
costWeight[costDim] = value;
225-
else
226-
jobDelay[costDim] = value;
227-
a += 2;
267+
//if ( parameters[a] == "setCost" && value <= 0 )
268+
// return CR_WRONG_USAGE;
269+
if ( parameters[a] == "setCost" ) {
270+
abilities.costWeight[costDim] = value;
271+
} else {
272+
abilities.jobDelay[costDim] = value;
273+
}
274+
a += 3;
228275
} else if ( parameters[a] == "edgeCost" ) {
276+
if ( a+1 >= parameters.size() )
277+
return CR_WRONG_USAGE;
278+
279+
string raceString = parameters[a+1];
280+
281+
if ( digAbilities.find(raceString) == digAbilities.end() ) {
282+
out.print("Race %s does not have dig abilities assigned.\n", raceString.c_str());
283+
return CR_WRONG_USAGE;
284+
}
285+
DigAbilities& abilities = digAbilities[raceString];
286+
229287
df::coord bob = Gui::getCursorPos();
230-
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));
288+
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, abilities));
231289
lastDebugEdgeCostPoint = bob;
290+
a++;
232291
} else if ( parameters[a] == "now" ) {
233292
activeDigging = true;
234293
findAndAssignInvasionJob(out, (void*)0);
235294
} else if ( parameters[a] == "clear" ) {
236295
diggingRaces.clear();
296+
digAbilities.clear();
237297
} else if ( parameters[a] == "edgesPerTick" ) {
238298
if ( a+1 >= parameters.size() )
239299
return CR_WRONG_USAGE;
@@ -335,8 +395,12 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
335395
out.print("%s,%d: WTF? Couldn't find creature raw.\n", __FILE__, __LINE__);
336396
continue;
337397
}
398+
/*
338399
if ( diggingRaces.find(raw->creature_id) == diggingRaces.end() )
339400
continue;
401+
*/
402+
if ( digAbilities.find(raw->creature_id) == digAbilities.end() )
403+
continue;
340404
if ( invaderPts.find(unit->pos) != invaderPts.end() )
341405
continue;
342406
//must be able to wield a pick: this is overly pessimistic
@@ -380,6 +444,14 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
380444
fringe.clear();
381445
return;
382446
}
447+
448+
df::creature_raw* creature_raw = df::creature_raw::find(firstInvader->race);
449+
if ( creature_raw == NULL || digAbilities.find(creature_raw->creature_id) == digAbilities.end() ) {
450+
//inappropriate digger: no dig abilities
451+
fringe.clear();
452+
return;
453+
}
454+
DigAbilities& abilities = digAbilities[creature_raw->creature_id];
383455
//TODO: check that firstInvader is an appropriate digger
384456
//out << firstInvader->id << endl;
385457
//out << firstInvader->pos.x << ", " << firstInvader->pos.y << ", " << firstInvader->pos.z << endl;
@@ -421,7 +493,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
421493

422494
cost_t myCost = costMap[pt];
423495
clock_t edgeTime = clock();
424-
vector<Edge>* myEdges = getEdgeSet(out, pt, cache, xMax, yMax, zMax);
496+
vector<Edge>* myEdges = getEdgeSet(out, pt, cache, xMax, yMax, zMax, abilities);
425497
totalEdgeTime += (clock() - edgeTime);
426498
for ( auto a = myEdges->begin(); a != myEdges->end(); a++ ) {
427499
Edge &e = *a;
@@ -476,7 +548,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
476548
while ( parentMap.find(pt) != parentMap.end() ) {
477549
//out.print("(%d,%d,%d)\n", pt.x, pt.y, pt.z);
478550
df::coord parent = parentMap[pt];
479-
cost_t cost = getEdgeCost(out, parent, pt);
551+
cost_t cost = getEdgeCost(out, parent, pt, abilities);
480552
if ( cost < 0 ) {
481553
//path invalidated
482554
return;
@@ -514,7 +586,7 @@ void findAndAssignInvasionJob(color_ostream& out, void* tickTime) {
514586
}
515587
*/
516588

517-
assignJob(out, firstImportantEdge, parentMap, costMap, invaders, requiresZNeg, requiresZPos, cache);
589+
assignJob(out, firstImportantEdge, parentMap, costMap, invaders, requiresZNeg, requiresZPos, cache, abilities);
518590
lastInvasionDigger = firstInvader->id;
519591
lastInvasionJob = firstInvader->job.current_job ? firstInvader->job.current_job->id : -1;
520592
invaderJobs.erase(lastInvasionJob);

0 commit comments

Comments
 (0)