-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathroom.populator.js
318 lines (269 loc) · 13.1 KB
/
room.populator.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
/*
Note that the order in which the class is listed determines it's priority since creep creation is aborted in the spawn is busy
For levels 1 and 2 only use peasants
For level 3, phase in harvesters so that the haulers will have conainters ready for them,
also phase in upgraders so that that the harvesters' energy is not wasted
Phase 4 incorporates mineral harvesters
SATELITE ROOMS:
-use a cyan flag with the room name
-place blue flags with the role_num_options in the satelite room
TODO:
-make the spawns multi roomed
-implement a spawn queue
-fix builders to work with distance builders
*/
var role_proto = require('prototype.role');
var rolePeasant = require('role.peasant');
var roleHarvester = require('role.harvester');
var roleHauler = require('role.hauler');
var roleUpgrader = require('role.upgrader');
var roleAllocator = require('role.allocator');
var roleBuilder = require('role.builder');
var roomPopulator = {
run: function (room_name,phase){
//control the creation of new creeps
//if the room is not mine, just pass
if(Game.rooms[room_name].controller===undefined){
return 1;
}else if(!Game.rooms[room_name].controller.my){
return 1;
}
// TODO set this up for multiple spawns
var spawn=_.filter(Game.spawns,(s) => {return s.pos.roomName == room_name;})[0];
if (spawn===undefined){
// this is the case for a freshly claimed room
return;
}
var spawned= false; // use this to prevent multiple spawn orders
if(phase==1){
spawned=this.phaseOne(room_name,spawn);
}
else if(phase==2){
spawned=this.phaseTwo(room_name,spawn);
}
else if(phase==3){
spawned=this.phaseThree(room_name,spawn);
}
else if(phase==4){
spawned=this.phaseFour(room_name,spawn);
}
//spawn creeps that are flag designated for this room
if (!spawned){
spawned=this.satellite(room_name,room_name); // sneaky;)
}
// spawn creeps for satellite rooms
if (!spawned){
//query for cyan flags
var cyanBrownFlags = Game.rooms[room_name].find(FIND_FLAGS,{filter: (f) => {return (f.color ==COLOR_CYAN&& f.secondaryColor==COLOR_BROWN); }});
var cyanFlags = Game.rooms[room_name].find(FIND_FLAGS,{filter: (f) => {return (f.color ==COLOR_CYAN); }});
var spawned=false;
for (var i in cyanBrownFlags){
// this is so that I can jump the queue
if (spawned){
break;
}
spawned=this.satellite(cyanBrownFlags[i].name,room_name);
}
// for each dependent room build their stuff
for (var i in cyanFlags){
// I do the blue flags first so that guards are higher in priority than harvesters in the case of attacks
if (spawned){
break;
}
spawned=this.satellite(cyanFlags[i].name,room_name);
if (spawned){
break;
}
if ((cyanFlags[i].secondaryColor == COLOR_RED) && (phase >2)){
// a cyan/red flag indicates that this remote room should be mined
// satelliteRemoteMine requires a storage so only phase 3 and up rooms will call this function
spawned=this.satelliteRemoteMine(cyanFlags[i].name,room_name);
}
}
}
},
phaseOne:function(room_name,spawn){
//this is the first phase of a room and only uses peasants
//TODO implement spawned in the peasant class
var spawned= false;
var peasants = _.sum(Game.creeps, (c) => c.memory.role == 'peasant' && c.memory.home == room_name);
if (peasants <(Game.rooms[room_name].controller.level*6) ){
rolePeasant.create(spawn);
}
return spawned;
},
phaseTwo:function(room_name,spawn){
//phase two phases in harvesters and some basic road construction, it's kind of efficient
var spawned = false
var sourceflags = Game.rooms[room_name].find(FIND_FLAGS,{filter: (f) => {return (f.color ==COLOR_RED && f.secondaryColor == COLOR_RED);}});
for (var sourceflag in sourceflags){
var harvester = _.sum(Game.creeps, (c) => c.memory.role == 'harvester' && (c.memory.source ==sourceflags[sourceflag].name));
if (!harvester && !spawned){
spawned=roleHarvester.create(spawn,[sourceflags[sourceflag].name]);
}
}
// the peasants will take from the containers
var peasants = _.sum(Game.creeps, (c) => c.memory.role == 'peasant' && c.memory.home == room_name );
//check the room controller level, if it is less than a set amount, build peasants
if ((peasants <10) &&!spawned){
spawned=rolePeasant.create(spawn);
}
return spawned;
},
phaseThree:function(room_name,spawn){
//phase three introduces haulers builders and upgraders as well as more roads
var spawned= false;
//query for relevant flags
var sourceflags = Game.rooms[room_name].find(FIND_FLAGS,{filter: (f) => {return (f.color ==COLOR_RED && f.secondaryColor == COLOR_RED); }});
var storageflags = Game.rooms[room_name].find(FIND_FLAGS,{filter: (f) => {return (f.color ==COLOR_WHITE&& f.secondaryColor == COLOR_WHITE); }});
// build allocators based on the number of extensions and age of youngest allocator
// TODO implement more complicated logic
var allocators = _.sum(Game.creeps, (c) => (c.memory.role == 'allocator')&& (c.memory.home ==room_name));
if((allocators<2 )&&!spawned) {
spawned= roleAllocator.create(spawn);
spawned= true;//TODO figure this out
}
// build haulers and harvesters
//check to see if there is a storage container available
var storage = Game.rooms[room_name].lookForAt(LOOK_STRUCTURES,storageflags[0]);
for (var sourceflag in sourceflags){
// we don't count the number of haulers directly because then if I want an extra hauling job for a container it would ruin this
var harvester = _.sum(Game.creeps, (c) => c.memory.role == 'harvester' && c.memory.source ==sourceflags[sourceflag].name);
var hauler = _.sum(Game.creeps, (c) => c.memory.role == 'hauler' && c.memory.source ==sourceflags[sourceflag].name);
if (!harvester && !spawned){
spawned=roleHarvester.create(spawn,[sourceflags[sourceflag].name]);
}
if (!hauler && storage.length &&!spawned){
spawned=roleHauler.create(spawn,["hauler","blank","blank",sourceflags[sourceflag].name,storageflags[0].name]);
}
}
// build builders based on the number of construction sites
var builders = _.sum(Game.creeps, (c) => c.memory.role == 'builder'&& c.memory.home ==room_name && !c.memory.work );
var numContructionSites = Game.rooms[room_name].find(FIND_CONSTRUCTION_SITES).length;
if(((10*builders)<numContructionSites) &&!spawned) {
roleBuilder.create(spawn);
spawned=true;
}
// build upgraders based on the amount of reserves present
var upgraders = _.sum(Game.creeps, (c) => c.memory.role == 'upgrader'&& c.memory.home ==room_name);
var storedEnergy= Game.rooms[room_name].find(FIND_STRUCTURES, {filter: (s)=> s.structureType==STRUCTURE_STORAGE})[0].store[RESOURCE_ENERGY];
if (storedEnergy>750000){
var additionalUpgraders=3;
}
else if (storedEnergy>500000){
var additionalUpgraders=2;
}
else if (storedEnergy>250000){
var additionalUpgraders=1;
}else{
var additionalUpgraders=0;
}
if((upgraders<(1+additionalUpgraders))&&!spawned) {
roleUpgrader.create(spawn , "placeholderTODO");
spawned=true;
}
return spawned;
},
phaseFour:function(room_name,spawn){
// phase 4 builds off of phase three but introduces extractors
var spawned= false;
spawned= this.phaseThree(room_name,spawn);
//query red/yellow flags which mark a mineral site
var mineralflags = Game.rooms[room_name].find(FIND_FLAGS,{filter: (f) => {return (f.color ==COLOR_RED && f.secondaryColor == COLOR_YELLOW); }});
var storageflags = Game.rooms[room_name].find(FIND_FLAGS,{filter: (f) => {return (f.color ==COLOR_WHITE&& f.secondaryColor == COLOR_WHITE); }});
var storage = Game.rooms[room_name].lookForAt(LOOK_STRUCTURES,storageflags[0]);
for (var mineralflag in mineralflags){
//check to see if the source is empty or not
var mineral= mineralflags[mineralflag].pos.findInRange(FIND_MINERALS,1);
if (!mineral.length || !mineral[0].mineralAmount){
continue;
}
// we don't count the number of haulers directly because then if I want an extra hauling job for a container it would ruin this
var harvester = _.sum(Game.creeps, (c) => c.memory.role == 'harvester' && c.memory.source ==mineralflags[mineralflag].name);
var hauler = _.sum(Game.creeps, (c) => c.memory.role == 'hauler' && c.memory.source ==mineralflags[mineralflag].name);
if (!harvester && !spawned){
spawned=roleHarvester.create(spawn,[mineralflags[mineralflag].name]);
}
if (!hauler && storage.length &&!spawned){
spawned=roleHauler.create(spawn,["hauler","blank","blank",mineralflags[mineralflag].name,storageflags[0].name]);
}
}
return spawned;
},
satellite: function(room_name,parent){
// check the flags in the satelite room and spawn units accordingly.
var spawn=_.filter(Game.spawns,(s) => {return s.pos.roomName == parent;})[0];
var spawned=false;
//query for blue flags
var blueFlags = _.filter(Game.flags, f => (f.pos.roomName ==room_name)&&(f.color ==COLOR_BLUE) );
for (var i in blueFlags){
if(spawned){
continue;
}
var info= blueFlags[i].name.split("_");
var role= info[0];
var exists = _.filter(Game.creeps, (c)=> (c.memory.flag ==blueFlags[i].name) );
if (exists.length){
continue;
}
if(this.roleExists(role)){
role = this.getRole(role);
}
var role = Object.create(role);
try { spawned = role.create(spawn,info); } catch(e) {
console.log(room_name+" satelite spawn error with role "+ info[0] +": " + e.stack);
};
}
if (spawned){
return true;
}
else{
return false
}
},
satelliteRemoteMine:function(room_name,parent){
// check the red flags in the satelite room and spawn harvesters and haulers accordingly.
// need to have visibility of the room!!!
var spawn=_.filter(Game.spawns,(s) => {return s.pos.roomName == parent;})[0];
var spawned=false;
if (Memory[room_name].defense.defcon>0){
//don't spawn miners if there are bad guys around
return spawned;
}
//storage flags are from the parent room while the source flags are from the satellite room
var sourceflags = _.filter(Game.flags, f => (f.pos.roomName ==room_name)&&(f.color ==COLOR_RED)&&(f.secondaryColor ==COLOR_RED) );
var storageflags = Game.rooms[parent].find(FIND_FLAGS,{filter: (f) => {return (f.color ==COLOR_WHITE)&&(f.secondaryColor ==COLOR_WHITE); }});
var storage = Game.rooms[parent].lookForAt(LOOK_STRUCTURES,storageflags[0]);
for (var sourceflag in sourceflags){
var harvester = _.sum(Game.creeps, (c) => c.memory.role == 'harvester' && c.memory.source ==sourceflags[sourceflag].name);
var hauler = _.sum(Game.creeps, (c) => c.memory.role == 'hauler' && c.memory.source ==sourceflags[sourceflag].name);
if (!harvester && !spawned){
spawned=roleHarvester.create(spawn,[sourceflags[sourceflag].name]);
}
if (!hauler && storage.length && !spawned){
spawned=roleHauler.create(spawn,["hauler","blank","blank",sourceflags[sourceflag].name,storageflags[0].name]);
}
}
return spawned;
},
roleExists: function(role){
try
{
require("role." + role);
return true;
}
catch(e)
{
console.log("role exist error"+e);
return false;
}
},
getRole: function(role){
if(!this.roleExists(role))
return false;
var roleObject = require("role." + role);
roleObject = Object.assign( role_proto,roleObject);
return roleObject;
}
};
module.exports = roomPopulator;