UNPKG

@screeps/engine

Version:

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

417 lines (358 loc) 13.7 kB
'use strict'; var utils = require('./../utils'), rooms = require('./rooms'), driver = utils.getRuntimeDriver(), _ = require('lodash'), C = driver.constants; var runtimeData, intents, register, globals; function calcFreePowerLevels() { var level = Math.floor(Math.pow((runtimeData.user.power || 0) / C.POWER_LEVEL_MULTIPLY, 1 / C.POWER_LEVEL_POW)); var used = Object.keys(runtimeData.userPowerCreeps).length + _.sum(runtimeData.userPowerCreeps, 'level'); return level - used; } function data(id) { return Object.assign({}, runtimeData.userPowerCreeps[id], runtimeData.roomObjects[id]); } function _storeGetter(o) { return new globals.Store(o); } exports.make = function (_runtimeData, _intents, _register, _globals) { runtimeData = _runtimeData; intents = _intents; register = _register; globals = _globals; if (globals.PowerCreep) { return; } var PowerCreep = register.wrapFn(function (id) { var _data = data(id); if (_data.room) { globals.RoomObject.call(this, _data.x, _data.y, _data.room); } this.id = id; }); PowerCreep.prototype = Object.create(globals.RoomObject.prototype); PowerCreep.prototype.constructor = PowerCreep; utils.defineGameObjectProperties(PowerCreep.prototype, data, { name: o => o.name, my: o => o.user == runtimeData.user._id, owner: o => new Object({ username: runtimeData.users[o.user].username }), level: o => o.level, className: o => o.className, hitsMax: o => o.hitsMax, hits: o => o.hits, shard: o => o.shard || undefined, spawnCooldownTime: o => o.spawnCooldownTime !== null && o.spawnCooldownTime > Date.now() ? o.spawnCooldownTime : undefined, deleteTime: o => o.deleteTime || undefined, powers: o => _.mapValues(o.powers, i => ({ level: i.level, cooldown: Math.max(0, (i.cooldownTime || 0) - runtimeData.time) })), saying: o => { if (!o.actionLog || !o.actionLog.say) { return undefined; } if (o.user == runtimeData.user._id) { return o.actionLog.say.message; } return o.actionLog.say.isPublic ? o.actionLog.say.message : undefined; }, carry: _storeGetter, store: _storeGetter, carryCapacity: o => o.storeCapacity, ticksToLive: o => o.ageTime - runtimeData.time }); Object.defineProperty(PowerCreep.prototype, 'memory', { get: function () { if (this.id && !this.my) { return undefined; } if (_.isUndefined(globals.Memory.powerCreeps) || globals.Memory.powerCreeps === 'undefined') { globals.Memory.powerCreeps = {}; } if (!_.isObject(globals.Memory.powerCreeps)) { return undefined; } return globals.Memory.powerCreeps[this.name] = globals.Memory.powerCreeps[this.name] || {}; }, set: function (value) { if (this.id && !this.my) { throw new Error('Could not set other player\'s creep memory'); } if (_.isUndefined(globals.Memory.powerCreeps) || globals.Memory.powerCreeps === 'undefined') { globals.Memory.powerCreeps = {}; } if (!_.isObject(globals.Memory.powerCreeps)) { throw new Error('Could not set creep memory'); } globals.Memory.powerCreeps[this.name] = value; } }); PowerCreep.prototype.toString = register.wrapFn(function () { return `[powerCreep ${this.name}]`; }); PowerCreep.prototype.move = register.wrapFn(function (target) { if (!this.room) { return C.ERR_BUSY; } return globals.Creep.prototype.move.call(this, target); }); PowerCreep.prototype.moveTo = register.wrapFn(function (firstArg, secondArg, opts) { if (!this.room) { return C.ERR_BUSY; } return globals.Creep.prototype.moveTo.call(this, firstArg, secondArg, opts); }); PowerCreep.prototype.moveByPath = register.wrapFn(function (path) { if (!this.room) { return C.ERR_BUSY; } return globals.Creep.prototype.moveByPath.call(this, path); }); PowerCreep.prototype.transfer = register.wrapFn(function (target, resourceType, amount) { if (!this.room) { return C.ERR_BUSY; } return globals.Creep.prototype.transfer.call(this, target, resourceType, amount); }); PowerCreep.prototype.withdraw = register.wrapFn(function (target, resourceType, amount) { if (!this.room) { return C.ERR_BUSY; } return globals.Creep.prototype.withdraw.call(this, target, resourceType, amount); }); PowerCreep.prototype.drop = register.wrapFn(function (resourceType, amount) { if (!this.room) { return C.ERR_BUSY; } return globals.Creep.prototype.drop.call(this, resourceType, amount); }); PowerCreep.prototype.pickup = register.wrapFn(function (target) { if (!this.room) { return C.ERR_BUSY; } return globals.Creep.prototype.pickup.call(this, target); }); PowerCreep.prototype.say = register.wrapFn(function (message, isPublic) { if (!this.room) { return C.ERR_BUSY; } return globals.Creep.prototype.say.call(this, message, isPublic); }); PowerCreep.prototype.spawn = register.wrapFn(function (powerSpawn) { if (this.room) { return C.ERR_BUSY; } if (!(powerSpawn instanceof globals.StructurePowerSpawn)) { return C.ERR_INVALID_TARGET; } if (!this.my || !powerSpawn.my) { return C.ERR_NOT_OWNER; } if (!utils.checkStructureAgainstController(data(powerSpawn.id), register.objectsByRoom[data(powerSpawn.id).room], data(powerSpawn.room.controller.id))) { return C.ERR_RCL_NOT_ENOUGH; } if (this.spawnCooldownTime) { return C.ERR_TIRED; } if (_.isUndefined(globals.Memory.powerCreeps)) { globals.Memory.powerCreeps = {}; } if (_.isObject(globals.Memory.powerCreeps) && _.isUndefined(globals.Memory.powerCreeps[this.name])) { globals.Memory.powerCreeps[this.name] = {}; } intents.pushByName('global', 'spawnPowerCreep', { id: powerSpawn.id, name: this.name }, 50); return C.OK; }); PowerCreep.prototype.suicide = register.wrapFn(function () { if (!this.room) { return C.ERR_BUSY; } if (!this.my) { return C.ERR_NOT_OWNER; } intents.pushByName('global', 'suicidePowerCreep', { id: this.id }, 50); return C.OK; }); PowerCreep.prototype.delete = register.wrapFn(function (cancel) { if (this.room) { return C.ERR_BUSY; } if (!this.my) { return C.ERR_NOT_OWNER; } intents.pushByName('global', 'deletePowerCreep', { id: this.id, cancel }, 50); return C.OK; }); PowerCreep.prototype.upgrade = register.wrapFn(function (power) { if (!this.my) { return C.ERR_NOT_OWNER; } if (calcFreePowerLevels() <= 0) { return C.ERR_NOT_ENOUGH_RESOURCES; } if (this.level >= C.POWER_CREEP_MAX_LEVEL) { return C.ERR_FULL; } var powerInfo = C.POWER_INFO[power]; if (!powerInfo || powerInfo.className !== this.className) { return C.ERR_INVALID_ARGS; } var powerData = data(this.id).powers[power]; var powerLevel = powerData ? powerData.level : 0; if (powerLevel == 5) { return C.ERR_FULL; } if (this.level < powerInfo.level[powerLevel]) { return C.ERR_FULL; } intents.pushByName('global', 'upgradePowerCreep', { id: this.id, power }, 50); return C.OK; }); PowerCreep.prototype.usePower = register.wrapFn(function (power, target) { if (!this.my) { return C.ERR_NOT_OWNER; } if (!this.room) { return C.ERR_BUSY; } if (this.room.controller) { if (!this.room.controller.isPowerEnabled) { return C.ERR_INVALID_ARGS; } if (!this.room.controller.my && this.room.controller.safeMode) { return C.ERR_INVALID_ARGS; } } var powerData = data(this.id).powers[power]; var powerInfo = C.POWER_INFO[power]; if (!powerData || !powerData.level || !powerInfo) { return C.ERR_NO_BODYPART; } if (powerData.cooldownTime > runtimeData.time) { return C.ERR_TIRED; } var ops = powerInfo.ops || 0; if (_.isArray(ops)) { ops = ops[powerData.level - 1]; } if ((data(this.id).store.ops || 0) < ops) { return C.ERR_NOT_ENOUGH_RESOURCES; } if (powerInfo.range) { if (!target) { return C.ERR_INVALID_TARGET; } if (!this.pos.inRangeTo(target, powerInfo.range)) { return C.ERR_NOT_IN_RANGE; } var currentEffect = _.find(target.effects, i => i.power == power); if (currentEffect && currentEffect.level > powerData.level && currentEffect.ticksRemaining > 0) { return C.ERR_FULL; } } intents.set(this.id, 'usePower', { power, id: target ? target.id : undefined }); return C.OK; }); PowerCreep.prototype.enableRoom = register.wrapFn(function (target) { if (!this.my) { return C.ERR_NOT_OWNER; } if (!this.room) { return C.ERR_BUSY; } if (!target || !target.id || !register.structures[target.id] || !(target instanceof globals.Structure)) { register.assertTargetObject(target); return C.ERR_INVALID_TARGET; } if (!target.pos.isNearTo(this.pos)) { return C.ERR_NOT_IN_RANGE; } if (target.structureType != 'controller' || target.safeMode && !target.my) { return C.ERR_INVALID_TARGET; } intents.set(this.id, 'enableRoom', { id: target.id }); return C.OK; }); PowerCreep.prototype.renew = register.wrapFn(function (target) { if (!this.my) { return C.ERR_NOT_OWNER; } if (!this.room) { return C.ERR_BUSY; } if (!target || !target.id || !register.structures[target.id] || !(target instanceof globals.StructurePowerBank) && !(target instanceof globals.StructurePowerSpawn)) { register.assertTargetObject(target); return C.ERR_INVALID_TARGET; } if (target instanceof globals.StructurePowerSpawn && !utils.checkStructureAgainstController(data(target.id), register.objectsByRoom[data(target.id).room], data(target.room.controller.id))) { return C.ERR_RCL_NOT_ENOUGH; } if (!target.pos.isNearTo(this.pos)) { return C.ERR_NOT_IN_RANGE; } intents.set(this.id, 'renew', { id: target.id }); return C.OK; }); PowerCreep.prototype.cancelOrder = register.wrapFn(function (name) { if (!this.room) { return C.ERR_BUSY; } if (!this.my) { return C.ERR_NOT_OWNER; } if (intents.remove(this.id, name)) { return C.OK; } return C.ERR_NOT_FOUND; }); PowerCreep.prototype.rename = register.wrapFn(function (name) { if (this.room) { return C.ERR_BUSY; } if (!this.my) { return C.ERR_NOT_OWNER; } if (!name || !_.isString(name) || name.length > 100) { return C.ERR_INVALID_ARGS; } if (_.any(runtimeData.userPowerCreeps, { name })) { return C.ERR_NAME_EXISTS; } intents.pushByName('global', 'renamePowerCreep', { id: this.id, name }, 50); return C.OK; }); PowerCreep.prototype.notifyWhenAttacked = register.wrapFn(function (enabled) { if (!this.room) { return C.ERR_BUSY; } if (!this.my) { return C.ERR_NOT_OWNER; } if (!_.isBoolean(enabled)) { return C.ERR_INVALID_ARGS; } if (enabled != data(this.id).notifyWhenAttacked) { intents.set(this.id, 'notifyWhenAttacked', { enabled }); } return C.OK; }); PowerCreep.create = register.wrapFn(function (name, className) { if (!name || !_.isString(name) || name.length > 100) { return C.ERR_INVALID_ARGS; } if (calcFreePowerLevels() <= 0) { return C.ERR_NOT_ENOUGH_RESOURCES; } if (_.any(runtimeData.userPowerCreeps, { name })) { return C.ERR_NAME_EXISTS; } if (Object.values(C.POWER_CLASS).indexOf(className) === -1) { return C.ERR_INVALID_ARGS; } intents.pushByName('global', 'createPowerCreep', { name, className }, 50); return C.OK; }); Object.defineProperty(globals, 'PowerCreep', { enumerable: true, value: PowerCreep }); }; //# sourceMappingURL=../sourcemaps/game/power-creeps.js.map