Add Syntax Highlighting (this will take a few seconds, probably freezing your browser while it works)
// ==UserScript==
// @name JHunz's KOL Consumption Management
// @namespace hunsley@gmail.com
// @description Warns you when are about to overdrink via the inventory. Tracks fullness and spleen.
// @include *kingdomofloathing.com/*.php*
// ==/UserScript==
//
// Version 1.0 02/04/2008 Released.
// Limitations:
// 1) Only works on the inventory page
// 2) Does not take NPC booze stores (Gnomish Cafe/Crimbo) into account
// 3) May or may not replace links created by other scripts, depending on run order.
// Version 1.1 02/10/2008 Update: Drunkenness amounts are now displayed in drink links. Is also now compatible with compact mode.
//
// Version 2.0 02/21/2008 Renamed to Consumption Management after a total revamp to include food and spleen.
// New features:
// 1) Fullness and spleen hits are now included in the text of links to eat or use spleen items.
// 2) Integration with cmeister's itemdb, so that new items will be recognized by the script as soon as he adds them
// 3) Consumption of food and spleen via the normal inventory links is now tracked. Tracked fullness and spleen are displayed on the character pane.
// Version 2.1 02/24/2008 Bugfix: Logging in can no longer cause an infinite loop.
// Version 2.2 02/25/2008 Bugfix: Counters are now reset properly upon ascension.
// Version 2.2.1 02/25/2008 Bugfix to previous bugfix. I swear it's right now.
// Version 2.3 02/26/2008 Updated to account for the new date display in the chat launch pane.
// Auto-update implemented in case they sneak in anything else that might break it.
// Version 2.4 03/12/2008 Updated active pages so that links generated by other scripts should be handled as long as it runs last.
// Added Micromicrobrewery and Chez Snootee support, and crimbo support if that store follows the same conventions.
// Automatically updates overdrunk level on Steel Margarita consumption
// Added support for detection of multi-using spleen items
// Version 2.5 04/19/2008 Added protection against overdrinking by accidentally double-clicking a drink link.
// The food and spleen counters should no longer allow or show fullness or spleen greater than your current maximum. In other news, your current max fullness and spleen are now tracked.
// You can now sort food and drink by total adventures, or adventures per fullness/drunk
// Version 2.5.1 04/20/2008 Added a conditional to prevent a recurring error in the non-consumable sections of the inventory
// Version 2.5.2 04/21/2008 Unknown and special items (e.g. dusty bottles) should no longer be sorted randomly among your other items.
const VERSION=252;
//auto-update checking code
var lastUpdateCheck = GM_getValue('lastUpdateCheck','NEVER');
var curTime = new Date().getTime();
if ((lastUpdateCheck == 'NEVER') || (parseInt(lastUpdateCheck) < (curTime - 86400000))) {
GM_setValue('lastUpdateCheck',''+curTime);
GM_xmlhttpRequest({method: 'GET',url: 'http://userscripts.org/scripts/source/22297.user.js',
onload: function(responseDetails) {
var bodyText = responseDetails.responseText;
var curVersionNum = parseInt((bodyText.split("const VERSION="))[1].split(";")[0]);
if (curVersionNum > VERSION) {
GM_setValue('outOfDate','true');
}
else {
GM_setValue('outOfDate','false');
}
}
});
}
var curVersion = GM_getValue('curVersion','0');
if (parseInt(curVersion) != VERSION) {
GM_setValue('curVersion',VERSION);
GM_setValue('outOfDate','false');
}
//Nag user with update link if the script is out of date
var outOfDate = GM_getValue('outOfDate');
if((outOfDate == 'true') && (window.location.pathname != "/charpane.php") && (window.location.pathname != "/chatlaunch.php")) {
var newElement = document.createElement('tr');
newElement.innerHTML = '<tr><td><div style="color: red;font-size: 90%;width: 100%;text-align:center;">A new version of Consumption Management is available! <a href="http://userscripts.org/scripts/source/22297.user.js" target="_blank">Update</a></div></td></tr>';
//insert the counter at the top of the page
var element = document.getElementsByTagName("tr")[0];
element.parentNode.insertBefore(newElement,element);
}
if (window.location.pathname == "/login.php") {
GM_setValue("curDate","");
GM_setValue("curCharName",'UNDEFINED');
return false;
}
var ITEMDB_URL = "http://kol.cmeister2.co.uk/items/?mode=limiter2";
updatedb();
var itemdb = getdb();
//Set up configs for various words to use for fullness/spleen
if (GM_getValue("fullnessText",'UNDEFINED')=='UNDEFINED') {
GM_setValue("fullnessText",'Ful,Fullness,Repletion,Satiation,Gluttony,Belt Size');
GM_setValue("spleenText",'Spl,Black Bile,Splenomegaly,Spleneticism','Spleenerality');
alert("This is the first time the consumption manager script has run. If you are currently logged in, please be aware that it will not work properly until you log out and back in.");
}
//Set up configs new in 2.4
if (GM_getValue("drunkText",'UNDEFINED')=='UNDEFINED') {
GM_setValue("drunkText",'Drunk,Tipsiness,Drunkenness,Temulency,Inebriety');
alert("Note: For optimum compatibility with other scripts,\nConsumption manager should be set to run AFTER any other scripts\nthat might insert eat, drink, or use links onto the page.");
}
//Configs new in 2.5
var invSortOrder = GM_getValue("invSortOrder",'UNDEFINED');
if (invSortOrder=='UNDEFINED') {
invSortOrder = 'alpha';
GM_setValue('invSortOrder',invSortOrder);
}
var fullnessDisplayTR,spleenDisplayTR;
//On the charpane, we get the current character name and drunkenness
if (window.location.pathname == "/charpane.php") {
// Get the current name
var charName = document.getElementsByTagName("b")[0].textContent;
GM_setValue('curCharName',charName);
//Grab drunkenness
var drunkTextNode,moxTextNode;
var textNodes = document.evaluate("//text()",document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null);
for (var i=0;i<textNodes.snapshotLength;i++) {
node = textNodes.snapshotItem(i);
s=node.data;
if(s.match("^Temulency:$") || s.match("^Tipsiness:$") || s.match("^Drunkenness:$") || s.match("^Inebriety:$") || s.match("^Drunk:$")) {
drunkTextNode = node;
}
else if (s.match("^Moxie:$") || s.match("^Mox:$")) {
moxTextNode = node;
}
}
if(drunkTextNode) {
drunkenness = parseInt(drunkTextNode.parentNode.nextSibling.textContent);
}
else {
drunkenness = 0;
}
GM_setValue(charName + '.drunkenness',drunkenness);
//alert("drunkenness is " + drunkenness);
//Build fullness and spleen stat nodes
fullnessDisplayTR = document.createElement('tr');
var fullnessDisplayTD1 = document.createElement('td');
var fullnessDisplayTD2 = document.createElement('td');
var fullnessDisplayB = document.createElement('b');
fullnessDisplayB.appendChild(document.createTextNode('temp'));
fullnessDisplayTD1.align = 'right';
fullnessDisplayTD1.appendChild(document.createTextNode(GetFullnessText(moxTextNode.data)));
fullnessDisplayTD2.align = 'left';
fullnessDisplayTD2.appendChild(fullnessDisplayB);
fullnessDisplayTR.appendChild(fullnessDisplayTD1);
fullnessDisplayTR.appendChild(fullnessDisplayTD2);
spleenDisplayTR = document.createElement('tr');
var spleenDisplayTD1 = document.createElement('td');
var spleenDisplayTD2 = document.createElement('td');
var spleenDisplayB = document.createElement('b');
spleenDisplayB.appendChild(document.createTextNode('temp'));
spleenDisplayTD1.align = 'right';
spleenDisplayTD1.appendChild(document.createTextNode(GetSpleenText(moxTextNode.data)));
spleenDisplayTD2.align = 'left';
spleenDisplayTD2.appendChild(spleenDisplayB);
spleenDisplayTR.appendChild(spleenDisplayTD1);
spleenDisplayTR.appendChild(spleenDisplayTD2);
//Insert fullness and spleen stats after the moxie node.
curDate = GM_getValue('curDate','');
if(curDate == '') {
//date not known yet, so we don't know if the fullness/spleen are accurate. Add ? and set timeout
fullnessDisplayB.textContent = '?';
spleenDisplayB.textContent = '?';
moxTextNode.parentNode.parentNode.parentNode.appendChild(fullnessDisplayTR);
moxTextNode.parentNode.parentNode.parentNode.appendChild(spleenDisplayTR);
window.setTimeout(CharPaneTimeout,1500);
}
else {
//date known, so add fullness/spleen as appropriate. don't set timeout.
var fullness = GM_getValue(charName + '.fullness');
var spleen = GM_getValue(charName + '.spleen');
fullnessDisplayB.textContent = fullness;
spleenDisplayB.textContent = spleen;
if (fullness != 0) {
moxTextNode.parentNode.parentNode.parentNode.appendChild(fullnessDisplayTR);
}
if (spleen != 0) {
moxTextNode.parentNode.parentNode.parentNode.appendChild(spleenDisplayTR);
}
}
}
else {
var charName = GM_getValue('curCharName','UNDEFINED');
var drunkenness = GM_getValue(charName + '.drunkenness','UNDEFINED');
}
var t,curDateString;
//Get date from chat launch pane.
//If rollover has passed since the script last ran, reset fullness and spleen.
if (window.location.pathname == "/chatlaunch.php") {
var dateParentNode,dateParentNode2;
centeredTextNodes = document.evaluate("//center//text()",document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null);
for (var i=0;i<centeredTextNodes.snapshotLength;i++) {
if (centeredTextNodes.snapshotItem(i).data.match("^Today's KoL date is ")) {
dateParentNode = centeredTextNodes.snapshotItem(i).parentNode;
break;
}
else if (centeredTextNodes.snapshotItem(i).data.match("Today is:")) {
dateParentNode2 = centeredTextNodes.snapshotItem(i).parentNode;
break;
}
}
if(dateParentNode) {
curDateString = dateParentNode.getElementsByTagName('b')[0].textContent;
}
else if (dateParentNode2) {
curDateString = dateParentNode2.lastChild.textContent;
}
else {
alert("Can't find date parent node. Consumption manager won't work right.");
}
curDateString = curDateString.replace(/\s/,'');
t = window.setInterval(ChatLaunchFunction,100);
return false;
}
//If the character name is undefined, exit and wait for the script to run on the character pane first
if (charName == 'UNDEFINED') {
return false;
}
//Check if the script has been run before. If not, set all preferences to defaults.
var overdrunk = GM_getValue(charName + '.overdrunk','UNDEFINED');
if (overdrunk == 'UNDEFINED') {
overdrunk = 15;
GM_setValue(charName + '.overdrunk',overdrunk);
}
//Configs new in 2.5
var overfull = GM_getValue(charName + '.overfull','UNDEFINED');
var overspleen = GM_getValue(charName + '.overspleen','UNDEFINED');
if (overfull=='UNDEFINED') {
overfull = 16;
GM_setValue(charName + '.overfull',overfull);
}
if (overspleen=='UNDEFINED') {
overspleen = 16;
GM_setValue(charName + '.overspleen',overspleen);
}
//Account page - create an element to let the user set their overdrunk threshold
if (window.location.pathname == "/account.php") {
//title bar
var titleBar = document.createElement('div');
with (titleBar) {
appendChild(document.createTextNode('Consumption Management'));
style.padding = "1px 0 1px 0";
style.textAlign = "center";
style.color = "white";
style.backgroundColor = "blue";
style.fontWeight = "bold";
}
//create form
var optionsForm = document.createElement('form');
optionsForm.style.textAlign = 'center';
//create text input for overdrunk level
var textInput = document.createElement('input');
with(textInput) {
setAttribute("type","text");
setAttribute("value",overdrunk);
setAttribute("name","overdrunk");
style.width='15%';
}
//create button to save overdrunk level
var saveButton = document.createElement('input');
with (saveButton) {
setAttribute("class","button");
setAttribute("type","button");
setAttribute("value","Save");
addEventListener('click',function(event) {
overdrunk = parseInt(this.previousSibling.value);
GM_setValue(charName + '.overdrunk',overdrunk);
},false);
}
//Create dropdown to select inventory sorting type.
var sortSelect = document.createElement('select');
var sortOptionAlpha = document.createElement('option');
with(sortOptionAlpha) {
value = 1;
appendChild(document.createTextNode('Alphabetical'));
if (invSortOrder == 'alpha') {
selected = 'true';
}
}
var sortOptionTotalAdv = document.createElement('option');
with(sortOptionTotalAdv) {
value = 2;
appendChild(document.createTextNode('Average Adv Gain (Total)'));
if (invSortOrder == 'totalAdv') {
selected = 'true';
}
}
var sortOptionPerAdv = document.createElement('option');
with(sortOptionPerAdv) {
value = 3;
appendChild(document.createTextNode('Average Adv Gain (Per Fullness/Drunkenness)'));
if (invSortOrder == 'perAdv') {
selected = 'true';
}
}
sortSelect.appendChild(sortOptionAlpha);
sortSelect.appendChild(sortOptionTotalAdv);
sortSelect.appendChild(sortOptionPerAdv);
sortSelect.addEventListener('change',function(event) {
var newTarget = this.selectedIndex;
if (newTarget == 0) {
invSortOrder = 'alpha';
}
else if (newTarget == 1) {
invSortOrder = 'totalAdv';
}
else if (newTarget == 2) {
invSortOrder = 'perAdv';
}
GM_setValue('invSortOrder',invSortOrder);
},false);
//Create a nice table to hold the options
var optTab = document.createElement('table');
var optTr1 = document.createElement('tr');
var optTr2 = document.createElement('tr');
var optTd1 = document.createElement('td');
var optTd2 = document.createElement('td');
var optCenter1 = document.createElement('center');
var optCenter2 = document.createElement('center');
optCenter1.appendChild(document.createTextNode('How drunk is too drunk? '));
optCenter1.appendChild(textInput);
optCenter1.appendChild(saveButton);
optTd1.appendChild(optCenter1);
optTr1.appendChild(optTd1);
optCenter2.appendChild(document.createTextNode('Sorting of consumables on inventory page '));
optCenter2.appendChild(sortSelect);
optTd2.appendChild(optCenter2);
optTr2.appendChild(optTd2);
optTab.appendChild(optTr1);
optTab.appendChild(optTr2);
//add stuff to form
with(optionsForm) {
appendChild(optTab);
}
wrapper = document.createElement('div');
with(wrapper) {
style.width = '95%';
style.border = 'thin solid blue';
appendChild(titleBar);
appendChild(optionsForm);
}
var loc = document.getElementsByTagName('center')[2];
if(loc.lastChild.textContent.indexOf("This account will") != 0)var loc = document.getElementsByTagName('center')[3];
loc.insertBefore(wrapper,loc.lastChild);
}
//Reset thresholds upon ascension
if (window.location.pathname == "/valhalla.php") {
GM_setValue(charName + '.overdrunk',15);
GM_setValue(charName + '.overfull',16);
GM_setValue(charName + '.overspleen',16);
GM_setValue(charName + '.fullness',0);
GM_setValue(charName + '.spleen',0);
}
//Cafe page - Detect buying the standard drinks/foods and daily specials
if (window.location.pathname == "/cafe.php") {
if (window.location.search) {
var cafeid = parseInt(window.location.search.split("cafeid=")[1].split("&")[0]);
}
else {
//submitting the form without selecting a drink takes you to cafe.php...without the parameters.
breweryNode = document.evaluate('//b[.="The Gnomish Micromicrobrewery"]',document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
if (breweryNode) {
cafeid=2;
}
else {
chezNode = document.evaluate('//b[.="Chez Snootée"]',document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
if (chezNode) {
cafeid=1;
}
}
}
var consumeType,whichItemSelected,consumeAmount,consumeTypeText;
var cafeForm = document.evaluate('//form[@action="cafe.php"]',document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
var originalSubmitButton = document.evaluate('//form[@action="cafe.php"]//input[@class="button" and @type="submit"]',document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
var radioButtons = document.evaluate('//form[@action="cafe.php"]//input[@type="radio" and @name="whichitem"]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
//detects only the node that gets checked
for(var i=0;i<radioButtons.snapshotLength;i++) {
radioButtons.snapshotItem(i).addEventListener('change',function() {
if (this.checked) {
whichItemSelected = parseInt(this.value);
//NPC-only items
if(whichItemSelected < 0) {
whichItemSelected = whichItemSelected.toString().replace('-','neg');
if(cafeid == 1) {
whichItemSelected += 'f';
}
else if (cafeid == 2) {
whichItemSelected += 'b';
}
else {
tempConsumption = HowMuchConsumption(whichItemSelected + 'f');
if(tempConsumption != 999) {
whichItemSelected += 'f';
}
else {
whichItemSelected += 'b';
}
}
consumeType = ConsumptionType(whichItemSelected);
consumeTypeText = GetConsumptionText('',consumeType).toLowerCase().replace(':','');
consumeAmount = HowMuchConsumption(whichItemSelected);
}
else {
consumeType = ConsumptionType(whichItemSelected);
consumeTypeText = GetConsumptionText('',consumeType).toLowerCase().replace(':','');
consumeAmount = HowMuchConsumption(whichItemSelected);
}
if((consumeAmount != 999)&&(consumeType != 'unknown')) {
originalSubmitButton.value = 'Order ('+consumeAmount+' '+consumeTypeText+')';
}
else {
originalSubmitButton.value = 'Order (unknown item)';
}
}
},false);
}
originalSubmitButton.type = 'button';
originalSubmitButton.addEventListener('click',function() {
if(whichItemSelected) {
//if spleen or fullness type, just add that amount and submit.
//if booze, then special protection ensues.
if (ConsumptionType(whichItemSelected)=='spleen') {
AddSpleen(whichItemSelected);
cafeForm.submit();
}
else if (ConsumptionType(whichItemSelected)=='food') {
AddFullness(whichItemSelected);
cafeForm.submit();
}
else if (ConsumptionType(whichItemSelected)=='booze') {
//Overdrink protection
drunkenness = GM_getValue(charName + '.drunkenness');
overdrunk = GM_getValue(charName + '.overdrunk');
if ((drunkenness + consumeAmount) >= overdrunk) {
if (originalSubmitButton.value != 'Order (overdrink)') {
alert("This drink will cause you to overdrink");
originalSubmitButton.value = 'Order (overdrink)';
}
else {
GM_setValue(charName + '.drunkenness',(drunkenness + consumeAmount));
cafeForm.submit();
}
}
else {
cafeForm.submit();
}
}
else {
cafeForm.submit();
}
}
else {
cafeForm.submit();
}
},false);
}
//All other pages - Replace drinking,eating,spleen using links with a link that calls the event listener functions. Also display amounts of usage in each link.
if ((window.location.pathname != "/charpane.php")&&(window.location.pathname != "/chatlaunch.php")&&(window.location.pathname != "/account.php")&&(window.location.pathname != "/valhalla.php")&&(window.location.pathname != "/cafe.php")&&(window.location.pathname != "/login.php")) {
//if (window.location.pathname == "/inventory.php") {
var drinkLinks = document.evaluate('//a[contains(@href,"inv_booze.php") and contains(@href,"&which=1")]',document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null);
var foodLinks = document.evaluate('//a[contains(@href,"inv_eat.php") and contains(@href,"&which=1")]',document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null);
var spleenLinks = document.evaluate('//a[contains(@href,"inv_use.php") and contains(@href,"&which=1")]',document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null);
//variables used for re-sorting categories of items in the inventory
var drinkNodeArray = new Array();
var foodNodeArray = new Array();
var spleenNodeArray = new Array();
//Drink link management
for (var i=0;i<drinkLinks.snapshotLength;i++) {
node = drinkLinks.snapshotItem(i);
node.style.visibility = "hidden";
ChangeTextContent(node,"[overdrink]");
var whichDrink = parseInt(node.href.split("&whichitem=")[1].split("&")[0]);
var drinkDrunkenness = HowMuchConsumption(whichDrink);
var newDrinkNode = document.createElement('a');
with (newDrinkNode) {
if (drinkDrunkenness == 999) {
ChangeTextContent(newDrinkNode,'[drink]');
}
else {
ChangeTextContent(newDrinkNode,'[drink (' + drinkDrunkenness + ')]');
}
addEventListener('click',OverdrinkProtect,false);
href = 'javascript:void(0)';
}
node.parentNode.insertBefore(newDrinkNode,node);
//Add to the array, for possible re-sorting
if (window.location.pathname == "/inventory.php") {
drinkNodeArray[i] = new Object();
drinkNodeArray[i].node = document.evaluate('./ancestor::td[1]',node,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
drinkNodeArray[i].imgNode = drinkNodeArray[i].node.previousSibling;
drinkNodeArray[i].adv = getAdventures(whichDrink);
drinkNodeArray[i].advPer = ((drinkDrunkenness == 999)||(drinkDrunkenness == 0))?0:(drinkNodeArray[i].adv / parseFloat(drinkDrunkenness));
drinkNodeArray[i].name = drinkNodeArray[i].node.firstChild.textContent;
}
//Update overdrunk threshold on steel margarita consumption
if (whichDrink == 2743) {
node.addEventListener('click',function() {
GM_setValue(charName + '.overdrunk',20);
},false);
}
}
//Eat link management
for (var i=0;i<foodLinks.snapshotLength;i++) {
node = foodLinks.snapshotItem(i);
var whichFood = parseInt(node.href.split("&whichitem=")[1].split("&")[0]);
var foodConsumption = HowMuchConsumption(whichFood);
if (foodConsumption != 999) {
ChangeTextContent(node,node.textContent.split(']')[0] + ' (' + foodConsumption + ')]');
}
node.addEventListener('click',AddFullness,false);
//Add to the array, for possible re-sorting
if (window.location.pathname == "/inventory.php") {
foodNodeArray[i] = new Object();
foodNodeArray[i].node = document.evaluate('./ancestor::td[1]',node,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
foodNodeArray[i].imgNode = foodNodeArray[i].node.previousSibling;
foodNodeArray[i].adv = getAdventures(whichFood);
foodNodeArray[i].advPer = foodNodeArray[i].adv / parseFloat(foodConsumption);
foodNodeArray[i].name = foodNodeArray[i].node.firstChild.textContent;
}
}
//Use link management (spleen)
for (var i=0;i<spleenLinks.snapshotLength;i++) {
node = spleenLinks.snapshotItem(i);
var whichSpleen = parseInt(node.href.split("&whichitem=")[1].split("&")[0]);
var spleenConsumption = HowMuchConsumption(whichSpleen);
if((spleenConsumption != 999) && (IsSpleen(whichSpleen))) {
ChangeTextContent(node,node.textContent.split(']')[0] + ' (' + spleenConsumption + ')]');
}
node.addEventListener('click',AddSpleen,false);
//Add to the array, for possible re-sorting
//if (window.location.pathname == "/inventory.php") {
// spleenNodeArray[i] = new Object();
// spleenNodeArray[i].node = document.evaluate('./ancestor::td[1]',node,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
// spleenNodeArray[i].imgNode = spleenNodeArray[i].node.previousSibling;
// spleenNodeArray[i].adv = getAdventures(whichSpleen);
//}
}
//TODO - HANDLE MULTI-USE OF SPLEEN ITEMS HERE
//form action=multiuse.php
//official multi-use page has a select[@name="whichitem"] with options underneath where value = item#
//Mr. Script and possibly other scripts use an input[@type="hidden" and @name="whichitem"] and value= item#
//both types use standard submit buttons
//both types use an input[@type="text" and @name="quantity"] where the value is the number to use
//
//Add an event listener to the submit button which adds the specified amount * the amount per item
//Processes only the first multi-use form on a page because it is easier that way and there are unlikely to be more
multiUseForm = document.evaluate('//form[@action="multiuse.php"]',document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
if (multiUseForm) {
multiSubmit = document.evaluate('.//input[@class="button" and @type="submit"]',multiUseForm,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
numInput = document.evaluate('.//input[@type="text" and @name="quantity"]',multiUseForm,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
var whichItem;
if (numInput && multiSubmit) {
//handling of the official multi-use form and and other multi-use forms using a select
selectNode = document.evaluate('.//select[@name="whichitem"]',multiUseForm,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
if (selectNode) {
if(selectNode.selectedIndex) {
whichItem = selectNode.options[selectNode.selectedIndex].value;
if(IsSpleen(whichItem)) {
multiSubmit.value = 'Use (' + HowMuchConsumption(whichItem) + ' ' + GetConsumptionText('','spleen').toLowerCase().replace(':','') + ' each)';
}
}
selectNode.addEventListener('change',function() {
if(this.selectedIndex) {
whichItem = this.options[this.selectedIndex].value;
if(IsSpleen(whichItem)) {
multiSubmit.value = 'Use (' + HowMuchConsumption(whichItem) + ' ' + GetConsumptionText('','spleen').toLowerCase().replace(':','') + ' each)';
}
else {
multiSubmit.value = 'Use';
}
}
},false);
}
//handling of various multi-use boxes added by Mr. Script and probably other scripts
else {
hiddenInput = document.evaluate('.//input[@type="hidden" and @name="whichitem"]',multiUseForm,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
if (hiddenInput) {
whichItem = hiddenInput.value;
if(IsSpleen(whichItem)) {
multiSubmit.value = 'Use (' + HowMuchConsumption(whichItem) + ' ' + GetConsumptionText('','spleen').toLowerCase().replace(':','') + ' each)';
}
}
}
//event listener on the submit button adds the appropriate amount
multiSubmit.addEventListener('click',function() {
if (IsSpleen(whichItem)) {
usedNum = parseInt(numInput.value);
if (usedNum > 0) {
AddConstSpleen((usedNum * HowMuchConsumption(whichItem)));
}
}
},false);
}
}
//Add dropdown to select inventory sorting order
if (window.location.search.match("which=1")) {
var sortSelectTr = document.createElement('tr');
var sortSelectTd = document.createElement('td');
sortSelectTd.innerHTML = '<center>Food/Booze sort order:<select id="sortSelect"><option value="1"' + ((invSortOrder == 'alpha')?' selected="true">':'>')
+ 'Alphabetical</option><option value="2"' + ((invSortOrder == 'totalAdv')?' selected="true">':'>')
+ 'Average Adventure Gain (Total)</option><option value="3"' + ((invSortOrder == 'perAdv')?' selected="true">':'>')
+ 'Average Adventure Gain (Per Fullness/Drunkenness)</option></select></center>';
sortSelectTd.setAttribute('colspan','4');
sortSelectTr.appendChild(sortSelectTd);
var sortSelectTrParent = document.evaluate('//div[@id="section1"]//table//tbody',document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
if (sortSelectTrParent && sortSelectTrParent.firstChild) {
sortSelectTrParent.insertBefore(sortSelectTr,sortSelectTrParent.firstChild);
}
var sortSelect = document.getElementById('sortSelect');
sortSelect.addEventListener('change',function(event) {
var newTarget = this.selectedIndex;
var prevSortOrder = invSortOrder;
if (newTarget == 0) {
invSortOrder = 'alpha';
}
else if (newTarget == 1) {
invSortOrder = 'totalAdv';
}
else if (newTarget == 2) {
invSortOrder = 'perAdv';
}
GM_setValue('invSortOrder',invSortOrder);
if (prevSortOrder != invSortOrder) {
SortInv(foodNodeArray,drinkNodeArray);
}
},false);
if(invSortOrder != 'alpha') {
SortInv(foodNodeArray,drinkNodeArray);
}
}
}
//This event listener function is where all the magic happens.
function OverdrinkProtect() {
//Get new values for drunkenness and overdrunk, since they might have changed
drunkenness = GM_getValue(charName + '.drunkenness');
overdrunk = GM_getValue(charName + '.overdrunk');
var drinkHref = this.nextSibling.href;
var whichDrink = parseInt(drinkHref.split("&whichitem=")[1].split("&")[0]);
var drinkDrunkenness = HowMuchConsumption(whichDrink);
if (drinkDrunkenness == 999) {
alert("Unknown drink. Drink at your own risk.");
this.nextSibling.style.visibility = 'visible';
ChangeTextContent(this.nextSibling,"[overdrink?]");
this.removeEventListener("click",OverdrinkProtect,false);
this.parentNode.removeChild(this);
}
else if((drunkenness + drinkDrunkenness) >= overdrunk) {
alert("This drink will cause you to overdrink.");
this.nextSibling.style.visibility = 'visible';
this.removeEventListener("click",OverdrinkProtect,false);
this.parentNode.removeChild(this);
}
else {
//Since we know we're exiting the page, clean up event listeners
var drinkLinks = document.evaluate('//a[contains(@href,"javascript:void(0)")]',document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null);
for (var i=0;i<drinkLinks.snapshotLength;i++) {
drinkLinks.snapshotItem(i).removeEventListener("click",OverdrinkProtect,false);
}
//redirect to the actual drinking
GM_setValue(charName + '.drunkenness',(drunkenness + drinkDrunkenness));
window.location.href = drinkHref;
}
}
//Callback to add fullness when you eat
function AddFullness(itemID) {
if ((itemID==undefined)||(typeof itemID=='object')) {
whichFood = parseInt(this.href.split("&whichitem=")[1].split("&")[0]);
}
else {
whichFood = itemID;
}
addFullness = HowMuchConsumption(whichFood);
if (addFullness != 999) {
var curFullness = GM_getValue(charName + '.fullness');
if ((parseInt(curFullness) + parseInt(addFullness)) < overfull) {
GM_setValue(charName + '.fullness',parseInt(curFullness) + parseInt(addFullness));
if (whichFood == 2742) {
overfull = 21;
GM_setValue(charName + '.overfull',overfull);
}
}
}
}
//Callback to add spleen
function AddSpleen(itemID) {
if ((itemID==undefined)||(typeof itemID=='object')) {
whichSpleen = parseInt(this.href.split("&whichitem=")[1].split("&")[0]);
}
else {
whichSpleen = itemID;
}
addSpleen = HowMuchConsumption(whichSpleen);
if (addSpleen != 999) {
var curSpleen = GM_getValue(charName + '.spleen');
if ((parseInt(curSpleen) + parseInt(addSpleen)) < overspleen) {
GM_setValue(charName + '.spleen',parseInt(curSpleen) + parseInt(addSpleen));
if (whichSpleen == 2744) {
overspleen = 21;
GM_setValue(charName + '.overspleen',overspleen);
}
}
}
}
//Add a specific number of spleen instead of passing itemID
function AddConstSpleen(numSpleen) {
var curSpleen = GM_getValue(charName + '.spleen');
if ((parseInt(curSpleen) + parseInt(numSpleen)) < overspleen) {
GM_setValue(charName + '.spleen',parseInt(curSpleen) + parseInt(numSpleen));
}
}
//Function to generate appropriate random spleen text, given the mox text (to know whether it's compact)
function GetSpleenText(moxText) {
textArray = GM_getValue('spleenText').split(',');
if(moxText == 'Mox:') {
return (textArray[0] + ':');
}
else {
return (textArray[rand(textArray.length - 1)] + ':');
}
}
//Function to generate appropriate random fullness text, given the mox text (to know whether it's compact)
function GetFullnessText(moxText) {
textArray = GM_getValue('fullnessText').split(',');
if(moxText == 'Mox:') {
return (textArray[0] + ':');
}
else {
return (textArray[rand(textArray.length - 1)] + ':');
}
}
//functions a little differently since it is never added to the charpane
function GetDrunkText() {
textArray = GM_getValue('drunkText').split(',');
return (textArray[rand(textArray.length - 1)]);
}
function GetConsumptionText(moxText,consumeType) {
switch(consumeType) {
case 'booze':return GetDrunkText();break;
case 'food':return GetFullnessText(moxText);break;
case 'spleen':return GetSpleenText(moxText);break;
}
return 'unknown';
}
//Callback to re-check fullness/spleen on charpane
function CharPaneTimeout() {
var curDate = GM_getValue('curDate','');
var fullness = GM_getValue(charName + '.fullness');
var spleen = GM_getValue(charName + '.spleen');
if ((curDate == '') || (fullness == 0)) {
fullnessDisplayTR.parentNode.removeChild(fullnessDisplayTR);
}
else {
fullnessDisplayTR.lastChild.firstChild.textContent = fullness;
}
if ((curDate == '') || (spleen == 0)) {
spleenDisplayTR.parentNode.removeChild(spleenDisplayTR);
}
else {
spleenDisplayTR.lastChild.firstChild.textContent = spleen;
}
}
function ChatLaunchFunction() {
//alert("chat launch function triggered");
charName = GM_getValue('curCharName','UNDEFINED');
if (charName == 'UNDEFINED') {
return false;
}
else {
var storedDate = GM_getValue(charName + '.storedDate','');
if(storedDate != curDateString) {
//alert("resetting variables\ncurDateString:"+curDateString+"\nstoredDate:"+storedDate
// +"\nlengths:"+curDateString.length+ " " +storedDate.length);
GM_setValue(charName + '.fullness',0);
GM_setValue(charName + '.spleen',0);
GM_setValue(charName + '.storedDate',curDateString);
GM_setValue('curDate',curDateString);
}
else if (curDateString != GM_getValue('curDate','')) {
//alert("setting curDate from null, value:"+curDateString);
GM_setValue('curDate',curDateString);
}
clearInterval(t);
}
}
//Returns 999 if unknown, or drunkenness/fullness/spleen
function HowMuchConsumption (itemid) {
if (itemdb.items[itemid]) {
return parseInt(itemdb.items[itemid].limiter);
}
else {
return 999;
}
}
//Returns average adventure gain from the item
//TODO when itemdb is updated properly
function getAdventures(itemid) {
if (itemdb.items[itemid]) {
return parseFloat(itemdb.items[itemid].adv);
}
else {
return 999;
}
}
//Returns whether an item is a spleen item (some non-spleen items have use links)
function IsSpleen (itemid) {
if ((itemdb.items[itemid]) && (itemdb.items[itemid].type == "spleen")) {
return true;
}
return false;
}
function ConsumptionType (itemid) {
if (itemdb.items[itemid]) {
return itemdb.items[itemid].type;
}
else {
return 'unknown';
}
}
//wrapper function to account for the fact that sometimes the font tags are outside and sometimes inside
//should be called from a node
function ChangeTextContent(node,text) {
fontChildren = node.getElementsByTagName('font');
if(fontChildren.length > 0) {
fontChildren[0].textContent = text;
}
else {
node.textContent = text;
}
}
function updatedb(){
var lastupdated = GM_getValue('lastUpdate',0);
var version = GM_getValue('version',0);
var now = (new Date()).getTime()/1000; //make unix timestamp
if( (now - lastupdated) > 60*60*24 ){ //have we checked today?
GM_get(ITEMDB_URL+'&version='+version,function(response){
if(response!=''){
//we get here if our version is not current
GM_setValue('itemdb',response);
if(m=(/"version":"(\d+)"/).exec(response)){
GM_setValue('version',m[1]);
}
}
});
x=Math.floor((new Date()).getTime()/1000);
GM_setValue('lastUpdate',x);
}
}
function getdb(){
//Simple function to load itemdb from config and return as an object
var tmp = GM_getValue('itemdb','');
if(tmp!=''){
var itemdb = eval('('+tmp+')');
return itemdb;
}else{
return false;
}
}
function GM_get(dest, callback)
{ GM_xmlhttpRequest({
method: 'GET',
url: dest,
//onerror:function(error) { GM_log("GM_get Error: " + error); },
onload:function(details) {
if( typeof(callback)=='function' ){
callback(details.responseText);
} } }); }
function rand ( n )
{
return ( Math.floor ( Math.random ( ) * n + 1 ) );
}
function TotalAdvSort (a,b) {
if ((!a.adv)||(a.adv==999)) {
return 1;
}
else if ((!b.adv)||(b.adv==999)) {
return -1;
}
else {
return (b.adv - a.adv);
}
}
function PerAdvSort (a,b) {
if (!a.advPer) {
return 1;
}
else if (!b.advPer) {
return -1;
}
else {
return (b.advPer - a.advPer);
}
}
function AlphaSort(a,b) {
if(a.name.toLowerCase() < b.name.toLowerCase()) return -1;
else if (a.name == b.name) return 0;
else return 1;
}
//Version 2.5 - Code to re-sort the inventory sections in terms of adventures, if that option is enabled
function SortInv(foodNodeArray,drinkNodeArray) {
//Remove the inventory nodes from their parents
for (i=0;i<foodNodeArray.length;i++) {
foodNodeArray[i].node.parentNode.removeChild(foodNodeArray[i].node);
foodNodeArray[i].imgNode.parentNode.removeChild(foodNodeArray[i].imgNode);
}
for (i=0;i<drinkNodeArray.length;i++) {
drinkNodeArray[i].node.parentNode.removeChild(drinkNodeArray[i].node);
drinkNodeArray[i].imgNode.parentNode.removeChild(drinkNodeArray[i].imgNode);
}
if (invSortOrder == 'totalAdv') {
foodNodeArray.sort(TotalAdvSort);
drinkNodeArray.sort(TotalAdvSort);
}
else if (invSortOrder == 'perAdv') {
foodNodeArray.sort(PerAdvSort);
drinkNodeArray.sort(PerAdvSort);
}
else if (invSortOrder == 'alpha') {
foodNodeArray.sort(AlphaSort);
drinkNodeArray.sort(AlphaSort);
}
//Re-sort the arrays
var foodParents = document.evaluate('//div[@id="section1"]//tr',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
var drinkParents = document.evaluate('//div[@id="section2"]//tr',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
//Re-add the food in the new order
for (i=1;i<foodParents.snapshotLength;i++) {
curParent = foodParents.snapshotItem(i);
if(foodNodeArray[2*(i-1)]) {
curParent.appendChild(foodNodeArray[2*(i-1)].imgNode);
curParent.appendChild(foodNodeArray[2*(i-1)].node);
}
if(foodNodeArray[(2*(i-1))+1]) {
curParent.appendChild(foodNodeArray[(2*(i-1))+1].imgNode);
curParent.appendChild(foodNodeArray[(2*(i-1))+1].node);
}
}
//Re-add the booze in the new order
for (i=0;i<drinkParents.snapshotLength;i++) {
curParent = drinkParents.snapshotItem(i);
if(drinkNodeArray[2*i]) {
curParent.appendChild(drinkNodeArray[2*i].imgNode);
curParent.appendChild(drinkNodeArray[2*i].node);
}
if(drinkNodeArray[(2*i)+1]) {
curParent.appendChild(drinkNodeArray[(2*i)+1].imgNode);
curParent.appendChild(drinkNodeArray[(2*i)+1].node);
}
}
}