UNPKG

@screeps/engine

Version:

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

261 lines (235 loc) 9.97 kB
'use strict'; var _ = require('lodash'), utils = require('../utils'), driver = utils.getRuntimeDriver(), C = driver.constants, util = require('util'); exports.make = function (runtimeData, intents, register) { var ordersCreatedDuringTick = 0, cachedOrders = {}, cachedHistory = {}, _incomingTransactions, _outgoingTransactions, _orders; function _getOrders(resourceType) { if (!resourceType) { resourceType = 'all'; } if (!cachedOrders[resourceType]) { if (resourceType != 'all' && !_.contains(C.RESOURCES_ALL, resourceType) && !_.contains(C.INTERSHARD_RESOURCES, resourceType)) { return {}; } cachedOrders[resourceType] = JSON.parse(JSON.stringify(runtimeData.market.orders[resourceType]) || '{}'); for (var i in cachedOrders[resourceType]) { cachedOrders[resourceType][i].price /= 1000; } } return cachedOrders[resourceType]; } var market = { calcTransactionCost: register.wrapFn(function (amount, roomName1, roomName2) { var distance = utils.calcRoomsDistance(roomName1, roomName2, true); return utils.calcTerminalEnergyCost(amount, distance); }), getAllOrders: register.wrapFn(function (filter) { var orders = _getOrders(filter && filter.resourceType); return _.filter(orders, filter); }), getHistory: register.wrapFn(function (resourceType) { if (!resourceType) { resourceType = 'all'; } if (!cachedHistory[resourceType]) { if (resourceType != 'all' && !_.contains(C.RESOURCES_ALL, resourceType) && !_.contains(C.INTERSHARD_RESOURCES, resourceType)) { return {}; } cachedHistory[resourceType] = JSON.parse(JSON.stringify(runtimeData.market.history[resourceType] || {})); } return cachedHistory[resourceType]; }), getOrderById: register.wrapFn(function (id) { if (this.orders[id]) { return JSON.parse(JSON.stringify(this.orders[id])); } const order = runtimeData.market.orders.all[id]; if (order) { const result = JSON.parse(JSON.stringify(order)); result.price /= 1000; return result; } return null; }), createOrder: register.wrapFn(function (type, resourceType, price, totalAmount, roomName) { if (_.isObject(type)) { var type = type.type, resourceType = type.resourceType, price = type.price, totalAmount = type.totalAmount, roomName = type.roomName; } if (!_.contains(C.RESOURCES_ALL, resourceType) && !_.contains(C.INTERSHARD_RESOURCES, resourceType)) { return C.ERR_INVALID_ARGS; } if (type != C.ORDER_BUY && type != C.ORDER_SELL) { return C.ERR_INVALID_ARGS; } price = parseFloat(price); totalAmount = parseInt(totalAmount); if (!price || price <= 0 || !totalAmount) { return C.ERR_INVALID_ARGS; } if (price * totalAmount * C.MARKET_FEE > this.credits) { return C.ERR_NOT_ENOUGH_RESOURCES; } if (!_.contains(C.INTERSHARD_RESOURCES, resourceType) && (!roomName || !_.any(runtimeData.userObjects, { type: 'terminal', room: roomName }))) { return C.ERR_NOT_OWNER; } if (_.size(this.orders) + ordersCreatedDuringTick >= C.MARKET_MAX_ORDERS) { return C.ERR_FULL; } ordersCreatedDuringTick++; intents.pushByName('global', 'createOrder', { type, resourceType, price, totalAmount, roomName }); return C.OK; }), cancelOrder: register.wrapFn(function (orderId) { if (!this.orders[orderId]) { return C.ERR_INVALID_ARGS; } intents.pushByName('global', 'cancelOrder', { orderId }, 50); return C.OK; }), deal: register.wrapFn(function (orderId, amount, targetRoomName) { var order = runtimeData.market.orders.all[orderId]; if (!order) { return C.ERR_INVALID_ARGS; } amount = parseInt(amount); if (!amount || amount < 0) { return C.ERR_INVALID_ARGS; } if (_.contains(C.INTERSHARD_RESOURCES, order.resourceType)) { if (order.type == C.ORDER_BUY && (runtimeData.user.resources[order.resourceType] || 0) < amount) { return C.ERR_NOT_ENOUGH_RESOURCES; } } else { if (!targetRoomName) { return C.ERR_INVALID_ARGS; } var terminal = _.find(runtimeData.userObjects, { type: 'terminal', room: targetRoomName }), transferCost = this.calcTransactionCost(amount, targetRoomName, order.roomName); if (!terminal) { return C.ERR_NOT_OWNER; } if (!terminal.store || terminal.store[C.RESOURCE_ENERGY] < transferCost) { return C.ERR_NOT_ENOUGH_RESOURCES; } if (terminal.cooldownTime > runtimeData.time) { return C.ERR_TIRED; } if (order.type == C.ORDER_BUY) { if (order.resourceType != C.RESOURCE_ENERGY && (!terminal.store[order.resourceType] || terminal.store[order.resourceType] < amount) || order.resourceType == C.RESOURCE_ENERGY && terminal.store[C.RESOURCE_ENERGY] < amount + transferCost) { return C.ERR_NOT_ENOUGH_RESOURCES; } } } if (order.type == C.ORDER_SELL && (runtimeData.user.money || 0) < amount * order.price) { return C.ERR_NOT_ENOUGH_RESOURCES; } if (!intents.pushByName('global', 'deal', { orderId, targetRoomName, amount }, 10)) { return C.ERR_FULL; } return C.OK; }), changeOrderPrice: register.wrapFn(function (orderId, newPrice) { var order = this.orders[orderId]; if (!order) { return C.ERR_INVALID_ARGS; } newPrice = parseFloat(newPrice); if (!newPrice || newPrice <= 0) { return C.ERR_INVALID_ARGS; } if (newPrice > order.price && (newPrice - order.price) * order.remainingAmount * C.MARKET_FEE > this.credits) { return C.ERR_NOT_ENOUGH_RESOURCES; } intents.pushByName('global', 'changeOrderPrice', { orderId, newPrice }, 50); return C.OK; }), extendOrder: register.wrapFn(function (orderId, addAmount) { var order = this.orders[orderId]; if (!order) { return C.ERR_INVALID_ARGS; } addAmount = parseInt(addAmount); if (!addAmount || addAmount <= 0) { return C.ERR_INVALID_ARGS; } if (order.price * addAmount * C.MARKET_FEE > this.credits) { return C.ERR_NOT_ENOUGH_RESOURCES; } intents.pushByName('global', 'extendOrder', { orderId, addAmount }, 50); return C.OK; }) }; Object.defineProperties(market, { credits: { enumerable: true, get() { return (runtimeData.user.money || 0) / 1000; } }, incomingTransactions: { enumerable: true, get() { if (!_incomingTransactions) { _incomingTransactions = _.map(runtimeData.transactions.incoming || [], i => { i.transactionId = "" + i._id; delete i._id; i.sender = i.sender ? { username: runtimeData.users[i.sender].username } : undefined; i.recipient = i.recipient ? { username: runtimeData.users[i.recipient].username } : undefined; return i; }); } return _incomingTransactions; } }, outgoingTransactions: { enumerable: true, get() { if (!_outgoingTransactions) { _outgoingTransactions = _.map(runtimeData.transactions.outgoing || [], i => { i.transactionId = "" + i._id; delete i._id; i.sender = i.sender ? { username: runtimeData.users[i.sender].username } : undefined; i.recipient = i.recipient ? { username: runtimeData.users[i.recipient].username } : undefined; return i; }); } return _outgoingTransactions; } }, orders: { enumerable: true, get() { if (!_orders) { _orders = _(runtimeData.market.myOrders).map(i => { i.id = "" + i._id; delete i._id; delete i.user; i.price /= 1000; return i; }).indexBy('id').value(); } return _orders; } } }); return market; }; //# sourceMappingURL=../sourcemaps/game/market.js.map