Skip to content

Instantly share code, notes, and snippets.

@VirtuosiMedia
Created April 6, 2016 23:02
Show Gist options
  • Save VirtuosiMedia/fca9db43bdb38ed3f10ce9b36bf90358 to your computer and use it in GitHub Desktop.
Save VirtuosiMedia/fca9db43bdb38ed3f10ce9b36bf90358 to your computer and use it in GitHub Desktop.
/**
* Calculates all trade functionality.
* Copyright Virtuosi Media, Inc.
*/
jg.calculate.trade = {
resources: false,
components: false,
/**
* Retrieves a base price for a given good based on the base prices of all resources used to craft it.
* @param {string} good The good id.
* @return {numeric} The base price of the good.
*/
getGoodBasePrice: function(good){
if (!this.resources){
this.resources = _.container(_.language.getDataSet('resources'));
}
if (!this.components){
this.components = _.container(_.language.getDataSet('items'));
}
var price = 0;
if (this.resources.keys().contains(good)){
price = this.resources[good].basePrice;
} else {
var costs = _.container(this.components[good].costs);
var self = this;
//Recursively get the cost for the component.
costs.each(function(quantity, resource){
if (resource === 'items'){
var components = _.container(quantity);
components.each(function(numComponents, component){
price += numComponents * self.getGoodBasePrice(component);
});
} else {
price += quantity * self.getGoodBasePrice(resource);
}
});
}
return price;
},
/**
* Gets the average sales price for a good from all entities that are selling it.
* @param {int} holdingId The holding id.
* @param {string} good The good id.
* @return {numeric} The average sales price for the good.
*/
getAverageGoodSalesPrice: function(holdingId, good){
var numSellers = 1;
var totalPrice = this.getGoodBasePrice(good);
jg.data.holdings.each(function(holding){
if (holding.data.id !== holdingId){ //Prevent local price manipulation
var sales = holding.data.economic.trade.sales;
if (sales.hasKey(good)){
totalPrice += sales[good].price;
numSellers++;
}
}
});
var averagePrice = totalPrice/numSellers;
return averagePrice;
},
/**
* Gets the order purchase price for a particular good from a holding.
* @param {int} holding The holding id.
* @param {string} good The good id.
* @return {mixed} The order purchase price if the order exists, false otherwise.
*/
getGoodOrderPrice: function(holding, good){
var orders = jg.data.holdings[holding].data.economic.trade.orders;
return (orders.hasKey(good)) ? orders[good].price : false;
},
/**
* Gets the order quantity for a particular good from a holding.
* @param {int} holding The holding id.
* @param {string} good The good id.
* @return {mixed} The order quantity if the order exists, false otherwise.
*/
getGoodOrderQuantity: function(holding, good){
var orders = jg.data.holdings[holding].data.economic.trade.orders;
return (orders.hasKey(good)) ? orders[good].quantity : false;
},
/**
* Gets the order type for a particular good from a holding.
* @param {int} holding The holding id.
* @param {string} good The good id.
* @return {mixed} The order type if the order exists, false otherwise.
*/
getGoodOrderType: function(holding, good){
var orders = jg.data.holdings[holding].data.economic.trade.orders;
return (orders.hasKey(good)) ? orders[good].orderType : false;
},
/**
* Gets the order action for a particular good from a holding.
* @param {int} holding The holding id.
* @param {string} good The good id.
* @return {string} 'cancel' if the order exists, 'bid' otherwise.
*/
getGoodOrderAction: function(holding, good){
var orders = jg.data.holdings[holding].data.economic.trade.orders;
return (orders.hasKey(good)) ? 'cancel' : 'bid';
},
/**
* Places an order for a good from a holding.
* @param {int} holdingId The holding id.
* @param {string} good The good id.
* @param {string} goodCategory The good category: resource, component.
* @param {float} price The price of the order.
* @param {int} quantity The quantity of goods ordered.
* @param {string} orderType The type of purchase: trade or order.
* @return {boolean} TRUE if the order was placed, FALSE if there were insufficient resources.
*/
placeTradeOrder: function(holdingId, good, goodCategory, price, quantity, orderType){
var holding = jg.data.holdings[holdingId];
var totalCost = price * quantity;
var canOrder = (((orderType === 'order') && (holding.resources.supply.credits >= totalCost)) || (orderType === 'trade'));
if (canOrder){
holding.data.economic.trade.orders[good] = {
faction: holding.data.faction,
holding: holding.data.id,
good: good,
goodCategory: goodCategory,
price: price,
quantity: quantity,
total: totalCost,
orderType: orderType,
timestamp: jg.data.state.timestamp
};
if (orderType === 'order'){
holding.resources.supply.credits -= totalCost;
}
}
return canOrder;
},
/**
* Cancels an order for a good from a holding.
* @param {int} holdingId The holding id.
* @param {string} good The good id.
*/
cancelTradeOrder: function(holdingId, good){
var holding = jg.data.holdings[holdingId];
var order = holding.data.economic.trade.orders[good];
if (order.orderType === 'order'){
holding.resources.supply.credits += order.total;
}
delete holding.data.economic.trade.orders[good];
},
/**
* Gets the average purchase bid price for a good from all entities that have ordered it.
* @param {int} holdingId The holding id.
* @param {string} good The good id.
* @return {numeric} The average bid price for the good.
*/
getAverageGoodBidPrice: function(holdingId, good){
var numBidders = 1;
var totalPrice = this.getGoodBasePrice(good);
jg.data.holdings.each(function(holding){
if (holding.data.id !== holdingId){ //Prevent local price manipulation
var bids = holding.data.economic.trade.orders;
if (bids.hasKey(good)){
totalPrice += bids[good].price;
numBidders++;
}
}
});
var averagePrice = totalPrice/numBidders;
return averagePrice;
},
/**
* Gets the order purchase price for a particular good from a holding.
* @param {int} holding The holding id.
* @param {string} good The good id.
* @return {mixed} The order purchase price if the order exists, false otherwise.
*/
getGoodSalesProposalPrice: function(holding, good){
var sales = jg.data.holdings[holding].data.economic.trade.sales;
return (sales.hasKey(good)) ? sales[good].price : false;
},
/**
* Gets the order quantity for a particular good from a holding.
* @param {int} holding The holding id.
* @param {string} good The good id.
* @return {mixed} The order quantity if the order exists, false otherwise.
*/
getGoodSalesProposalQuantity: function(holding, good){
var sales = jg.data.holdings[holding].data.economic.trade.sales;
var quantity = 0;
if (sales.hasKey(good)){
quantity = sales[good].quantity;
} else {
if (!this.resources){
this.resources = _.container(_.language.getDataSet('resources'));
}
if (this.resources.hasKey(good)){
quantity = jg.data.holdings[holding].resources.supply[good];
} else if (jg.data.holdings[holding].inventory.hasOwnProperty(good)){
quantity = jg.data.holdings[holding].inventory[good];
}
}
return quantity;
},
/**
* Gets the order type for a particular good from a holding.
* @param {int} holding The holding id.
* @param {string} good The good id.
* @return {mixed} The order type if the order exists, false otherwise.
*/
getGoodSalesProposalType: function(holding, good){
var sales = jg.data.holdings[holding].data.economic.trade.sales;
return (sales.hasKey(good)) ? sales[good].orderType : false;
},
/**
* Gets the order action for a particular good from a holding.
* @param {int} holding The holding id.
* @param {string} good The good id.
* @return {string} 'cancel' if the order exists, 'sell' otherwise.
*/
getGoodSalesProposalAction: function(holding, good){
var sales = jg.data.holdings[holding].data.economic.trade.sales;
return (sales.hasKey(good)) ? 'cancel' : 'sell';
},
/**
* Places a sales proposal for a good from a holding.
* @param {int} holdingId The holding id.
* @param {string} good The good id.
* @param {string} goodCategory The good category: resource, component.
* @param {float} price The price of the order.
* @param {int} quantity The quantity of goods ordered.
* @param {string} orderType The type of purchase: trade or order.
* @return {boolean} TRUE if the proposal was valid, FALSE if there were insufficient resources.
*/
placeTradeSalesProposal: function(holdingId, good, goodCategory, price, quantity, orderType){
var holding = jg.data.holdings[holdingId];
var totalCost = price * quantity;
if (goodCategory === 'resource'){
var canSell = (((orderType === 'sale') && (holding.resources.supply[good] >= quantity)) || (orderType === 'trade'));
} else {
var canSell = (((orderType === 'sale') && (holding.inventory[good] >= quantity)) || (orderType === 'trade'));
}
if (canSell){
holding.data.economic.trade.sales[good] = {
faction: holding.data.faction,
holding: holding.data.id,
good: good,
goodCategory: goodCategory,
price: price,
quantity: quantity,
total: totalCost,
orderType: orderType,
timestamp: jg.data.state.timestamp
};
if (orderType === 'sale'){
if (goodCategory === 'resource'){
holding.resources.supply[good] -= quantity;
} else {
holding.inventory[good] -= quantity;
}
}
}
return canSell;
},
/**
* Cancels a sales proposal for a good from a holding.
* @param {int} holdingId The holding id.
* @param {string} good The good id.
*/
cancelTradeSalesProposal: function(holdingId, good){
var holding = jg.data.holdings[holdingId];
var proposal = holding.data.economic.trade.sales[good];
if (proposal.orderType === 'sale'){
if (proposal.goodCategory === 'resource'){
holding.resources.supply[good] += proposal.quantity;
} else {
holding.inventory[good] += proposal.quantity;
}
}
delete holding.data.economic.trade.sales[good];
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment