StillAlive

By Rick Scott Last update Apr 9, 2009 — Installed 152 times. Daily Installs: 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 2, 1, 2, 0, 0, 0, 5, 2, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1

There are 9 previous versions of this script.

// ==UserScript==
// @name           StillAlive
// @namespace      DoorbellsDingDong
// @description    Makes the Still better
// @include        *.kingdomofloathing.com/guild*
// @include        *127.0.0.1:*/guild*
// ==/UserScript==


var AllDrinks;
var AllMixers;
var AllGarnishes;

Init();



function Init()
{
  var CalcuttaEmerald = { Name: "bottle of Calcutta Emerald", Improved: null, Id: 0, AvailableQuantity: 0, CurrentQuantity: 0};
  var Definit = { Name: "bottle of Definit", Improved: null, Id: 0, AvailableQuantity: 0, CurrentQuantity: 0 };
  var LieutenantFreeman = { Name: "bottle of Lieutenant Freeman", Improved: null, Id: 0, AvailableQuantity: 0, CurrentQuantity: 0 };
  var DomesticatedTurkey = { Name: "bottle of Domesticated Turkey", Improved: null, Id: 0, AvailableQuantity: 0, CurrentQuantity: 0 };
  var JorgeSinsonte = { Name: "bottle of Jorge Sinsonte", Improved: null, Id: 0, AvailableQuantity: 0, CurrentQuantity: 0 };
  var BoxedChampagne = { Name: "boxed champagne", Improved: null, Id: 0, AvailableQuantity: 0, CurrentQuantity: 0 };

  var Gin = { Name: "bottle of gin", Improved: CalcuttaEmerald, Id: 237, AvailableQuantity: 0, CurrentQuantity: 0 };
  var Vodka = { Name: "bottle of vodka", Improved: Definit, Id: 238, AvailableQuantity: 0, CurrentQuantity: 0 };
  var Rum = { Name: "bottle of rum", Improved: LieutenantFreeman, Id: 787, AvailableQuantity: 0, CurrentQuantity: 0 };
  var Whiskey = { Name: "bottle of whiskey", Improved: DomesticatedTurkey, Id: 328, AvailableQuantity: 0, CurrentQuantity: 0 };
  var Tequila = { Name: "bottle of tequila", Improved: JorgeSinsonte, Id: 1004, AvailableQuantity: 0, CurrentQuantity: 0 };
  var Wine = { Name: "boxed wine", Improved: BoxedChampagne, Id: 1005, AvailableQuantity: 0, CurrentQuantity: 0 };

  var CocktailOnion = { Name: "cocktail onion", Improved: null, Id: 0, AvailableQuantity: 0, CurrentQuantity: 0 };
  var Tangerine = { Name: "tangerine", Improved: null, Id: 0, AvailableQuantity: 0, CurrentQuantity: 0 };
  var Kumquat = { Name: "kumquat", Improved: null, Id: 0, AvailableQuantity: 0, CurrentQuantity: 0 };
  var Kiwi = { Name: "kiwi", Improved: null, Id: 0, AvailableQuantity: 0, CurrentQuantity: 0 };
  var Raspberry = { Name: "raspberry", Improved: null, Id: 0, AvailableQuantity: 0, CurrentQuantity: 0 };
  var TonicWater = { Name: "tonic water", Improved: null, Id: 0, AvailableQuantity: 0, CurrentQuantity: 0 };

  var Olive = { Name: "olive", Improved: CocktailOnion, Id: 245, AvailableQuantity: 0, CurrentQuantity: 0 };
  var Grapefruit = { Name: "grapefruit", Improved: Tangerine, Id: 243, AvailableQuantity: 0, CurrentQuantity: 0 };
  var Orange = { Name: "orange", Improved: Kumquat, Id: 242, AvailableQuantity: 0, CurrentQuantity: 0 };
  var Lemon = { Name: "lemon", Improved: Kiwi, Id: 332, AvailableQuantity: 0, CurrentQuantity: 0 };
  var Strawberry = { Name: "strawberry", Improved: Raspberry, Id: 786, AvailableQuantity: 0, CurrentQuantity: 0 };
  var SodaWater = { Name: "soda water", Improved: TonicWater, Id: 1003, AvailableQuantity: 0, CurrentQuantity: 0 };

  var CoconutShell = { Name: "coconut shell", Improved: null, Id: 1007, AvailableQuantity: 0, CurrentQuantity: 0 };
  var MagicalIceCubes = { Name: "magical ice cubes", Improved: null, Id: 1008, AvailableQuantity: 0, CurrentQuantity: 0 };
  var LittlePaperUmbrella = { Name: "little paper umbrella", Improved: null, Id: 635, AvailableQuantity: 0, CurrentQuantity: 0 };
  
  var Neuromancer = { Name: "Neuromancer", Booze: CalcuttaEmerald, Mixer: CocktailOnion, Garnish: CoconutShell, Color:"#DDCCAA" };
  var VodkaStratocaster = {Name: "vodka stratocaster", Booze: Definit, Mixer: CocktailOnion, Garnish: CoconutShell, Color:"#DDCCAA" };
  var MonTiki = {Name: "Mon Tiki", Booze: LieutenantFreeman, Mixer: Kiwi, Garnish: CoconutShell, Color:"#FFAAAA" };
  var TeqiwilaSlammer = {Name: "teqiwila slammer", Booze: JorgeSinsonte, Mixer: Kiwi, Garnish: CoconutShell, Color:"#FFAAAA" };
  var Divine = {Name: "Divine", Booze: DomesticatedTurkey, Mixer: Kumquat, Garnish: LittlePaperUmbrella, Color:"#CCAADD" };
  var GordonBennett = {Name: "Gordon Bennett", Booze: BoxedChampagne, Mixer: Kumquat, Garnish: LittlePaperUmbrella, Color:"#CCAADD" };
  var Gimlet = {Name: "gimlet", Booze: CalcuttaEmerald, Mixer: TonicWater, Garnish: LittlePaperUmbrella, Color:"#AAAAFF" };
  var YellowBrickRoad = {Name: "yellow brick road", Booze: Definit, Mixer: TonicWater, Garnish: LittlePaperUmbrella, Color:"#AAAAFF" };
  var MandarinaColada = {Name: "mandarina colada", Booze: LieutenantFreeman, Mixer: Tangerine, Garnish: MagicalIceCubes, Color:"#AADDCC" };
  var Tangarita = {Name: "tangarita", Booze: JorgeSinsonte, Mixer: Tangerine, Garnish: MagicalIceCubes, Color:"#AADDCC" };
  var MaeWest =  {Name: "Mae West", Booze: DomesticatedTurkey, Mixer: Raspberry, Garnish: MagicalIceCubes, Color:"#AAFFAA" };
  var PrussianCathouse =  {Name: "prussian cathouse", Booze: BoxedChampagne, Mixer: Raspberry, Garnish: MagicalIceCubes, Color:"#AAFFAA" };
  

  AllDrinks = [Gin, Vodka, Rum, Whiskey, Tequila, Wine, CalcuttaEmerald, Definit, LieutenantFreeman, DomesticatedTurkey, JorgeSinsonte, BoxedChampagne];
  AllMixers = [Olive, Grapefruit, Orange, Lemon, Strawberry, SodaWater, CocktailOnion, Tangerine, Kumquat, Kiwi, Raspberry, TonicWater];
  AllGarnishes = [CoconutShell, MagicalIceCubes, LittlePaperUmbrella];
  AllMakeables = [Neuromancer, VodkaStratocaster, MonTiki, TeqiwilaSlammer, Divine, GordonBennett, Gimlet, YellowBrickRoad, MandarinaColada, Tangarita, MaeWest, PrussianCathouse];
  
  for(var i=0; i<AllDrinks.length; ++i)
  {
    if(AllDrinks[i].Improved != null)
      AllDrinks[i].Improved.Base = AllDrinks[i];
  }
  
  for(var i=0; i<AllMixers.length; ++i)
  {
    if(AllMixers[i].Improved != null)
      AllMixers[i].Improved.Base = AllMixers[i];
  }


  GM_xmlhttpRequest({method:"GET", url:"http://" + window.location.host + "/craft.php?mode=cocktail", onload:Init2 });
}


