UNPKG

@screeps/engine

Version:

This is a module for Screeps standalone server. See [main repository](https://github.com/screeps/screeps) for more info.

311 lines (275 loc) 9.13 kB
var _ = require('lodash'), utils = require('../../../utils'), driver = utils.getDriver(), C = driver.constants; module.exports = function(object, intent, scope) { const {roomObjects, roomTerrain, gameTime, bulk, eventLog, roomController} = scope; if(roomController) { if(!roomController.isPowerEnabled) { return; } if(roomController.user != object.user && roomController.safeMode > gameTime) { return; } } const powerInfo = C.POWER_INFO[intent.power]; if(!powerInfo) { return; } const creepPower = object.powers[intent.power]; let target; if(!creepPower || creepPower.level == 0 || creepPower.cooldownTime > gameTime) { return; } var ops = powerInfo.ops || 0; if(_.isArray(ops)) { ops = ops[creepPower.level-1]; } object.store = object.store || {}; if((object.store.ops || 0) < ops) { return; } if(powerInfo.range) { target = roomObjects[intent.id]; if(!target) { return; } if(utils.dist(object, target) > powerInfo.range) { return; } var currentEffect = _.find(target.effects, i => i.power == intent.power); if(currentEffect && currentEffect.level > creepPower.level && currentEffect.endTime > gameTime) { return; } } var applyEffectOnTarget = false; switch(intent.power) { case C.PWR_GENERATE_OPS: { bulk.update(object, { store:{[C.RESOURCE_OPS]: (object.store[C.RESOURCE_OPS] || 0) + powerInfo.effect[creepPower.level-1]}, }); let sum = utils.calcResources(object); if (sum > object.storeCapacity) { require('./drop')(object, { amount: Math.min(object.store[C.RESOURCE_OPS], sum - object.storeCapacity), resourceType: C.RESOURCE_OPS }, scope); } break; } case C.PWR_OPERATE_SPAWN: { if(target.type != 'spawn') { return; } applyEffectOnTarget = true; break; } case C.PWR_OPERATE_TOWER: { if(target.type != 'tower') { return; } applyEffectOnTarget = true; break; } case C.PWR_OPERATE_STORAGE: { if(target.type != 'storage') { return; } applyEffectOnTarget = true; break; } case C.PWR_OPERATE_LAB: { if(target.type != 'lab') { return; } applyEffectOnTarget = true; break; } case C.PWR_OPERATE_EXTENSION: { if(!target.store || target.type != 'storage' && target.type != 'terminal' && target.type != 'factory' && target.type !== 'container') { return; } if(target.user && target.user != roomController.user) { return; } var effect = _.find(target.effects, {power: C.PWR_DISRUPT_TERMINAL}); if(effect && effect.endTime > gameTime) { return; } var extensions = _.filter(roomObjects, i => i.type == 'extension' && i.user == roomController.user && !i.off); var energySent = 0; var energyLimit = Math.min( target.store.energy, powerInfo.effect[creepPower.level-1] * _.sum(extensions, 'storeCapacityResource.energy')); extensions.sort(utils.comparatorDistance(target)); extensions.every((extension) => { var energy = Math.min(energyLimit - energySent, extension.storeCapacityResource.energy - extension.store.energy); bulk.update(extension, {store: {energy: extension.store.energy + energy}}); energySent += energy; return energySent < energyLimit; }); if(energySent === 0) { return; } bulk.update(target, {store:{energy: target.store.energy - energySent}}); break; } case C.PWR_OPERATE_OBSERVER: { if(target.type != 'observer') { return; } applyEffectOnTarget = true; break; } case C.PWR_OPERATE_TERMINAL: { if(target.type != 'terminal') { return; } applyEffectOnTarget = true; break; } case C.PWR_DISRUPT_SPAWN: { if(target.type != 'spawn') { return; } applyEffectOnTarget = true; break; } case C.PWR_DISRUPT_TOWER: { if(target.type != 'tower') { return; } applyEffectOnTarget = true; break; } case C.PWR_DISRUPT_SOURCE: { if(target.type != 'source') { return; } applyEffectOnTarget = true; break; } case C.PWR_REGEN_SOURCE: { if(target.type != 'source') { return; } applyEffectOnTarget = true; break; } case C.PWR_REGEN_MINERAL: { if(target.type != 'mineral') { return; } if(target.mineralAmount == 0) { return; } if(target.nextRegenerationTime) { return; } applyEffectOnTarget = true; break; } case C.PWR_DISRUPT_TERMINAL: { if(target.type != 'terminal') { return; } applyEffectOnTarget = true; break; } case C.PWR_OPERATE_CONTROLLER: { if(target.type != 'controller') { return; } applyEffectOnTarget = true; break; } case C.PWR_OPERATE_POWER: { if(target.type != 'powerSpawn') { return; } applyEffectOnTarget = true; break; } case C.PWR_FORTIFY: { if(target.type != 'rampart' && target.type != 'constructedWall') { return; } applyEffectOnTarget = true; break; } case C.PWR_SHIELD: { var constructionSite = _.find(roomObjects, i => i.x == object.x && i.y == object.y && i.type == 'constructionSite'); if(constructionSite) { bulk.remove(constructionSite._id); delete roomObjects[constructionSite._id]; } if(!utils.checkConstructionSite(roomObjects, 'rampart', object.x, object.y) || !utils.checkConstructionSite(roomTerrain, 'rampart', object.x, object.y)) { return; } bulk.insert({ type: 'rampart', room: object.room, x: object.x, y: object.y, user: object.user, hits: powerInfo.effect[creepPower.level-1], hitsMax: 0, nextDecayTime: gameTime + powerInfo.duration, effects: [ { power: C.PWR_SHIELD, level: creepPower.level, endTime: gameTime + powerInfo.duration } ] }); break; } case C.PWR_OPERATE_FACTORY: { if(target.type != 'factory') { return; } if(!target.level) { bulk.update(target, {level: creepPower.level}); } else { if(target.level != creepPower.level) { return; } } applyEffectOnTarget = true; break; } } if(applyEffectOnTarget) { var effects = Object.values(target.effects || []); _.remove(effects, {power: intent.power}); effects.push({ effect: intent.power, power: intent.power, level: creepPower.level, endTime: gameTime + (_.isArray(powerInfo.duration) ? powerInfo.duration[creepPower.level-1] : powerInfo.duration) }); bulk.update(target, {effects: null}); bulk.update(target, {effects}); } bulk.update(object, { powers: { [intent.power]: { cooldownTime: gameTime + powerInfo.cooldown } }, store: {ops: (object.store.ops || 0) - ops} }); eventLog.push({event: C.EVENT_POWER, objectId: object._id, data: { power: intent.power, targetId: intent.id }}); object.actionLog.power = { id: intent.power, x: target ? target.x : object.x, y: target ? target.y : object.y, }; };