Browse Source

Convert builder role to new format.

David Franke 1 year ago
parent
commit
003c753250
6 changed files with 186 additions and 153 deletions
  1. 0
    3
      src/main.old.js
  2. 1
    5
      src/manager.spawn.js
  3. 2
    0
      src/process.creeps.js
  4. 1
    1
      src/process.rooms.owned.songs.js
  5. 175
    143
      src/role.builder.js
  6. 7
    1
      src/role.harvester.js

+ 0
- 3
src/main.old.js View File

@@ -6,7 +6,6 @@
6 6
 require('./manager.military');
7 7
 require('./manager.source');
8 8
 require('./role.brawler');
9
-require('./role.builder');
10 9
 require('./role.builder.exploit');
11 10
 require('./role.harvester.exploit');
12 11
 require('./role.harvester.remote');
@@ -61,8 +60,6 @@ const creepThrottleLevels = {
61 60
 };
62 61
 
63 62
 const creepLogicFunctions = {
64
-	repairer: 'runBuilderLogic',
65
-	builder: 'runBuilderLogic',
66 63
 	transporter: 'runTransporterLogic',
67 64
 	'harvester.remote': 'runRemoteHarvesterLogic',
68 65
 	'harvester.exploit': 'runExploitHarvesterLogic',

+ 1
- 5
src/manager.spawn.js View File

@@ -24,7 +24,6 @@ const roleNameMap = {
24 24
 	'harvester.minerals': 'HM',
25 25
 	'harvester.remote': 'HR',
26 26
 	'harvester.power': 'HP',
27
-	repairer: 'R',
28 27
 	scout: 'S',
29 28
 	transporter: 'T',
30 29
 	'hauler.exploit': 'TE',
@@ -514,9 +513,6 @@ Room.prototype.addBuilderSpawnOptions = function () {
514 513
 		maxWorkParts += 5;
515 514
 	}
516 515
 
517
-	_.each(this.creepsByRole.repairer, creep => {
518
-		numWorkParts += creep.memory.body.work || 0;
519
-	});
520 516
 	_.each(this.creepsByRole.builder, creep => {
521 517
 		numWorkParts += creep.memory.body.work || 0;
522 518
 	});
@@ -526,7 +522,7 @@ Room.prototype.addBuilderSpawnOptions = function () {
526 522
 		maxWorkParts += _.size(this.roomPlanner.memory.locations.rampart) / 10;
527 523
 	}
528 524
 
529
-	// Add more repairers if we have a lot of energy to spare.
525
+	// Add more builders if we have a lot of energy to spare.
530 526
 	if (this.storage && this.storage.store.energy > 400000) {
531 527
 		maxWorkParts *= 2;
532 528
 	}

+ 2
- 0
src/process.creeps.js View File

@@ -4,6 +4,7 @@ const Process = require('./process');
4 4
 const CreepManager = require('./creep-manager');
5 5
 
6 6
 // Normal creep roles.
7
+const BuilderRole = require('./role.builder');
7 8
 const ClaimerRole = require('./role.claimer');
8 9
 const DismantlerRole = require('./role.dismantler');
9 10
 const GiftRole = require('./role.gift');
@@ -29,6 +30,7 @@ const CreepsProcess = function (params, data) {
29 30
 	Process.call(this, params, data);
30 31
 
31 32
 	this.creepManager = new CreepManager();
33
+	this.creepManager.registerCreepRole('builder', new BuilderRole());
32 34
 	this.creepManager.registerCreepRole('claimer', new ClaimerRole());
33 35
 	this.creepManager.registerCreepRole('dismantler', new DismantlerRole());
34 36
 	this.creepManager.registerCreepRole('gift', new GiftRole());

+ 1
- 1
src/process.rooms.owned.songs.js View File

@@ -5,7 +5,7 @@ const Process = require('./process');
5 5
 /* eslint-disable array-element-newline */
6 6
 const songs = {
7 7
 	harder: {
8
-		roles: ['harvester', 'harvester.mineral', 'transporter', 'upgrader', 'repairer', 'builder', 'hauler'],
8
+		roles: ['harvester', 'harvester.mineral', 'transporter', 'upgrader', 'builder', 'hauler'],
9 9
 		lines: [
10 10
 			// 2 x 2 nothing
11 11
 			'work it', '', 'make it', '', 'do it', '', 'makes us', '', '♪', '♪', '♪', '♬', '♪', '♪', '♪', '♬',

+ 175
- 143
src/role.builder.js View File

@@ -5,7 +5,15 @@ STRUCTURE_RAMPART STRUCTURE_WALL STRUCTURE_ROAD STRUCTURE_CONTAINER
5 5
 STRUCTURE_SPAWN */
6 6
 
7 7
 const utilities = require('./utilities');
8
+const Role = require('./role');
8 9
 
10
+const BuilderRole = function () {
11
+	Role.call(this);
12
+};
13
+
14
+BuilderRole.prototype = Object.create(Role.prototype);
15
+
16
+// @todo Calculate from constants.
9 17
 const wallHealth = {
10 18
 	0: 1,
11 19
 	1: 5000,
@@ -18,17 +26,137 @@ const wallHealth = {
18 26
 	8: 300000000,
19 27
 };
20 28
 
29
+/**
30
+ * Makes this creep behave like a builder.
31
+ *
32
+ * @param {Creep} creep
33
+ *   The creep to run logic for.
34
+ */
35
+BuilderRole.prototype.run = function (creep) {
36
+	if (creep.memory.repairing && creep.carry.energy === 0) {
37
+		this.setBuilderState(creep, false);
38
+	}
39
+	else if (!creep.memory.repairing && _.sum(creep.carry) >= creep.carryCapacity * 0.9) {
40
+		this.setBuilderState(creep, true);
41
+	}
42
+
43
+	if (creep.memory.repairing) {
44
+		this.performRepair(creep);
45
+		return;
46
+	}
47
+
48
+	creep.performGetEnergy();
49
+};
50
+
51
+/**
52
+ * Puts this creep into or out of repair mode.
53
+ *
54
+ * @param {Creep} creep
55
+ *   The creep to run logic for.
56
+ * @param {boolean} repairing
57
+ *   Whether to start building / repairing or not.
58
+ */
59
+BuilderRole.prototype.setBuilderState = function (creep, repairing) {
60
+	creep.memory.repairing = repairing;
61
+	delete creep.memory.order;
62
+};
63
+
64
+/**
65
+ * Makes the creep repair damaged buildings.
66
+ *
67
+ * @param {Creep} creep
68
+ *   The creep to run logic for.
69
+ *
70
+ * @return {boolean}
71
+ *   True if an action was performed.
72
+ */
73
+BuilderRole.prototype.performRepair = function (creep) {
74
+	if (!creep.memory.order || !creep.memory.order.target) {
75
+		this.calculateBuilderTarget(creep);
76
+	}
77
+
78
+	if (!creep.memory.order || !creep.memory.order.target) {
79
+		return false;
80
+	}
81
+
82
+	const target = Game.getObjectById(creep.memory.order.target);
83
+	if (!target) {
84
+		this.calculateBuilderTarget(creep);
85
+		return true;
86
+	}
87
+
88
+	if (creep.memory.order.type === 'repair') {
89
+		let maxHealth = target.hitsMax;
90
+		if (creep.memory.order.maxHealth) {
91
+			maxHealth = creep.memory.order.maxHealth;
92
+
93
+			// Repair ramparts past their maxHealth to counteract decaying.
94
+			if (target.structureType === STRUCTURE_RAMPART) {
95
+				maxHealth = Math.min(maxHealth + 10000, target.hitsMax);
96
+			}
97
+		}
98
+
99
+		if (!target.hits || target.hits >= maxHealth) {
100
+			this.calculateBuilderTarget(creep);
101
+			return true;
102
+		}
103
+
104
+		this.repairTarget(creep, target);
105
+		return true;
106
+	}
107
+
108
+	if (creep.memory.order.type === 'build') {
109
+		this.buildTarget(creep, target);
110
+		return true;
111
+	}
112
+
113
+	// Unknown order type, recalculate!
114
+	hivemind.log('creeps', creep.pos.roomName).info('Unknown order type detected on', creep.name);
115
+	this.calculateBuilderTarget(creep);
116
+	return true;
117
+};
118
+
119
+/**
120
+ * Sets a good repair or build target for this creep.
121
+ *
122
+ * @param {Creep} creep
123
+ *   The creep to run logic for.
124
+ */
125
+BuilderRole.prototype.calculateBuilderTarget = function (creep) {
126
+	delete creep.memory.order;
127
+
128
+	const best = utilities.getBestOption(this.getAvailableBuilderTargets(creep));
129
+	if (!best) return;
130
+
131
+	if (best.type === 'structure') {
132
+		creep.memory.order = {
133
+			type: 'repair',
134
+			target: best.object.id,
135
+			maxHealth: best.maxHealth,
136
+		};
137
+	}
138
+	else if (best.type === 'site') {
139
+		creep.memory.order = {
140
+			type: 'build',
141
+			target: best.object.id,
142
+		};
143
+	}
144
+};
145
+
21 146
 /**
22 147
  * Collects information about all damaged or unfinished buildings in the current room.
23 148
  *
149
+ * @param {Creep} creep
150
+ *   The creep to run logic for.
151
+ *
24 152
  * @return {Array}
25 153
  *   An array of repair or build option objects.
26 154
  */
27
-Creep.prototype.getAvailableBuilderTargets = function () {
155
+BuilderRole.prototype.getAvailableBuilderTargets = function (creep) {
28 156
 	const options = [];
29 157
 
30
-	this.addRepairOptions(options);
31
-	this.addBuildOptions(options);
158
+	this.addRepairOptions(creep, options);
159
+	this.addBuildOptions(creep, options);
32 160
 
33 161
 	return options;
34 162
 };
@@ -36,11 +164,13 @@ Creep.prototype.getAvailableBuilderTargets = function () {
36 164
 /**
37 165
  * Collects damaged structures with priorities for repairing.
38 166
  *
167
+ * @param {Creep} creep
168
+ *   The creep to run logic for.
39 169
  * @param {Array} options
40 170
  *   An array of repair or build option objects to add to.
41 171
  */
42
-Creep.prototype.addRepairOptions = function (options) {
43
-	const targets = this.room.find(FIND_STRUCTURES, {
172
+BuilderRole.prototype.addRepairOptions = function (creep, options) {
173
+	const targets = creep.room.find(FIND_STRUCTURES, {
44 174
 		filter: structure => structure.hits < structure.hitsMax && !structure.needsDismantling(),
45 175
 	});
46 176
 	for (const target of targets) {
@@ -52,7 +182,7 @@ Creep.prototype.addRepairOptions = function (options) {
52 182
 		};
53 183
 
54 184
 		if (target.structureType === STRUCTURE_WALL || target.structureType === STRUCTURE_RAMPART) {
55
-			this.modifyRepairDefensesOption(option, target);
185
+			this.modifyRepairDefensesOption(creep, option, target);
56 186
 		}
57 187
 		else {
58 188
 			if (target.hits / target.hitsMax > 0.9) {
@@ -69,7 +199,7 @@ Creep.prototype.addRepairOptions = function (options) {
69 199
 			}
70 200
 
71 201
 			// Slightly adjust weight so that closer structures get prioritized. Not for walls or Ramparts, though, we want those to be equally strong all arond.
72
-			option.weight -= this.pos.getRangeTo(target) / 100;
202
+			option.weight -= creep.pos.getRangeTo(target) / 100;
73 203
 		}
74 204
 
75 205
 		// For many decaying structures, we don't care if they're "almost" full.
@@ -81,7 +211,7 @@ Creep.prototype.addRepairOptions = function (options) {
81 211
 
82 212
 		if (target.hits >= (option.maxHealth || target.hitsMax)) continue;
83 213
 
84
-		option.priority -= this.room.getCreepsWithOrder('repair', target.id).length;
214
+		option.priority -= creep.room.getCreepsWithOrder('repair', target.id).length;
85 215
 
86 216
 		options.push(option);
87 217
 	}
@@ -90,12 +220,14 @@ Creep.prototype.addRepairOptions = function (options) {
90 220
 /**
91 221
  * Modifies basic repair order for defense structures.
92 222
  *
223
+ * @param {Creep} creep
224
+ *   The creep to run logic for.
93 225
  * @param {object} option
94 226
  *   The repair order to modify.
95 227
  * @param {Structure} target
96 228
  *   The defensive structure in question.
97 229
  */
98
-Creep.prototype.modifyRepairDefensesOption = function (option, target) {
230
+BuilderRole.prototype.modifyRepairDefensesOption = function (creep, option, target) {
99 231
 	option.priority--;
100 232
 	if (target.structureType === STRUCTURE_WALL) {
101 233
 		option.priority--;
@@ -103,7 +235,7 @@ Creep.prototype.modifyRepairDefensesOption = function (option, target) {
103 235
 
104 236
 	// Walls and ramparts get repaired up to a certain health level.
105 237
 	let maxHealth = wallHealth[target.room.controller.level];
106
-	if (this.room.roomPlanner && this.room.roomPlanner.isPlannedLocation(target.pos, 'wall.blocker')) {
238
+	if (creep.room.roomPlanner && creep.room.roomPlanner.isPlannedLocation(target.pos, 'wall.blocker')) {
107 239
 		maxHealth = 10000;
108 240
 	}
109 241
 	else if (target.hits >= maxHealth * 0.9 && target.hits < target.hitsMax) {
@@ -115,7 +247,7 @@ Creep.prototype.modifyRepairDefensesOption = function (option, target) {
115 247
 	option.weight = 1 - (target.hits / maxHealth);
116 248
 	option.maxHealth = maxHealth;
117 249
 
118
-	if (target.structureType === STRUCTURE_RAMPART && target.hits < 10000 && this.room.controller.level >= 4) {
250
+	if (target.structureType === STRUCTURE_RAMPART && target.hits < 10000 && creep.room.controller.level >= 4) {
119 251
 		// Low ramparts get special treatment so they don't decay.
120 252
 		option.priority++;
121 253
 		option.weight++;
@@ -125,11 +257,13 @@ Creep.prototype.modifyRepairDefensesOption = function (option, target) {
125 257
 /**
126 258
  * Collects construction sites with priorities for building.
127 259
  *
260
+ * @param {Creep} creep
261
+ *   The creep to run logic for.
128 262
  * @param {Array} options
129 263
  *   An array of repair or build option objects to add to.
130 264
  */
131
-Creep.prototype.addBuildOptions = function (options) {
132
-	const targets = this.room.find(FIND_MY_CONSTRUCTION_SITES);
265
+BuilderRole.prototype.addBuildOptions = function (creep, options) {
266
+	const targets = creep.room.find(FIND_MY_CONSTRUCTION_SITES);
133 267
 	for (const target of targets) {
134 268
 		const option = {
135 269
 			priority: 4,
@@ -139,9 +273,9 @@ Creep.prototype.addBuildOptions = function (options) {
139 273
 		};
140 274
 
141 275
 		// Slightly adjust weight so that closer sites get prioritized.
142
-		option.weight -= this.pos.getRangeTo(target) / 100;
276
+		option.weight -= creep.pos.getRangeTo(target) / 100;
143 277
 
144
-		option.priority -= this.room.getCreepsWithOrder('build', target.id).length;
278
+		option.priority -= creep.room.getCreepsWithOrder('build', target.id).length;
145 279
 
146 280
 		if (target.structureType === STRUCTURE_SPAWN) {
147 281
 			// Spawns have highest construction priority - we want to make
@@ -153,136 +287,62 @@ Creep.prototype.addBuildOptions = function (options) {
153 287
 	}
154 288
 };
155 289
 
156
-/**
157
- * Sets a good repair or build target for this creep.
158
- */
159
-Creep.prototype.calculateBuilderTarget = function () {
160
-	const creep = this;
161
-	const best = utilities.getBestOption(creep.getAvailableBuilderTargets());
162
-
163
-	if (best) {
164
-		if (best.type === 'structure') {
165
-			creep.memory.order = {
166
-				type: 'repair',
167
-				target: best.object.id,
168
-				maxHealth: best.maxHealth,
169
-			};
170
-		}
171
-		else if (best.type === 'site') {
172
-			creep.memory.order = {
173
-				type: 'build',
174
-				target: best.object.id,
175
-			};
176
-		}
177
-	}
178
-	else {
179
-		delete creep.memory.order;
180
-	}
181
-};
182
-
183
-/**
184
- * Makes the creep repair damaged buildings.
185
- *
186
- * @return {boolean}
187
- *   True if an action was performed.
188
- */
189
-Creep.prototype.performRepair = function () {
190
-	const creep = this;
191
-	if (!creep.memory.order || !creep.memory.order.target) {
192
-		creep.calculateBuilderTarget();
193
-	}
194
-
195
-	if (!creep.memory.order || !creep.memory.order.target) {
196
-		return false;
197
-	}
198
-
199
-	const target = Game.getObjectById(creep.memory.order.target);
200
-	if (!target) {
201
-		creep.calculateBuilderTarget();
202
-		return true;
203
-	}
204
-
205
-	if (creep.memory.order.type === 'repair') {
206
-		let maxHealth = target.hitsMax;
207
-		if (creep.memory.order.maxHealth) {
208
-			maxHealth = creep.memory.order.maxHealth;
209
-
210
-			// Repair ramparts past their maxHealth to counteract decaying.
211
-			if (target.structureType === STRUCTURE_RAMPART) {
212
-				maxHealth = Math.min(maxHealth + 10000, target.hitsMax);
213
-			}
214
-		}
215
-
216
-		if (!target.hits || target.hits >= maxHealth) {
217
-			creep.calculateBuilderTarget();
218
-			return true;
219
-		}
220
-
221
-		creep.repairTarget(target);
222
-		return true;
223
-	}
224
-
225
-	if (creep.memory.order.type === 'build') {
226
-		this.buildTarget(target);
227
-		return true;
228
-	}
229
-
230
-	// Unknown order type, recalculate!
231
-	hivemind.log('creeps', this.pos.roomName).info('Unknown order type detected on', creep.name);
232
-	creep.calculateBuilderTarget();
233
-	return true;
234
-};
235
-
236 290
 /**
237 291
  * Moves towards a target structure and repairs it once close enough.
238 292
  *
293
+ * @param {Creep} creep
294
+ *   The creep to run logic for.
239 295
  * @param {Structure} target
240 296
  *   The structure to repair.
241 297
  */
242
-Creep.prototype.repairTarget = function (target) {
243
-	if (this.pos.getRangeTo(target) > 3) {
244
-		this.moveToRange(target, 3);
298
+BuilderRole.prototype.repairTarget = function (creep, target) {
299
+	if (creep.pos.getRangeTo(target) > 3) {
300
+		creep.moveToRange(target, 3);
245 301
 
246 302
 		// Also try to repair things that are close by when appropriate.
247
-		if ((this.carry.energy > this.carryCapacity * 0.7 || this.carry.energy < this.carryCapacity * 0.3) && !utilities.throttle(this.memory.throttleOffset)) {
248
-			this.repairNearby();
249
-		}
303
+		this.repairNearby(creep);
250 304
 	}
251 305
 	else {
252
-		this.repair(target);
306
+		creep.repair(target);
253 307
 	}
254 308
 };
255 309
 
256 310
 /**
257 311
  * Moves towards a target construction site and builds it once close enough.
258 312
  *
313
+ * @param {Creep} creep
314
+ *   The creep to run logic for.
259 315
  * @param {ConstructionSite} target
260 316
  *   The construction site to build.
261 317
  */
262
-Creep.prototype.buildTarget = function (target) {
263
-	if (this.pos.getRangeTo(target) > 3) {
264
-		this.moveToRange(target, 3);
318
+BuilderRole.prototype.buildTarget = function (creep, target) {
319
+	if (creep.pos.getRangeTo(target) > 3) {
320
+		creep.moveToRange(target, 3);
265 321
 
266 322
 		// Also try to repair things that are close by when appropriate.
267
-		if ((this.carry.energy > this.carryCapacity * 0.7 || this.carry.energy < this.carryCapacity * 0.3) && !utilities.throttle(this.memory.throttleOffset)) {
268
-			this.repairNearby();
269
-		}
323
+		this.repairNearby(creep);
270 324
 	}
271 325
 	else {
272
-		this.build(target);
326
+		creep.build(target);
273 327
 	}
274 328
 };
275 329
 
276 330
 /**
277 331
  * While not actively working on anything else, use carried energy to repair nearby structures.
332
+ *
333
+ * @param {Creep} creep
334
+ *   The creep to run logic for.
278 335
  */
279
-Creep.prototype.repairNearby = function () {
280
-	const workParts = this.memory.body.work;
336
+BuilderRole.prototype.repairNearby = function (creep) {
337
+	if (creep.carry.energy < creep.carryCapacity * 0.7 && creep.carry.energy > creep.carryCapacity * 0.3) return;
338
+	if (utilities.throttle(creep.memory._tO)) return;
339
+
340
+	const workParts = creep.memory.body.work;
281 341
 	if (!workParts) return;
282 342
 
283
-	const needsRepair = this.room.find(FIND_STRUCTURES);
343
+	const needsRepair = creep.room.find(FIND_STRUCTURES);
284 344
 	for (const structure of needsRepair) {
285
-		if (this.pos.getRangeTo(structure) > 3) continue;
345
+		if (creep.pos.getRangeTo(structure) > 3) continue;
286 346
 		if (structure.needsDismantling()) continue;
287 347
 
288 348
 		let maxHealth = structure.hitsMax;
@@ -292,7 +352,7 @@ Creep.prototype.repairNearby = function () {
292 352
 
293 353
 		if (structure.hits <= maxHealth - (workParts * 100)) {
294 354
 			if (needsRepair.length > 0) {
295
-				this.repair(needsRepair[0]);
355
+				creep.repair(needsRepair[0]);
296 356
 			}
297 357
 
298 358
 			return;
@@ -300,32 +360,4 @@ Creep.prototype.repairNearby = function () {
300 360
 	}
301 361
 };
302 362
 
303
-/**
304
- * Puts this creep into or out of repair mode.
305
- *
306
- * @param {boolean} repairing
307
- *   Whether to start building / repairing or not.
308
- */
309
-Creep.prototype.setBuilderState = function (repairing) {
310
-	this.memory.repairing = repairing;
311
-	delete this.memory.order;
312
-};
313
-
314
-/**
315
- * Makes this creep behave like a builder.
316
- */
317
-Creep.prototype.runBuilderLogic = function () {
318
-	if (this.memory.repairing && this.carry.energy === 0) {
319
-		this.setBuilderState(false);
320
-	}
321
-	else if (!this.memory.repairing && _.sum(this.carry) >= this.carryCapacity * 0.9) {
322
-		this.setBuilderState(true);
323
-	}
324
-
325
-	if (this.memory.repairing) {
326
-		this.performRepair();
327
-		return;
328
-	}
329
-
330
-	this.performGetEnergy();
331
-};
363
+module.exports = BuilderRole;

+ 7
- 1
src/role.harvester.js View File

@@ -183,7 +183,13 @@ HarvesterRole.prototype.performHarvesterDeliver = function (creep) {
183 183
 		});
184 184
 
185 185
 		if (sites.length > 0) {
186
-			creep.buildTarget(sites[0]);
186
+			if (creep.pos.getRangeTo(target) > 3) {
187
+				creep.moveToRange(target, 3);
188
+			}
189
+			else {
190
+				creep.build(target);
191
+			}
192
+
187 193
 			return;
188 194
 		}
189 195
 	}