function Init2(response)
{
  if(response.readyState != 4)
    return;

  // starting from the end of the list of all tables, get the one with the "stillfruit" keyword in it
  var aAllTables = document.getElementsByTagName("table");
  var eStillTable = null;
  for(var i=aAllTables.length - 1; i>0; --i)
  {
    if(aAllTables[i].innerHTML != null && aAllTables[i].innerHTML.indexOf("stillfruit") >= 0)
    {
      eStillTable = aAllTables[i];
      break;
    }
  }
  
  if(eStillTable == null)
  {
    // Could not find Still table in which to insert my love :(
    return;
  }

  var sCocktailCraftPageHtml = response.responseText;
  
  var bSuccess = false;
  for(var i=0; i<5; ++i)
  {
    if(GetQuantityFromPageHtml(sCocktailCraftPageHtml, AllDrinks) == true)
    {
      bSuccess = true;
      break;
    }
  }

  for(var i=0; i<5; ++i)
  {
    if(GetQuantityFromPageHtml(sCocktailCraftPageHtml, AllMixers) == true)
    {
      bSuccess = true;
      break;
    }
  }

  for(var i=0; i<5; ++i)
  {
    if(GetQuantityFromPageHtml(sCocktailCraftPageHtml, AllGarnishes) == true)
    {
      bSuccess = true;
      break;
    }
  }
  
  var tr = eStillTable.insertRow(eStillTable.rows.length);
  var tc = tr.insertCell(0);
  var sCellHtml = "<table><tr><th>Drinks</th><th>Mixers</th><th>Garnishes</th><th>Makeables</th></tr><tr style='font-size:8pt;'><td>";
  for(var i=0; i<AllDrinks.length; ++i)
  {
    if(AllDrinks[i].CurrentQuantity > 0)
      sCellHtml += AllDrinks[i].Name + " (" + AllDrinks[i].CurrentQuantity + ")<br>";
  }

  sCellHtml += "</td><td>";
  for(var i=0; i<AllMixers.length; ++i)
  {
    if(AllMixers[i].CurrentQuantity > 0)
      sCellHtml += AllMixers[i].Name + " (" + AllMixers[i].CurrentQuantity + ")<br>";
  }

  sCellHtml += "</td><td>";
  for(var i=0; i<AllGarnishes.length; ++i)
  {
    if(AllGarnishes[i].CurrentQuantity > 0)
      sCellHtml += AllGarnishes[i].Name + " (" + AllGarnishes[i].CurrentQuantity + ")<br>";
  }
  
  sCellHtml += "</td><td>";
  for(var i=0; i<AllMakeables.length; ++i)
  {
    sCellHtml += "<span style='background-color:" + AllMakeables[i].Color + "' title='";
    sCellHtml += AllMakeables[i].Booze.Name;
    if(AllMakeables[i].Booze.Base != null)
      sCellHtml += " (" + AllMakeables[i].Booze.Base.Name + ")";
    sCellHtml += " + " + AllMakeables[i].Mixer.Name;
    if(AllMakeables[i].Booze.Base != null)
      sCellHtml += " (" + AllMakeables[i].Mixer.Base.Name + ")";

    sCellHtml += " + " + AllMakeables[i].Garnish.Name;
    
    sCellHtml += "'>";
    var oBaseMixer = AllMakeables[i].Mixer;
    if(AllMakeables[i].Mixer.Base != null)
      oBaseMixer = AllMakeables[i].Mixer.Base;
    switch(ShortestMakeableMethod(AllMakeables[i]))
    {
      case 1: sCellHtml += "<b>" + AllMakeables[i].Name + "</b>"; break;
      case 2: sCellHtml += AllMakeables[i].Name + " (use still once)"; break;
      case 3: sCellHtml += AllMakeables[i].Name + " (use still twice)"; break;
      case 4: sCellHtml += AllMakeables[i].Name + " (buy " + oBaseMixer.Name + " and use still once)"; break;
      case 5: sCellHtml += AllMakeables[i].Name + " (buy " + oBaseMixer.Name + " and use still twice)"; break;
    }
    
    sCellHtml += "</span><br>";
  }
  
  sCellHtml += "</td></tr></table>";
  tc.innerHTML = sCellHtml;
}




