Last active
May 2, 2017 12:09
-
-
Save juliarose/4ed4b5bfa606b53c00ed876ad3400e02 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
For use on backpack.tf inventory pages only. | |
Used for converting any type of value (string, jQuery object, number) | |
to an easy to use interface for working with prices. | |
Usage: | |
Instance: | |
1. new Price('1 key'); // value = 1, currency = 'keys' | |
2. new Price($item); // convert jQuery item which has data-p_bptf attribute | |
3. new Price(5, 6, 'keys'); // 5-6 keys | |
4. new Price({ value: 2, value_high: 3, currency: metal }) // 2-3 ref | |
Instance Getters: | |
average: | |
Description: | |
Produces an average of value and value_high. | |
Usage: | |
new Price(3,4).avereage // 3.5 | |
Instance Methods: | |
getRefinedValue: | |
Description: | |
Gets the value in refined. Bases conversion on average | |
by default. Pass a parameter to use a different value. | |
Returns 0 if no number can be converted. | |
Usage: | |
1. price.getRefinedValue(); | |
2. price.getRefinedValue(price.value); | |
parseJQuery: | |
Description: | |
Parses jQuery item object for assigning values. | |
Usage: | |
price.parseJQuery($item); | |
parseUSD: | |
Description: | |
Parses USD value. | |
Usage: | |
price.parseUSD('$12.44'); | |
parseString: | |
Description: | |
Parses a price string for assigning values. | |
Usage: | |
price.parseString('2-3 ref'); | |
Class Methods: | |
setup: | |
Description: | |
Call when document is ready to set core attributes. | |
Usage: | |
$(document).ready(function() { | |
Price.setup(); // get key price | |
}); | |
stringToRefinedPrice: | |
Description: | |
Converts a string to a value in refined metal. | |
Usage: | |
Price.stringToRefinedPrice('1 key, 5 ref'); // 25 (when keys are 20 refined) | |
stringToCurrencies: | |
Description: | |
Converts a string to an object of currencies. | |
Usage: | |
Price.stringToCurrencies('1 key, 5 ref'); // { keys: 1, metal: 5 } | |
modifyBonusValue: | |
Description: | |
Modifies value gained from paint or strange parts. This method | |
accepts a 2nd parameter to modify seperate values for each type | |
of bonus (paint, or strangePart) | |
Usage: | |
1. Price.modifyBonusValue($item, { paint: 0.5, strangePart: 0 }); // 50% added value from paints, 0% from strange parts | |
2. Price.modifyBonusValue($item); // values from bonuses | |
roundRefinedValue: | |
Description: | |
Rounds a refined value to the nearest 1/36 in two decimals. | |
Usage: | |
Price.roundRefinedValue(3.3333); // 3.33 | |
Class Properites: | |
keyPrice: | |
The price of keys in refined metal. | |
instanceAttributes: | |
Array of attributes used by price instance. | |
RefinedCurrencyValue: | |
Value in refined metal of each currency. | |
CurrencyName: | |
Global name for currency string e.g. 'ref' = 'metal' | |
*/ | |
// p1 and p2 are optional | |
var Price = function(o, p1, p2) { | |
var self = this; | |
switch (typeof o) { | |
case 'string': | |
this.parseString(o); | |
break; | |
case 'object': | |
if (o instanceof jQuery) { | |
this.parseJQuery(o, p1, p2); | |
} else { | |
// basic price object | |
// { value: 1, value_high: 2, currency: 'metal' } | |
for (var k, i = 0; i < Price.instanceAttributes.length; i++) { | |
k = Price.instanceAttributes[i]; | |
if (o[k] !== undefined) { | |
this[k] = o[k]; // attach properties | |
} | |
} | |
} | |
break; | |
case 'number': | |
this.value = o; | |
this.value_high = !isNaN(p1) && p1; | |
this.currency = Price.CurrencyName[p2 || p1] || 'metal'; // presumed metal if no currency | |
break; | |
} | |
this.__defineGetter__('average', function() { | |
if (self.value_high && self.value) { | |
return (self.value + self.value_high) / 2; | |
} else { | |
return self.value || 0; | |
} | |
}); | |
} | |
Price.prototype.parseJQuery = function($item, scm) { | |
if ($item.data('p_bptf')) { | |
this.parseString($item.data('p_bptf')); | |
} else if ($item.data('p_scm_all') && scm) { // p1 must be set to use scm price as value | |
this.parseString($item.data('p_scm_all')); // the scm value is only the base scm value, and does not included value for additions | |
} | |
if ($item.data('p_bptf_all')) { | |
this.parseUSD($item.data('p_bptf_all')); | |
} | |
// if there is no value that could be found, but there is a price... | |
if (!this.value && $item.data('price')) { | |
this.value = $item.data('price'); | |
this.currency = 'metal'; | |
} | |
} | |
Price.prototype.parseString = function(string) { | |
var match = string.match(/^([\d\.]*)[\––]?([\d\.]*)? (\w*)/); // "1-1.2 keys" | |
if (match) { | |
this.value = parseFloat(match[1]); | |
this.currency = Price.CurrencyName[match[3] || match[2]]; // if it's not in the 3rd group, it's in the 2nd | |
// if there are 3 match groups, there is a range | |
if (match[3]) { | |
this.value_high = parseFloat(match[2]); | |
} | |
} | |
} | |
Price.prototype.parseUSD = function(string) { | |
var match = string.match(/\$(\d{1,}\.\d{2})/); // 290.00 ref, $33.35 | |
if (match) { | |
this.usd = parseFloat(match[1]); | |
} | |
} | |
Price.prototype.getRefinedValue = function(value) { | |
var currencyValue = Price.RefinedCurrencyValue[this.currency]; | |
if (currencyValue) { | |
return (value || this.average) * currencyValue; | |
} else { | |
return 0; | |
} | |
} | |
Price.RefinedCurrencyValue = { | |
'metal': 1, | |
'keys': 1 | |
}; | |
Price.CurrencyName = { | |
'keys': 'keys', | |
'key': 'keys', | |
'ref': 'metal', | |
'$': 'usd' | |
}; | |
// get the value of keys in metal | |
Price.getKeyPrice = function() { | |
// get key price only if a key price doesn't already exist, or the force value is truthy | |
// this process is slow (for larger inventories) and mostly only needs to be called once (should take 1-100ms) | |
if (Price.keyPrice) { | |
return; | |
} | |
var rawValue = Session.rawCurrency.value; | |
Price.RefinedCurrencyValue['usd'] = 1 / rawValue; // set value of usd | |
// find items priced in keys | |
// then sort items by price (the higher the price, the more accurate key value we can get) | |
jQuery('.item[data-p_bptf*="keys"]').sort(function(a,b) { | |
var ax = parseFloat($(a).attr('data-price')) || 0; | |
var bx = parseFloat($(b).attr('data-price')) || 0; | |
var val = 0; | |
if (ax > bx) { | |
return -1; | |
} else if (ax < bx) { | |
return 1; | |
} | |
return 0; | |
}).each(function() { | |
// loop through items until we find an item priced in keys | |
var price = new Price(jQuery(this)); | |
if (price.currency === 'keys' && price.value && price.usd) { | |
// to get the value of keys in metal... | |
// value of items is 2 keys, or $4.32 | |
// keys = 2 | |
// usd = 4.32 | |
// 4.32 / 2 = 2.16 (the value of 1 key) | |
// 2.16 / 0.12 (rawValue) = 18 (refined metal) | |
Price.setKeyPrice((price.usd / price.average) / rawValue); | |
return false; // we found what we're looking for, break the loop | |
} | |
}); | |
if (!Price.keyPrice) { | |
// set value using the value of a key, if no items in inventory are priced in keys | |
var key = $('.item[data-name="Mann Co. Supply Crate Key"]:first'); | |
var price = key && key.length && new Price(key); | |
if (price && price.value) { | |
Price.setKeyPrice(price.average); | |
} | |
} | |
} | |
Price.setKeyPrice = function(value) { | |
Price.keyPrice = value; | |
Price.RefinedCurrencyValue['keys'] = value; | |
console.log('key price is: ' + value); | |
} | |
Price.instanceAttributes = ['value', 'value_high', 'usd', 'currency']; | |
// convert a string to a value in refined metal | |
// when keys are 20 refined, 1 key, 5 ref -> 25 | |
Price.stringToRefinedPrice = function(string) { | |
var currencies = Price.stringToCurrencies(string), value = 0, k; | |
for (k in currencies) { | |
if (Price.RefinedCurrencyValue[k]) { | |
value += Price.RefinedCurrencyValue[k] * currencies[k]; // multiply amount of currency by value of currency in metal | |
} | |
} | |
return Price.roundRefinedValue(value); | |
} | |
// round down to nearest 1/36 of a ref | |
Price.roundRefinedValue = function(value) { | |
return value && Math.floor(Math.round(value * 36) / 36 * 100) / 100; | |
} | |
// modify an item's bonus values | |
// values is an object: | |
// { strangePart: 0.2, paint: 0.5 } | |
// to value strange parts as 20% value and paint as 50% value | |
Price.modifyBonusValue = function($item, multipliers) { | |
var bonusValue = 0; | |
var rawBonusValue = 0; | |
var baseValue = 0; | |
var isUnusual = $item.data('quality') == 5; | |
// does not apply to unusuals | |
if (multipliers && !isUnusual) { | |
var basePrice = $item.data('price') && new Price($item, true); | |
baseValue = (basePrice && basePrice.getRefinedValue()) || 0; // modify based on price attribute | |
var bonusValues = { | |
strangePart: [ | |
$item.data('part_price_1'), | |
$item.data('part_price_2'), | |
$item.data('part_price_3') | |
], | |
paint: [ | |
$item.data('paint_price') | |
] | |
}; | |
for (var k in bonusValues) { | |
// loop through values | |
for (var i = 0; i < bonusValues[k].length; i++) { | |
if (bonusValues[k][i]) { | |
var bonusPrice = new Price(bonusValues[k][i]); | |
var bonusPriceRefinedValue = bonusPrice.getRefinedValue(); | |
bonusValue += bonusPriceRefinedValue * (multipliers[k] || 0); // create price from attribute and multiply its average by multiplier | |
rawBonusValue += bonusPriceRefinedValue; | |
} | |
} | |
} | |
} else { | |
baseValue = new Price($item).getRefinedValue(); | |
} | |
return baseValue + bonusValue; | |
} | |
Price.hasBonuses = function($item) { | |
var bonusValues = { | |
strangePart: [ | |
$item.data('part_price_1'), | |
$item.data('part_price_2'), | |
$item.data('part_price_3') | |
], | |
paint: [ | |
$item.data('paint_price') | |
] | |
}; | |
for (var k in bonusValues) { | |
for (var i = 0; i < bonusValues[k].length; i++) { | |
if (bonusValues[k][i]) { | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
// convert string of currencies to object of currencies | |
// 5 keys, 5 ref -> { keys: 5, metal: 5 } | |
Price.stringToCurrencies = function(string) { | |
var vals = string.split(', '), i, currency, match, reg = /([\d\.]*) (\w*)/; // currency name, amount | |
var currencies = {}; | |
for (i = 0; i < vals.length; i++) { | |
match = vals[i].match(reg); | |
currency = match && Price.CurrencyName[match[2]]; | |
if (currency) { | |
currencies[currency] = parseFloat(match[1]); | |
} | |
} | |
return currencies; | |
} | |
Price.setup = function() { | |
Price.getKeyPrice(); // get key price | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment