antimarty fortune cookie script

Kingdom of Loathing fortune cookie tracker

  1. // antimarty's fortune cookie script, based in part on:
  2. // csemaj's KoL Script
  3. // Copyright (c) 2007, James Cammarata
  4. // Based on code written by Byung Kim (Tard) http://kol.dashida.com and OneTonTomato's scripts
  5. // toggle preference code from lukifer's mrscript
  6. // http://www.noblesse-oblige.org/lukifer/scripts/
  7. // script update code based on DrEvi1's hatrack helper, which credits Picklish
  8. // fixes for lag combatting inventory screens by Firvagor
  9. // now using Charon's account options tab code
  10. // Released under the GPL license
  11. // http://www.gnu.org/copyleft/gpl.html
  12. //
  13. // ==UserScript==
  14. // @name antimarty fortune cookie script
  15. // @namespace antimarty
  16. // @include *kingdomofloathing.com/*.php*
  17. // @include *127.0.0.1:600*/*.php*
  18. // @include *localhost:600*/*.php*
  19. // @include localhost:18481/*.php*
  20. // @version 0.5.8
  21. // @grant GM_getValue
  22. // @grant GM_setValue
  23. // @grant GM_xmlhttpRequest
  24. //
  25. // @description Kingdom of Loathing fortune cookie tracker
  26. // ==/UserScript==
  27.  
  28. // released versions:
  29. // Version 0.5.7 - clan speakeasy, new topmenu frame rearrangement, gm grant stuff, move to Greasy Fork
  30. // Version 0.5.5 - kolhs semis; red fox; bram the stoker
  31. // Version 0.5.4 - new undersea SRs
  32. // Version 0.5.3 - new giant castle SRs, fix oxygenarian detection
  33. // Version 0.5.2 - updated for new level 8 and level 9 semis, and typo for friars
  34. // Version 0.5.1 - new hidden temple semi rare
  35. // Version 0.5.0 - add last location info to char pane if no popups
  36. // Version 0.4.9 - bug fix for deep fat friars' adventure name
  37. // Version 0.4.8 - bug fix for auto-attack combat macros, change version check
  38. // Version 0.4.7 - add disable popups option as FF4 workaround
  39. // Version 0.4.6 - bug fix for noncombat semis
  40. // Version 0.4.5 - Show initial bracket for new ascension, bug fix for puttied/faxed/arrow'd SR monsters
  41. // Version 0.4.4 - ascii, kge fights from fax/putty/camera/arrowing aren't semis; support new options page
  42. // Version 0.4.3 - add elf alley semi
  43. // Version 0.4.2 - add the pixel stopwatch
  44. // Version 0.4.1, use the turnsplayed native counter
  45. // Version 0.4.0, display a predicted cookie window if no cookie eaten
  46. // Version 0.3.9, support for billiards room semi
  47. // Version 0.3.8, sanity check numbers when user loads charsheet
  48. // Version 0.3.7, misc bug fixes
  49. // Version 0.3.6, fixes (courtesy Firvagor) for crimbo anti-lag changes to inventory screens; clear counter after semi-rare
  50. // Version 0.3.5, filter impossible cookie values; check for updates automatically
  51. // Version 0.3.4, support for hobopolis adventures
  52. // Version 0.3.3, bugfixes encore
  53. // Version 0.3.2, bugfixes
  54. // Version 0.3.1, bugfixes
  55. // Version 0.3.0, remember most recent semi-rare. Re-fix bugs re-introduced in 0.2.6
  56. // for unascended chars and compact mode, thanks to bad version control.
  57. // Version 0.2.6, reduced overhead, and bug fixes
  58. // Version 0.2.5, compact mode support and support for unascended chars
  59. // Version 0.2.3, improved sanity checker
  60. // Version 0.2.0, includes sanity checker
  61. // Version 0.1.1, bugfixes
  62. // Version 0.1.0 initial beta
  63.  
  64. // Known bugs:
  65. // doesn't work in the kolmafia relay browser if you have this option set:
  66. // [] Force results to reload inline for [use] links
  67. // ... because the results page never reloads, so greasemonkey scripts don't run
  68. // may not save data correctly if Firefox doesn't exit cleanly (Greasemonkey issue)
  69.  
  70. // basic logic to do this without retrieving character pane data:
  71. // - store an internal counter for adventures used
  72. // - look at the adventures remaining
  73. // - every time the pane is refreshed:
  74. // - if the remaining adventures decreases, decrease the counter by that amount
  75. // - if stays the same, do nothing
  76. // - if increases, do nothing
  77. // warn when hit zero
  78. //
  79. // read char sheet as a sanity check when the counter doesn't seem to be
  80. // decrementing normally
  81.  
  82. // (temporarily?) unused, with move to Greasy Fork
  83. /* var currentVersion = "0.5.7";
  84. var scriptSite = "http://userscripts.org/scripts/show/13180"
  85. // this is autogenerated by userscripts.org from Userscript @ comments above, use to reduce bandwidth on version check
  86. var scriptURL = "http://userscripts.org/scripts/source/13180.meta.js";
  87. */
  88. ////////////////////////////////////////////////////////////////////////////////
  89. // Based on a function taken from OneTonTomato's UpUp skill script
  90. function GM_get(target, callback) {
  91. GM_xmlhttpRequest({
  92. method: 'GET',
  93. url: target,
  94. onload:function(details) {
  95. if( typeof callback=='function' ){
  96. callback(details.responseText);
  97. }
  98. }
  99. });
  100. }
  101.  
  102. // Check version number of script on the web
  103. function CheckScriptVersion(data)
  104. {
  105. // alert("inside version check");
  106. // Preemptively set error, in case request fails...
  107. GM_setValue("webVersion", "Error")
  108.  
  109. var m = data.match(/@version\s*([0-9.]+)/);
  110. if (m) {
  111. GM_setValue("webVersion", m[1]);
  112. }
  113. }
  114.  
  115. ////////////////////////////////////////////////////////////////////////////////
  116. // parse the char pane for the player name
  117. // revised version! now taken directly from kolpreviousnadventures to handle compact mode
  118. function getPlayerNameFromCharpane() {
  119. var username = document.getElementsByTagName("b");
  120. if (!username || username.length < 1) return false;
  121. username = username[0];
  122. if (!username) return false;
  123. username = username.firstChild;
  124. if (!username) return false;
  125. // in full mode the link is <a><b>Name</b></a>
  126. // in compact mode it's <b><a>Name</a></b>
  127. // so have to handle this, and also can use it to tell
  128. // whether it's in compact mode or not.
  129. var fullmode = true;
  130. while (username && username.nodeType == 1)
  131. {
  132. username = username.firstChild;
  133. fullmode = false;
  134. }
  135. if (!username) return false;
  136. username = username.nodeValue;
  137. if (!username) return false;
  138. username = username.toLowerCase();
  139. // alert("found username " + username + ", fullmode: " + fullmode);
  140. return {'username': username, 'fullmode': fullmode};
  141. }
  142.  
  143. ////////////////////////////////////////////////////////////////////////////////
  144. // parse the char sheet (not the sidepane) for the player name
  145. function getPlayerNameFromCharsheet(data) {
  146. // it's an href with syntax something like
  147. // showplayer.php?who=PlayerID">PlayerName</a>
  148. var playerName = /showplayer\.php\?who\=\d+\">([^<]+)<\/a/i.exec(data); // sometimes this fails, don't know why
  149. if(playerName)
  150. return playerName[1].toLowerCase();
  151. else
  152. return null;
  153. }
  154.  
  155. ////////////////////////////////////////////////////////////////////////////////
  156. // parse the char sheet (not pane) for the total adventure count
  157. // taken from the csemaj cookie script
  158. // the "(this run)" only appears if you have ascended
  159. function getTurnsPlayed(data) {
  160. var turncount = "0";
  161. if(data.indexOf("Turns Played (this run)") >= 0) {
  162. // alert("parsing datasheet for turns for an ascended char");
  163. turncount = /Turns Played \(this run\)[^>]*>(<[^>]+>)*([\d,]+)/i.exec(data)[2];
  164. }
  165. else {
  166. // alert("parsing datasheet for turns for an UNascended char");
  167. turncount = /Turns Played[^>]*>(<[^>]+>)*([\d,]+)/i.exec(data)[2];
  168. }
  169. // alert("found turncount=" + turncount);
  170. return parseInt(turncount.replace(',',''),10);
  171. }
  172.  
  173. function getDaysPlayed(data) {
  174. var dayCount = 0;
  175. if(data.indexOf("Days Played (this run)") >= 0) {
  176. // alert("parsing datasheet for days for an ascended char");
  177. dayCount = /Days Played \(this run\)[^>]*>(<[^>]+>)*([\d,]+)/i.exec(data)[2];
  178. }
  179. else {
  180. // alert("parsing datasheet for days for an UNascended char");
  181. dayCount = /Days Played[^>]*>(<[^>]+>)*([\d,]+)/i.exec(data)[2];
  182. }
  183. // alert("found dayCount=" + dayCount);
  184. return parseInt(dayCount.replace(',',''),10);
  185. }
  186.  
  187. // parse the charpane info for the password hash (use as a session ID)
  188. function getPwdHash(data){
  189. var pwdHash = /pwdhash \= \"(.*?)\"/i.exec(data)[1]; // the .*? is the non-greedy version of .*
  190.  
  191. // alert("got pwdHash: " + pwdHash);
  192. return pwdHash;
  193. }
  194.  
  195. // parse the charpane info for the turnsplayed counter
  196. // updates at the end of the adventure, not during the fight
  197. function getTurnsplayedVar(data){
  198. var turnsplayed = /turnsthisrun \= (\d+)/i.exec(data)[1];
  199.  
  200. return parseInt(turnsplayed);
  201. }
  202.  
  203. ////////////////////////////////////////////////////////////////////////////////
  204. // parse the main page for the name of the (noncombat) adventure - assuming
  205. // it's the next bolded thing after "Adventure Results:"
  206. function getAdventureName(data) {
  207. var adventureName = "";
  208. if ( data.indexOf( "Adventure Results:" ) != -1 ) { // kol mafia can put up stuff that requires this check
  209. adventureName = /Results:<\/b>.*?<b>(.*?)<\/b>/i.exec(data)[1];
  210. }
  211. // the hobopolis rares are choice adventures, not normal noncombats
  212. else if(document.location.pathname.indexOf("choice.php") != -1) {
  213. // look for adventure name as something in bold on blue background
  214. adventureName = /bgcolor=\"blue\"><b>(.*?)<\/b>/i.exec(data)[1];
  215. }
  216. // check for known broken adventures
  217. if(adventureName == "") {
  218. if(data.indexOf( "There once was a bleary-eyed cyclops" ) != -1 ){
  219. adventureName = "The Bleary-Eyed Cyclops";
  220. }
  221. }
  222.  
  223. // alert("got adventure name: " + adventureName);
  224. return adventureName;
  225. }
  226.  
  227. ////////////////////////////////////////////////////////////////////////////////
  228. // parse the main page for the name of the adventure
  229. function getMonsterName(data) {
  230. var monsterName = /id=\"monname\"> *(.*?)<\/span>/i.exec(data);
  231. if(monsterName)
  232. monsterName = monsterName[1].toLowerCase();
  233. else
  234. return {'monsterName': "", 'fromPutty': false};
  235. // don't count monsters from putty/fax/camera/arrowing
  236. var fromPutty = data.indexOf("You put the copied monster on the ground") != -1 ? true : false;
  237. if(!fromPutty)
  238. fromPutty = data.indexOf("You gaze at the photocopy") != -1 ? true : false;
  239. if(!fromPutty)
  240. fromPutty = data.indexOf("You reach down to open up the camera") != -1 ? true : false;
  241. if(!fromPutty)
  242. fromPutty = data.indexOf("hear a wolf whistle from behind you") != -1 ? true : false;
  243. if(!fromPutty)
  244. fromPutty = data.indexOf("You play back the recording") != -1 ? true : false;
  245. if(!fromPutty)
  246. fromPutty = data.indexOf("%%") != -1 ? true : false; // some sort of error we see a lot with copied monsters
  247. // alert("got monster name: *" + monsterName + "*; from putty = " + fromPutty);
  248. return {'monsterName': monsterName, 'fromPutty': fromPutty};
  249. }
  250.  
  251. // process a noncombat result for semi-rareness
  252. var semis =
  253. {
  254. noncombats: {
  255. "Play Misty For Me" : "the Haunted Kitchen",
  256. "Like the Sunglasses, But Less Comfortable" : "the Haunted Library",
  257. "The Pilsbury Doughjerk" : "the Haunted Pantry",
  258. "The Bleary-Eyed Cyclops" : "the Limerick Dungeon", // I don't see the title appear when I get this adv.
  259. "In the Still of the Alley" : "the Sleazy Back Alley",
  260. "Natural Selection" : "the Goatlet",
  261. "Not Quite as Cold as Ice" : "the Lair of the Ninja Snowmen",
  262. "Prior to Always" : "a Battlefield",
  263. "How Does He Smell?" : "the Batrat and Ratbat Burrow",
  264. "All The Rave" : "the Castle Top Floor",
  265. "Le Chauve-Souris du Parfum" : "Guano Junction",
  266. "Hands On" : "the Harem",
  267. "You Can Top Our Desserts, But You Can't Beat Our Meats" : "the Laboratory",
  268. "Rokay, Raggy!" : "the Menagerie Level 2",
  269. "A Menacing Phantom" : "the Misspelled Cemetery",
  270. "Lunchboxing" : "the Outskirts of Cobb's Knob",
  271. "Filth, Filth, and More Filth" : "South of the Border",
  272. "It's The Only Way To Be Sure" : "the Deep Fat Friars",
  273. "It's the Only Way to be Sure" : "Pandamonium slums",
  274. "Two Sizes Too Small" : "the Hidden City",
  275. "Some Bricks Do, In Fact, Hang in the Air" : "the Inexplicable Door",
  276. "Blaaargh! Blaaargh!" : "the Spooky Forest",
  277. "Monty of County Crisco" : "Whitey's Grove",
  278. "The Latest Sorcerous Developments" : "the Hippy Camp (pre-war)",
  279. "Sand in the Vaseline" : "the Orcish Frat House (pre-war)",
  280. "Yo Ho Ho and a Bottle of Whatever This Is" : "the Obligatory Pirate's Cove",
  281. "A Tight Squeeze" : "BurnBarrel Blvd.",
  282. "Cold Comfort" : "Exposure Esplanade",
  283. "Juicy!" : "the Heap",
  284. "Flowers for You" : "the Ancient Hobo Burial Ground",
  285. "Maybe It's a Sexy Snake!" : "the Purple Light District",
  286. "What a Tosser" : "Elf Alley",
  287. "A Shark's Chum" : "The Haunted Billiards Room",
  288. "The Time This Fire" : "Vanya's Castle Chapel",
  289. "Oh, <i>There</i> Have it Gone" : "A-Boo Peek",
  290. "Synecdoche, Twin Peak" : "Twin Peak",
  291. "It's a Gas Gas Gas" : "Oil Peak",
  292. "Fit and Finish" : "the Castle Basement",
  293. "Ahead of the Game" : "the Castle Ground Floor",
  294. "Razor, Scooter" : "the Dive Bar",
  295. "Deeps Impact" : "the Briny Deeps",
  296. "The Haggling" : "the Brinier Deepers",
  297. "Camera On, James" : "the Wreck of the Edgar Fitzsimmons",
  298. "Dragon the Line" : "Madness Reef",
  299. "A Drawer of Chests" : "the Mer-Kin Outpost",
  300. "Through the Locking Glass" : "the Hallowed Halls",
  301. "Clay Is Great, But Leather Is Bether" : "Ye Olde Medievale Villagee",
  302. "Where There's Smoke...": "The Copperhead Club",
  303. "Methinks the Protesters Doth Protest Too Little": "A Mob of Zeppelin Protesters",
  304. // fake ones for testing
  305. // "A Dash of Boulder" : "the Dungeons of Doom - Boulder",
  306. // "Meat Score!" : "the Treasury - Meat Score",
  307. },
  308. combats: { // use lowercase
  309. "some bad ascii art" : "the Valley Beyond The Orc Chasm",
  310. "a knob goblin elite guard captain" : "the Cobb's Knob Kitchens",
  311. "a knob goblin embezzler" : "the Treasury",
  312. "a c. h. u. m. chieftain" : "a Maze of Sewer Tunnels",
  313. "baa'baa'bu'ran" : "the Hidden Temple",
  314. "a 7-foot dwarf foreman" : "Itznotyerzitz Mine",
  315. "a moister oyster" : "An Octopus's Garden",
  316. "françois verte, art teacher" : "Art Class", // some encoding issue with this one
  317. "x-fingered shop teacher" : "Shop Class", // need to resolve the X (1-11)
  318. "mrs. k, the chemistry teacher" : "Chemistry class",
  319. "the red fox" : "The Red Zeppelin",
  320. "bram the stoker" : "The Haunted Boiler Room",
  321. "a full-length mirror" : "The Haunted Storage Room",
  322. // fake ones for testing
  323. // "a knob goblin elite guardsman" : "the Treasury",
  324. // "a swarm of killer bees" : "the Dungeons of Doom",
  325. },
  326. };
  327.  
  328. function clearCounters(playerName) {
  329. GM_setValue(playerName+"_lastSemiTurn",-1);
  330. GM_setValue(playerName+"_lastSemiLocation","");
  331. GM_setValue(playerName+"_luckyTurn1", -1);
  332. GM_setValue(playerName+"_luckyTurn2", -1);
  333. GM_setValue(playerName+"_luckyTurn3", -1);
  334. }
  335.  
  336. function checkForNoncombatSemi(data) {
  337. theAdv = getAdventureName(document.body.innerHTML);
  338. // alert("in checkForNoncombatSemi(), adv name = " + theAdv);
  339. // alert("semis.noncombats[theAdv] = " + semis.noncombats[theAdv]);
  340. if(semis.noncombats[theAdv] != undefined) {
  341. var playerName = GM_getValue("currentPlayer");
  342. var turncount = GM_getValue(playerName+"_turncount", 0);
  343. // var turncount = getTurnsplayedVar(top.frames[0].document);
  344.  
  345. // alert("Found semirare adv \'" + theAdv + "\' in area " + semis.noncombats[theAdv] + " on tuncount " + turncount + " for player " + playerName);
  346. // found a semi, clear counters
  347. // this might backfire if using the counter as a generic countdown for other purposes, e.g. wossname tracking
  348. clearCounters(playerName);
  349.  
  350. GM_setValue(playerName+"_lastSemiTurn",turncount+1); // the turncount var isn't updated yet
  351. GM_setValue(playerName+"_allowBracket",true);
  352. GM_setValue(playerName+"_lastSemiLocation",semis.noncombats[theAdv]);
  353.  
  354. // trigger char pane refresh with the new info
  355. top.frames[0].location.reload();
  356. }
  357. }
  358.  
  359. function checkForCombatSemi(data) {
  360. var monster = getMonsterName(document.body.innerHTML);
  361. theAdv = monster.monsterName;
  362.  
  363. if(monster.fromPutty == false && semis.combats[theAdv] != undefined) {
  364. var playerName = GM_getValue("currentPlayer");
  365. var turncount = GM_getValue(playerName+"_turncount", 0);
  366. // var turncount = getTurnsplayedVar(top.frames[0].document);
  367.  
  368. // alert("Found semi rare adv \'" + theAdv + "\' in area " + semis.combats[theAdv] + " - for player " + playerName + " on turn " + turncount );
  369. // found a semi, clear counters
  370. // this might backfire if using the counter as a generic countdown for other purposes, e.g. wossname tracking
  371. clearCounters(playerName);
  372.  
  373. GM_setValue(playerName+"_lastSemiTurn",turncount+1); // the turncount var isn't updated yet
  374. GM_setValue(playerName+"_allowBracket",true);
  375. GM_setValue(playerName+"_lastSemiLocation",semis.combats[theAdv]);
  376.  
  377. // trigger char pane refresh with the new info
  378. top.frames[0].location.reload();
  379. }
  380. }
  381.  
  382. ////////////////////////////////////////////////////////////////////////////////
  383. // callback function to process the main charsheet as a sanity check after
  384. // something questionable was spotted, or just on a new session
  385. // **** mostly deprecated ****
  386. function sanityCheckCharsheet(data) {
  387. // alert("entering sanity check");
  388. var playerName = getPlayerNameFromCharsheet(data);
  389. GM_setValue("currentPlayer", playerName);
  390. var turncount = getTurnsPlayed(data); // total turns played
  391. if(isNaN(turncount) ) {
  392. // alert("sanityCheckCharsheet - unable to parse either turncount (" + turncount + ") or remaining adv count (" + remainingAdventureCount + "), aborting");
  393. return; // hopefully will try again with more success, can't continue
  394. }
  395.  
  396. GM_setValue(playerName+"_turncount", turncount); // I'll try to keep this up to date
  397.  
  398. // if the previous turncount makes no sense, zero it. After ascending would be an example
  399. var lastSemiTurn = GM_getValue(playerName+"_lastSemiTurn",-1);
  400. if( lastSemiTurn > turncount+1) {
  401. GM_setValue(playerName+"_lastSemiTurn",-1);
  402. GM_setValue(playerName+"_lastSemiLocation","");
  403. }
  404. var prevDayCount = GM_getValue(playerName+"_dayCount",-1);
  405.  
  406. var dayCount = getDaysPlayed(data);
  407. if(!isNaN(dayCount)) {
  408. if(dayCount < prevDayCount) { // must have ascended
  409. GM_setValue(playerName+"_lastSemiTurn",-1);
  410. GM_setValue(playerName+"_lastSemiLocation","");
  411. }
  412. GM_setValue(playerName+"_dayCount",dayCount);
  413. }
  414.  
  415. // set a flag is we are oxy, since it affects the cookie spacing
  416. if( data.match("Oxygenarian"))
  417. GM_setValue(playerName+"_isOxy", true);
  418. else
  419. GM_setValue(playerName+"_isOxy", false);
  420. }
  421.  
  422. ////////////////////////////////////////////////////////////////////////////////
  423. // watch for the lucky numbers result on the main page
  424. function processMain(doc) {
  425. var countdown1 = -1;
  426. var countdown2 = -1;
  427. var countdown3 = -1;
  428. var pos = -1;
  429.  
  430. // alert("in processMain()");
  431. ///////NEW STUFF (Firvagor) - changed the if line to use the div instead of the body, since the results, and a hidden field is made inside the div so infinite looping doesn't occur//////////
  432. //if the hidden field is found, don't do anything
  433. if (doc.getElementById("cookiedone")!=null){return;}
  434.  
  435. var playerName = GM_getValue( "currentPlayer");
  436. var divElement = doc.getElementById("effdiv");
  437. var bqElement = doc.getElementsByTagName("blockquote");
  438. // if(bqElement[0])
  439. // alert("processMain: speakeasy quote = " + bqElement[0]);
  440.  
  441. if ( divElement ) {
  442. // alert("found divElement");
  443.  
  444. doc.getElementById("effdiv").innerHTML += "<input type='hidden' id='cookiedone' name='completed' value='yes'>";
  445. if((pos = doc.getElementById("effdiv").innerHTML.indexOf( "Lucky numbers:" )) != -1 ) {
  446.  
  447. // alert("found lucky numbers");
  448. // need to parse the text, format is "Lucky numbers: ###, ###, ###"
  449. var cookieText = doc.getElementById("effdiv").innerHTML.substring(pos, pos+30);
  450.  
  451. // first one starts after the colon, next two after commas
  452. pos = cookieText.indexOf(":");
  453. cookieText = cookieText.substring(pos+1);
  454. countdown1 = parseInt(cookieText);
  455.  
  456. pos = cookieText.indexOf(",");
  457. cookieText = cookieText.substring(pos+1);
  458. countdown2 = parseInt(cookieText);
  459.  
  460. pos = cookieText.indexOf(",");
  461. cookieText = cookieText.substring(pos+1);
  462. countdown3 = parseInt(cookieText);
  463.  
  464. // elegantly sort them
  465. {
  466. var temp;
  467. if(countdown1 > countdown2) {
  468. temp = countdown1; countdown1 = countdown2; countdown2 = temp;
  469. }
  470. if(countdown2 > countdown3) {
  471. temp = countdown2; countdown2 = countdown3; countdown3 = temp;
  472. }
  473. if(countdown1 > countdown2) {
  474. temp = countdown1; countdown1 = countdown2; countdown2 = temp;
  475. }
  476. }
  477. // alert("processMain: cookie cookieText=" + cookieText + ", lucky numbers are " + countdown1 + ", " + countdown2 + ", " + countdown3);
  478. }
  479. }
  480. // speakeasy drink; format is "burp-speak the number <b>30</b>"
  481. // doesn't work, is there really an effdiv for this? didn't see it in the text
  482. // try a blockquote instead... doesn't sound too reliable
  483. // else if((pos = doc.getElementById("effdiv").innerHTML.indexOf( "burp-speak the number" )) != -1 ) {
  484. if(bqElement[0] && (pos = bqElement[0].innerHTML.indexOf( "burp-speak the number" )) != -1 ) {
  485. // alert("processing speakeasy");
  486. bqElement[0].innerHTML += "<input type='hidden' id='cookiedone' name='completed' value='yes'>";
  487. var cookieText = bqElement[0].innerHTML.substring(pos, pos+30);
  488.  
  489. // just one number, bolded
  490. pos = cookieText.indexOf("<b>");
  491. cookieText = cookieText.substring(pos+3);
  492. countdown1 = parseInt(cookieText);
  493. countdown2 = -1;
  494. countdown3 = -1;
  495. // alert("processMain: speakeasy cookieText=" + cookieText + ", lucky numbers are " + countdown1 + ", " + countdown2 + ", " + countdown3);
  496. }
  497.  
  498. if(countdown1>=0 || countdown2>=0 || countdown3>=0) {
  499. // filter out nonsense values:
  500. // - too high ( > 200 since last semi, 120 for oxy)
  501. // - too low ( < 160 since last semi, or < 100 if oxy)
  502. // the filters only apply if you found a semi recently; otherwise the counter starts
  503. // after a would-be semi, or ascension, with your first adventure.php location
  504. // adventure, but it's too much trouble to keep track
  505. GM_setValue(playerName+"_allowSanityCheck", false); // lock out the other pane from panicking
  506. // must call processCharsheet now, to clear this
  507. var allowBracket = GM_getValue(playerName+"_allowBracket",false);
  508. GM_setValue(playerName+"_allowBracket",false); // no reason to put up reminder after this
  509.  
  510. var turncount = GM_getValue(playerName+"_turncount", 0);
  511. var lastSemiTurn = GM_getValue(playerName+"_lastSemiTurn",-1);
  512. var wasOxy = GM_getValue(playerName+"_isOxy", false);
  513. GM_setValue(playerName+"_isOxy", false); // ate a cookie, must not be oxy
  514. var minCount = 160; var maxCount = 200;
  515. if( wasOxy ) {
  516. minCount = 100; maxCount = 120;
  517. }
  518. if(turncount < 70) { // newly ascended
  519. minCount = 70; maxCount = 80; lastSemiTurn = 0;
  520. }
  521. var turnsSinceSemi = turncount - lastSemiTurn;
  522.  
  523. // alert("filtering lucky numbers for " + playerName + " based on turncount=" + turncount + ", lastSemiTurn=" + lastSemiTurn + ", wasOxy=" + wasOxy + ", turnsSinceSemi = " + turnsSinceSemi );
  524. // eliminate counters that are too high on an absolute basis, then try to
  525. // eliminate ones too high and low based on last semi
  526. if(countdown1 > maxCount) countdown1 = -1;
  527. if(countdown2 > maxCount) countdown2 = -1;
  528. if(countdown3 > maxCount) countdown3 = -1;
  529. if(lastSemiTurn != -1 && turnsSinceSemi <= maxCount && allowBracket) {
  530. if( countdown1 + turnsSinceSemi > maxCount ) countdown1 = -1;
  531. if( countdown2 + turnsSinceSemi > maxCount ) countdown2 = -1;
  532. if( countdown3 + turnsSinceSemi > maxCount ) countdown3 = -1;
  533. }
  534. if(lastSemiTurn != -1) {
  535. if( countdown1 + turnsSinceSemi < minCount ) countdown1 = -1;
  536. if( countdown2 + turnsSinceSemi < minCount ) countdown2 = -1;
  537. if( countdown3 + turnsSinceSemi < minCount ) countdown3 = -1;
  538. }
  539. // now to compare them vs existing numbers
  540. // if there is no match, stick them in as the current numbers
  541. // if there is a match, use that and zero the other two
  542. var oldLuckyTurn1 = GM_getValue(playerName+"_luckyTurn1",-1);
  543. var oldLuckyTurn2 = GM_getValue(playerName+"_luckyTurn2",-1);
  544. var oldLuckyTurn3 = GM_getValue(playerName+"_luckyTurn3",-1);
  545. var oldCountdown1 = oldLuckyTurn1 != -1 ? oldLuckyTurn1 - turncount : -1;
  546. var oldCountdown2 = oldLuckyTurn2 != -1 ? oldLuckyTurn2 - turncount : -1;
  547. var oldCountdown3 = oldLuckyTurn3 != -1 ? oldLuckyTurn3 - turncount : -1;
  548.  
  549. var noPopups = GM_getValue("noPopups", false);
  550. // need to watch out for -1 matching -1 since we reset values above
  551. // check for self-match in new cookie values first
  552. if(countdown1 != -1 && (countdown1==countdown2 || countdown1 == countdown3)) {
  553. if(!noPopups) alert(countdown1 + " turns until a semi-rare!");
  554. countdown2 = -1;
  555. countdown3 = -1;
  556. }
  557. else if(countdown2 != -1 && countdown2 == countdown3) {
  558. if(!noPopups) alert(countdown2 + " turns until a semi-rare!");
  559. countdown1 = -1;
  560. countdown3 = -1;
  561. }
  562. else if (countdown1 != -1 && (countdown1 == oldCountdown1 || countdown1 == oldCountdown2 || countdown1 == oldCountdown3 || countdown2 == -1 && countdown3 == -1)) {
  563. if(!noPopups) alert(countdown1 + " turns until a semi-rare!");
  564. countdown2 = -1;
  565. countdown3 = -1;
  566. }
  567. else if (countdown2 != -1 && (countdown2 == oldCountdown1 || countdown2 == oldCountdown2 || countdown2 == oldCountdown3 || countdown1 == -1 && countdown3 == -1)) {
  568. if(!noPopups) alert(countdown2 + " turns until a semi-rare!");
  569. countdown1 = -1;
  570. countdown3 = -1;
  571. }
  572. else if (countdown3 != -1 && (countdown3 == oldCountdown1 || countdown3 == oldCountdown2 || countdown3 == oldCountdown3 || countdown1 == -1 && countdown2 == -1)) {
  573. if(!noPopups) alert(countdown3 + " turns until a semi-rare!");
  574. countdown1 = -1;
  575. countdown2 = -1;
  576. }
  577. GM_setValue(playerName+"_luckyTurn1",countdown1 != -1 ? countdown1 + turncount : -1);
  578. GM_setValue(playerName+"_luckyTurn2",countdown2 != -1 ? countdown2 + turncount : -1);
  579. GM_setValue(playerName+"_luckyTurn3",countdown3 != -1 ? countdown3 + turncount : -1);
  580.  
  581. // load and parse the main charsheet to set the behind the scene variables that
  582. // convert the cookie countdown into actual adventure number for each cookie
  583. // GM_get(baseURL + charSheet, processCharsheet);
  584.  
  585. // trigger char pane refresh with the new info
  586. top.frames[0].location.reload();
  587. }
  588. }
  589.  
  590. ////////////////////////////////////////////////////////////////////////////////
  591. function manualCookieEntry() {
  592. var playerName = getPlayerNameFromCharpane().username;
  593. // alert("player name: " + playerName);
  594. GM_setValue("currentPlayer", playerName); // store for other functions that need to know who's playing
  595. var noPopups = GM_getValue("noPopups", false);
  596. if(noPopups) return; // need to figure out some way to enter values without using a popup
  597. var turncount = GM_getValue(playerName+"_turncount", -1);
  598. var luckyTurn1 = GM_getValue(playerName+"_luckyTurn1", -1);
  599. var luckyTurn2 = GM_getValue(playerName+"_luckyTurn2", -1);
  600. var luckyTurn3 = GM_getValue(playerName+"_luckyTurn3", -1);
  601. var oldCountdown1 = luckyTurn1 > 0 ? luckyTurn1 - turncount : -1;
  602. var oldCountdown2 = luckyTurn2 > 0 ? luckyTurn2 - turncount : -1;
  603. var oldCountdown3 = luckyTurn3 > 0 ? luckyTurn3 - turncount : -1;
  604.  
  605. var countdown1 = -1;
  606. var countdown2 = -1;
  607. var countdown3 = -1;
  608. var displayText = "";
  609. if(oldCountdown1 > -1)
  610. displayText += oldCountdown1;
  611. if(oldCountdown2 > -1) {
  612. if(displayText != "") displayText += ", ";
  613. displayText += oldCountdown2;
  614. }
  615. if(oldCountdown3 > -1) {
  616. if(displayText != "") displayText += ", ";
  617. displayText += oldCountdown3;
  618. }
  619.  
  620. var lastSemiTurn = GM_getValue(playerName+"_lastSemiTurn",-1);
  621. var lastSemiLocation = GM_getValue(playerName+"_lastSemiLocation","");
  622. var promptText = "";
  623. if(lastSemiTurn > -1 && turncount >= lastSemiTurn ) {
  624. promptText = "Last semirare found " + (turncount - lastSemiTurn) + " turns ago, at " + lastSemiLocation + ".\n\n";
  625. }
  626. else {
  627. promptText = "Last semirare unknown.\n\n"
  628. }
  629. cookieText = prompt(promptText + "Enter 1-3 new cookie vals (-1 to clear)\n", displayText);
  630.  
  631. if(cookieText) { // will be null if user cancels
  632. countdown1 = parseInt(cookieText);
  633. var pos = cookieText.indexOf(",");
  634. if(pos > 0) {
  635. cookieText = cookieText.substring(pos+1);
  636. countdown2 = parseInt(cookieText);
  637. pos = cookieText.indexOf(",");
  638. if(pos > 0) {
  639. cookieText = cookieText.substring(pos+1);
  640. countdown3 = parseInt(cookieText);
  641. }
  642. }
  643. // alert("manual text entry, got values " + countdown1 + ", " + countdown2 + ", " + countdown3);
  644. GM_setValue(playerName+"_luckyTurn1",countdown1+turncount);
  645. GM_setValue(playerName+"_luckyTurn2",countdown2+turncount);
  646. GM_setValue(playerName+"_luckyTurn3",countdown3+turncount);
  647. GM_setValue(playerName+"_needSanityCheck", false); // just in case we were in the middle of something
  648. GM_setValue(playerName+"_allowBracket",false); // no reason to put up reminder after this
  649.  
  650. // load and parse the main charsheet to set the behind the scene variables that
  651. // convert the cookie countdown into actual adventure number for each cookie
  652. // GM_get(baseURL + charSheet, processCharsheet);
  653. // trigger char pane refresh with the new info
  654. top.frames[0].location.reload();
  655.  
  656. }
  657. }
  658.  
  659. ////////////////////////////////////////////////////////////////////////////////
  660. // this function must be called when we are in the char sidepane
  661. function getPlayerLevel(data) {
  662. var playerLevel = /Level (\d+)/i.exec(data); // full mode
  663. if( !playerLevel)
  664. playerLevel = /Lvl\. (\d+)/i.exec(data); // compact mode
  665. if( playerLevel)
  666. return parseInt(playerLevel[1],10);
  667.  
  668. // normal level checks fail if astral spirit
  669. if(data.indexOf("Astral Spirit") != -1)
  670. return 0; // astral spirit
  671. else
  672. return -1; // error
  673. }
  674.  
  675. ////////////////////////////////////////////////////////////////////////////////
  676. // this function must be called when we are in the char sidepane
  677. function updateCharacterPane() {
  678. var a = getPlayerNameFromCharpane();
  679. var playerName = a.username;
  680. var fullmode = a.fullmode;
  681. if( playerName == null ) // not sure why we sometimes see this, but doesn't seem to be at critical times
  682. return;
  683.  
  684. GM_setValue("currentPlayer", playerName); // store for other functions that need to know who's playing
  685. // if astral plane, need to reset counters
  686. // getPlayerLevel() returns 0 for astral plane
  687. var playerLevel = getPlayerLevel(document.documentElement.innerHTML);
  688. if(playerLevel == 0) {
  689. // clear the counters, no point in doing anything else
  690. clearCounters(playerName);
  691. return;
  692. }
  693.  
  694. // check the session ID to see if we are still in the same session
  695. // if a new session, check if an update is available
  696. var pwdHash = getPwdHash(document.documentElement.innerHTML);
  697. var oldPwdHash = GM_getValue(playerName + "_pwdHash", 0);
  698. if(pwdHash != oldPwdHash) {
  699. // new session
  700. GM_setValue(playerName + "_pwdHash", pwdHash);
  701. // run sanity check on new session, make sure we haven't missed anything
  702. // alert("calling sanity check");
  703. GM_get(baseURL + charSheet, sanityCheckCharsheet);
  704. // check for a new version of script if none seen already (asynch call, will run in parallel)
  705. // (temporarily?) removed for use with greasy fork
  706. /* var webVer = GM_getValue("webVersion", "Error");
  707. if(webVer == "Error" || webVer <= currentVersion) {
  708. // alert("calling version check");
  709. GM_get(scriptURL, CheckScriptVersion);
  710. }
  711. */
  712. }
  713.  
  714. // new native counter!
  715. var turncount = getTurnsplayedVar(document.documentElement.innerHTML);
  716. var oldTurncount = GM_getValue(playerName+"_turncount", 0);
  717. GM_setValue(playerName+"_turncount", turncount);
  718.  
  719. var lastSemiTurn = GM_getValue(playerName+"_lastSemiTurn",-1);
  720. var lastSemiLocation = GM_getValue(playerName+"_lastSemiLocation","");
  721. if(lastSemiTurn > turncount + 1) { // turncount var lags behind when fighting, so can have an off-by-1 issue
  722. // could happen if ascended
  723. lastSemiTurn = -1;
  724. GM_setValue(playerName+"_lastSemiTurn",-1);
  725. GM_setValue(playerName+"_lastSemiLocation","");
  726. }
  727.  
  728. var luckyTurn1 = GM_getValue(playerName+"_luckyTurn1", -1);
  729. var luckyTurn2 = GM_getValue(playerName+"_luckyTurn2", -1);
  730. var luckyTurn3 = GM_getValue(playerName+"_luckyTurn3", -1);
  731.  
  732. // if anything hit zero, warn the user
  733. var noPopups = GM_getValue("noPopups", false);
  734. var atSemi = false;
  735. if( turncount == luckyTurn1 || turncount == luckyTurn2 || turncount == luckyTurn3) {
  736. atSemi = true;
  737. if(!noPopups && turncount != oldTurncount) {
  738. var alertText = "Fortune cookie countdown hit zero!";
  739. if(lastSemiTurn > -1 && turncount >= lastSemiTurn) {
  740. alertText += "\n\nLast semirare found " + (turncount - lastSemiTurn) + " turns ago, at " + lastSemiLocation + ".";
  741. }
  742. else {
  743. alertText += "\n\nLast semirare unknown.";
  744. }
  745. confirm(alertText);
  746. }
  747. }
  748. var displayText = "";
  749. if(luckyTurn1 >= turncount)
  750. displayText += luckyTurn1 - turncount;
  751. if(luckyTurn2 >= turncount) {
  752. if(displayText != "") displayText += ", ";
  753. displayText += luckyTurn2 - turncount;
  754. }
  755. if(luckyTurn3 >= turncount) {
  756. if(displayText != "") displayText += ", ";
  757. displayText += luckyTurn3 - turncount;
  758. }
  759. if(atSemi && noPopups)
  760. displayText += " (last SR: " + (lastSemiLocation == "" ? "unknown" : lastSemiLocation) + ")";
  761. if(atSemi && fullmode) { // shows the html literally in compact mode
  762. displayText = "<font color=\"red\"><b>" + displayText + "</b></font>";
  763. }
  764.  
  765. // display turn var to figure out exactly how it works
  766. // displayText += " (tp=" + turnsplayedVar+")";
  767. var hideIfZeros = GM_getValue("hideIfZeros", false);
  768.  
  769. if(displayText != ""
  770. || hideIfZeros == false ) {
  771. // display an FC bracket if no cookie eaten, and have found a semi recently
  772. var isOxy = GM_getValue(playerName+"_isOxy", false);
  773. var turnsSinceSemi = turncount - lastSemiTurn;
  774. var minCount = 160; var maxCount = 200;
  775. if( isOxy ) {
  776. minCount = 100; maxCount = 120;
  777. }
  778. if(displayText == "" && lastSemiTurn != -1 && turnsSinceSemi <= maxCount ) {
  779. displayText = "[" + Math.max(0, minCount - turnsSinceSemi) + "...";
  780. displayText += Math.max(0, maxCount - turnsSinceSemi) + "]";
  781. } else if (displayText == "" && turncount < 70) { // default just-ascended bracket
  782. displayText = "[" + Math.max(0, 70 - turncount) + "...";
  783. displayText += Math.max(0, 80 - turncount) + "]";
  784. }
  785. if(fullmode) {
  786. var newElement = document.createElement("FONT");
  787. newElement.innerHTML = "<b>"
  788. + "<font size=2>Cookie Count: "
  789. + displayText
  790. + "</font></b><br><br>"; ;
  791. newElement.setAttribute("onmouseover", 'this.style.opacity="0.5"');
  792. newElement.setAttribute("onmouseout", 'this.style.opacity="1"');
  793. newElement.setAttribute("id", 'fortuneCookieCounter');
  794. newElement.addEventListener("click", manualCookieEntry, true);
  795. newElement.align = "center";
  796. var elements = document.getElementsByTagName( "FONT" );
  797. for ( var i = 0; i < elements.length; ++i ){
  798. if ( elements[i].innerHTML.indexOf( "Last Adventure" ) != -1 ){
  799. // insert our before this one
  800. elements[i].parentNode.insertBefore(newElement,elements[i]);
  801. break;
  802. }
  803. }
  804. }
  805. else { // compact mode - different layout, make a table row and two data element
  806. var newTR = document.createElement('tr');
  807.  
  808. var newElement = document.createElement("td");
  809. newElement.appendChild(document.createTextNode("Cookie:"));
  810. newElement.align = "right";
  811. newTR.appendChild(newElement);
  812. newElement = document.createElement("td");
  813. newElement.setAttribute("onmouseover", 'this.style.opacity="0.5"');
  814. newElement.setAttribute("onmouseout", 'this.style.opacity="1"');
  815. newElement.setAttribute("id", 'fortuneCookieCounter');
  816. newElement.addEventListener("click", manualCookieEntry, true);
  817. newElement.align = "left";
  818. newElement.style.fontWeight = "bold";
  819. newElement.appendChild(document.createTextNode(displayText));
  820. newTR.appendChild(newElement);
  821. var elements = document.getElementsByTagName( "TR" );
  822. var done = false;
  823. // if the last adventures script is running, insert before, else append to table
  824. for ( var i = 1; i < elements.length; ++i ){
  825. // normally "Adv", might be "Last Adventures" if that script is running
  826. if ( elements[i].innerHTML.indexOf( "Last Adventures" ) != -1 ){
  827. // insert ours before this one - experiment, back up one more
  828. elements[i].parentNode.insertBefore(newTR,elements[i-1]);
  829. done = true;
  830. break;
  831. }
  832. }
  833. if(!done) { // normal, no last adv script
  834. for ( var i = 0; i < elements.length; ++i ){
  835. if ( elements[i].innerHTML.indexOf( "Adv" ) != -1 ){
  836. // insert ours at end of the table in compact mode
  837. elements[i].parentNode.appendChild(newTR);
  838. break;
  839. }
  840. }
  841. }
  842. }
  843. }
  844. }
  845.  
  846. ////////////////////////////////////////////////////////////////////////////////
  847. // set preferences
  848. // code stolen from mr script
  849. // not set on a per-player basis, would need to add code to parse account pane for char name
  850. function toggleHideCountdown() {
  851. // alert("in toggleHideCountdown()");
  852.  
  853. var hideIfZeros = GM_getValue("hideIfZeros", false);
  854. hideIfZeros = !hideIfZeros;
  855. GM_setValue("hideIfZeros", hideIfZeros);
  856. // trigger char pane refresh with the new info
  857. top.frames[0].location.reload();
  858. var msg = document.getElementById('cookiecountertoggle');
  859. msg.innerHTML = (hideIfZeros ? "Hiding" : "Showing") + " Inactive Counter - Click to Change";
  860. }
  861.  
  862. function togglePopups() {
  863. // alert("in toggleHideCountdown()");
  864.  
  865. var noPopups = GM_getValue("noPopups", false);
  866. noPopups = !noPopups;
  867. GM_setValue("noPopups", noPopups);
  868. // trigger char pane refresh with the new info
  869. var msg = document.getElementById('cookiepopups');
  870. msg.innerHTML = (noPopups ? "Popups Disabled " : "Using Popups") + " (disable for FF4) - Click to Change";
  871. top.frames[0].location.reload();
  872. }
  873.  
  874. // --------------------------------------------
  875. // ---------- account menu option -------------
  876. // --------------------------------------------
  877.  
  878. // Charon's code
  879. function buildPrefs() {
  880. if (!document.querySelector('#privacy'))
  881. return;
  882. if (!document.querySelector('#scripts')) {
  883. //scripts tab is not built, do it here
  884. var scripts = document.querySelector('ul').appendChild(document.createElement('li'));
  885. scripts.id = 'scripts';
  886. var a = scripts.appendChild(document.createElement('a'));
  887. a.href = '#';
  888. var img = a.appendChild(document.createElement('img'));
  889. img.src = 'http://images.kingdomofloathing.com/itemimages/cmonkey1.gif';
  890. img.align = 'absmiddle';
  891. img.border = '0';
  892. img.style.paddingRight = '10px';
  893. a.appendChild(document.createTextNode('Scripts'));
  894. a.addEventListener('click', function (e) {
  895. //make our new tab active when clicked, clear out the #guts div and add our settings to it
  896. e.stopPropagation();
  897. document.querySelector('.active').className = '';
  898. document.querySelector('#scripts').className = 'active';
  899. document.querySelector('#guts').innerHTML = '<div class="scaffold"></div>';
  900. document.querySelector('#guts').appendChild(getSettings());
  901. }, false);
  902. } else {
  903. //script tab already exists
  904. document.querySelector('#scripts').firstChild.addEventListener('click', function (e) {
  905. //some other script is doing the activation work, just add our settings
  906. e.stopPropagation();
  907. document.querySelector('#guts').appendChild(getSettings());
  908. }, false);
  909. }
  910. }
  911.  
  912. function getSettings() {
  913. //build our settings and return them for appending
  914. var guts = document.body.appendChild(document.createElement('div'));
  915. guts.id = 'cookieprefs';
  916. var subhead = guts.appendChild(document.createElement('div'));
  917. subhead.className = 'subhead';
  918. subhead.textContent = 'Fortune Cookie Counter';
  919. var section = guts.appendChild(document.createElement('div'));
  920. section.className = 'indent';
  921. //call function in main script to actually make the settings
  922. section.appendChild(buildSettings());
  923. return guts;
  924. }
  925.  
  926. function buildSettings() {
  927. var prefLink = document.createElement('a');
  928. var hideIfZeros = GM_getValue("hideIfZeros", false);
  929.  
  930. prefLink.setAttribute('href','javascript:void(0)');
  931. prefLink.setAttribute('id','cookiecountertoggle');
  932. prefLink.innerHTML = (hideIfZeros ? "Hiding" : "Showing") + " Inactive Counter - Click to Change";
  933. prefLink.addEventListener("click", toggleHideCountdown, true);
  934.  
  935. var prefAnchor = document.createElement('a');
  936. prefAnchor.setAttribute('name','opt'); prefAnchor.innerHTML = " ";
  937. var pDiddy = document.createElement('p');
  938. with(pDiddy)
  939. { appendChild(prefAnchor);
  940. appendChild(prefLink);
  941. }
  942.  
  943. prefLink = document.createElement('a');
  944. var noPopups = GM_getValue("noPopups", false);
  945.  
  946. prefLink.setAttribute('href','javascript:void(0)');
  947. prefLink.setAttribute('id','cookiepopups');
  948. prefLink.innerHTML = (noPopups ? "Popups Disabled " : "Using Popups") + " (disable for FF4) - Click to Change";
  949. prefLink.addEventListener("click", togglePopups, true);
  950.  
  951. prefAnchor = document.createElement('p');
  952. prefAnchor.setAttribute('name','opt'); prefAnchor.innerHTML = " ";
  953. with(pDiddy)
  954. { appendChild(prefAnchor);
  955. appendChild(prefLink);
  956. }
  957. // add a link to update, if an update is available
  958. // (temporarily?) removed for use with Greasy Fork
  959. /* var webVer = GM_getValue("webVersion");
  960. if (webVer != "Error" && webVer > currentVersion) { // this is actually a text string comparison, not numerical
  961. var newElement = document.createElement('p');
  962. newElement.style.fontSize = "x-small";
  963. newElement.appendChild(document.createTextNode("New cookie script version " + webVer + " available: "));
  964.  
  965. var hrefElement = document.createElement('a');
  966. hrefElement.setAttribute('href', scriptSite);
  967. hrefElement.setAttribute('target', "_blank");
  968. hrefElement.appendChild(document.createTextNode("here"));
  969. newElement.appendChild(hrefElement);
  970. pDiddy.appendChild(newElement);
  971. }
  972. */
  973. return pDiddy;
  974. }
  975.  
  976. ////////////////////////////////////////////////////////////////////////////////
  977. // main prog, just call the proper routine if we are on a pane we care about
  978. var nodeBody = document.getElementsByTagName("body").item(0);
  979. var textBody = "";
  980. var baseURL = "";
  981. var charSheet = "charsheet.php";
  982. var playerName = GM_getValue( "currentPlayer");
  983.  
  984. if (nodeBody) {
  985. if (nodeBody.textContent) {
  986. textBody = nodeBody.textContent;
  987. }
  988. else if (nodeBody.text) {
  989. textBody = nodeBody.text;
  990. }
  991. baseURL = nodeBody.baseURI.substring(0,nodeBody.baseURI.lastIndexOf('/')+1);
  992. }
  993.  
  994. // do normal page processing independently of whether started sanity check
  995. if ( document.location.pathname.indexOf("charpane.php") != -1 ) {
  996. //////NEW STUFF (Firvagor) - since the charpane refreshes every time something is used, if the results section is found, run main function using manually located mainpane (can only use indexing for some reason)/////
  997. if (top.frames[2].document.getElementById("effdiv")!=null) // was frames[1] until aug 2014 topmenu update
  998. processMain(top.frames[2].document);
  999. updateCharacterPane();
  1000. }
  1001. else if ( document.location.pathname.indexOf("inventory.php") != -1
  1002. || document.location.pathname.indexOf("clan_viplounge.php")!= -1){
  1003. //alert("calling processMain() for " + document.location.pathname);
  1004. //////NEW STUFF (Firvagor) - passes in current document instead of nothing, just to define the frame used/////
  1005. GM_setValue(playerName+"_fighting",0);
  1006. processMain(document);
  1007. }
  1008. else if ( document.location.pathname.indexOf("charsheet.php") != -1){
  1009. // alert("calling sanityCheckCharsheet() for " + document.location.pathname);
  1010. GM_setValue(playerName+"_fighting",0);
  1011. sanityCheckCharsheet(document.body.innerHTML);
  1012. }
  1013. else if ( document.location.pathname.indexOf("account.php") != -1 ) {
  1014. // alert("calling set prefs for " + document.location.pathname);
  1015. GM_setValue(playerName+"_fighting",0);
  1016. buildPrefs();
  1017. // setPrefs();
  1018. }
  1019. else if ( document.location.pathname.indexOf("adventure.php") != -1
  1020. || document.location.pathname.indexOf("choice.php") != -1) {
  1021. // adventure.php should trap all "normal" noncombats
  1022. // choice noncombats are in choice.php - now needed for hobopolis
  1023. // for the fortune cookie combat rares, need to process fight.php
  1024. GM_setValue(playerName+"_fighting",0);
  1025. checkForNoncombatSemi(document.body.innerHTML);
  1026. }
  1027. else if ( document.location.pathname.indexOf("fight.php") != -1 ) {
  1028. // see if we are actively fighting (no asynch calls allowed while fighting!)
  1029. var fighting = GM_getValue(playerName+"_fighting",0)
  1030. // alert("prefight check - page = " + document.location.pathname + ", fighting = " + fighting);
  1031. {
  1032. if( fighting == 0) {
  1033. // just started a fight, see if it's a combat semi (orc chasm, kitchens, treasury)
  1034. checkForCombatSemi(document.body.innerHTML);
  1035. }
  1036. // alert("incrementing fighting from " + fighting);
  1037. fighting = fighting + 1; // also count rounds, prevents doing things twice in same fight
  1038. // fighting, but maybe we're done, look for adventure again tag
  1039. // I forget why we look at paragraphs here!
  1040. // var paragraphs = document.getElementsByTagName( "p" );
  1041. // for ( var i = 0; i < paragraphs.length; ++i ) {
  1042. // if ( paragraphs[i].innerHTML.indexOf( "Adventure Again (" ) != -1
  1043. // || paragraphs[i].innerHTML.indexOf("Go back to Your Inventory") != -1) {
  1044. if ( document.body.innerHTML.indexOf( "Adventure Again (" ) != -1
  1045. || document.body.innerHTML.indexOf("Go back to Your Inventory") != -1) {
  1046. fighting = 0;
  1047. // break;
  1048. }
  1049. // }
  1050. }
  1051. GM_setValue(playerName+"_fighting",fighting);
  1052. // alert("post fight - fighting = " + fighting);
  1053.  
  1054. }
  1055. else {
  1056. // alert("ignoring " + document.location.pathname);
  1057. }
  1058.  
  1059. // do sanity check (load charsheet asynchronously) if requested - not while fighting
  1060. if(GM_getValue(playerName+"_needSanityCheck",false) == true
  1061. && GM_getValue(playerName+"_allowSanityCheck",false) == true ) {
  1062. // alert("need sanity check flag detected!");
  1063. // no sanity check allowed if fighting
  1064. if( GM_getValue(playerName+"_fighting",0) == 0) {
  1065. // alert("calling sanity check");
  1066. GM_setValue(playerName+"_needSanityCheck", false);
  1067. // alert("calling sanity check");
  1068. GM_get(baseURL + charSheet, sanityCheckCharsheet);
  1069. }
  1070. }