// Takes a makeable concoction and returns a number representing the easiest method to create the makeable.
// 0 = cannot create
// 1 = creatable with currently available items
// 2 = creatable if the still is used once
// 3 = creatable if the still is used twice
// 4 = use the still once and buy the fruit
// 5 = use the still twice and by the fruit
function ShortestMakeableMethod(oMakeable)
{
  var iDrinkMethod = 0;
  for(var i=0; i<AllDrinks.length; ++i)
  {
    if(AllDrinks[i].CurrentQuantity < 1)
      continue;
      
    if(oMakeable.Booze == AllDrinks[i])
    {
      iDrinkMethod = 1;
      break;
    }
    else if(oMakeable.Booze == AllDrinks[i].Improved)
    {
      iDrinkMethod = 2;
    }
  }
  
  var iMixerMethod = 0;
  for(var i=0; i<AllMixers.length; ++i)
  {
    if(AllMixers[i].CurrentQuantity < 1)
      continue;
      
    if(oMakeable.Mixer == AllMixers[i])
    {
      iMixerMethod = 1;
      break;
    }
    else if(oMakeable.Mixer == AllMixers[i].Improved)
    {
      iMixerMethod = 2;
    }
  }
  
  var bHaveGarnish = false;
  for(var i=0; i<AllGarnishes.length; ++i)
  {
    if(AllGarnishes[i].CurrentQuantity < 1)
      continue;
      
    if(oMakeable.Garnish.Name == AllGarnishes[i].Name)
    {
      bHaveGarnish = true;
      break;
    }
  }
  
  //alert(oMakeable.Name + ": Drink=" + iDrinkMethod + ", Mix=" + iMixerMethod);
  
  if(bHaveGarnish == false || iDrinkMethod == 0)
    return 0;
  else if(iDrinkMethod == 2 && iMixerMethod == 2)
    return 3;
  else if( (iDrinkMethod == 2 && iMixerMethod == 1) || (iDrinkMethod == 1 && iMixerMethod == 2) )
    return 2;
  else if(iDrinkMethod == 1 && iMixerMethod == 0)
    return 4;
  else if(iDrinkMethod == 2 && iMixerMethod == 0)
    return 5;
  else
    return 1;
}


