@screeps/engine
Version:
This is a module for Screeps standalone server. See [main repository](https://github.com/screeps/screeps) for more info.
295 lines (255 loc) • 9.82 kB
JavaScript
'use strict';
var _ = require('lodash'),
config = require('../../../config'),
utils = require('../../../utils'),
driver = utils.getDriver(),
C = driver.constants;
var createdStructureCounter = 0;
module.exports = function (object, intent, { roomObjects, roomTerrain, bulk, roomController, stats, gameTime, eventLog }) {
if (object.type != 'creep') {
return;
}
if (object.spawning || !object.store || object.store.energy <= 0) {
return;
}
var target = roomObjects[intent.id];
if (!target || target.type != 'constructionSite' || !C.CONSTRUCTION_COST[target.structureType]) {
return;
}
if (Math.abs(target.x - object.x) > 3 || Math.abs(target.y - object.y) > 3) {
return;
}
const objectsInTile = [],
creepsInTile = [],
myCreepsInTile = [];
let structure = null;
_.forEach(roomObjects, function (obj) {
if (obj.x == target.x && obj.y == target.y) {
if (obj.type == target.structureType) {
structure = obj;
return;
}
if (obj.type == 'creep') {
creepsInTile.push(obj);
if (obj.user == object.user) {
myCreepsInTile.push(obj);
}
} else {
objectsInTile.push(obj);
}
}
});
if (!!structure) {
return;
}
if (_.contains(C.OBSTACLE_OBJECT_TYPES, target.structureType)) {
if (_.any(objectsInTile, i => _.contains(C.OBSTACLE_OBJECT_TYPES, i.type))) {
return;
}
const mySafeMode = roomController && roomController.user == object.user && roomController.safeMode > gameTime;
const blockingCreeps = mySafeMode ? myCreepsInTile : creepsInTile;
if (_.any(blockingCreeps)) {
return;
}
}
if (target.structureType != 'extractor' && target.structureType != 'road' && utils.checkTerrain(roomTerrain, target.x, target.y, C.TERRAIN_MASK_WALL)) {
return;
}
var buildPower = _.filter(object.body, i => (i.hits > 0 || i._oldHits > 0) && i.type == C.WORK).length * C.BUILD_POWER || 0,
buildRemaining = target.progressTotal - target.progress,
buildEffect = Math.min(buildPower, buildRemaining, object.store.energy),
boostedParts = _.map(object.body, i => {
if (i.type == C.WORK && i.boost && C.BOOSTS[C.WORK][i.boost].build > 0) {
return (C.BOOSTS[C.WORK][i.boost].build - 1) * C.BUILD_POWER;
}
return 0;
});
boostedParts.sort((a, b) => b - a);
boostedParts = boostedParts.slice(0, buildEffect);
var boostedEffect = Math.min(Math.floor(buildEffect + _.sum(boostedParts)), buildRemaining);
target.progress += boostedEffect;
object.store.energy -= buildEffect;
stats.inc('energyConstruction', object.user, buildEffect);
object.actionLog.build = { x: target.x, y: target.y };
bulk.update(object, { store: { energy: object.store.energy } });
const incomplete = target.progress < target.progressTotal;
eventLog.push({
event: C.EVENT_BUILD,
objectId: object._id,
data: {
targetId: target._id,
amount: boostedEffect,
structureType: target.structureType,
x: target.x,
y: target.y,
incomplete
} });
if (incomplete) {
bulk.update(target, {
progress: target.progress
});
} else {
bulk.remove(target._id);
var newObject = {
type: target.structureType,
x: target.x,
y: target.y,
room: target.room,
notifyWhenAttacked: true
};
if (target.structureType == 'spawn') {
_.extend(newObject, {
name: target.name,
user: target.user,
store: { energy: 0 },
storeCapacityResource: { energy: C.SPAWN_ENERGY_CAPACITY },
hits: C.SPAWN_HITS,
hitsMax: C.SPAWN_HITS
});
}
if (target.structureType == 'extension') {
_.extend(newObject, {
user: target.user,
store: { energy: 0 },
storeCapacityResource: { energy: 0 },
hits: C.EXTENSION_HITS,
hitsMax: C.EXTENSION_HITS
});
}
if (target.structureType == 'link') {
_.extend(newObject, {
user: target.user,
store: { energy: 0 },
storeCapacityResource: { energy: C.LINK_CAPACITY },
cooldown: 0,
hits: C.LINK_HITS,
hitsMax: C.LINK_HITS_MAX
});
}
if (target.structureType == 'storage') {
_.extend(newObject, {
user: target.user,
store: { energy: 0 },
storeCapacity: C.STORAGE_CAPACITY,
hits: C.STORAGE_HITS,
hitsMax: C.STORAGE_HITS
});
}
const hitsMax = !!roomController && roomController.user == object.user ? C.RAMPART_HITS_MAX[roomController.level] || 0 : 0;
if (target.structureType == 'rampart') {
_.extend(newObject, {
user: target.user,
hits: C.RAMPART_HITS,
hitsMax,
nextDecayTime: gameTime + C.RAMPART_DECAY_TIME
});
}
if (target.structureType == 'road') {
var hits = C.ROAD_HITS;
if (_.any(roomObjects, { x: target.x, y: target.y, type: 'swamp' }) || utils.checkTerrain(roomTerrain, target.x, target.y, C.TERRAIN_MASK_SWAMP)) {
hits *= C.CONSTRUCTION_COST_ROAD_SWAMP_RATIO;
}
if (_.any(roomObjects, { x: target.x, y: target.y, type: 'wall' }) || utils.checkTerrain(roomTerrain, target.x, target.y, C.TERRAIN_MASK_WALL)) {
hits *= C.CONSTRUCTION_COST_ROAD_WALL_RATIO;
}
_.extend(newObject, {
hits,
hitsMax: hits,
nextDecayTime: gameTime + C.ROAD_DECAY_TIME
});
}
if (target.structureType == 'constructedWall') {
_.extend(newObject, {
hits: C.WALL_HITS,
hitsMax: C.WALL_HITS_MAX
});
}
if (target.structureType == 'tower') {
_.extend(newObject, {
user: target.user,
store: { energy: 0 },
storeCapacityResource: { energy: C.TOWER_CAPACITY },
hits: C.TOWER_HITS,
hitsMax: C.TOWER_HITS
});
}
if (target.structureType == 'observer') {
_.extend(newObject, {
user: target.user,
hits: C.OBSERVER_HITS,
hitsMax: C.OBSERVER_HITS
});
}
if (target.structureType == 'extractor') {
_.extend(newObject, {
user: target.user,
hits: C.EXTRACTOR_HITS,
hitsMax: C.EXTRACTOR_HITS
});
}
if (target.structureType == 'lab') {
_.extend(newObject, {
user: target.user,
hits: C.LAB_HITS,
hitsMax: C.LAB_HITS,
mineralAmount: 0,
cooldown: 0,
store: { energy: 0 },
storeCapacity: C.LAB_ENERGY_CAPACITY + C.LAB_MINERAL_CAPACITY,
storeCapacityResource: { energy: C.LAB_ENERGY_CAPACITY }
});
}
if (target.structureType == 'powerSpawn') {
_.extend(newObject, {
user: target.user,
store: { energy: 0 },
storeCapacityResource: { energy: C.POWER_SPAWN_ENERGY_CAPACITY, power: C.POWER_SPAWN_POWER_CAPACITY },
hits: C.POWER_SPAWN_HITS,
hitsMax: C.POWER_SPAWN_HITS
});
}
if (target.structureType == 'terminal') {
_.extend(newObject, {
user: target.user,
store: { energy: 0 },
storeCapacity: C.TERMINAL_CAPACITY,
hits: C.TERMINAL_HITS,
hitsMax: C.TERMINAL_HITS
});
}
if (target.structureType == 'container') {
_.extend(newObject, {
store: { energy: 0 },
storeCapacity: C.CONTAINER_CAPACITY,
hits: C.CONTAINER_HITS,
hitsMax: C.CONTAINER_HITS,
nextDecayTime: gameTime + C.CONTAINER_DECAY_TIME
});
}
if (target.structureType == 'nuker') {
_.extend(newObject, {
user: target.user,
store: { energy: 0 },
storeCapacityResource: { energy: config.ptr ? 1 : C.NUKER_ENERGY_CAPACITY, G: config.ptr ? 1 : C.NUKER_GHODIUM_CAPACITY },
hits: C.NUKER_HITS,
hitsMax: C.NUKER_HITS,
cooldownTime: gameTime + (config.ptr ? 100 : C.NUKER_COOLDOWN)
});
}
if (target.structureType == 'factory') {
_.extend(newObject, {
user: target.user,
store: { energy: 0 },
storeCapacity: C.FACTORY_CAPACITY,
hits: C.FACTORY_HITS,
hitsMax: C.FACTORY_HITS,
cooldown: 0
});
}
bulk.insert(newObject);
roomObjects['createdStructure' + createdStructureCounter] = newObject;
createdStructureCounter++;
delete roomObjects[intent.id];
}
};
//# sourceMappingURL=../../../sourcemaps/processor/intents/creeps/build.js.map