// This function takes the raw HTML of a page and scrapes it looking for items and their quantities
// The first param, sHtml, is just a big string that happens to be the HTML of a page.
// The second param, aItemArray is an array of objects. Each object should have a Name attribute (string) and a CurrentQuantity attribute (int)
// Assumptions: The quantity will be within 200 characters of the name of the item and will be of the form "(X)" where X is the quantity.
function GetQuantityFromPageHtml(sHtml, aItemArray)
{
  if(sHtml == null || sHtml.length < 1 || aItemArray == null || aItemArray.length < 1)
    return false;
    
  for(var i=0; i<aItemArray.length; ++i)
  {
    var iStartPos = sHtml.indexOf(aItemArray[i].Name);
    if(iStartPos < 0)
      continue;
    aItemArray[i].CurrentQuantity = parseInt(StringBetween(sHtml.substr(iStartPos, 200), "(", ")"), 10);
    
    // if we get insane numbers, pass that data back to the calling function so it can try again
    if(aItemArray[i].CurrentQuantity > 9999 || aItemArray[i].CurrentQuantity == NaN)
      return false;
  }
  
  return true;
}



// This function returns the string between 2 given characters.
// The first param, sInput, is the string to search
// The second param, sStart, is the start of the string you want. This string will NOT be included in the result
// The third param, sEnd, is the end of the string you want. This string will also NOT be included in the result
// Note: The function will only look for the first occurence of sStart, but will start at the END of that string to find sEnd.
// Example: StringBetween("ABC(2) DEF(3) GHI(4)", "DEF(", ")"); will return "3"
function StringBetween(sInput, sStart, sEnd)
{
  if(sInput == null)
    return null;
    
  var iStart = sInput.indexOf(sStart);
  if(iStart < 0)
    return null;
  
  iStart += sStart.length;

  if(sEnd != null)
  {
    var iEnd = sInput.indexOf(sEnd, iStart);
    if(iEnd < 0)
      return null;
    
    return sInput.substring(iStart, iEnd);
  }
  else
    return sInput.substring(iStart);
}