├── .github └── workflows │ └── main.yml ├── Bundle_ASH_script.py ├── Images ├── Aftercore.png ├── Instructions.png ├── No_IOTM_character.png ├── Quest_1.JPG ├── Quest_2.JPG ├── Resource_1.png ├── Resource_2.png └── Window_Picture.png ├── LICENSE ├── Matrix ├── glyphs.png ├── matrix.html └── matrix.js ├── README.md └── Source └── relay ├── TourGuide ├── Daily Resources.ash ├── Items of the Month │ ├── Asdon Martin.ash │ ├── Barrel God.ash │ ├── Bastille Battalion.ash │ ├── Beach Comb.ash │ ├── Better Shrooms and Gardens.ash │ ├── Bird-a-Day Calendar.ash │ ├── BoomBox.ash │ ├── Boxing Daycare.ash │ ├── Cat Burglar.ash │ ├── Clan Floundry.ash │ ├── Comprehensive Cartography.ash │ ├── Crown of Thrones.ash │ ├── DNA.ash │ ├── Deck of Every Card.ash │ ├── Detective School.ash │ ├── Eight Days a Week Pills.ash │ ├── Garbage Tote.ash │ ├── Gardens.ash │ ├── GenieBottle.ash │ ├── Getaway Campsite.ash │ ├── Gingerbread City.ash │ ├── God Lobster.ash │ ├── Grimstone.ash │ ├── Guzzlr.ash │ ├── Haunted Doghouse.ash │ ├── Horsery.ash │ ├── Intergnat.ash │ ├── Items of the Month import.ash │ ├── KGBriefcase.ash │ ├── Kramco Sausage-o-Matic.ash │ ├── Latte.ash │ ├── Libram.ash │ ├── Lil Doctor Bag.ash │ ├── Machine Elf.ash │ ├── May Saber.ash │ ├── Mayo Clinic.ash │ ├── Melodramedary.ash │ ├── Meteor Lore.ash │ ├── Neverending Party.ash │ ├── New You.ash │ ├── Pizza Cube.ash │ ├── Plastic Vampire Fangs.ash │ ├── Pocket Professor.ash │ ├── Portable Pantogram.ash │ ├── Powerful Glove.ash │ ├── Protonic Accelerator Pack.ash │ ├── Psychoanalytic.ash │ ├── Red Nosed Snapper.ash │ ├── Rune Spoon.ash │ ├── Smithsness.ash │ ├── Snojo.ash │ ├── Source Terminal.ash │ ├── Space Jellyfish.ash │ ├── Spacegate.ash │ ├── Speakeasy.ash │ ├── Sugar.ash │ ├── Superhero Cape.ash │ ├── Tea Tree.ash │ ├── Telegraph Office.ash │ ├── Thanksgarden.ash │ ├── Time-Spinner.ash │ ├── Tomes.ash │ ├── Tunnel of Love.ash │ ├── Vampire Cloak.ash │ ├── Voting Booth.ash │ ├── Witchess.ash │ ├── XO Skeleton.ash │ └── Zutara.ash ├── Limit Mode │ ├── Batfellow State.ash │ ├── Batfellow.ash │ └── Spelunking.ash ├── Main.ash ├── Missing Items.ash ├── Paths │ ├── Actually Ed the Undying.ash │ ├── Avatar of Jarlsberg.ash │ ├── Avatar of Sneaky Pete.ash │ ├── Avatar of West of Loathing.ash │ ├── Bad Moon.ash │ ├── Bugbear Invasion.ash │ ├── Community Service.ash │ ├── Dark Gift.ash │ ├── Explosions.ash │ ├── G-Lover.ash │ ├── Gelatinous Noob.ash │ ├── Grey Goo.ash │ ├── Heavy Rains.ash │ ├── KOLHS.ash │ ├── License to Adventure.ash │ ├── Low Key.ash │ ├── Nuclear Autumn.ash │ ├── Paths import.ash │ ├── The Source.ash │ ├── Way of the Surprising Fist.ash │ └── Zombie Slayer.ash ├── Plants.ash ├── Pulls.ash ├── QuestState.ash ├── Quests.ash ├── Quests │ ├── Airport.ash │ ├── Artist.ash │ ├── Azazel.ash │ ├── Felonia.ash │ ├── Guild.ash │ ├── Intergalaktik.ash │ ├── Legendary Beat.ash │ ├── Level 10.ash │ ├── Level 11 - Copperhead.ash │ ├── Level 11 - Desert.ash │ ├── Level 11 - Hidden City.ash │ ├── Level 11 - Hidden Temple.ash │ ├── Level 11 - Manor.ash │ ├── Level 11 - Palindome.ash │ ├── Level 11 - Pyramid.ash │ ├── Level 11.ash │ ├── Level 12.ash │ ├── Level 13.ash │ ├── Level 2.ash │ ├── Level 3.ash │ ├── Level 4.ash │ ├── Level 5.ash │ ├── Level 6.ash │ ├── Level 7.ash │ ├── Level 8.ash │ ├── Level 9.ash │ ├── Madness Bakery.ash │ ├── Manor.ash │ ├── Marty.ash │ ├── Meatsmith.ash │ ├── Memories.ash │ ├── Nemesis.ash │ ├── Old Landfill.ash │ ├── Pirate.ash │ ├── Quest import.ash │ ├── Sea.ash │ ├── Space Elves.ash │ ├── Spookyraven Lights Out.ash │ ├── Subject 37.ash │ ├── Untinker.ash │ ├── White Citadel.ash │ └── Wizard of Ego.ash ├── Sections │ ├── API.ash │ ├── CSS.ash │ ├── Checklists.ash │ ├── Contextual Menu.ash │ ├── Data.ash │ ├── Globals.ash │ ├── Location Bar Popup.ash │ ├── Location Bar.ash │ ├── Messages.ash │ ├── Navigation Bar.ash │ ├── Tests.ash │ └── User Preferences.ash ├── Sets.ash ├── Sets │ ├── 8-bit Realm.ash │ ├── Aftercore.ash │ ├── Area Unlocks.ash │ ├── Bounty Hunter Hunter.ash │ ├── Buff Upkeep.ash │ ├── Calculate Universe.ash │ ├── Classes.ash │ ├── Copied Monsters.ash │ ├── Council.ash │ ├── Counters.ash │ ├── Daily Dungeon.ash │ ├── Demon Summon.ash │ ├── Dispensary.ash │ ├── Dungeons of Doom.ash │ ├── Equipment.ash │ ├── Events.ash │ ├── Familiars.ash │ ├── Fax.ash │ ├── Florist.ash │ ├── Hole in the Sky.ash │ ├── Holidays.ash │ ├── Level 13 Door.ash │ ├── Misc Items.ash │ ├── Misc Tasks.ash │ ├── Monorail.ash │ ├── Old Level 9 quest.ash │ ├── Olfaction.ash │ ├── PVP.ash │ ├── Powerlevel.ash │ ├── Pulverise.ash │ ├── Reminders.ash │ ├── Semi-rare.ash │ ├── Sets import.ash │ ├── Skills.ash │ └── Sweet Synthesis.ash ├── Settings.ash ├── State.ash ├── Strategy.ash ├── Support │ ├── AdventurePHP Locations.ash │ ├── Banishers.ash │ ├── Campground.ash │ ├── Checklist.ash │ ├── Cornucopias.ash │ ├── Cost To Acquire.ash │ ├── Counter.ash │ ├── Equipment Requirement.ash │ ├── Error.ash │ ├── Fold Groups.ash │ ├── HTML.ash │ ├── Holiday.ash │ ├── IOTMs.ash │ ├── Ingredients.ash │ ├── Item Filter.ash │ ├── KOLImage.ash │ ├── Library 2.ash │ ├── Library.ash │ ├── List.ash │ ├── Location Choice.ash │ ├── LocationAvailable.ash │ ├── Math.ash │ ├── Modifiers.ash │ ├── Monster Data.ash │ ├── Numberology.ash │ ├── Page.ash │ ├── Passive Damage.ash │ ├── Spell Damage.ash │ ├── Statics 2.ash │ ├── Statics.ash │ └── Strings.ash ├── Tasks.ash └── TourGuide.js └── relay_TourGuide.ash /Images/Aftercore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdrock/TourGuide/a823041fea0597b317ce6b053a5faa3c8c1d581e/Images/Aftercore.png -------------------------------------------------------------------------------- /Images/Instructions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdrock/TourGuide/a823041fea0597b317ce6b053a5faa3c8c1d581e/Images/Instructions.png -------------------------------------------------------------------------------- /Images/No_IOTM_character.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdrock/TourGuide/a823041fea0597b317ce6b053a5faa3c8c1d581e/Images/No_IOTM_character.png -------------------------------------------------------------------------------- /Images/Quest_1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdrock/TourGuide/a823041fea0597b317ce6b053a5faa3c8c1d581e/Images/Quest_1.JPG -------------------------------------------------------------------------------- /Images/Quest_2.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdrock/TourGuide/a823041fea0597b317ce6b053a5faa3c8c1d581e/Images/Quest_2.JPG -------------------------------------------------------------------------------- /Images/Resource_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdrock/TourGuide/a823041fea0597b317ce6b053a5faa3c8c1d581e/Images/Resource_1.png -------------------------------------------------------------------------------- /Images/Resource_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdrock/TourGuide/a823041fea0597b317ce6b053a5faa3c8c1d581e/Images/Resource_2.png -------------------------------------------------------------------------------- /Images/Window_Picture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdrock/TourGuide/a823041fea0597b317ce6b053a5faa3c8c1d581e/Images/Window_Picture.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /Matrix/glyphs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdrock/TourGuide/a823041fea0597b317ce6b053a5faa3c8c1d581e/Matrix/glyphs.png -------------------------------------------------------------------------------- /Matrix/matrix.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | The Matrix 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TourGuide 2 | 3 | ### Installation 4 | 5 | `svn checkout https://github.com/cdrock/TourGuide/branches/Release/` 6 | 7 | ### Updating 8 | 9 | `svn update` 10 | 11 | ### How do I use it? 12 | Once it's installed, look in the relay browser. In the upper-right, there will be a **"run script"** menu. Select TourGuide and it will dock to the side of your window. 13 | 14 | ![Instructions](/Images/Instructions.png) 15 | 16 | 17 | ### What does it do? 18 | TourGuide is a relay script which will give advice on playing [Kingdom of Loathing](http://www.kingdomofloathing.com) within [KoLmafia](http://kolmafia.sourceforge.net). It details how to complete quests you're on, and what resources you have available. 19 | 20 | It keeps track of your quests and resources and helps you complete ascensions as fast as possible. 21 | 22 | #### Quest advice: 23 | 24 | ![Quest Example 1](/Images/Quest_1.JPG) 25 | 26 | ![Quest Example 2](/Images/Quest_2.JPG) 27 | 28 | #### Resources: 29 | 30 | ![Resource 1](/Images/Resource_1.png) 31 | 32 | ![Resource 2](/Images/Resource_2.png) 33 | 34 | The script will inform you of many resources you have - free runaways, banishes, semi-rares, etc. - and ideas on what to use them on. 35 | 36 | **Quests supported**: All council quests, azazel, pretentious artist, untinker, legendary beat, most of the sea, unlocking the manor, the nemesis quest, pirate quest, repairing the shield generator in outer space, white citadel, the old level 9 quest, jung man's psychoses jars, and the wizard of ego. 37 | 38 | ### Development guidelines 39 | TourGuide is open source and contributions are encouraged! 40 | 41 | The release above is a compiled version of the development version, which can be found by checking out https://github.com/cdrock/TourGuide. The release is compiled via Compile ASH script.rb, which collects many scripts into one for ease of release. 42 | 43 | This script, as well as its support scripts, are in the public domain. 44 | 45 | Contact me in-game: **cdrock (#2912644)** 46 | 47 | Or in discord: **cdrock7#1898** 48 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Bastille Battalion.ash: -------------------------------------------------------------------------------- 1 | 2 | 3 | RegisterTaskGenerationFunction("IOTMBastilleBattalionGenerateTasks"); 4 | void IOTMBastilleBattalionGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 5 | { 6 | if (lookupItem("Bastille Battalion control rig").available_amount() == 0 || my_sign().to_lower_case() == "bad moon") return; 7 | 8 | if (lookupItem("Draftsman's driving gloves").available_amount() > 0 || lookupItem("Nouveau nosering").available_amount() > 0 || lookupItem("Brutal brogues").available_amount() > 0) return; 9 | 10 | string [int] description; 11 | string url = "inv_use.php?pwd=" + my_hash() + "&whichitem=9928"; 12 | 13 | //FIXME suggest the right configuration 14 | if (lookupItem("Bastille Battalion control rig").storage_amount() > 0) 15 | { 16 | url = "storage.php?which=3"; 17 | description.listAppend("Free pull from Hagnk's."); 18 | } 19 | //FIXME in the future, we might want to suggest options for them. We haven't, because it's a lot of space, especially the equipment. 20 | string [int] suggested_configuration; 21 | if (__misc_state["need to level"]) 22 | { 23 | int stats_gained = ceil(250 * (1.0 + numeric_modifier(my_primestat() + " experience percent") / 100.0)); 24 | if (my_primestat() == $stat[muscle]) 25 | { 26 | description.listAppend(HTMLGenerateSpanOfClass("Babar", "r_bold") + ": " + stats_gained + " muscle stats."); 27 | suggested_configuration.listAppend("Babar"); 28 | } 29 | else if (my_primestat() == $stat[mysticality]) 30 | { 31 | description.listAppend(HTMLGenerateSpanOfClass("Barbarian Barbecue", "r_bold") + ": " + stats_gained + " mysticality stats."); 32 | suggested_configuration.listAppend("Barbarian Barbecue"); 33 | } 34 | else if (my_primestat() == $stat[moxie]) 35 | { 36 | description.listAppend(HTMLGenerateSpanOfClass("Barbershop", "r_bold") + ": " + stats_gained + " moxie stats."); 37 | suggested_configuration.listAppend("Barbershop"); 38 | } 39 | } 40 | string [int] accessories; 41 | accessories.listAppend(HTMLGenerateSpanOfClass("Accessory:", "r_bold")); 42 | accessories.listAppend(HTMLGenerateSpanOfClass("Brutalist", "r_bold") + ": +50% muscle, +50% weapon damage, +8 familiar weight, +4 muscle stats/fight."); 43 | accessories.listAppend(HTMLGenerateSpanOfClass("Draftsman", "r_bold") + ": +50% myst, +50% spell damage, +8 adventures/day, +4 myst stats/fight."); 44 | accessories.listAppend(HTMLGenerateSpanOfClass("Art Nouveau", "r_bold") + ": +50% moxie, +25% item, +25 HP/MP, +4 moxie stats/fight."); 45 | description.listAppend(accessories.listJoinComponents("|*")); 46 | 47 | string [int] buffs; 48 | buffs.listAppend(HTMLGenerateSpanOfClass("Buff:", "r_bold") + " (100 turns)"); 49 | buffs.listAppend(HTMLGenerateSpanOfClass("Cannon", "r_bold") + ": +25 muscle, +10% critical hit, ~15 HP/adventure."); 50 | buffs.listAppend(HTMLGenerateSpanOfClass("Catapult", "r_bold") + ": +25 myst, +10% spell critical hit, ~7.5 MP/adventure."); 51 | buffs.listAppend(HTMLGenerateSpanOfClass("Gesture", "r_bold") + ": +25 moxie, +25% init, +25% meat."); 52 | description.listAppend(buffs.listJoinComponents("|*")); 53 | 54 | if (!in_ronin()) 55 | { 56 | //+adventures in aftercore 57 | suggested_configuration.listAppend("Draftsman"); 58 | } 59 | else if (my_primestat() == $stat[muscle]) 60 | { 61 | suggested_configuration.listAppend("Brutalist"); 62 | } 63 | else if (my_primestat() == $stat[mysticality]) 64 | { 65 | suggested_configuration.listAppend("Draftsman"); 66 | } 67 | else if (my_primestat() == $stat[moxie]) 68 | { 69 | suggested_configuration.listAppend("Art Nouveau"); 70 | } 71 | 72 | if (!in_ronin()) 73 | suggested_configuration.listAppend("Gesture"); 74 | else 75 | suggested_configuration.listAppend("Catapult"); 76 | 77 | description.listAppend("Suggested configuration: " + HTMLGenerateSpanOfClass(suggested_configuration.listJoinComponents(" / "), "r_bold") + "."); 78 | 79 | optional_task_entries.listAppend(ChecklistEntryMake("__item Bastille Battalion control rig", url, ChecklistSubentryMake("Collect Bastille rewards", "", description), 8).ChecklistEntrySetIDTag("Bastille Battalion daily")); 80 | } 81 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Beach Comb.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("IOTMBeachCombGenerateResource"); 3 | void IOTMBeachCombGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (lookupItem("beach comb").available_amount() == 0) return; 6 | int free_walks_left = clampi(11 - get_property_int("_freeBeachWalksUsed"), 0, 11); 7 | if (free_walks_left == 0) 8 | return; 9 | 10 | boolean [int] beach_heads_used = get_property("_beachHeadsUsed").stringToIntIntList(",").listInvert(); 11 | 12 | string [int] description; 13 | string [int] buffs; 14 | 15 | string [int] elemental_buffs; 16 | boolean in_run = __misc_state["in run"]; 17 | if (!beach_heads_used[1]) 18 | elemental_buffs.listAppend(HTMLGenerateSpanOfClass("Hot-Headed", "r_element_hot")); 19 | if (!beach_heads_used[2]) 20 | elemental_buffs.listAppend(HTMLGenerateSpanOfClass("Cold as Nice", "r_element_cold")); 21 | if (!beach_heads_used[3]) 22 | elemental_buffs.listAppend(HTMLGenerateSpanOfClass("A Brush with Grossness", "r_element_stench")); 23 | if (!beach_heads_used[4]) 24 | elemental_buffs.listAppend(HTMLGenerateSpanOfClass("Does It Have a Skull In There??", "r_element_spooky")); 25 | if (!beach_heads_used[5]) 26 | elemental_buffs.listAppend(HTMLGenerateSpanOfClass("Oiled\, Slick", "r_element_sleaze")); 27 | 28 | if (elemental_buffs.count() > 0 && in_run) 29 | buffs.listAppend("" + elemental_buffs.listJoinComponents(" / ") + ": +3 X resistance, +15 X damage, +15 X spell damage."); 30 | if (!beach_heads_used[6] && in_run) 31 | buffs.listAppend("Lack of Body-Building: +50% muscle, +25% weapon damage."); // hah 32 | if (!beach_heads_used[7] && in_run) 33 | buffs.listAppend("We're All Made of Starfish: +50% myst, +25% spell damage."); 34 | if (!beach_heads_used[8] && in_run) 35 | buffs.listAppend("Pomp & Circumsands: +50% moxie, +25% ranged damage."); 36 | if (!beach_heads_used[9] && in_run) 37 | buffs.listAppend("Resting Beach Face: +50% init."); 38 | if (!beach_heads_used[10]) 39 | buffs.listAppend("Do I Know You From Somewhere?: +5 familiar weight."); 40 | if (!beach_heads_used[11] && in_run) 41 | buffs.listAppend("You Learned Something Maybe!: +5 stats/fight."); 42 | 43 | if (buffs.count() > 0) 44 | description.listAppend("Buffs:
" + buffs.listJoinComponents("
")); 45 | if (free_walks_left >= 10) 46 | description.listAppend((description.count() > 0 ? "Or collect" : "Collect") + " a bunch of items? (10 walks)"); 47 | description.listAppend("Or farm the beach."); 48 | resource_entries.listAppend(ChecklistEntryMake("__item beach comb", "main.php?comb=1", ChecklistSubentryMake(pluralise(free_walks_left, "beach comb", "beach combs"), "", description), 3).ChecklistEntrySetIDTag("Beach comb resource")); 49 | } 50 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Better Shrooms and Gardens.ash: -------------------------------------------------------------------------------- 1 | RegisterResourceGenerationFunction("IOTMBetterShroomsAndGardensGenerateResource"); 2 | void IOTMBetterShroomsAndGardensGenerateResource(ChecklistEntry [int] resource_entries) 3 | { 4 | ChecklistSubentry getFreeFights() { 5 | int freeFightsUsed = get_property_int("_mushroomGardenFights"); 6 | int totalFreeFights = 1; 7 | 8 | if (my_path_id() == PATH_OF_THE_PLUMBER) { 9 | totalFreeFights = 5; 10 | } 11 | int freeFightsLeft = totalFreeFights - freeFightsUsed; 12 | 13 | // Title 14 | string main_title = pluralise(freeFightsLeft,"Piranha Plant fight","Piranha Plant fights"); 15 | 16 | // Subtitle 17 | string subtitle = ""; 18 | 19 | // Entries 20 | string [int] description; 21 | if (freeFightsLeft > 0) { 22 | description.listAppend("Free fight."); 23 | if (my_path_id() == PATH_OF_THE_PLUMBER) { 24 | description.listAppend("Drops extra coins and mushrooms."); 25 | } 26 | } 27 | 28 | return ChecklistSubentryMake(main_title, subtitle, description); 29 | } 30 | 31 | ChecklistSubentry getMushroomState() { 32 | int mushroomLevel = get_property_int("mushroomGardenCropLevel"); 33 | int expectedFilets = MIN(3, mushroomLevel)*3; 34 | int expectedSlabs = clampi(mushroomLevel - 3, 0, 2); 35 | 36 | // Title 37 | string main_title = "Upkeep your mushroom"; 38 | 39 | // Subtitle 40 | string subtitle = "One action per day"; 41 | 42 | // Entries 43 | string [int] description; 44 | 45 | string [int] shroomYield; 46 | string [int] futureYield; 47 | if (!get_property_boolean("_mushroomGardenVisited")) { 48 | description.listAppend("Mushroom is at tier " + mushroomLevel); 49 | shroomYield.listAppend(expectedFilets + " filets"); 50 | if (mushroomLevel > 3) 51 | shroomYield.listAppend( pluralise(expectedSlabs,"slab","slabs") ); 52 | 53 | if (mushroomLevel < 2) 54 | futureYield.listAppend("+3 filets at tier 2"); 55 | if (mushroomLevel < 3) 56 | futureYield.listAppend("+3 filets at tier 3"); 57 | if (mushroomLevel < 4) 58 | futureYield.listAppend("+1 slab at tier 4"); 59 | if (mushroomLevel < 5) 60 | futureYield.listAppend("+1 slab at tier 5"); 61 | 62 | if (mushroomLevel > 10) 63 | shroomYield.listAppend("A mushroom house"); 64 | else 65 | futureYield.listAppend("+1 mushroom house at tier 11"); 66 | 67 | description.listAppend("Harvesting now will give:" + HTMLGenerateIndentedText(shroomYield)); 68 | description.listAppend( mushroomLevel > 10 ? HTMLGenerateSpanOfClass("No reason to fertilize any longer", "r_bold") : to_buffer("Otherwise, fertilize it, incrementing its size:" + HTMLGenerateIndentedText(futureYield)) ); 69 | } 70 | 71 | return ChecklistSubentryMake(main_title, subtitle, description); 72 | } 73 | 74 | if (!__iotms_usable[lookupItem("packet of mushroom spores")]) return; 75 | 76 | ChecklistEntry entry; 77 | entry.image_lookup_name = "__item Better Shrooms and Gardens catalog"; 78 | entry.url = "campground.php"; 79 | entry.tags.id = "Mushroom garden resource"; 80 | 81 | ChecklistSubentry piranhas = getFreeFights(); 82 | if (piranhas.entries.count() > 0) { 83 | entry.subentries.listAppend(piranhas); 84 | // Want this part to appear both in the garden's tile, and the free fights tile, so making a new entry 85 | resource_entries.listAppend(ChecklistEntryMake("__item Better Shrooms and Gardens catalog", "campground.php", piranhas).ChecklistEntrySetCombinationTag("daily free fight")); 86 | } 87 | 88 | ChecklistSubentry shroom = getMushroomState(); 89 | if (shroom.entries.count() > 0) { 90 | entry.subentries.listAppend(shroom); 91 | } 92 | 93 | if (entry.subentries.count() > 0) { 94 | resource_entries.listAppend(entry); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/BoomBox.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterTaskGenerationFunction("IOTMBoomBoxGenerateTasks"); 3 | void IOTMBoomBoxGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 4 | { 5 | if (lookupItem("SongBoom™ BoomBox").available_amount() == 0) return; 6 | 7 | string song = get_property("boomBoxSong"); 8 | int changes_left = get_property_int("_boomBoxSongsLeft"); //the boys are back in town, eleven times. everyone will love it 9 | 10 | if (song == "" && changes_left > 0) 11 | { 12 | string [int] description; 13 | if (!__quest_state["Level 7"].finished && my_path_id() != PATH_COMMUNITY_SERVICE) 14 | description.listAppend("Eye of the Giger: Nightmare Fuel for the cyrpt."); 15 | if (fullness_limit() > 0) 16 | description.listAppend("Food Vibrations: extra adventures from food" + (__misc_state["in run"] ? ", +30% food drop" : "") + "."); 17 | description.listAppend("Total Eclipse of Your Meat: extra meat, +30% meat."); 18 | 19 | 20 | optional_task_entries.listAppend(ChecklistEntryMake("__item SongBoom™ BoomBox", "inv_use.php?pwd=" + my_hash() + "&whichitem=9919", ChecklistSubentryMake("Set BoomBox song", "", description), 8).ChecklistEntrySetIDTag("SongBoom BoomBox turn on")); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Boxing Daycare.ash: -------------------------------------------------------------------------------- 1 | RegisterTaskGenerationFunction("IOTMBoxingDaycareGenerateTasks"); 2 | void IOTMBoxingDaycareGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 3 | { 4 | if (!__iotms_usable[lookupItem("Boxing Day care package")]) return; 5 | //collect nap consumable 6 | ChecklistEntry entry; 7 | entry.url = "place.php?whichplace=town_wrong&action=townwrong_boxingdaycare"; 8 | entry.image_lookup_name = "__item orange boxing gloves"; 9 | entry.tags.id = "Boxing daycare daily tasks"; 10 | entry.importance_level = 8; 11 | if (!get_property_boolean("_daycareNap")) 12 | { 13 | entry.subentries.listAppend(ChecklistSubentryMake("Take a daycare nap", "", "Gives a consumable.")); 14 | } 15 | //scavenge once 16 | if (get_property_int("_daycareGymScavenges") == 0 && __misc_state["need to level"]) 17 | { 18 | entry.subentries.listAppend(ChecklistSubentryMake("Scavenge for daycare equipment", "", "Statgain.")); 19 | } 20 | else if (get_property_int("_daycareRecruits") < 1 && __misc_state["in run"] && $skill[Army of Toddlers].skill_is_usable() && __misc_state["need to level"] && my_meat() >= 100) 21 | { 22 | entry.subentries.listAppend(ChecklistSubentryMake("Recruit at the boxing daycare?", "", "100 meat, benefits army of toddlers statgain.")); 23 | } 24 | if (entry.subentries.count() > 0) 25 | { 26 | optional_task_entries.listAppend(entry); 27 | } 28 | } 29 | 30 | RegisterResourceGenerationFunction("IOTMBoxingDaycareGenerateResource"); 31 | void IOTMBoxingDaycareGenerateResource(ChecklistEntry [int] resource_entries) 32 | { 33 | if (!__iotms_usable[lookupItem("Boxing Day care package")]) return; 34 | //buffs 35 | if (!get_property_boolean("_daycareSpa")) 36 | { 37 | string [int] description; 38 | if (in_ronin()) 39 | { 40 | description.listAppend("+200% muscle, +15 ML"); 41 | description.listAppend("+200% moxie, +50% init"); 42 | description.listAppend("+200% myst, +25% item"); 43 | description.listAppend("+100 HP, +50 MP, +25 DR, +~8 MP regen, +~15 HP regen"); 44 | } 45 | else 46 | description.listAppend("+200% myst, +25% item"); 47 | resource_entries.listAppend(ChecklistEntryMake("__item orange boxing gloves", "place.php?whichplace=town_wrong&action=townwrong_boxingdaycare", ChecklistSubentryMake("Boxing daycare buff (100 turns)", description), 5).ChecklistEntrySetCombinationTag("boxing daycare resources").ChecklistEntrySetIDTag("Boxing daycare daily spa")); 48 | } 49 | if (hippy_stone_broken() && !get_property_boolean("_daycareFights") && !__misc_state["in run"]) 50 | { 51 | string [int] description; 52 | description.listAppend("Costs one adventure. Spar."); 53 | if (get_property_int("daycareToddlers") <= 2) 54 | description.listAppend("Should recruit first."); 55 | resource_entries.listAppend(ChecklistEntryMake("__item orange boxing gloves", "place.php?whichplace=town_wrong&action=townwrong_boxingdaycare", ChecklistSubentryMake("Boxing daycare PVP fights", description), 5).ChecklistEntrySetCombinationTag("boxing daycare resources").ChecklistEntrySetIDTag("Boxing daycare daily spar")); 56 | 57 | } 58 | if (__misc_state["in run"] && $skill[Army of Toddlers].skill_is_usable() && !get_property_boolean("_armyToddlerCast") && __misc_state["need to level"]) 59 | { 60 | string [int] description; 61 | //is this mainstat or what 62 | float total_statgain = sqrt(get_property_int("daycareToddlers"));// * (1.0 + numeric_modifier(my_primestat() + " experience percent") / 100.0); 63 | float [stat] split_statgain = {$stat[muscle]:total_statgain * 0.25, $stat[mysticality]:total_statgain * 0.25, $stat[moxie]:total_statgain * 0.25}; 64 | split_statgain[my_primestat()] = total_statgain * 0.5; 65 | foreach s, v in split_statgain 66 | { 67 | split_statgain[s] = v * (1.0 + numeric_modifier(s + " experience percent") / 100.0); 68 | } 69 | string [int] stats_out; 70 | stats_out.listAppend(split_statgain[$stat[muscle]].roundForOutput(0)); 71 | stats_out.listAppend(split_statgain[$stat[mysticality]].roundForOutput(0)); 72 | stats_out.listAppend(split_statgain[$stat[moxie]].roundForOutput(0)); 73 | 74 | description.listAppend("50 MP, gain " + stats_out.listJoinComponents(" / ") + " stats."); 75 | if (split_statgain[my_primestat()] < 3.0 || get_property_int("daycareToddlers") <= 2) 76 | description.listAppend("Might want to recruit first."); 77 | resource_entries.listAppend(ChecklistEntryMake("__skill Army of Toddlers", "", ChecklistSubentryMake("Army of Toddlers castable", description), 5).ChecklistEntrySetCombinationTag("boxing daycare resources").ChecklistEntrySetIDTag("Boxing daycare toddler army")); 78 | 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Cat Burglar.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("IOTMCatBurglarGenerateResource"); 3 | void IOTMCatBurglarGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (!lookupFamiliar("cat burglar").familiar_is_usable()) return; 6 | 7 | int charges_left = CatBurglarChargesLeftToday(); 8 | if (charges_left > 0) { 9 | string [int] description; 10 | string url = "familiar.php"; 11 | if (my_familiar() == lookupFamiliar("cat burglar")) 12 | url = "main.php?heist=1"; 13 | //√rusty hedge trimmers 14 | //√bowling ball 15 | //cigarette lighter, if they're doing zeppelin 16 | //scent glands, but only if they don't xoxoxoxo 17 | //√green smoke bomb 18 | //There are also certainly even more options. 19 | description.listAppend("Obtains one item from a recent fight."); 20 | string [int] options; 21 | if (__misc_state["in run"] && my_path_id() != PATH_COMMUNITY_SERVICE) { 22 | int bowling_progress = get_property_int("hiddenBowlingAlleyProgress"); 23 | if (bowling_progress < 7) { 24 | int balls_needed = 6 - bowling_progress - $item[bowling ball].available_amount(); 25 | if (balls_needed > 0) 26 | options.listAppend("Bowling ball, from the hidden bowling alley."); 27 | } 28 | if (get_property_int("twinPeakProgress") != 15 && $item[rusty hedge trimmers].available_amount() < __quest_state["Level 9"].state_int["peak tests remaining"]) { 29 | options.listAppend("Rusty hedge trimmers, from the twin peak."); 30 | } 31 | if (!__quest_state["Level 12"].finished && get_property("sidequestOrchardCompleted") == "none") { 32 | options.listAppend("Green smoke bomb, from the war."); 33 | if (!lookupFamiliar("XO Skeleton").familiar_is_usable()) 34 | options.listAppend("Scent glands, from the filthworms quest."); 35 | } 36 | if (get_property_int("zeppelinProtestors") < 80 && QuestState("questL11Ron").mafia_internal_step < 3) { 37 | options.listAppend("Cigarette lighters, from the zeppelin protesters."); 38 | } 39 | if ($item[pirate fledges].available_amount() == 0 && !have_outfit_components("Swashbuckling Getup") && __quest_state["Pirate Quest"].state_boolean["valid"]) { 40 | options.listAppend("Pirate outfit."); 41 | } 42 | 43 | if ($item[S.O.C.K.].available_amount() == 0) { 44 | string [int] airship_stealables; 45 | foreach it in $items[mohawk wig,amulet of extreme plot significance] { 46 | if (it.available_amount() == 0) 47 | airship_stealables.listAppend(it); 48 | } 49 | if (airship_stealables.count() > 0) 50 | options.listAppend(airship_stealables.listJoinComponents(", ", "and").capitaliseFirstLetter() + ", from the airship."); 51 | } 52 | if (__quest_state["Level 4"].state_int["areas unlocked"] + $item[sonar-in-a-biscuit].available_amount() < 3) 53 | options.listAppend("Sonar-in-a-biscuit, from the bat hole."); 54 | if (!__quest_state["Level 11 Desert"].state_boolean["Desert Explored"] && !__quest_state["Level 11 Desert"].state_boolean["Killing Jar Given"] && $item[killing jar].available_amount() == 0) // && !($location[The Haunted Gallery].locationAvailable() && !$location[The Haunted Library].locationAvailable()) //that was from when you could use copied/wished writing desks to skip the library... 55 | options.listAppend("Killing jar, from the haunted library."); 56 | if (!have_outfit_components("Knob Goblin Elite Guard Uniform") && !have_outfit_components("Knob Goblin Harem Girl Disguise") && !__quest_state["Level 5"].finished) 57 | options.listAppend("Harem girl outfit, if you can't reach +400% item."); 58 | } 59 | if (options.count() > 0) 60 | description.listAppend("Could steal:|*-" + options.listJoinComponents("|*-")); 61 | 62 | resource_entries.listAppend(ChecklistEntryMake("__familiar Cat Burglar", url, ChecklistSubentryMake(pluralise(charges_left, "heist", "heists"), "", description), 1).ChecklistEntrySetIDTag("Cat burglar resource")); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Clan Floundry.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("IOTMClanFloundryGenerateResource"); 3 | void IOTMClanFloundryGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (!__misc_state["VIP available"] || !$item[Clan Floundry].is_unrestricted()) 6 | return; 7 | if (!__misc_state["in run"]) 8 | return; 9 | if (my_path_id() == PATH_G_LOVER) 10 | return; 11 | 12 | //if (get_property_boolean("_floundryFabricated") || !mafiaIsPastRevision(18000)) 13 | //return; 14 | foreach it in $items[bass clarinet,fish hatchet,carpe,codpiece,troutsers,tunac] 15 | { 16 | if (it.available_amount() > 0) 17 | return; 18 | if (it == $item[none]) 19 | return; 20 | } 21 | 22 | string [int] description; 23 | 24 | string [int][int] equipment; 25 | if (__misc_state["can equip just about any weapon"]) 26 | { 27 | //Bass clarinet: -10% combat, 1h ranged weapon, +100% moxie, -3 MP skill cost, +50 ranged damage, 10 white pixels 28 | string line = "-10% combat, +100% moxie, -3 MP skill cost, +50 ranged damage"; 29 | if (!__quest_state["Level 13"].state_boolean["digital key used"] && ($item[digital key].available_amount() + creatable_amount($item[digital key])) == 0) 30 | line += ", 10 white pixels"; 31 | equipment.listAppend(listMake("Bass clarinet", "ranged weapon", line)); 32 | //Fish hatchet: -10% combat, 1h axe, +100% muscle, +5 familiar weight, +50 weapon damage, +5 bridge progress 33 | line = "-10% combat, +100% muscle, +5 familiar weight, +50 weapon damage"; 34 | if (!__quest_state["Level 9"].state_boolean["bridge complete"]) 35 | line += ", +5 bridge progress"; 36 | equipment.listAppend(listMake("Fish hatchet", "weapon", line)); 37 | } 38 | //Codpiece: acc, -?% combat, +100% myst, +100 max MP, +50 spell damage, 8 bubblin' crudes 39 | equipment.listAppend(listMake("Codpiece", "acc", "-10% combat, +100% myst, +100 max MP, +50 spell damage" + (can_interact() ? "" : ", 8 bubblin' crudes"))); 40 | //Carpe: back, +combat, +50% myst, regen ~8 MP, +50% meat 41 | equipment.listAppend(listMake("Carpe", "back", "+combat, +50% meat, +50% myst, regen ~8 MP")); 42 | //Tunac tunac tun: +combat, shirt, +50% muscle, +25 ML, +25% item 43 | if (__misc_state["Torso aware"]) 44 | { 45 | equipment.listAppend(listMake("Tunac", "shirt", "+combat, +25 ML, +25% item, +50% muscle")); 46 | } 47 | //Troutsers: pants, +50% moxie, +50% pickpocket, +5 all res, +11 prismatic damage 48 | equipment.listAppend(listMake("Troutsers", " pants", "+50% moxie, +50% pickpocket, +5 all res, +11 prismatic damage")); 49 | description.listAppend(HTMLGenerateSimpleTableLines(equipment)); 50 | 51 | 52 | resource_entries.listAppend(ChecklistEntryMake("__item fishy fish", "clan_viplounge.php?action=floundry", ChecklistSubentryMake("Rentable floundry equipment", "", description), 8).ChecklistEntrySetIDTag("Clan floundry resource")); 53 | } 54 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Comprehensive Cartography.ash: -------------------------------------------------------------------------------- 1 | RegisterTaskGenerationFunction("IOTMComprehensiveCartographyGenerateTasks"); 2 | void IOTMComprehensiveCartographyGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 3 | { 4 | if (!lookupSkill("Map the Monsters").have_skill()) return; 5 | if (get_property_boolean("mappingMonsters")) { 6 | task_entries.listAppend(ChecklistEntryMake("__skill Map the Monsters", "", ChecklistSubentryMake("Mapping the Monsters now!", "", "Fight a chosen monster in the next zone."), -11).ChecklistEntrySetIDTag("Cartography skill map now")); 7 | } 8 | } 9 | 10 | RegisterResourceGenerationFunction("IOTMComprehensiveCartographyGenerateResource"); 11 | void IOTMComprehensiveCartographyGenerateResource(ChecklistEntry [int] resource_entries) 12 | { 13 | if (!lookupSkill("Map the Monsters").have_skill()) return; 14 | int casts_remaining = 3 - get_property_int("_monstersMapped"); 15 | if (casts_remaining > 0) { 16 | resource_entries.listAppend(ChecklistEntryMake("__skill Map the Monsters", "skillz.php", ChecklistSubentryMake(casts_remaining.pluralise(" monster mapping", " monster mappings") + " remaining", "", "Cast Map the Monsters, for anything on the olfaction list.")).ChecklistEntrySetIDTag("Cartography skill map resource")); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Detective School.ash: -------------------------------------------------------------------------------- 1 | RegisterTaskGenerationFunction("IOTMDetectiveSchoolGenerateTasks"); 2 | void IOTMDetectiveSchoolGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 3 | { 4 | if (!mafiaIsPastRevision(17048)) 5 | return; 6 | if (!__iotms_usable[$item[detective school application]]) 7 | return; 8 | 9 | //Should we always mention this in aftercore? 10 | //Hmm... I suppose. 11 | int cases_remaining = clampi(3 - get_property_int("_detectiveCasesCompleted"), 0, 3); 12 | if (cases_remaining > 0) 13 | { 14 | optional_task_entries.listAppend(ChecklistEntryMake("__item noir fedora", "place.php?whichplace=town_wrong&action=townwrong_precinct", ChecklistSubentryMake("Solve " + pluraliseWordy(cases_remaining, "more case", "more cases"), "", "Gives cop dollars."), 5).ChecklistEntrySetIDTag("Detective school daily cases")); 15 | } 16 | if ($items[plastic detective badge,bronze detective badge,silver detective badge,gold detective badge].available_amount() == 0) 17 | { 18 | optional_task_entries.listAppend(ChecklistEntryMake("__item plastic detective badge", "place.php?whichplace=town_wrong&action=townwrong_precinct", ChecklistSubentryMake("Collect your Precinct badge", "", ""), 5).ChecklistEntrySetIDTag("Detective school new badge")); 19 | 20 | } 21 | } 22 | 23 | RegisterResourceGenerationFunction("IOTMDetectiveSchoolGenerateResource"); 24 | void IOTMDetectiveSchoolGenerateResource(ChecklistEntry [int] resource_entries) 25 | { 26 | if (!mafiaIsPastRevision(17048)) 27 | return; 28 | if (!__iotms_usable[$item[detective school application]]) 29 | return; 30 | 31 | //FIXME mention how much more they need to upgrade to the next badge? 32 | if (__misc_state["in run"] && in_ronin()) 33 | { 34 | int cop_dollars_have = $item[cop dollar].available_amount(); 35 | if (cop_dollars_have > 0) 36 | { 37 | string [int] description; 38 | 39 | string [int] buyables; 40 | 41 | string [int] ml_types_can_eat_drink; 42 | if (__misc_state["can eat just about anything"]) 43 | ml_types_can_eat_drink.listAppend("food"); 44 | if (__misc_state["can drink just about anything"]) 45 | ml_types_can_eat_drink.listAppend("drink"); 46 | if (ml_types_can_eat_drink.count() > 0 && cop_dollars_have >= 4) 47 | buyables.listAppend(ml_types_can_eat_drink.listJoinComponents("/")); 48 | if (cop_dollars_have >= 10) 49 | { 50 | buyables.listAppend("a -combat potion (50 turns)"); 51 | } 52 | if (buyables.count() > 0) 53 | description.listAppend("Buy " + buyables.listJoinComponents(", ", "or") + "."); 54 | resource_entries.listAppend(ChecklistEntryMake("__item cop dollar", "shop.php?whichshop=detective", ChecklistSubentryMake(pluralise($item[cop dollar]), "", description), 7).ChecklistEntrySetIDTag("Detective school precinct shop")); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Eight Days a Week Pills.ash: -------------------------------------------------------------------------------- 1 | RegisterResourceGenerationFunction("IOTMEightDaysAWeekPillsGenerateResource"); 2 | void IOTMEightDaysAWeekPillsGenerateResource(ChecklistEntry [int] resource_entries) 3 | { 4 | if (!__iotms_usable[lookupItem("Eight Days a Week Pill Keeper")]) return; 5 | if (get_property_boolean("_freePillKeeperUsed") && spleen_limit() - my_spleen_use() < 3) return; 6 | 7 | ChecklistSubentry getPills() { 8 | // Title 9 | string main_title = "Take a pill"; 10 | 11 | // Subtitle 12 | string subtitle = "First is Free!"; 13 | if (get_property_boolean("_freePillKeeperUsed")) { 14 | subtitle = "-3 Spleen"; 15 | } 16 | 17 | // Entries 18 | string [int] description; 19 | description.listAppend(HTMLGenerateSpanOfClass("Monday:", "r_bold") + " Yellow ray (30 turns)"); 20 | description.listAppend(HTMLGenerateSpanOfClass("Tuesday:", "r_bold") + " Double potion length"); 21 | description.listAppend(HTMLGenerateSpanOfClass("Wednesday:", "r_bold") + " Force Non-Combat"); 22 | description.listAppend(HTMLGenerateSpanOfClass("Thursday:", "r_bold") + " +4 all res (30 turns)"); 23 | description.listAppend(HTMLGenerateSpanOfClass("Friday:", "r_bold") + " +100% all stats (30 turns)"); 24 | description.listAppend(HTMLGenerateSpanOfClass("Saturday:", "r_bold") + " Familiars 20 pounds (30 turns)"); 25 | description.listAppend(HTMLGenerateSpanOfClass("Sunday:", "r_bold") + " Force semi-rare"); 26 | description.listAppend(HTMLGenerateSpanOfClass("Funday:", "r_bold") + " Random adventures (30 turns)"); 27 | 28 | return ChecklistSubentryMake(main_title, subtitle, description); 29 | } 30 | 31 | ChecklistEntry entry; 32 | entry.image_lookup_name = "__item Eight Days a Week Pill Keeper"; 33 | entry.url = "main.php?eowkeeper=1"; 34 | entry.tags.id = "Pill keeper resource"; 35 | 36 | ChecklistSubentry pills = getPills(); 37 | if (pills.entries.count() > 0) { 38 | entry.subentries.listAppend(pills); 39 | } 40 | 41 | if (entry.subentries.count() > 0) { 42 | resource_entries.listAppend(entry); 43 | } 44 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/GenieBottle.ash: -------------------------------------------------------------------------------- 1 | RegisterResourceGenerationFunction("IOTMGenieBottleGenerateResource"); 2 | void IOTMGenieBottleGenerateResource(ChecklistEntry [int] resource_entries) 3 | { 4 | if (lookupItem("genie bottle").item_amount() + lookupItem("pocket wish").item_amount() == 0) return; 5 | 6 | int wishes_left = 0; 7 | if (__misc_state["in run"] && in_ronin()) 8 | wishes_left += lookupItem("pocket wish").item_amount(); 9 | if (lookupItem("genie bottle").item_amount() > 0 && mafiaIsPastRevision(18219) && my_path_id() != PATH_BEES_HATE_YOU) 10 | wishes_left += clampi(3 - get_property_int("_genieWishesUsed"), 0, 3); 11 | string [int] description; 12 | 13 | if (wishes_left > 0) 14 | { 15 | string url = "inv_use.php?pwd=" + my_hash() + "&whichitem=9529"; 16 | if (lookupItem("genie bottle").item_amount() == 0 || get_property_int("_genieWishesUsed") >= 3) 17 | url = "inv_use.php?pwd=" + my_hash() + "&whichitem=9537"; 18 | 19 | string potential_monsters = SFaxGeneratePotentialFaxes(true, $monsters[ninja snowman assassin,modern zmobie,giant swarm of ghuol whelps, screambat]).listJoinComponents("|
"); 20 | if (potential_monsters != "") 21 | description.listAppend("Could fight a monster:
" + potential_monsters); 22 | resource_entries.listAppend(ChecklistEntryMake("__item genie bottle", url, ChecklistSubentryMake(pluralise(wishes_left, "wish", "wishes"), "", description), 1).ChecklistEntrySetIDTag("Genie bottle resource")); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Gingerbread City.ash: -------------------------------------------------------------------------------- 1 | RegisterResourceGenerationFunction("IOTMGingerbreadCityGenerateResource"); 2 | void IOTMGingerbreadCityGenerateResource(ChecklistEntry [int] resource_entries) 3 | { 4 | if ($skill[Ceci N'Est Pas Un Chapeau].have_skill() && !get_property_boolean("_ceciHatUsed") && my_basestat($stat[moxie]) >= 150 && __misc_state["in run"]) 5 | { 6 | //Umm... I guess? 7 | //It doesn't seem amazing in aftercore, so we're not displaying it? Is that the right decision? 8 | //Almost all of its enchantments are better on other hats. And you can't choose which one you get, so it'd just be annoying the user. 9 | resource_entries.listAppend(ChecklistEntryMake("__skill Ceci N'Est Pas Un Chapeau", "skillz.php", ChecklistSubentryMake("Ceci N'Est Pas Un Chapeau", "", "Random enchantment hat, 300MP."), 10).ChecklistEntrySetIDTag("Gingerbread city not-a-chapeau skill")); 10 | } 11 | 12 | if ($skill[Gingerbread Mob Hit].skill_is_usable() && mafiaIsPastRevision(17566)) 13 | { 14 | if (!get_property_boolean("_gingerbreadMobHitUsed")) 15 | { 16 | string [int] description; 17 | description.listAppend("Combat skill, win a fight without taking a turn."); 18 | //FIXME replace with a better image 19 | resource_entries.listAppend(ChecklistEntryMake("__familiar Penguin Goodfella", "", ChecklistSubentryMake("Gingerbread mob hit", "", description), 0).ChecklistEntrySetCombinationTag("free instakill").ChecklistEntrySetIDTag("Gingerbread city mob hit free kill")); 20 | 21 | } 22 | } 23 | 24 | //http://kol.coldfront.net/thekolwiki/index.php/A_GingerGuide_to_Gingerbread_City 25 | 26 | //Things to acquire/unlock: 27 | //Studying in the library, which lets you acquire the seven-day sugar raygun. 28 | //Unlocking various areas. 29 | //Chocolate puppy. 30 | //Moneybag 31 | //gingerbread pistol 32 | //chocolate pocketwatch 33 | //Two skills...? 34 | //Laying track (does this reset on ascension...?) for a briefcase with lots of sprinkles...? 35 | //Studying train schedules for ??? 36 | //Gingerbread Best outfit components. 37 | //Um... candy crowbar -> breaking in? Do you ever do this in run? No, I think? 38 | //Counterfeit city to sell. 39 | //Gingerbread cigarette to sell. 40 | //Chocolate sculpture to sell. 41 | //Gingerbread gavel 42 | //More...? 43 | if ($locations[Gingerbread Civic Center,Gingerbread Industrial Zone,Gingerbread Train Station,Gingerbread Sewers,Gingerbread Upscale Retail District] contains __last_adventure_location) 44 | { 45 | //Show details: 46 | /* 47 | Unlocks: 48 | gingerAdvanceClockUnlocked 49 | gingerRetailUnlocked 50 | gingerSewersUnlocked 51 | gingerExtraAdventures - +10 adventures in area 52 | 53 | gingerSubwayLineUnlocked 54 | 55 | _gingerBiggerAlligators - a born liverpooler 56 | _gingerbreadMobHitUsed - used once/day free kill 57 | gingerNegativesDropped 58 | gingerTrainScheduleStudies - times studied the schedule 59 | gingerDigCount - times went digging at the train station 60 | gingerLawChoice - times studied law 61 | gingerMuscleChoice - times laid track 62 | */ 63 | //There's no per-turn tracker for this area. 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Haunted Doghouse.ash: -------------------------------------------------------------------------------- 1 | RegisterResourceGenerationFunction("IOTMHauntedDoghouseGenerateResource"); 2 | void IOTMHauntedDoghouseGenerateResource(ChecklistEntry [int] resource_entries) 3 | { 4 | if (!__misc_state["in run"]) 5 | return; 6 | if ($item[tennis ball].available_amount() > 0 && in_ronin() && $item[tennis ball].item_is_usable()) 7 | { 8 | resource_entries.listAppend(ChecklistEntryMake("__item tennis ball", "", ChecklistSubentryMake(pluralise($item[tennis ball]), "", "Free run/banish."), 6).ChecklistEntrySetCombinationTag("banish").ChecklistEntrySetIDTag("Haunted doghouse banish")); 9 | } 10 | //I, um, hmm. I guess there's not much to say. Poor lonely file, nearly empty. 11 | } 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Horsery.ash: -------------------------------------------------------------------------------- 1 | RegisterTaskGenerationFunction("IOTMHorseryGenerateTasks"); 2 | void IOTMHorseryGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 3 | { 4 | if (!__iotms_usable[lookupItem("Horsery contract")]) return; 5 | if (get_property("_horsery") == "" && my_meat() >= 500) 6 | { 7 | optional_task_entries.listAppend(ChecklistEntryMake("__item magical pony: Spectrum Dash", "place.php?whichplace=town_right&action=town_horsery", ChecklistSubentryMake("Bring along a horse!", "", "Probably the dark horse.")).ChecklistEntrySetIDTag("Horsery get a horse")); 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Items of the Month import.ash: -------------------------------------------------------------------------------- 1 | import "relay/TourGuide/Items of the Month/Barrel God.ash"; 2 | import "relay/TourGuide/Items of the Month/Tea Tree.ash"; 3 | import "relay/TourGuide/Items of the Month/Speakeasy.ash"; 4 | import "relay/TourGuide/Items of the Month/Deck of Every Card.ash"; 5 | import "relay/TourGuide/Items of the Month/Haunted Doghouse.ash"; 6 | import "relay/TourGuide/Items of the Month/Mayo Clinic.ash"; 7 | import "relay/TourGuide/Items of the Month/Smithsness.ash"; 8 | import "relay/TourGuide/Items of the Month/Tomes.ash"; 9 | import "relay/TourGuide/Items of the Month/Sugar.ash"; 10 | import "relay/TourGuide/Items of the Month/Crown of Thrones.ash"; 11 | import "relay/TourGuide/Items of the Month/Libram.ash"; 12 | import "relay/TourGuide/Items of the Month/Gardens.ash"; 13 | import "relay/TourGuide/Items of the Month/Plastic Vampire Fangs.ash"; 14 | import "relay/TourGuide/Items of the Month/DNA.ash"; 15 | import "relay/TourGuide/Items of the Month/Psychoanalytic.ash"; 16 | import "relay/TourGuide/Items of the Month/Grimstone.ash"; 17 | import "relay/TourGuide/Items of the Month/Machine Elf.ash"; 18 | import "relay/TourGuide/Items of the Month/Snojo.ash"; 19 | import "relay/TourGuide/Items of the Month/Telegraph Office.ash"; 20 | import "relay/TourGuide/Items of the Month/Witchess.ash"; 21 | import "relay/TourGuide/Items of the Month/Clan Floundry.ash"; 22 | import "relay/TourGuide/Items of the Month/Intergnat.ash"; 23 | import "relay/TourGuide/Items of the Month/Source Terminal.ash"; 24 | import "relay/TourGuide/Items of the Month/Detective School.ash"; 25 | import "relay/TourGuide/Items of the Month/Protonic Accelerator Pack.ash"; 26 | import "relay/TourGuide/Items of the Month/Time-Spinner.ash"; 27 | import "relay/TourGuide/Items of the Month/Thanksgarden.ash"; 28 | import "relay/TourGuide/Items of the Month/Gingerbread City.ash"; 29 | import "relay/TourGuide/Items of the Month/Space Jellyfish.ash"; 30 | import "relay/TourGuide/Items of the Month/Tunnel of Love.ash"; 31 | import "relay/TourGuide/Items of the Month/Spacegate.ash"; 32 | import "relay/TourGuide/Items of the Month/New You.ash"; 33 | import "relay/TourGuide/Items of the Month/KGBriefcase.ash"; 34 | import "relay/TourGuide/Items of the Month/Asdon Martin.ash"; 35 | import "relay/TourGuide/Items of the Month/Meteor Lore.ash"; 36 | import "relay/TourGuide/Items of the Month/GenieBottle.ash"; 37 | import "relay/TourGuide/Items of the Month/Horsery.ash"; 38 | import "relay/TourGuide/Items of the Month/XO Skeleton.ash"; 39 | import "relay/TourGuide/Items of the Month/Portable Pantogram.ash"; 40 | 41 | // 2018 42 | import "relay/TourGuide/Items of the Month/Garbage Tote.ash"; 43 | import "relay/TourGuide/Items of the Month/Zutara.ash"; 44 | // Missing: Pokefam 45 | // Missing: FantasyRealm 46 | import "relay/TourGuide/Items of the Month/God Lobster.ash"; 47 | import "relay/TourGuide/Items of the Month/BoomBox.ash"; 48 | import "relay/TourGuide/Items of the Month/Cat Burglar.ash"; 49 | import "relay/TourGuide/Items of the Month/Bastille Battalion.ash"; 50 | import "relay/TourGuide/Items of the Month/Neverending Party.ash"; 51 | import "relay/TourGuide/Items of the Month/Latte.ash"; 52 | import "relay/TourGuide/Items of the Month/Voting Booth.ash"; 53 | import "relay/TourGuide/Items of the Month/Boxing Daycare.ash"; 54 | 55 | // 2019 56 | import "relay/TourGuide/Items of the Month/Kramco Sausage-o-Matic.ash"; 57 | import "relay/TourGuide/Items of the Month/Lil Doctor Bag.ash"; 58 | import "relay/TourGuide/Items of the Month/Vampire Cloak.ash"; 59 | // Missing: PirateRealm 60 | import "relay/TourGuide/Items of the Month/May Saber.ash"; 61 | import "relay/TourGuide/Items of the Month/Rune Spoon.ash"; 62 | import "relay/TourGuide/Items of the Month/Beach Comb.ash"; 63 | import "relay/TourGuide/Items of the Month/Getaway Campsite.ash"; 64 | import "relay/TourGuide/Items of the Month/Pocket Professor.ash"; 65 | import "relay/TourGuide/Items of the Month/Eight Days a week Pills.ash"; 66 | import "relay/TourGuide/Items of the Month/Pizza Cube.ash"; 67 | import "relay/TourGuide/Items of the Month/Red Nosed Snapper.ash"; 68 | 69 | // 2020 70 | import "relay/TourGuide/Items of the Month/Bird-a-Day Calendar.ash"; 71 | import "relay/TourGuide/Items of the Month/Powerful Glove.ash"; 72 | import "relay/TourGuide/Items of the Month/Better Shrooms and Gardens.ash"; 73 | // Missing: Left-Hand Man 74 | import "relay/TourGuide/Items of the Month/Guzzlr.ash"; 75 | // Missing: Iunion 76 | import "relay/TourGuide/Items of the Month/Melodramedary.ash"; 77 | // Missing: SpinMaster lathe 78 | // Missing: Cargo cultist shorts 79 | import "relay/TourGuide/Items of the Month/Comprehensive Cartography.ash"; 80 | import "relay/TourGuide/Items of the Month/Superhero Cape.ash"; 81 | // Missing: box o' ghosts 82 | 83 | // 2021 84 | // Missing: packaged miniature crystal ball 85 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/KGBriefcase.ash: -------------------------------------------------------------------------------- 1 | RegisterResourceGenerationFunction("IOTMKGBriefcaseGenerateResource"); 2 | void IOTMKGBriefcaseGenerateResource(ChecklistEntry [int] resource_entries) 3 | { 4 | if (!__iotms_usable[lookupItem("kremlin's greatest briefcase")]) return; 5 | ChecklistEntry entry; 6 | entry.image_lookup_name = "__item Kremlin's Greatest Briefcase"; 7 | entry.importance_level = 5; 8 | entry.url = "place.php?whichplace=kgb"; 9 | entry.tags.id = "Kremlin Briefcase resource"; 10 | if (get_property_int("_kgbTranquilizerDartUses") < 3 && my_path_id() != PATH_POCKET_FAMILIARS) 11 | { 12 | string [int] description; 13 | description.listAppend("Free run/banishes for twenty turns.|Use the KGB tranquilizer dart skill in-combat."); 14 | if (lookupItem("kremlin's greatest briefcase").equipped_amount() == 0) 15 | { 16 | description.listAppend("Equip the briefcase first."); 17 | //entry.url = "inventory.php?which=2"; 18 | } 19 | resource_entries.listAppend(ChecklistEntryMake("__item Kremlin's Greatest Briefcase", entry.url, ChecklistSubentryMake(pluralise(3 - get_property_int("_kgbTranquilizerDartUses"), "briefcase dart", "briefcase darts"), "", description)).ChecklistEntrySetCombinationTag("banish").ChecklistEntrySetIDTag("Kremlin Briefcase tranq dart banish")); 20 | } 21 | int clicks_remaining = clampi(22 - get_property_int("_kgbClicksUsed"), 0, 22); 22 | if (!mafiaIsPastRevision(18110)) 23 | clicks_remaining = 0; 24 | if (clicks_remaining > 0) 25 | { 26 | string [int] description; 27 | description.listAppend("All sorts of things. Buffs, martinis, cigars!"); 28 | 29 | entry.subentries.listAppend(ChecklistSubentryMake(pluralise(clicks_remaining, "click", "clicks"), "", description)); 30 | } 31 | if (entry.subentries.count() > 0) 32 | resource_entries.listAppend(entry); 33 | } 34 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Latte.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("IOTMLatteGenerateResource"); 3 | void IOTMLatteGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (lookupItem("latte lovers member's mug").available_amount() == 0) return; 6 | 7 | int refills_remaining = clampi(3 - get_property_int("_latteRefillsUsed"), 0, 3); 8 | boolean banish_used = get_property_boolean("_latteBanishUsed"); 9 | boolean copy_used = get_property_boolean("_latteCopyUsed"); //more of an olfact than a copy 10 | boolean drink_used = get_property_boolean("_latteDrinkUsed"); 11 | 12 | int banishes_available = refills_remaining + (!banish_used ? 1 : 0); 13 | int copies_available = refills_remaining + (!copy_used ? 1 : 0); 14 | 15 | string url; 16 | boolean latte_needs_equipping = false; 17 | if (lookupItem("latte lovers member's mug").equipped_amount() == 0) 18 | { 19 | url = "inventory.php?which=2"; 20 | latte_needs_equipping = true; 21 | } 22 | if (banishes_available > 0) 23 | { 24 | string banish_url = url; 25 | string [int] description; 26 | 27 | if (banish_used) { 28 | banish_url = "main.php?latte=1"; 29 | description.listAppend(HTMLGenerateSpanFont("Must refill latte first.", "red")); 30 | } else if (latte_needs_equipping) { 31 | banish_url = "inventory.php?which=3"; 32 | description.listAppend(HTMLGenerateSpanFont("Equip the latte first", "red")); 33 | } else { 34 | description.listAppend("Free run/banish"); 35 | } 36 | 37 | resource_entries.listAppend(ChecklistEntryMake("__item latte lovers member's mug", banish_url, ChecklistSubentryMake(pluralise(banishes_available, "latte banish", "latte banishes"), "", description), 0).ChecklistEntrySetCombinationTag("banish").ChecklistEntrySetIDTag("Latte lovers mug throw banish")); 38 | } 39 | 40 | ChecklistEntry entry; 41 | entry.image_lookup_name = "__item latte lovers member's mug"; 42 | entry.url = "main.php?latte=1"; 43 | entry.tags.id = "Latte lovers mug resource"; 44 | 45 | if (refills_remaining > 0) 46 | { 47 | string [int] description; 48 | if (!banish_used && __misc_state["in run"]) 49 | description.listAppend(HTMLGenerateSpanFont("Use banish first.", "red")); 50 | entry.subentries.listAppend(ChecklistSubentryMake(pluralise(refills_remaining, "latte refill", "latte refills"), "", description)); 51 | } 52 | if (copies_available > 0) 53 | { 54 | string [int] description; 55 | description.listAppend("Offer Latte to Opponent in combat."); 56 | if (copy_used) 57 | { 58 | description.listAppend(HTMLGenerateSpanFont("Must refill latte first.", "red")); 59 | } 60 | if ($skill[Transcendent Olfaction].have_skill()) 61 | description.listAppend("Stack with Transcendent Olfaction."); 62 | entry.subentries.listAppend(ChecklistSubentryMake(pluralise(copies_available, "latte olfaction", "latte olfactions"), "", description)); 63 | } 64 | if (!drink_used && my_path_id() != PATH_VAMPIRE) 65 | { 66 | entry.subentries.listAppend(ChecklistSubentryMake("Gulp Latte available", "", "Restores half your HP and MP. Cast in combat.")); 67 | } 68 | if (entry.subentries.count() > 0) 69 | resource_entries.listAppend(entry); 70 | } 71 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/May Saber.ash: -------------------------------------------------------------------------------- 1 | RegisterTaskGenerationFunction("IOTMMaySaberPartyGenerateTasks"); 2 | void IOTMMaySaberPartyGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 3 | { 4 | if (lookupItem("Fourth of May Cosplay Saber").available_amount() == 0) return; 5 | 6 | if (get_property_int("_saberMod") == 0) { 7 | string [int] options; 8 | if (in_ronin()) { 9 | options.listAppend("Regen ~17 MP/adventure."); 10 | options.listAppend("+20 ML."); 11 | options.listAppend("+3 all resistances."); 12 | } 13 | options.listAppend("+10 familiar weight."); 14 | 15 | string [int] description; 16 | if (options.count() > 1) 17 | description.listAppend("Choose one of:|*" + options.listJoinComponents("|*")); 18 | else 19 | description.listAppend(options.listJoinComponents("|")); 20 | optional_task_entries.listAppend(ChecklistEntryMake("__item Fourth of May Cosplay Saber", "main.php?action=may4", ChecklistSubentryMake("Modify your lightsaber", "", description), 8).ChecklistEntrySetIDTag("Fourth may saber daily upgrade")); 21 | } 22 | 23 | 24 | monster saber_monster = get_property_monster("_saberForceMonster"); 25 | if (saber_monster != $monster[none]) { 26 | int fights_left = clampi(get_property_int("_saberForceMonsterCount"), 0, 3); 27 | location [int] possible_appearance_locations = saber_monster.getPossibleLocationsMonsterCanAppearInNaturally().listInvert(); 28 | 29 | if (fights_left > 0 && possible_appearance_locations.count() > 0) 30 | optional_task_entries.listAppend(ChecklistEntryMake("__monster " + saber_monster, possible_appearance_locations[0].getClickableURLForLocation(), ChecklistSubentryMake("Fight " + pluralise(fights_left, "more " + saber_monster, "more " + saber_monster + "s"), "", "Will appear when you adventure in " + possible_appearance_locations.listJoinComponents(", ", "or") + "."), -1).ChecklistEntrySetIDTag("Fourth may saber friend copies")); 31 | } 32 | } 33 | 34 | RegisterResourceGenerationFunction("IOTMMaySaberGenerateResource"); 35 | void IOTMMaySaberGenerateResource(ChecklistEntry [int] resource_entries) 36 | { 37 | if (lookupItem("Fourth of May Cosplay Saber").available_amount() == 0) return; 38 | 39 | int uses_remaining = clampi(5 - get_property_int("_saberForceUses"), 0, 5); 40 | 41 | if (uses_remaining > 0) { 42 | if (true) { 43 | //The section that will be sent as a stand-alone resource 44 | string url; 45 | if (!lookupItem("Fourth of May Cosplay Saber").equipped()) 46 | url = "inventory.php?ftext=fourth+of+may+cosplay+saber"; 47 | 48 | string [int] description; 49 | description.listAppend("Use the force skill in combat, which lets you:"); 50 | description.listAppend("Banish a monster for thirty turns."); 51 | description.listAppend("Make the monster appear 3x times its zone."); 52 | description.listAppend("Or collect all* their items."); 53 | if (my_path_id() == PATH_COMMUNITY_SERVICE && $skill[Meteor Lore].have_skill()) 54 | description.listAppend("Bonus! Use Meteor Shower + lightsaber skill to save a bunch of turns on weapon damage/spell damage/familiar weight tests."); 55 | 56 | //description.listAppend("Choose one of:|*" + options.listJoinComponents("|*")); 57 | resource_entries.listAppend(ChecklistEntryMake("__item Fourth of May Cosplay Saber", url, ChecklistSubentryMake(uses_remaining.pluralise("force use", "forces uses"), "", description)).ChecklistEntrySetIDTag("Fourth may saber force resource")); //"forces uses"? typo or reference/joke? 58 | } 59 | 60 | if (true) { 61 | //The section that will be sent as a "banish" tile 62 | string [int] description; 63 | if (!lookupItem("Fourth of May Cosplay Saber").equipped()) 64 | description.listAppend(HTMLGenerateSpanFont("Equip the Fourth of May saber first", "red")); 65 | else 66 | description.listAppend("Rollover runaway-like/banish"); 67 | 68 | resource_entries.listAppend(ChecklistEntryMake("__item Fourth of May Cosplay Saber", "inventory.php?which=2", ChecklistSubentryMake("(up to) " + uses_remaining.pluralise("force banish", "forces banishes"), "", description)).ChecklistEntrySetCombinationTag("banish").ChecklistEntrySetIDTag("Fourth may saber force banish")); 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Melodramedary.ash: -------------------------------------------------------------------------------- 1 | RegisterTaskGenerationFunction("IOTMMelodramedaryGenerateTasks"); 2 | void IOTMMelodramedaryGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 3 | { 4 | if (my_familiar() != lookupFamiliar("Melodramedary")) return; 5 | 6 | if (get_property_int("camelSpit") == 100) 7 | task_entries.listAppend(ChecklistEntryMake("__familiar Melodramedary", "familiar.php", ChecklistSubentryMake("Melodramedary: Locked and Loaded!", "", HTMLGenerateSpanFont("Spit!", "blue")), -11).ChecklistEntrySetIDTag("Melodramedary familiar spit ready")); 8 | } 9 | 10 | RegisterResourceGenerationFunction("IOTMMelodramedaryResource"); 11 | void IOTMMelodramedaryResource(ChecklistEntry [int] resource_entries) 12 | { 13 | if (!lookupFamiliar("Melodramedary").familiar_is_usable()) return; 14 | 15 | int spit_o_meter = get_property_int("camelSpit"); 16 | 17 | if (!__misc_state["in run"] && spit_o_meter < 100 && my_familiar() != lookupFamiliar("Melodramedary")) return; 18 | 19 | string title; 20 | string [int] description; 21 | 22 | if (spit_o_meter < 100) { 23 | title = spit_o_meter + "% Melodramedary Spit Charge"; 24 | 25 | boolean camelCapped = lookupFamiliar("Melodramedary").familiar_equipped_equipment() == lookupItem("dromedary drinking helmet"); 26 | int fights_left = floor((101 - spit_o_meter) / 3.33); 27 | if (camelCapped) 28 | fights_left = ceil(fights_left / 1.3); 29 | 30 | description.listAppend("Ready in " + (camelCapped ? "~" : "") + fights_left.pluralise("fight", "fights") + "."); 31 | } else { 32 | title = "Melodramedary: Locked and Loaded!"; 33 | description.listAppend(HTMLGenerateSpanFont("Spit!", "blue")); 34 | } 35 | 36 | description.listAppend("Spit on self for 15 turns of +100% stats & weapon/spell dmg."); 37 | description.listAppend("Spit on monsters to get 4x of each of their items (2x for conditional items)."); 38 | //There are also certainly even more options of varying effectiveness. 39 | 40 | string [int] options; 41 | if (__misc_state["in run"] && my_path_id() != PATH_COMMUNITY_SERVICE) { 42 | int bowling_progress = get_property_int("hiddenBowlingAlleyProgress"); 43 | if (bowling_progress > 0 && bowling_progress < 7) { 44 | int balls_needed = 6 - bowling_progress - $item[bowling ball].available_amount(); 45 | if (balls_needed >= 2) 46 | options.listAppend("Pygmy bowler; needs +150% item."); 47 | } 48 | 49 | if (__quest_state["Level 9"].state_boolean["bridge complete"] && __quest_state["Level 9"].state_int["twin peak progress"] != 15 && $item[rusty hedge trimmers].available_amount() < __quest_state["Level 9"].state_int["peak tests remaining"] - 1) 50 | options.listAppend("Hedge beast; needs +567% item."); 51 | 52 | if (__quest_state["Level 11 Ron"].mafia_internal_step == 3 || __quest_state["Level 11 Ron"].mafia_internal_step == 4) //Can't really compare with progress/cable uses for that day, since they could encounter red herring/snapper / wait for the next day 53 | options.listAppend("Red butler; needs +234% item."); 54 | 55 | if (__quest_state["Level 12"].mafia_internal_step > 1 && !__quest_state["Level 12"].state_boolean["Lighthouse Finished"] && $item[barrel of gunpowder].available_amount() < 4) 56 | options.listAppend("Lobsterfrogman; prob. a weak option."); 57 | 58 | if (!__quest_state["Level 12"].finished && __quest_state["Level 12"].state_int["hippies left on battlefield"] > 0 && __quest_state["Level 12"].state_int["hippies left on battlefield"] <= 600 && __misc_state["yellow ray potentially available"]) 59 | options.listAppend("Green Ops Soldier (for free runaways); needs yellow ray."); 60 | } 61 | if (options.count() > 0) 62 | description.listAppend("Possible targets:" + options.listJoinComponents("
").HTMLGenerateIndentedText()); 63 | 64 | resource_entries.listAppend(ChecklistEntryMake("__familiar Melodramedary", "familiar.php", ChecklistSubentryMake(title, description), 1).ChecklistEntrySetIDTag("Melodramedary familiar resource")); 65 | } 66 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/New You.ash: -------------------------------------------------------------------------------- 1 | RegisterResourceGenerationFunction("IOTMNewYouGenerateResource"); 2 | void IOTMNewYouGenerateResource(ChecklistEntry [int] resource_entries) 3 | { 4 | if (__misc_state["in run"] && in_ronin()) 5 | { 6 | string [item] affirmation_effects; 7 | string [item] affirmation_combat_uses; 8 | affirmation_effects[lookupItem("Daily Affirmation: Adapt to Change Eventually")] = "+4 stats/fight, +50% init"; 9 | if (!__misc_state["need to level"]) 10 | affirmation_effects[lookupItem("Daily Affirmation: Adapt to Change Eventually")] = "+50% init"; 11 | affirmation_effects[lookupItem("Daily Affirmation: Always be Collecting")] = "+50% item, +100% meat"; 12 | affirmation_effects[lookupItem("Daily Affirmation: Be a Mind Master")] = "+100% spell damage, 15 MP regen"; 13 | affirmation_effects[lookupItem("Daily Affirmation: Be Superficially interested")] = "-combat / +combat (togglable)"; 14 | affirmation_effects[lookupItem("Daily Affirmation: Keep Free Hate in your Heart")] = "+30 ML"; 15 | affirmation_effects[lookupItem("Daily Affirmation: Think Win-Lose")] = "+50% all stats"; 16 | affirmation_effects[lookupItem("Daily Affirmation: Work For Hours a Week")] = "+5 familiar weight, 15 HP regen"; 17 | if (__misc_state["familiars temporarily blocked"]) 18 | affirmation_effects[lookupItem("Daily Affirmation: Work For Hours a Week")] = "15 HP regen"; 19 | 20 | 21 | affirmation_combat_uses[lookupItem("Daily Affirmation: Adapt to Change Eventually")] = "reroll monster"; //monster change 22 | affirmation_combat_uses[lookupItem("Daily Affirmation: Always be Collecting")] = "duplicate item drops"; 23 | affirmation_combat_uses[lookupItem("Daily Affirmation: Be a Mind Master")] = "banish for 80 turns (not free)"; 24 | if (!__misc_state["have reusable olfaction equivalent"]) 25 | affirmation_combat_uses[lookupItem("Daily Affirmation: Be Superficially interested")] = "olfact weakly"; 26 | if (hippy_stone_broken()) 27 | affirmation_combat_uses[lookupItem("Daily Affirmation: Keep Free Hate in your Heart")] = "gain 3 PVP fights"; 28 | affirmation_combat_uses[lookupItem("Daily Affirmation: Think Win-Lose")] = "instakill"; 29 | affirmation_combat_uses[lookupItem("Daily Affirmation: Work For Hours a Week")] = "earn some meat"; 30 | 31 | ChecklistEntry entry; 32 | foreach it in affirmation_effects 33 | { 34 | if (it.item_amount() == 0) continue; 35 | if (!it.item_is_usable()) continue; 36 | if (!it.to_effect().effect_is_usable()) continue; 37 | if (entry.image_lookup_name == "") 38 | entry.image_lookup_name = "__item " + it; 39 | string combat_text = ""; 40 | if (affirmation_combat_uses[it] != "") 41 | combat_text = "Or throw in combat to " + affirmation_combat_uses[it] + "."; 42 | ChecklistSubentry subentry = ChecklistSubentryMake(pluralise(it), "100 turns, " + affirmation_effects[it], combat_text); 43 | if (it == lookupItem("Daily Affirmation: Think Win-Lose")) 44 | { 45 | resource_entries.listAppend(ChecklistEntryMake("__item " + it, "", subentry).ChecklistEntrySetCombinationTag("free instakill").ChecklistEntrySetIDTag("New you affirmation win-lose free kill")); 46 | } 47 | else if (it == lookupItem("Daily Affirmation: Be a Mind Master")) 48 | { 49 | resource_entries.listAppend(ChecklistEntryMake("__item " + it, "", subentry).ChecklistEntrySetCombinationTag("banish").ChecklistEntrySetIDTag("New you affirmation mind master banish")); 50 | } 51 | else 52 | entry.subentries.listAppend(subentry); 53 | } 54 | if (entry.subentries.count() > 0) 55 | { 56 | entry.url = "inventory.php?ftext=daily+affirmation"; 57 | entry.tags.id = "New you affirmation resource"; 58 | entry.importance_level = 6; 59 | resource_entries.listAppend(entry); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Pizza Cube.ash: -------------------------------------------------------------------------------- 1 | RegisterResourceGenerationFunction("IOTMPizzaCube"); 2 | void IOTMPizzaCube(ChecklistEntry [int] resource_entries) 3 | { 4 | if (!__iotms_usable[lookupItem("diabolic pizza cube")] || (fullness_limit() - my_fullness() < 3)) return; 5 | 6 | ChecklistSubentry getQuestItems() { 7 | // Title 8 | string main_title = "Make pizza"; 9 | 10 | // Subtitle 11 | string subtitle = "Some ingredients give useful items"; 12 | 13 | // Entries 14 | string [int] description; 15 | 16 | boolean need_cheese = !__quest_state["Trapper"].state_boolean["Past mine"] && $item[goat cheese].available_amount() < 3; 17 | 18 | if (need_cheese) { 19 | description.listAppend(HTMLGenerateSpanOfClass("\"cheese\"/\"milk\":", "r_bold") + " 3 goat cheese"); 20 | } 21 | description.listAppend(HTMLGenerateSpanOfClass("\"luck\"/\"green\":", "r_bold") + " clover"); 22 | description.listAppend(HTMLGenerateSpanOfClass("familiar equipment/hatchling:", "r_bold") + " equipment + xp for your familiar"); 23 | description.listAppend(HTMLGenerateSpanOfClass("\"cloak\":", "r_bold") + " dead mimic"); 24 | description.listAppend(HTMLGenerateSpanOfClass("combat item:", "r_bold") + " 3 of sonar-in-a-biscuit, Duskwalker syringe, cocktail napkin, unnamed cocktail, cigarette lighter, glark cable, short writ of habeas corpus"); 25 | 26 | return ChecklistSubentryMake(main_title, subtitle, description); 27 | } 28 | 29 | ChecklistSubentry getBuffs() { 30 | // Title 31 | string main_title = "Buffs"; 32 | 33 | // Subtitle 34 | string subtitle = ""; 35 | 36 | // Entries 37 | string [int] description; 38 | 39 | description.listAppend("Get any wishable buff"); 40 | 41 | return ChecklistSubentryMake(main_title, subtitle, description); 42 | } 43 | 44 | ChecklistEntry entry; 45 | entry.image_lookup_name = "__item diabolic pizza"; 46 | entry.url = "campground.php?action=workshed"; 47 | entry.tags.id = "Diabolic pizza cube resource"; 48 | 49 | ChecklistSubentry questItems = getQuestItems(); 50 | if (questItems.entries.count() > 0) { 51 | entry.subentries.listAppend(questItems); 52 | } 53 | 54 | ChecklistSubentry buffs = getBuffs(); 55 | if (buffs.entries.count() > 0) { 56 | entry.subentries.listAppend(buffs); 57 | } 58 | 59 | if (entry.subentries.count() > 0) { 60 | resource_entries.listAppend(entry); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Portable Pantogram.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterTaskGenerationFunction("IOTMPortablePantogramGenerateTasks"); 3 | void IOTMPortablePantogramGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 4 | { 5 | if (!__iotms_usable[lookupItem("portable pantogram")]) return; 6 | if (lookupItem("pantogram pants").available_amount() > 0) return; 7 | 8 | if (my_path_id() == PATH_BEES_HATE_YOU) return; 9 | string [int] description; 10 | 11 | 12 | string [int][int] slot_options; 13 | for i from 1 to 5 14 | slot_options[i] = listMakeBlankString(); 15 | 16 | //Slot 1: muscle, myst, moxie. Tower stat test, then muscle. 17 | if (__misc_state["in run"] && !__quest_state["Level 13"].state_boolean["Stat race completed"] && __quest_state["Level 13"].state_string["Stat race type"] != "") 18 | slot_options[1].listAppend(__quest_state["Level 13"].state_string["Stat race type"]); 19 | else if (__misc_state["in run"]) 20 | slot_options[1].listAppend("muscle"); 21 | //Slot 2: Resistance. Cold? Spooky? 22 | if (__misc_state["in run"]) 23 | { 24 | if (my_path_id() == PATH_COMMUNITY_SERVICE) 25 | slot_options[2].listAppend("hot resistance"); 26 | else if (!__quest_state["Level 9"].state_boolean["bridge complete"]) 27 | slot_options[2].listAppend("sleaze resistance"); //bridge building 28 | else 29 | slot_options[2].listAppend("spooky resistance"); //a-boo peak, and slightly more useful than cold resistance 30 | } 31 | //Slot 3: drops of blood (+40 HP). -3 MP to use skills is nice, I guess? but it takes a baconstone 32 | if (__misc_state["in run"]) 33 | slot_options[3].listAppend("drops of blood (+40 HP)"); 34 | if ($item[baconstone].available_amount() > 0 && __misc_state["in run"]) 35 | slot_options[3].listAppend("baconstone (-3 MP to use skills)"); 36 | //Slot 4: 37 | if ($item[taco shell].npc_price() > 0) 38 | slot_options[4].listAppend("taco shell (+30% meat)"); 39 | if (($item[porquoise].npc_price() > 0 && __misc_state["in run"]) || can_interact()) 40 | slot_options[4].listAppend("porquoise (+60% meat)"); 41 | if (my_path_id() == PATH_COMMUNITY_SERVICE) 42 | { 43 | slot_options[4].listAppend("your hopes (+20 weapon damage)"); 44 | slot_options[4].listAppend("your dreams (+20% spell damage)"); 45 | } 46 | if (__misc_state["in run"]) 47 | { 48 | } 49 | else 50 | { 51 | slot_options[4].listAppend("tiny dancer (+30% item)"); 52 | } 53 | //slot_options[4].listAppend("???"); 54 | //Slot 5: 55 | slot_options[5].listAppend("some self-respect (-combat)"); 56 | if (my_path_id() != PATH_COMMUNITY_SERVICE) 57 | slot_options[5].listAppend("some self-control (+combat)"); 58 | if (!__misc_state["in run"]) 59 | slot_options[5].listAppend("ten-leaf clover (hilarious items)"); 60 | if ($item[bar skin].available_amount() > 0 && __misc_state["in run"]) 61 | slot_options[5].listAppend("bar skin (+50% init)"); 62 | 63 | foreach slot_id in slot_options 64 | { 65 | if (slot_options[slot_id].count() == 0) continue; 66 | description.listAppend(slot_options[slot_id].listJoinComponents(", ", "or").capitaliseFirstLetter() + "."); 67 | } 68 | optional_task_entries.listAppend(ChecklistEntryMake("__item portable pantogram", "inv_use.php?pwd=" + my_hash() + "&whichitem=9573", ChecklistSubentryMake("Summon pants", "", description), 1).ChecklistEntrySetIDTag("Portable pantogram summon")); 69 | } 70 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Powerful Glove.ash: -------------------------------------------------------------------------------- 1 | RegisterResourceGenerationFunction("IOTMPowerfulGloveGenerateResource"); 2 | void IOTMPowerfulGloveGenerateResource(ChecklistEntry [int] resource_entries) 3 | { 4 | if (!$item[Powerful Glove].have()) return; 5 | 6 | int chargeLeft = 100 - get_property_int("_powerfulGloveBatteryPowerUsed"); 7 | 8 | if (chargeLeft < 5) return; 9 | 10 | string url = "skillz.php"; 11 | if (!$item[Powerful Glove].equipped()) 12 | url = "inventory.php?ftext=powerful+glove"; 13 | 14 | string [int] description; 15 | description.listAppend(HTMLGenerateSpanOfClass("Invisible Avatar (5% charge):", "r_bold") + " -10% combat."); 16 | description.listAppend(HTMLGenerateSpanOfClass("Triple Size (5% charge):", "r_bold") + " +200% all attributes."); 17 | if (chargeLeft >= 10) 18 | description.listAppend(HTMLGenerateSpanOfClass("Replace Enemy (10% charge):", "r_bold") + " Swap monster."); 19 | description.listAppend(HTMLGenerateSpanOfClass("Shrink Enemy (5% charge):", "r_bold") + " Delevel."); 20 | 21 | resource_entries.listAppend(ChecklistEntryMake("__item Powerful Glove", url, ChecklistSubentryMake(chargeLeft + "% battery charge", "", description)).ChecklistEntrySetIDTag("Powerful glove skills resource")); 22 | } 23 | 24 | RegisterTaskGenerationFunction("IOTMPowerfulGloveTask"); 25 | void IOTMPowerfulGloveTask(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 26 | { 27 | if (!__misc_state["in run"] || !$item[Powerful Glove].have() || $item[Powerful Glove].have_equipped()) return; 28 | 29 | boolean is_plumber = my_path_id() == PATH_OF_THE_PLUMBER; 30 | 31 | string [int] glove_drops; 32 | 33 | if (!__quest_state["Level 13"].state_boolean["digital key used"] && $item[digital key].available_amount() + $item[digital key].creatable_amount() == 0) 34 | glove_drops.listAppend("pixels"); 35 | if (is_plumber) 36 | glove_drops.listAppend("coins"); 37 | 38 | if (glove_drops.count() == 0) return; 39 | 40 | optional_task_entries.listAppend(ChecklistEntryMake("__item white pixel", "place.php?whichplace=forestvillage&action=fv_mystic", ChecklistSubentryMake("Equip Powerful Glove", "", "Get extra " + glove_drops.listJoinComponents(" and ") + "."), is_plumber ? -10 : 0).ChecklistEntrySetIDTag("Powerful glove equip reminder")); 41 | } 42 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Rune Spoon.ash: -------------------------------------------------------------------------------- 1 | 2 | //moonTuned 3 | RegisterResourceGenerationFunction("IOTMRuneSpoonGenerateResource"); 4 | void IOTMRuneSpoonGenerateResource(ChecklistEntry [int] resource_entries) 5 | { 6 | item spoon = lookupItem("hewn moon-rune spoon"); 7 | if (!spoon.have() && spoon.closet_amount() == 0 || my_sign().to_lower_case() == "bad moon") return; 8 | 9 | if (!get_property_boolean("moonTuned")) 10 | { 11 | stat [string] stat_for_sign = 12 | { 13 | "Mongoose":$stat[Muscle], 14 | "Wallaby":$stat[Mysticality], 15 | "Vole":$stat[Moxie], 16 | 17 | "Platypus":$stat[Muscle], 18 | "Opossum":$stat[Mysticality], 19 | "Marmot":$stat[Moxie], 20 | 21 | "Wombat":$stat[Muscle], 22 | "Blender":$stat[Mysticality], 23 | "Packrat":$stat[Moxie], 24 | }; 25 | string [string] signs = 26 | { 27 | "Mongoose":"+20% physical damage, knoll access, and free smithing", 28 | "Wallaby":"+20% spell damage, knoll access, and free smithing", 29 | "Vole":"+20% init, knoll access, and free smithing", 30 | 31 | "Platypus":"+5 familiar weight and canadia access", 32 | "Opossum":"+5 adventures/day from food and canadia access", 33 | "Marmot":"+1 extra clover/day and canadia access", 34 | 35 | "Wombat":"+20% meat and gnome access", 36 | "Blender":"+5 adventures/day from drinks and gnome access", 37 | "Packrat":"+10% item and gnome access", 38 | 39 | }; 40 | boolean [string] signs_to_output_as_ideas = $strings[Marmot,Platypus,Opossum,Blender,Packrat]; 41 | 42 | if (!__misc_state["in run"]) 43 | signs_to_output_as_ideas = $strings[Platypus,Opossum,Wombat,Blender,Packrat]; 44 | boolean our_sign_is_currently_good_for_stats = stat_for_sign[my_sign()] == my_primestat(); 45 | string [int] description; 46 | description.listAppend("Use the hewn moon-rune spoon. Lets you switch to any other moon sign."); 47 | if ($strings[Mongoose,Wallaby,Vole] contains my_sign()) 48 | { 49 | string [int] todo; 50 | if (!__misc_state["desert beach available"]) 51 | todo.listAppend("assemble a bitchin' meatcar"); 52 | if (!have_outfit_components("Bugbear Costume")) 53 | todo.listAppend("buy a bugbear costume"); 54 | if (todo.count() > 0) 55 | description.listAppend("May want to " + todo.listJoinComponents(", ", "and") + " before switching signs."); 56 | } 57 | string [int] options; 58 | 59 | foreach sign, desc in signs 60 | { 61 | if (my_sign() == sign) continue; 62 | if (!signs_to_output_as_ideas[sign]) continue; 63 | if (sign == "Platypus" && __misc_state["familiars temporarily blocked"]) continue; 64 | if (sign == "Opossum" && (!__misc_state["can eat just about anything"] || my_path_id() == PATH_SLOW_AND_STEADY)) continue; 65 | if (sign == "Blender" && (!__misc_state["can drink just about anything"] || my_path_id() == PATH_SLOW_AND_STEADY)) continue; 66 | boolean this_sign_is_good_for_mainstat_gain = stat_for_sign[sign] == my_primestat(); 67 | string line = "" + sign + ": " + desc + "."; 68 | if (!this_sign_is_good_for_mainstat_gain && __misc_state["need to level"] && __misc_state["in run"]) 69 | line += " Won't give mainstat gains."; 70 | else if (this_sign_is_good_for_mainstat_gain && __misc_state["need to level"] && __misc_state["in run"]) 71 | line += " Will give mainstat gains."; 72 | options.listAppend(line); 73 | } 74 | 75 | description.listAppend("Currently " + my_sign() + ": " + signs[my_sign()] + "."); 76 | if (options.count() > 0) 77 | description.listAppend("Ideas:|*" + options.listJoinComponents("
")); 78 | 79 | string url = "inv_use.php?whichitem=10254&pwd=" + my_hash(); 80 | if (!spoon.have() && spoon.closet_amount() > 0) 81 | url = "closet.php?which=2"; 82 | resource_entries.listAppend(ChecklistEntryMake("__item " + spoon, url, ChecklistSubentryMake("Moon sign tunable", "", description), 10).ChecklistEntrySetIDTag("Roon spoon moon boon toon moon")); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Spacegate.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("IOTMSpacegateGenerateResource"); 3 | void IOTMSpacegateGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (!__iotms_usable[lookupItem("Spacegate access badge")]) 6 | return; 7 | if (!get_property_boolean("_spacegateVaccine") && my_path_id() != PATH_G_LOVER) 8 | { 9 | boolean rainbow_unlocked = get_property_boolean("spacegateVaccine1"); //+3 all res 10 | boolean broad_spectrum_unlocked = get_property_boolean("spacegateVaccine2"); //+50% all stats 11 | boolean emotional_unlocked = get_property_boolean("spacegateVaccine3"); //+30 ML 12 | 13 | string [int] options; 14 | if (emotional_unlocked) 15 | options.listAppend("+30 ML"); 16 | if (broad_spectrum_unlocked) 17 | options.listAppend("+50% stats"); 18 | if (rainbow_unlocked) 19 | options.listAppend("+3 all res"); 20 | 21 | boolean missing_one = !rainbow_unlocked || !broad_spectrum_unlocked || !emotional_unlocked; 22 | if (missing_one && lookupItem("spacegate research").available_amount() > 0) 23 | options.listAppend("unlock additional vaccines"); 24 | if (options.count() > 0) 25 | { 26 | string [int] description; 27 | description.listAppend("30 turns, once/day.|" + options.listJoinComponents(", ", "or").capitaliseFirstLetter() + "."); 28 | 29 | resource_entries.listAppend(ChecklistEntryMake("__item plus sign", "place.php?whichplace=spacegate&action=sg_vaccinator", ChecklistSubentryMake("Vaccination", "", description), 8).ChecklistEntrySetIDTag("Spacegate daily vaccine resource")); 30 | } 31 | } 32 | if (__misc_state["in run"] && my_primestat() == $stat[moxie] && __misc_state["need to level"] && get_property("_spacegatePlanetName") == "") 33 | { 34 | //Dial TFHSXKK: 35 | string [int] description; 36 | description.listAppend("Dial TFHSXKK, and skip every adventure until you reach Paradise Under a Strange Sun.|Will give 1000 stats and cost a turn. Not strictly optimal."); 37 | resource_entries.listAppend(ChecklistEntryMake("__item portable spacegate", "place.php?whichplace=spacegate&action=sg_Terminal", ChecklistSubentryMake("Spacegate dial", "", description), 8).ChecklistEntrySetIDTag("Spacegate moxie boost trick")); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Sugar.ash: -------------------------------------------------------------------------------- 1 | 2 | void SugarGenerateSuggestions(string [int] suggestions) 3 | { 4 | if (!__misc_state["in run"]) 5 | return; 6 | if ($item[sugar shield].available_amount() == 0 && $item[snow suit].available_amount() == 0) 7 | suggestions.listAppend("Sugar shield: +10 familiar weight equip"); 8 | if ($item[sugar chapeau].available_amount() == 0 && !__quest_state["Level 13"].state_boolean["past tower monsters"]) 9 | suggestions.listAppend("Sugar chapeau: +50% spell damage (tower killing)"); 10 | } 11 | 12 | RegisterResourceGenerationFunction("IOTMSugarGenerateResource"); 13 | void IOTMSugarGenerateResource(ChecklistEntry [int] resource_entries) 14 | { 15 | if (!$item[sugar sheet].is_unrestricted()) 16 | return; 17 | item [int] sugar_crafted_items; 18 | for i from 4178 to 4183 19 | { 20 | sugar_crafted_items.listAppend(i.to_item()); 21 | } 22 | ChecklistSubentry [int] subentries; 23 | TagGroup tags; 24 | tags.id = "Sugar sheet folding resource"; 25 | 26 | string image_name = ""; 27 | 28 | if ($item[sugar sheet].available_amount() > 0 && __misc_state["in run"] && in_ronin()) 29 | { 30 | string [int] suggestions; 31 | SugarGenerateSuggestions(suggestions); 32 | subentries.listAppend(ChecklistSubentryMake(pluralise($item[sugar sheet]), "", suggestions)); 33 | 34 | image_name = "sugar sheet"; 35 | } 36 | foreach key in sugar_crafted_items 37 | { 38 | item it = sugar_crafted_items[key]; 39 | if (it.available_amount() == 0) 40 | continue; 41 | int counter = get_property_int("sugarCounter" + it.to_int()); 42 | if (counter == 0 && (!__misc_state["in run"] || !in_ronin())) //in aftercore, probably not as relevant 43 | continue; 44 | int combats_left = 31 - counter; 45 | subentries.listAppend(ChecklistSubentryMake(pluralise(it), "", pluralise(combats_left, "combat", "combats") + " left.")); 46 | if (image_name.length() == 0) 47 | image_name = it; 48 | } 49 | if (subentries.count() > 0) 50 | { 51 | resource_entries.listAppend(ChecklistEntryMake(image_name, "", subentries, 10)); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Time-Spinner.ash: -------------------------------------------------------------------------------- 1 | RegisterResourceGenerationFunction("IOTMTimeSpinnerGenerateResource"); 2 | void IOTMTimeSpinnerGenerateResource(ChecklistEntry [int] resource_entries) 3 | { 4 | if (!mafiaIsPastRevision(17209)) 5 | return; 6 | //Warn about eating if they're low on turns - you can't use the time spinner when you're out of adventures. 7 | if ($item[Time-Spinner].available_amount() == 0) 8 | return; 9 | if (my_path_id() == PATH_G_LOVER) 10 | return; 11 | int minutes_left = clampi(10 - get_property_int("_timeSpinnerMinutesUsed"), 0, 10); 12 | if (minutes_left <= 0) 13 | return; 14 | 15 | string [int] description; 16 | 17 | if (minutes_left >= 3) 18 | { 19 | //Recent fight - 3 minutes - fight something past. Umm... hmm... same as any monster you copy? Though with restrictions. Plus olfaction-lite in NA. 20 | int amount = minutes_left / 3; 21 | description.listAppend(HTMLGenerateSpanOfClass(pluralise(amount, "recent fight", "recent fights"), "r_bold") + ": Re-fight a monster this ascension."); 22 | //Delicious meal - 3 minutes 23 | if (__misc_state["can eat just about anything"] && availableFullness() > 0) 24 | { 25 | description.listAppend(HTMLGenerateSpanOfClass(pluralise(amount, "meal", "meals"), "r_bold") + ": Re-eat something else today."); 26 | } 27 | } 28 | //Way back in time - 1 minute, stats, costs a turn(?) 29 | if (minutes_left >= 2) 30 | { 31 | //Visit the far future - 2 minutes, star-trek mini-game, lets you replicate things. Script fodder. 32 | if (!get_property_boolean("_timeSpinnerReplicatorUsed")) 33 | { 34 | string [int] options; 35 | if (__misc_state["can eat just about anything"] && availableFullness() > 0) 36 | options.listAppend("epic food"); 37 | if (__misc_state["can drink just about anything"] && availableDrunkenness() > 0) 38 | options.listAppend("drink"); 39 | if (!in_ronin()) 40 | options.listAppend("something to sell"); 41 | if (my_path_id() == PATH_GELATINOUS_NOOB && !lookupSkill("Pathological Greed").have_skill() && $item[shot of Kardashian Gin].available_amount() == 0) 42 | { 43 | options.listAppend("Kardashian Gin for +meat skill"); 44 | } 45 | if (options.count() == 0) 46 | options.listAppend("item"); 47 | description.listAppend(HTMLGenerateSpanOfClass("Future", "r_bold") + ": once/day " + options.listJoinComponents(" / ") + "."); 48 | } 49 | } 50 | //Play a time prank - 1 minute, heart 51 | 52 | resource_entries.listAppend(ChecklistEntryMake("Hourglass", "inv_use.php?whichitem=9104&pwd=" + my_hash(), ChecklistSubentryMake(pluralise(minutes_left, "Time-Spinner minute", "Time-Spinner minutes"), "", description), 5).ChecklistEntrySetIDTag("Time-spinner resource")); 53 | } 54 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Tunnel of Love.ash: -------------------------------------------------------------------------------- 1 | RegisterTaskGenerationFunction("IOTMTunnelOfLoveGenerateTasks"); 2 | void IOTMTunnelOfLoveGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 3 | { 4 | //FIXME whatever these end up being named: 5 | if (!mafiaIsPastRevision(17805)) 6 | return; 7 | if (!__iotms_usable[lookupItem("heart-shaped crate")]) 8 | return; 9 | if (get_property_boolean("_loveTunnelUsed")) 10 | return; 11 | 12 | string [int] description; 13 | //equipment: LOV Eardigan (+25% muscle exp, +25 ML), LOV Epaulettes (+25% myst exp), LOV Earrings (+25% moxie exp, +50% meat, +3 all res) 14 | //50-turn buffs: Lovebotamy (10 stats/fight), Open Heart Surgery (+10 familiar weight), Wandering Eye Surgery (+50% item) 15 | //item: boomerang (arrow), toy dart gun (???), chocolate (adventures), flowers (???), elephant (???), TOAST! (toasty!) 16 | 17 | description.listAppend("Three free fights. Attack, spell, and pickpocket respectively for elixirs."); 18 | if (my_path_id() == PATH_GELATINOUS_NOOB) 19 | description.listAppend("Equipment choice unimportant."); 20 | else 21 | { 22 | string [int] equipment_choices; 23 | equipment_choices.listAppend(HTMLBoldIfTrue("Eardigan", my_primestat() == $stat[muscle] && __misc_state["in run"] && my_level() < 13) + " (+25% muscle exp, +25 ML)"); 24 | if (my_path_id() != PATH_G_LOVER) 25 | equipment_choices.listAppend(HTMLBoldIfTrue("Epaulettes", my_primestat() == $stat[mysticality] && __misc_state["in run"] && my_level() < 13) + " (+25% myst exp)"); 26 | equipment_choices.listAppend(HTMLBoldIfTrue("Earrings", (my_primestat() == $stat[moxie] && __misc_state["in run"] && my_level() < 13) || __misc_state["in aftercore"] || my_level() >= 13) + " (+25% moxie exp, +50% meat, +3 all res)"); 27 | description.listAppend("Equipment choice:|*" + equipment_choices.listJoinComponents(", ", "or")); 28 | } 29 | string [int] buff_choices; 30 | if (my_path_id() != PATH_G_LOVER) 31 | buff_choices.listAppend("+10 stats/fight"); 32 | buff_choices.listAppend("+10 familiar weight"); 33 | buff_choices.listAppend("+50% item"); 34 | description.listAppend("Buff choice: (50 turns)|*" + buff_choices.listJoinComponents(", ", "or")); 35 | 36 | string [int] usable_items; 37 | if (my_path_id() != PATH_LIVE_ASCEND_REPEAT) 38 | usable_items.listAppend("single-use wandering copier"); 39 | usable_items.listAppend("chat hearts"); 40 | if (my_path_id() != PATH_SLOW_AND_STEADY && my_path_id() != PATH_G_LOVER) 41 | usable_items.listAppend("chocolate (adventures)"); 42 | if ($familiar[space jellyfish].familiar_is_usable()) 43 | usable_items.listAppend("toast"); 44 | description.listAppend("Item choice:|*" + usable_items.listJoinComponents(", ", "or").capitaliseFirstLetter() + "."); 45 | 46 | optional_task_entries.listAppend(ChecklistEntryMake("__item pink candy heart", "place.php?whichplace=town_wrong", ChecklistSubentryMake("Take a love trip", "", description)).ChecklistEntrySetIDTag("Love tunnel daily trip")); 47 | } 48 | 49 | RegisterResourceGenerationFunction("IOTMTunnelOfLoveGenerateResource"); 50 | void IOTMTunnelOfLoveGenerateResource(ChecklistEntry [int] resource_entries) 51 | { 52 | //mostly the boomerang 53 | //what does sokka throw? a boomeraang! 54 | 55 | if (__misc_state["in run"] && in_ronin()) 56 | { 57 | /*item enamorang = $item[LOV Enamorang]; 58 | if (enamorang.available_amount() > 0) 59 | { 60 | resource_entries.listAppend(ChecklistEntryMake("__item LOV Enamorang", "", ChecklistSubentryMake(pluralise(enamorang), "", "Copies the monster once as an arrow."), 5).ChecklistEntrySetIDTag("Love tunnel LOV enamorang")); 61 | 62 | }*/ 63 | item chocolate = lookupItem("LOV Extraterrestrial Chocolate"); 64 | if (chocolate.available_amount() > 0 && my_path_id() != PATH_SLOW_AND_STEADY) 65 | { 66 | //FIXME list other chocolates? 67 | resource_entries.listAppend(ChecklistEntryMake("__item LOV Extraterrestrial Chocolate", "", ChecklistSubentryMake(pluralise(chocolate), "", "Adventures!"), 5).ChecklistEntrySetIDTag("Love tunnel chocolates resource")); 68 | 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Vampire Cloak.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("IOTMVampireCloakGenerateResource"); 3 | void IOTMVampireCloakGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (!$item[vampyric cloake].have()) 6 | return; 7 | if (!(__misc_state["in run"] && in_ronin())) return; 8 | 9 | int uses_left = clampi(10 - get_property_int("_vampyreCloakeFormUses"), 0, 10); 10 | if (uses_left > 0 && my_path_id() != PATH_POCKET_FAMILIARS) { 11 | string [int] skills; 12 | skills.listAppend("Wolf: +50% muscle, +50% meat"); 13 | skills.listAppend("Mist: +2 all res"); 14 | skills.listAppend("Bat: +50% item"); 15 | 16 | string [int] description; 17 | description.listAppend("In-combat cast one of the Become skills, to gain a buff for that fight:|*" + skills.listJoinComponents("|*")); 18 | resource_entries.listAppend(ChecklistEntryMake("__item vampyric cloake", !$item[vampyric cloake].equipped() ? $item[vampyric cloake].invSearch() : "", ChecklistSubentryMake(pluralise(uses_left, "vampyric skill use", "vampyric skill uses"), "", description), 5).ChecklistEntrySetIDTag("Vampyric cloake combat skills resource")); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/XO Skeleton.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("IOTMXOSkeletonGenerateResource"); 3 | void IOTMXOSkeletonGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (!lookupFamiliar("XO Skeleton").familiar_is_usable()) return; 6 | 7 | 8 | 9 | int hugs_remaining = clampi(11 - get_property_int("_xoHugsUsed"), 0, 11); 10 | 11 | ChecklistEntry entry; 12 | entry.image_lookup_name = "__familiar xo skeleton"; 13 | entry.tags.id = "XO skeleton familiar resource"; 14 | entry.importance_level = 3; 15 | if (my_familiar() != lookupFamiliar("XO Skeleton")) 16 | entry.url = "familiar.php"; 17 | 18 | 19 | if ((my_familiar() == lookupFamiliar("XO Skeleton") || __misc_state["in run"]) && hugs_remaining > 0) 20 | { 21 | string [int] description; 22 | description.listAppend("Instantly v-pocket an item."); 23 | if (__misc_state["in run"] && my_path_id() != PATH_COMMUNITY_SERVICE) 24 | { 25 | string [int] options; 26 | if (!__quest_state["Level 12"].finished && get_property("sidequestOrchardCompleted") == "none" && !($effect[Filthworm Guard Stench].have_effect() > 0 || $item[Filthworm royal guard scent gland].available_amount() > 0)) 27 | options.listAppend("filthworms"); 28 | if (!__quest_state["Level 11 Desert"].state_boolean["Desert Explored"] && !QuestState("questM20Necklace").finished) 29 | options.listAppend("banshee librarian (killing jar)"); 30 | if (get_property_int("hiddenApartmentProgress") < 7 || get_property_int("hiddenOfficeProgress") < 7) 31 | options.listAppend("pygmy witch lawyer (short writs)"); 32 | if (!have_outfit_components("Swashbuckling Getup") && __quest_state["Pirate Quest"].state_boolean["valid"]) 33 | options.listAppend("obligatory pirate's cove (outfit)"); 34 | if (__quest_state["Level 9"].state_int["a-boo peak hauntedness"] >= 90) 35 | options.listAppend("Whatsian Commando Ghost (ghost free runaway)"); 36 | if (options.count() > 0) 37 | description.listAppend(options.listJoinComponents(", ").capitaliseFirstLetter() + ", etc."); 38 | } 39 | entry.subentries.listAppend(ChecklistSubentryMake(pluralise(hugs_remaining, "hug", "hugs"), "", description)); 40 | } 41 | 42 | if (__misc_state["in run"] && in_ronin()) 43 | { 44 | int xes = lookupItem("9543").available_amount(); 45 | int os = lookupItem("9544").available_amount(); 46 | 47 | //two Os: pair of candy glasses (10 adventures of +50% item) 48 | //Hide-rox™ cookie: 3 os, 1-size food, myst tower test 49 | //jug of booze: 3 xes, 1-size booze, moxie tower test 50 | //glyph of athleticism: 5 Os, 1-size spleen, muscle tower test 51 | //bridge truss: 23 xes, 15 bridge progress, takes forever to acquire 52 | 53 | string header; 54 | string [int] description; 55 | if (xes > 0) 56 | header += pluralise(xes, "X", "Xes"); 57 | if (os > 0) 58 | { 59 | if (header != "") 60 | header += ", "; 61 | header += pluralise(os, "O", "Os"); 62 | } 63 | 64 | boolean [string] options; 65 | 66 | options["pair of candy glasses: +50% item (10 turns)"] = (os >= 2); 67 | if (!__quest_state["Level 9"].state_boolean["bridge complete"] && my_path_id() != PATH_COMMUNITY_SERVICE) 68 | { 69 | int turns_left = (23 - xes) * 9 - get_property_int("xoSkeleltonXProgress"); 70 | string line = "bridge truss: half a bridge"; 71 | if (turns_left > 0) 72 | line += ", " + pluralise(turns_left, "combat", "combats") + " to get"; 73 | options[line] = (xes >= 23); 74 | } 75 | if (!__quest_state["Level 13"].state_boolean["Stat race completed"]) 76 | { 77 | stat stat_race_type = __quest_state["Level 13"].state_string["Stat race type"].to_stat(); 78 | //if (stat_race_type == $stat[muscle]) 79 | } 80 | foreach option, available in options 81 | { 82 | string line = option; 83 | if (!available) 84 | line = HTMLGenerateSpanFont(line, "gray"); 85 | description.listAppend(line); 86 | } 87 | 88 | entry.subentries.listAppend(ChecklistSubentryMake(header, "", description)); 89 | } 90 | 91 | if (entry.subentries.count() > 0) 92 | resource_entries.listAppend(entry); 93 | } 94 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Items of the Month/Zutara.ash: -------------------------------------------------------------------------------- 1 | 2 | 3 | RegisterResourceGenerationFunction("IOTMZutaraGenerateResource"); 4 | void IOTMZutaraGenerateResource(ChecklistEntry [int] resource_entries) 5 | { 6 | if (!__misc_state["VIP available"] || !lookupItem("Clan Carnival Game").is_unrestricted()) 7 | return; 8 | ChecklistEntry entry; 9 | entry.importance_level = 8; 10 | entry.image_lookup_name = "__item genie's turbane"; 11 | entry.url = "clan_viplounge.php?preaction=lovetester"; 12 | entry.tags.id = "Clan VIP madame Zatara consults"; 13 | if (!get_property_boolean("_clanFortuneBuffUsed")) 14 | { 15 | string [int] description; 16 | if (!__misc_state["familiars temporarily blocked"] && __misc_state["in run"]) 17 | description.listAppend(HTMLGenerateSpanOfClass("Susie:", "r_bold") + " +5 familiar weight, +familiar experience."); //only show in-run, because, like... +5 familiar weight for one hundred turns is not likely to pay out compared to hagnk/meatsmith in aftercore. 18 | if (my_path_id() != PATH_G_LOVER) 19 | description.listAppend(HTMLGenerateSpanOfClass("Hagnk:", "r_bold") + " +50% item/booze/food."); 20 | if (my_path_id() != PATH_G_LOVER) 21 | description.listAppend(HTMLGenerateSpanOfClass("Meatsmith:", "r_bold") + " +100% meat, +50% gear drop."); 22 | 23 | if (__misc_state["in run"]) 24 | { 25 | if (my_primestat() == $stat[muscle] || my_path_id() == PATH_COMMUNITY_SERVICE) 26 | description.listAppend(HTMLGenerateSpanOfClass("Gunther:", "r_bold") + " +5 muscle stats/fight, +100% muscle, +50% HP."); 27 | if (my_primestat() == $stat[moxie] || my_path_id() == PATH_COMMUNITY_SERVICE) 28 | description.listAppend(HTMLGenerateSpanOfClass("Gorgonzola:", "r_bold") + " +5 myst stats/fight, +100% myst, +50% MP."); 29 | //always show moxie, since I'm sure that +50% init will be super important to someone. maybe they have a bad lair test? 30 | if (my_path_id() != PATH_G_LOVER) 31 | description.listAppend(HTMLGenerateSpanOfClass("Shifty:", "r_bold") + " +5 moxie stats/fight, +100% moxie, +50% init."); 32 | } 33 | entry.subentries.listAppend(ChecklistSubentryMake("Fortune buff (100 turns)", "", description)); 34 | } 35 | if (get_property_int("_clanFortuneConsultUses") < 3) 36 | { 37 | string [int] description; 38 | entry.subentries.listAppend(ChecklistSubentryMake(pluralise(3 - get_property_int("_clanFortuneConsultUses"), "fortune clan consult", "fortune clan consults"), "", description)); 39 | } 40 | if (entry.subentries.count() > 0) 41 | resource_entries.listAppend(entry); 42 | } 43 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Paths/Avatar of Jarlsberg.ash: -------------------------------------------------------------------------------- 1 | boolean PathJarlsbergGenerateStaff(ChecklistEntry entry, item staff, string property_name, string description, boolean always_output) 2 | { 3 | if (staff.available_amount() == 0) 4 | return false; 5 | 6 | 7 | int uses_remaining = MAX(0, 5 - get_property_int(property_name)); 8 | if (uses_remaining > 0 || always_output) 9 | { 10 | string title; 11 | title = staff; 12 | if (uses_remaining != 0) 13 | { 14 | title = uses_remaining + " " + staff.to_string().replace_string("Staff of the ", ""); 15 | if (staff == $item[Staff of the Standalone Cheese]) 16 | { 17 | if (uses_remaining == 1) 18 | title += " staff banish"; 19 | else 20 | title += " staff banishes"; 21 | } 22 | else 23 | { 24 | if (uses_remaining == 1) 25 | title += " use"; 26 | else 27 | title += " uses"; 28 | } 29 | } 30 | //description = pluraliseWordy(uses_remaining, "use remains", "uses remain").capitaliseFirstLetter() + ".|" + description; 31 | entry.subentries.listAppend(ChecklistSubentryMake(title, "", description)); 32 | if (entry.image_lookup_name == "") 33 | entry.image_lookup_name = "__item " + staff; 34 | return true; 35 | } 36 | return false; 37 | } 38 | 39 | 40 | RegisterResourceGenerationFunction("PathJarlsbergGenerateResource"); 41 | void PathJarlsbergGenerateResource(ChecklistEntry [int] resource_entries) 42 | { 43 | if (my_path_id() != PATH_AVATAR_OF_JARLSBERG) return; 44 | 45 | ChecklistEntry entry; 46 | entry.tags.id = "Jarlsberg path staff resource"; 47 | 48 | 49 | //wizard staff: 50 | //Show uses: 51 | //_jiggleCheesedMonsters split by | 52 | 53 | PathJarlsbergGenerateStaff(entry, $item[Staff of the All-Steak], "_jiggleSteak", "+300% items.", false); 54 | 55 | if (true) 56 | { 57 | string olfacted_monster = get_property("_jiggleCreamedMonster"); 58 | boolean always_output = false; 59 | string cream_line = "Monster olfaction"; 60 | if (olfacted_monster != "") 61 | { 62 | always_output = true; 63 | cream_line += "|Following a " + olfacted_monster.HTMLEscapeString() + "."; 64 | } 65 | PathJarlsbergGenerateStaff(entry, $item[Staff of the Cream of the Cream], "_jiggleCream", cream_line, always_output); 66 | } 67 | if (true) 68 | { 69 | //I must capture the avatar (of jarlsberg) to regain my honor 70 | string [int] banished_monsters = split_string_alternate(get_property("_jiggleCheesedMonsters"), "\\|"); 71 | boolean always_output = false; 72 | string cheese_line = ""; 73 | if (get_property("_jiggleCheesedMonsters") != "") 74 | { 75 | cheese_line += "Monsters banished: " + banished_monsters.listJoinComponents(", ", "and").HTMLEscapeString() + "."; 76 | always_output = true; 77 | } 78 | 79 | ChecklistEntry entry2; 80 | boolean should_add = PathJarlsbergGenerateStaff(entry2, $item[Staff of the Standalone Cheese], "_jiggleCheese", cheese_line, always_output); 81 | entry2.tags.id = "Jarlsberg path staff banish"; 82 | entry2.tags.combination = "banish"; 83 | if (should_add) 84 | resource_entries.listAppend(entry2); 85 | } 86 | PathJarlsbergGenerateStaff(entry, $item[Staff of the Staff of Life], "_jiggleLife", "Restores all HP.", false); 87 | 88 | if (entry.subentries.count() > 0) 89 | resource_entries.listAppend(entry); 90 | } 91 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Paths/Dark Gift.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("PathDarkGiftGenerateResource"); 3 | void PathDarkGiftGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (my_path_id() != PATH_VAMPIRE) 6 | return; 7 | 8 | int banishes_left = clampi(10 - get_property_int("_balefulHowlUses"), 0, 10); 9 | if (banishes_left > 0 && lookupSkill("Baleful Howl").skill_is_usable()) 10 | { 11 | string url; 12 | string [int] description; 13 | description.listAppend("Free run/banish."); 14 | description.listAppend("There's a lot of them, so you might just want to use them as a free run?"); 15 | Banish banish_entry = BanishByName("Baleful Howl"); 16 | int turns_left_of_banish = banish_entry.BanishTurnsLeft(); 17 | if (turns_left_of_banish > 0) 18 | { 19 | //is this relevant? we don't describe this for pantsgiving 20 | description.listAppend("Currently used on " + banish_entry.banished_monster + " for " + pluralise(turns_left_of_banish, "more turn", "more turns") + "."); 21 | } 22 | resource_entries.listAppend(ChecklistEntryMake("__skill Baleful Howl", url, ChecklistSubentryMake(pluralise(banishes_left, "baleful howl", "baleful howls"), "", description), 0).ChecklistEntrySetCombinationTag("banish").ChecklistEntrySetIDTag("Dark gyffte path baleful howl banish")); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Paths/Explosions.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("PathExplosionsGenerateResource"); 3 | void PathExplosionsGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (my_path_id() != PATH_EXPLOSIONS) 6 | return; 7 | item isotopes = lookupItem("rare Meat isotope"); 8 | if (isotopes.have()) 9 | { 10 | string [int] description; 11 | int isotope_amount = isotopes.available_amount(); 12 | if (isotope_amount >= 5) 13 | { 14 | description.listAppend("Space chowder - for eating or hippy-fighting war."); 15 | description.listAppend("Space wine - for drinking or frat-fighting war."); 16 | } 17 | if (isotope_amount >= 10 && !$item[antique accordion].have() && my_class() != $class[accordion thief]) 18 | description.listAppend("antique accordion - casting AT buffs."); 19 | if (isotope_amount >= 20 && availableSpleen() > $item[lucky pill].available_amount()) 20 | description.listAppend("lucky pill - extra clovers, super useful."); 21 | if (isotope_amount >= 25 && !lookupItem("signal jammer").have()) 22 | description.listAppend("signal jammer - deals with those troublesome wandering skeletons. Equipped this in non-delay-burning areas."); 23 | if (isotope_amount >= 25 && !lookupItem("space shield").have() && ($item[digital key].have() || $item[white pixel].available_amount() >= 30)) 24 | description.listAppend("space shield - wear this everywhere that is adventure.php, prevents invader bullets"); 25 | 26 | 27 | //if (isotope_amount >= 10 && !lookupItem("low-pressure oxygen tank").have()) 28 | //description.listAppend("low-pressure oxygen tank - prevents HP damage at end of fight, but you probably want to ignore this."); 29 | 30 | resource_entries.listAppend(ChecklistEntryMake("__item rare Meat isotope", "shop.php?whichshop=exploathing", ChecklistSubentryMake(pluralise(isotopes), "", description), 5).ChecklistEntrySetIDTag("Exploathing path rare meat isotope shop")); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Paths/G-Lover.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("PathGLoverGenerateResource"); 3 | void PathGLoverGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (my_path_id() != PATH_G_LOVER) 6 | return; 7 | 8 | item g = lookupItem("9909"); 9 | if (g.available_amount() > 0) 10 | { 11 | string [int] description; 12 | if (__quest_state["Level 9"].state_int["a-boo peak hauntedness"] > 0 && !__quest_state["Level 9"].finished && lookupItems("a-boo glue,glued a-boo clue").available_amount() * 30 < __quest_state["Level 9"].state_int["a-boo peak hauntedness"]) 13 | description.listAppend("A-Boo glue: lets you use one a-boo clue."); 14 | if (!__quest_state["Level 9"].state_boolean["Peak Jar Completed"] && !__quest_state["Level 9"].finished && $item[jar of oil].available_amount() == 0 && g.available_amount() >= 3) 15 | description.listAppend("Crude oil congealer: lets you create a jar of oil."); 16 | description.listAppend("Food, drink, +100% spleen item for fifty turns."); 17 | resource_entries.listAppend(ChecklistEntryMake("__item g", "shop.php?whichshop=glover", ChecklistSubentryMake(pluralise(g) + " available", "", description), 3).ChecklistEntrySetIDTag("G-lover path G shop")); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Paths/Grey Goo.ash: -------------------------------------------------------------------------------- 1 | RegisterTaskGenerationFunction("PathGreyGooGenerateTasks"); 2 | void PathGreyGooGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 3 | { 4 | if (my_path_id() != PATH_GREY_GOO) 5 | return; 6 | 7 | if (my_daycount() >= 3) { 8 | task_entries.listAppend(ChecklistEntryMake("astral gash", "place.php?whichplace=greygoo", ChecklistSubentryMake("Ascend", "", "Prism appeared. Ascend whenever."),-10).ChecklistEntrySetIDTag("Grey goo path prism open")); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Paths/Low Key.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterLowKeyGenerationFunction("PathLowKeyGenerateKeys"); 3 | void PathLowKeyGenerateKeys(ChecklistEntry [int] low_key_entries) { 4 | 5 | if (my_path_id() != PATH_LOW_KEY_SUMMER) return; 6 | if (__quest_state["Lair"].state_boolean["past keys"]) return; 7 | 8 | //LKS-specific keys 9 | foreach index, key in LKS_keys { 10 | if (key.was_used || key.it.available_amount() > 0) continue; 11 | 12 | string url; 13 | 14 | // Entries 15 | string [int] description; 16 | 17 | // Set unlock messages or delay messages 18 | if (!key.zone.locationAvailable()) { 19 | description.listAppend("Unlock " + key.zone + " by " + key.condition_for_unlock); 20 | url = key.pre_unlock_url; 21 | } else { 22 | int delayLeft = 11 - key.zone.turns_spent; 23 | if (delayLeft > 0) 24 | description.listAppend("Delay for " + pluralise(delayLeft, "turn", "turns") + " in " + key.zone + " to find key."); 25 | else 26 | description.listAppend("Find key on next turn in " + key.zone); 27 | 28 | url = key.zone.getClickableURLForLocation(); 29 | } 30 | 31 | low_key_entries.listAppend(ChecklistEntryMake("__item " + key.it.name, url, ChecklistSubentryMake(key.it.name.capitaliseFirstLetter(), key.enchantment, description), boolean [location] {key.zone:true}).ChecklistEntrySetIDTag("Low key summer path " + key.it.name)); 32 | } 33 | 34 | //base keys 35 | SLevel13DoorGenerateMissingItems(low_key_entries); 36 | } 37 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Paths/Paths import.ash: -------------------------------------------------------------------------------- 1 | import "relay/TourGuide/Paths/Actually Ed the Undying.ash"; 2 | import "relay/TourGuide/Paths/Avatar of Jarlsberg.ash"; 3 | import "relay/TourGuide/Paths/Avatar of Sneaky Pete.ash"; 4 | import "relay/TourGuide/Paths/Avatar of West of Loathing.ash"; 5 | import "relay/TourGuide/Paths/Bad Moon.ash"; 6 | import "relay/TourGuide/Paths/Bugbear Invasion.ash"; 7 | import "relay/TourGuide/Paths/Community Service.ash"; 8 | import "relay/TourGuide/Paths/Heavy Rains.ash"; 9 | import "relay/TourGuide/Paths/KOLHS.ash"; 10 | import "relay/TourGuide/Paths/Way of the Surprising Fist.ash"; 11 | import "relay/TourGuide/Paths/The Source.ash"; 12 | import "relay/TourGuide/Paths/Zombie Slayer.ash"; 13 | import "relay/TourGuide/Paths/Nuclear Autumn.ash"; 14 | import "relay/TourGuide/Paths/Gelatinous Noob.ash"; 15 | import "relay/TourGuide/Paths/License to Adventure.ash"; 16 | import "relay/TourGuide/Paths/G-Lover.ash"; 17 | import "relay/TourGuide/Paths/Dark Gift.ash"; 18 | import "relay/TourGuide/Paths/Explosions.ash"; 19 | //missing plumber 20 | import "relay/TourGuide/Paths/Low Key.ash"; 21 | import "relay/TourGuide/Paths/Grey Goo.ash"; 22 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Paths/Way of the Surprising Fist.ash: -------------------------------------------------------------------------------- 1 | //Some simple suggestions for this forgotten path: 2 | RegisterResourceGenerationFunction("PathWOTSFGenerateResource"); 3 | void PathWOTSFGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (my_path_id() != PATH_WAY_OF_THE_SURPRISING_FIST) 6 | return; 7 | //Meat: 8 | if (have_outfit_components("Knob Goblin Harem Girl Disguise") && !get_property_boolean("_treasuryHaremMeatCollected") && locationAvailable($location[Cobb's Knob Barracks])) 9 | { 10 | resource_entries.listAppend(ChecklistEntryMake("meat", "cobbsknob.php", ChecklistSubentryMake("Cobb's Knob treasury meat", "", "Wear harem girl disguise, adventure once for 500 meat."), 5).ChecklistEntrySetIDTag("Surprising fist path knob harem meat")); 11 | } 12 | //Skills: 13 | string [int] fist_teaching_properties = split_string_alternate("fistTeachingsBarroomBrawl,fistTeachingsBatHole,fistTeachingsConservatory,fistTeachingsFratHouse,fistTeachingsFunHouse,fistTeachingsHaikuDungeon,fistTeachingsMenagerie,fistTeachingsNinjaSnowmen,fistTeachingsPokerRoom,fistTeachingsRoad,fistTeachingsSlums", ","); 14 | location [string] teaching_properties_to_locations; 15 | teaching_properties_to_locations["fistTeachingsBarroomBrawl"] = $location[A Barroom Brawl]; 16 | teaching_properties_to_locations["fistTeachingsBatHole"] = $location[The Bat Hole Entrance]; 17 | teaching_properties_to_locations["fistTeachingsConservatory"] = $location[The Haunted Conservatory]; 18 | teaching_properties_to_locations["fistTeachingsFratHouse"] = $location[Frat House]; 19 | teaching_properties_to_locations["fistTeachingsFunHouse"] = $location[The "Fun" House]; 20 | teaching_properties_to_locations["fistTeachingsHaikuDungeon"] = $location[The Haiku Dungeon]; 21 | teaching_properties_to_locations["fistTeachingsMenagerie"] = $location[Cobb's Knob Menagerie\, Level 2]; 22 | teaching_properties_to_locations["fistTeachingsNinjaSnowmen"] = $location[Lair of the Ninja Snowmen]; 23 | teaching_properties_to_locations["fistTeachingsPokerRoom"] = $location[The Poker Room]; 24 | teaching_properties_to_locations["fistTeachingsRoad"] = $location[The Road to the White Citadel]; 25 | teaching_properties_to_locations["fistTeachingsSlums"] = $location[Pandamonium Slums]; 26 | 27 | string [int] missing_areas; 28 | foreach key in fist_teaching_properties 29 | { 30 | string property = fist_teaching_properties[key]; 31 | if (!get_property_boolean(property)) 32 | { 33 | location place = teaching_properties_to_locations[property]; 34 | missing_areas.listAppend(place.HTMLGenerateFutureTextByLocationAvailability()); 35 | } 36 | } 37 | if (missing_areas.count() > 0) 38 | resource_entries.listAppend(ChecklistEntryMake("__item Teachings of the Fist", "", ChecklistSubentryMake("Teachings of the Fist", "", "Found in " + missing_areas.listJoinComponents(", ", "and") + "."), 5).ChecklistEntrySetIDTag("Surprising fist path find fist skills")); 39 | 40 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Paths/Zombie Slayer.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterTaskGenerationFunction("PathZombieSlayerGenerateTasks"); 3 | void PathZombieSlayerGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 4 | { 5 | if (my_path_id() != PATH_ZOMBIE_SLAYER) 6 | return; 7 | //zombiePoints is the number of points "permed" on the character, not how many they have at the moment 8 | //Let's see.. I think this means we can infer how many points they have to spend, right? You start with zombiePoints + 1, then gain one for each level you have, minus how many hunter brains you have, minus whether you've fought the right hunter yet... but, we can't know that information. Hmm. So, no, no reminder. Alas. 9 | //We could, however, suggest they eat a hunter brain. 10 | //ashq string out; foreach s in $skills[] if (s.class == $class[zombie master]) out += ", " + s; print(out); 11 | if ($item[hunter brain].available_amount() > 0 && availableFullness() >= 1) 12 | { 13 | int zombie_skills_have = 0; 14 | foreach s in $skills[Infectious Bite, Bite Minion, Lure Minions, Undying Greed, Hunter's Sprint, Insatiable Hunger, Devour Minions, Indefatigable, Skullcracker, Neurogourmet, Ravenous Pounce, Distracting Minion, Plague Claws, Flesh Mob, Elemental Obliviousness, Vigor Mortis, Virulence, Bilious Burst, Unyielding Flesh, Corpse Pile, Howl of the Alpha, Summon Minion, Zombie Chow, Smash & Graaagh, Scavenge, Meat Shields, Summon Horde, His Master's Voice, Ag-grave-ation, Disquiet Riot, Zombie Maestro, Recruit Zombie] 15 | { 16 | if (s.have_skill()) 17 | zombie_skills_have += 1; 18 | } 19 | if (zombie_skills_have < 30) 20 | { 21 | //probably should suggest eat X hunter brains but 22 | optional_task_entries.listAppend(ChecklistEntryMake("__item hunter brain", "inventory.php?ftext=hunter+brain", ChecklistSubentryMake("Eat a hunter brain", "", "Gain a skill point."), -1).ChecklistEntrySetIDTag("Zombie slayer path skill points")); 23 | } 24 | } 25 | 26 | } 27 | 28 | RegisterResourceGenerationFunction("PathZombieSlayerGenerateResource"); 29 | void PathZombieSlayerGenerateResource(ChecklistEntry [int] resource_entries) 30 | { 31 | if (my_path_id() != PATH_ZOMBIE_SLAYER) return; 32 | 33 | if ($item[right bear arm].available_amount() > 0 && $item[left bear arm].available_amount() > 0) 34 | { 35 | int bear_hugs_remaining = clampi(10 - get_property_int("_bearHugs"), 0, 10); 36 | 37 | if (bear_hugs_remaining > 0) 38 | { 39 | string url; 40 | string [int] description; 41 | description.listAppend("Converts monster to zombies. Ideally, use against group monsters."); 42 | string [int] items_to_equip; 43 | foreach it in $items[right bear arm,left bear arm] 44 | { 45 | if (it.equipped_amount() == 0) 46 | items_to_equip.listAppend(it); 47 | } 48 | if (items_to_equip.count() > 0) 49 | { 50 | url = "inventory.php?which=2"; 51 | description.listAppend("Equip " + items_to_equip.listJoinComponents(", ", "and") + "."); 52 | } 53 | resource_entries.listAppend(ChecklistEntryMake("__item right bear arm", url, ChecklistSubentryMake(pluralise(bear_hugs_remaining, "bear hug", "bear hugs"), "", description), 8).ChecklistEntrySetIDTag("Zombie slayer path bear arms hugs")); 54 | 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/QuestState.ash: -------------------------------------------------------------------------------- 1 | import "relay/TourGuide/Support/Library.ash" 2 | 3 | //Quest status stores all/most of our quest information in an internal format that's easier to understand. 4 | record QuestState 5 | { 6 | string quest_name; 7 | string image_name; 8 | 9 | boolean startable; //can be started, but hasn't yet 10 | boolean started; 11 | boolean in_progress; 12 | boolean finished; 13 | 14 | int mafia_internal_step; //0 for not started. INT32_MAX for finished. This is +1 versus mafia's "step1/step2/stepX" system. "step1" is represented as 2, "step2" as 3, etc. 15 | 16 | boolean [string] state_boolean; 17 | string [string] state_string; 18 | int [string] state_int; 19 | float [string] state_float; 20 | 21 | boolean council_quest; 22 | }; 23 | 24 | QuestState [string] __quest_state; 25 | boolean [string] __misc_state; 26 | string [string] __misc_state_string; 27 | int [string] __misc_state_int; 28 | float [string] __misc_state_float; 29 | 30 | int QuestStateConvertQuestPropertyValueToNumber(string property_value) 31 | { 32 | int result = 0; 33 | if (property_value == "") 34 | return -1; 35 | if (property_value == "started") 36 | { 37 | result = 1; 38 | } 39 | else if (property_value == "finished") 40 | { 41 | result = INT32_MAX; 42 | } 43 | else if (property_value.contains_text("step")) 44 | { 45 | //lazy: 46 | string theoretical_int = property_value.replace_string(" ", "").replace_string("step", ""); //one revision had a bug that set questL11Worship to "step 4", so remove spaces 47 | int step_value = theoretical_int.to_int_silent(); 48 | 49 | result = step_value + 1; 50 | 51 | if (result < 0) 52 | result = 0; 53 | } 54 | else 55 | { 56 | //unknown 57 | } 58 | return result; 59 | } 60 | 61 | boolean questPropertyPastInternalStepNumber(string quest_property, int number) 62 | { 63 | return QuestStateConvertQuestPropertyValueToNumber(get_property(quest_property)) >= number; 64 | } 65 | 66 | void QuestStateParseMafiaQuestPropertyValue(QuestState state, string property_value) 67 | { 68 | state.started = false; 69 | state.finished = false; 70 | state.in_progress = false; 71 | state.mafia_internal_step = QuestStateConvertQuestPropertyValueToNumber(property_value); 72 | 73 | if (state.mafia_internal_step > 0) 74 | state.started = true; 75 | if (state.mafia_internal_step == INT32_MAX) 76 | state.finished = true; 77 | if (state.started && !state.finished) 78 | state.in_progress = true; 79 | } 80 | 81 | boolean QuestStateEquals(QuestState q1, QuestState q2) 82 | { 83 | //not sure how to do record equality otherwise 84 | if (q1.quest_name != q2.quest_name) 85 | return false; 86 | if (q1.image_name != q2.image_name) 87 | return false; 88 | if (q1.startable != q2.startable) 89 | return false; 90 | if (q1.started != q2.started) 91 | return false; 92 | if (q1.in_progress != q2.in_progress) 93 | return false; 94 | if (q1.finished != q2.finished) 95 | return false; 96 | if (q1.mafia_internal_step != q2.mafia_internal_step) 97 | return false; 98 | 99 | if (q1.state_boolean != q2.state_boolean) 100 | return false; 101 | if (q1.state_string != q2.state_string) 102 | return false; 103 | if (q1.state_int != q2.state_int) 104 | return false; 105 | return true; 106 | } 107 | 108 | void QuestStateParseMafiaQuestProperty(QuestState state, string property_name, boolean allow_quest_log_load) 109 | { 110 | state.QuestStateParseMafiaQuestPropertyValue(get_property(property_name)); 111 | } 112 | 113 | void QuestStateParseMafiaQuestProperty(QuestState state, string property_name) 114 | { 115 | QuestStateParseMafiaQuestProperty(state, property_name, true); 116 | } 117 | 118 | QuestState QuestState(string property_name) 119 | { 120 | QuestState state; 121 | QuestStateParseMafiaQuestProperty(state, property_name); 122 | return state; 123 | } 124 | 125 | QuestState QuestStateFromManualStep(string manual_value) 126 | { 127 | QuestState state; 128 | state.QuestStateParseMafiaQuestPropertyValue(manual_value); 129 | return state; 130 | } 131 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Quests.ash: -------------------------------------------------------------------------------- 1 | import "relay/TourGuide/Support/Checklist.ash" 2 | import "relay/TourGuide/Support/LocationAvailable.ash" 3 | import "relay/TourGuide/Quests/Quest import.ash" 4 | 5 | 6 | void QuestsInit() 7 | { 8 | QPirateInit(); 9 | QLevel2Init(); 10 | QLevel3Init(); 11 | QLevel4Init(); 12 | QLevel5Init(); 13 | QLevel6Init(); 14 | QLevel7Init(); 15 | QLevel8Init(); 16 | QLevel9Init(); 17 | QLevel10Init(); 18 | QLevel11Init(); 19 | QLevel12Init(); 20 | QLevel13Init(); 21 | QNemesisInit(); 22 | QSeaInit(); 23 | QSpaceElvesInit(); 24 | QAzazelInit(); 25 | QUntinkerInit(); 26 | QArtistInit(); 27 | QLegendaryBeatInit(); 28 | QMemoriesInit(); 29 | QWhiteCitadelInit(); 30 | QWizardOfEgoInit(); 31 | QFeloniaInit(); 32 | QGuildInit(); 33 | QSubject37Init(); 34 | QMartyInit(); 35 | QMeatsmithInit(); 36 | QGalaktikInit(); 37 | QOldLandfillInit(); 38 | QMadnessBakeryInit(); 39 | QManorInit(); 40 | } 41 | 42 | 43 | void QuestsGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 44 | { 45 | QLevel2GenerateTasks(task_entries, optional_task_entries, future_task_entries); 46 | QLevel3GenerateTasks(task_entries, optional_task_entries, future_task_entries); 47 | QLevel4GenerateTasks(task_entries, optional_task_entries, future_task_entries); 48 | QLevel5GenerateTasks(task_entries, optional_task_entries, future_task_entries); 49 | QLevel6GenerateTasks(task_entries, optional_task_entries, future_task_entries); 50 | QLevel7GenerateTasks(task_entries, optional_task_entries, future_task_entries); 51 | QLevel8GenerateTasks(task_entries, optional_task_entries, future_task_entries); 52 | QLevel9GenerateTasks(task_entries, optional_task_entries, future_task_entries); 53 | QLevel10GenerateTasks(task_entries, optional_task_entries, future_task_entries); 54 | QLevel11GenerateTasks(task_entries, optional_task_entries, future_task_entries); 55 | QLevel12GenerateTasks(task_entries, optional_task_entries, future_task_entries); 56 | QLevel13GenerateTasks(task_entries, optional_task_entries, future_task_entries); 57 | 58 | QManorGenerateTasks(task_entries, optional_task_entries, future_task_entries); 59 | QPirateGenerateTasks(task_entries, optional_task_entries, future_task_entries); 60 | QNemesisGenerateTasks(task_entries, optional_task_entries, future_task_entries); 61 | QSeaGenerateTasks(task_entries, optional_task_entries, future_task_entries); 62 | QSpaceElvesGenerateTasks(task_entries, optional_task_entries, future_task_entries); 63 | QAzazelGenerateTasks(task_entries, optional_task_entries, future_task_entries); 64 | QGuildGenerateTasks(task_entries, optional_task_entries, future_task_entries); 65 | 66 | QUntinkerGenerateTasks(task_entries, optional_task_entries, future_task_entries); 67 | QArtistGenerateTasks(task_entries, optional_task_entries, future_task_entries); 68 | QLegendaryBeatGenerateTasks(task_entries, optional_task_entries, future_task_entries); 69 | QMemoriesGenerateTasks(task_entries, optional_task_entries, future_task_entries); 70 | QWhiteCitadelGenerateTasks(task_entries, optional_task_entries, future_task_entries); 71 | QWizardOfEgoGenerateTasks(task_entries, optional_task_entries, future_task_entries); 72 | QSpookyravenLightsOutGenerateTasks(task_entries, optional_task_entries, future_task_entries); 73 | QFeloniaGenerateTasks(task_entries, optional_task_entries, future_task_entries); 74 | 75 | QAirportGenerateTasks(task_entries, optional_task_entries, future_task_entries); 76 | QSubject37GenerateTasks(task_entries, optional_task_entries, future_task_entries); 77 | QMartyGenerateTasks(task_entries, optional_task_entries, future_task_entries); 78 | QMeatsmithGenerateTasks(task_entries, optional_task_entries, future_task_entries); 79 | QGalaktikGenerateTasks(task_entries, optional_task_entries, future_task_entries); 80 | QOldLandfillGenerateTasks(task_entries, optional_task_entries, future_task_entries); 81 | QMadnessBakeryGenerateTasks(task_entries, optional_task_entries, future_task_entries); 82 | } 83 | 84 | void QuestsGenerateResources(ChecklistEntry [int] resource_entries) 85 | { 86 | QSpookyravenLightsOutGenerateResource(resource_entries); 87 | QAirportGenerateResource(resource_entries); 88 | } 89 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Quests/Artist.ash: -------------------------------------------------------------------------------- 1 | 2 | void QArtistInit() 3 | { 4 | QuestState state; 5 | 6 | QuestStateParseMafiaQuestProperty(state, "questM02Artist"); 7 | 8 | if (!state.started && $items[pail of pretentious paint, pretentious paintbrush, pretentious palette].available_amount() > 0) 9 | QuestStateParseMafiaQuestPropertyValue(state, "started"); 10 | 11 | if (my_path_id() == PATH_ZOMBIE_SLAYER || my_path_id() == PATH_GREY_GOO) //cannot be done 12 | QuestStateParseMafiaQuestPropertyValue(state, "unstarted"); 13 | 14 | state.quest_name = "Pretentious Artist's Quest"; 15 | state.image_name = "__item pretentious palette"; 16 | 17 | state.startable = true; 18 | 19 | __quest_state["Artist"] = state; 20 | } 21 | 22 | 23 | void QArtistGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 24 | { 25 | QuestState base_quest_state = __quest_state["Artist"]; 26 | if (!base_quest_state.in_progress) 27 | return; 28 | 29 | ChecklistSubentry subentry; 30 | 31 | subentry.header = base_quest_state.quest_name; 32 | 33 | string active_url = ""; 34 | 35 | boolean output_modifiers = false; 36 | if ($item[pretentious palette].available_amount() == 0) 37 | { 38 | //haunted pantry 39 | if (active_url == "") 40 | active_url = $location[the haunted pantry].getClickableURLForLocation(); 41 | subentry.entries.listAppend("Adventure in the haunted pantry for palette. (25% superlikely)"); 42 | output_modifiers = true; 43 | } 44 | if ($item[pretentious paintbrush].available_amount() == 0) 45 | { 46 | //cobb's knob 47 | if (active_url == "") 48 | active_url = $location[the outskirts of Cobb's Knob].getClickableURLForLocation(); 49 | subentry.entries.listAppend("Adventure in the outskirts of Cobb's Knob for paintbrush. (25% superlikely)"); 50 | output_modifiers = true; 51 | } 52 | if ($item[pail of pretentious paint].available_amount() == 0) 53 | { 54 | //sleazy back alley 55 | if (active_url == "") 56 | active_url = $location[the sleazy back alley].getClickableURLForLocation(); 57 | subentry.entries.listAppend("Adventure in the sleazy back alley for pail of paint. (25% superlikely)"); 58 | output_modifiers = true; 59 | } 60 | 61 | if (output_modifiers) 62 | { 63 | if (__misc_state["free runs available"]) 64 | { 65 | subentry.modifiers.listAppend("free runs"); 66 | } 67 | if (__misc_state["have hipster"]) 68 | { 69 | subentry.modifiers.listAppend(__misc_state_string["hipster name"]); 70 | } 71 | } 72 | 73 | if ($item[pretentious palette].available_amount() > 0 && $item[pretentious paintbrush].available_amount() > 0 && $item[pail of pretentious paint].available_amount() > 0) 74 | { 75 | subentry.entries.listAppend("Talk to the pretentious artist."); 76 | active_url = "place.php?whichplace=town_wrong"; 77 | } 78 | 79 | optional_task_entries.listAppend(ChecklistEntryMake(base_quest_state.image_name, active_url, subentry, $locations[the sleazy back alley, the outskirts of cobb's knob, the haunted pantry]).ChecklistEntrySetIDTag("Pretentious artist quest")); 80 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Quests/Intergalaktik.ash: -------------------------------------------------------------------------------- 1 | void QGalaktikInit() 2 | { 3 | QuestState state; 4 | 5 | QuestStateParseMafiaQuestProperty(state, "questM24Doc"); 6 | 7 | 8 | state.quest_name = "What's Up, Doc?"; 9 | state.image_name = "__item pretty flower"; 10 | 11 | state.startable = true; 12 | 13 | __quest_state["Galaktik"] = state; 14 | } 15 | 16 | 17 | void QGalaktikGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 18 | { 19 | QuestState base_quest_state = __quest_state["Galaktik"]; 20 | if (!base_quest_state.in_progress) 21 | return; 22 | 23 | ChecklistSubentry subentry; 24 | 25 | subentry.header = base_quest_state.quest_name; 26 | 27 | string active_url = "place.php?whichplace=town_wrong"; 28 | string image_name = base_quest_state.image_name; 29 | 30 | string [int] missing_item_descriptions; 31 | foreach it in $items[swindleblossom,fraudwort,shysterweed] 32 | { 33 | if (it.available_amount() >= 3) 34 | continue; 35 | missing_item_descriptions.listAppend(pluraliseWordy(3 - it.available_amount(), "more " + it, "more " + it.plural)); 36 | } 37 | 38 | if (missing_item_descriptions.count() > 0) 39 | { 40 | subentry.entries.listAppend("Collect " + missing_item_descriptions.listJoinComponents(", ", "and") + " in the overgrown lot."); 41 | if ($item[brown paper bag mask].available_amount() > 0 && $item[brown paper bag mask].equipped_amount() == 0) 42 | subentry.entries.listAppend("Could equip the brown paper bag mask to meet the Lot's wife, if you haven't already."); 43 | 44 | if (__misc_state["in run"] && __last_adventure_location != $location[the overgrown lot] && !in_bad_moon()) 45 | return; 46 | } 47 | else 48 | { 49 | //shop.php?whichshop=doc&action=talk 50 | active_url = "shop.php?whichshop=doc&action=talk"; 51 | subentry.entries.listAppend("Return to Doc Galaktik."); 52 | //image_name = "__familiar o.a.f."; 53 | } 54 | 55 | optional_task_entries.listAppend(ChecklistEntryMake(image_name, active_url, subentry, $locations[the overgrown lot]).ChecklistEntrySetIDTag("Doc Galaktik flower quest")); 56 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Quests/Level 2.ash: -------------------------------------------------------------------------------- 1 | 2 | void QLevel2Init() 3 | { 4 | //questL02Larva 5 | QuestState state; 6 | 7 | QuestStateParseMafiaQuestProperty(state, "questL02Larva"); 8 | if (my_path_id() == PATH_COMMUNITY_SERVICE) QuestStateParseMafiaQuestPropertyValue(state, "finished"); 9 | 10 | state.quest_name = "Spooky Forest Quest"; 11 | state.image_name = "Spooky Forest"; 12 | state.council_quest = true; 13 | 14 | if (my_level() >= 2 || my_path_id() == PATH_EXPLOSIONS) 15 | state.startable = true; 16 | 17 | if (state.in_progress) 18 | { 19 | if ($item[mosquito larva].available_amount() > 0) 20 | { 21 | state.state_boolean["have mosquito"] = true; 22 | } 23 | } 24 | else if (state.finished) 25 | { 26 | state.state_boolean["have mosquito"] = true; 27 | } 28 | 29 | __quest_state["Level 2"] = state; 30 | __quest_state["Spooky Forest"] = state; 31 | } 32 | 33 | 34 | void QLevel2GenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 35 | { 36 | QuestState base_quest_state = __quest_state["Level 2"]; 37 | if (!base_quest_state.in_progress) 38 | return; 39 | 40 | if (my_path_id() == PATH_COMMUNITY_SERVICE || __misc_state["in aftercore"]) 41 | return; 42 | 43 | ChecklistSubentry subentry; 44 | string url = "place.php?whichplace=woods"; 45 | 46 | subentry.header = base_quest_state.quest_name; 47 | 48 | 49 | if (base_quest_state.state_boolean["have mosquito"]) 50 | { 51 | subentry.entries.listAppend("Finished, go chat with the council."); 52 | url = "place.php?whichplace=town"; 53 | } 54 | else 55 | { 56 | string [int] modifiers; 57 | modifiers.listAppend("-combat"); 58 | 59 | if (delayRemainingInLocation($location[the spooky forest]) > 0) 60 | { 61 | string hipster_text = ""; 62 | if (__misc_state["have hipster"]) 63 | { 64 | hipster_text = " (use " + __misc_state_string["hipster name"] + ")"; 65 | modifiers.listAppend(__misc_state_string["hipster name"]); 66 | } 67 | string line = "Delay for " + pluralise(delayRemainingInLocation($location[the spooky forest]), "turn", "turns") + hipster_text + "."; 68 | subentry.entries.listAppend(line); 69 | subentry.entries.listAppend("Run -combat after that."); 70 | } 71 | else 72 | subentry.entries.listAppend("Run -combat"); 73 | subentry.entries.listAppend("Explore the stream" + __html_right_arrow_character + "March to the marsh"); 74 | 75 | 76 | if (!__quest_state["Manor Unlock"].state_boolean["ballroom song effectively set"]) 77 | subentry.entries.listAppend("Possibly wait until -combat ballroom song set. (marginal)"); 78 | 79 | if (__misc_state["free runs available"]) 80 | { 81 | subentry.entries.listAppend("Free run from monsters (low stats)"); 82 | modifiers.listAppend("free runs"); 83 | } 84 | 85 | 86 | subentry.modifiers = modifiers; 87 | } 88 | 89 | task_entries.listAppend(ChecklistEntryMake(base_quest_state.image_name, url, subentry, $locations[the spooky forest]).ChecklistEntrySetIDTag("Council L2 mosquito quest")); 90 | } 91 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Quests/Madness Bakery.ash: -------------------------------------------------------------------------------- 1 | //questM25Armorer 2 | void QMadnessBakeryInit() 3 | { 4 | QuestState state; 5 | 6 | QuestStateParseMafiaQuestProperty(state, "questM25Armorer"); 7 | 8 | state.quest_name = "Lending a Hand (and a Foot)"; 9 | state.image_name = "__item unlit birthday cake"; 10 | 11 | 12 | __quest_state["Madness Bakery"] = state; 13 | } 14 | 15 | 16 | void QMadnessBakeryGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 17 | { 18 | QuestState base_quest_state = __quest_state["Madness Bakery"]; 19 | if (!base_quest_state.in_progress) 20 | return; 21 | 22 | ChecklistSubentry subentry; 23 | 24 | subentry.header = base_quest_state.quest_name; 25 | 26 | string url = "place.php?whichplace=town_right"; 27 | 28 | if ($item[no-handed pie].available_amount() > 0 || base_quest_state.mafia_internal_step >= 5) 29 | { 30 | subentry.entries.listAppend("Talk to the leggerer."); 31 | url = "place.php?whichplace=town_market"; 32 | } 33 | else 34 | { 35 | //step1 seems to exist, but no information on office visits left 36 | //step2 - cake lord 37 | //step3 - in the progress of talking to madeline 38 | //step4 - acquire cake 39 | //step5 - melon lord? 40 | subentry.entries.listAppend("Adventure in the Madness Bakery|Choose the first option in the non-combat repeatedly."); 41 | } 42 | 43 | optional_task_entries.listAppend(ChecklistEntryMake(base_quest_state.image_name, url, subentry, $locations[Madness Bakery]).ChecklistEntrySetIDTag("Armory madness bakery quest")); 44 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Quests/Meatsmith.ash: -------------------------------------------------------------------------------- 1 | 2 | void QMeatsmithInit() 3 | { 4 | //questM23Meatsmith 5 | QuestState state; 6 | 7 | QuestStateParseMafiaQuestProperty(state, "questM23Meatsmith"); 8 | 9 | state.quest_name = "Helping Make Ends Meat"; 10 | state.image_name = "__item gnawed-up dog bone"; 11 | 12 | state.startable = true; 13 | 14 | __quest_state["Meatsmith"] = state; 15 | } 16 | 17 | 18 | void QMeatsmithGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 19 | { 20 | QuestState base_quest_state = __quest_state["Meatsmith"]; 21 | if (base_quest_state.finished) 22 | return; 23 | 24 | if (__last_adventure_location != $location[the skeleton store] || __last_adventure_location == $location[none]) 25 | return; 26 | 27 | ChecklistSubentry subentry; 28 | 29 | subentry.header = base_quest_state.quest_name; 30 | 31 | string active_url = "place.php?whichplace=town_market"; 32 | 33 | boolean done = false; 34 | boolean have_reason_to_add = false; 35 | 36 | if (!base_quest_state.started) 37 | { 38 | have_reason_to_add = true; 39 | subentry.entries.listAppend("Go talk to the meatsmith to start the quest."); 40 | } 41 | else if (base_quest_state.mafia_internal_step == 1) 42 | { 43 | have_reason_to_add = true; 44 | if ($item[skeleton store office key].available_amount() == 0) 45 | { 46 | subentry.entries.listAppend("Check out the cash register at the NC."); 47 | } 48 | else 49 | { 50 | subentry.entries.listAppend("Head into the manager's office at the NC."); 51 | } 52 | } 53 | else if (base_quest_state.mafia_internal_step == 2) 54 | { 55 | have_reason_to_add = true; 56 | done = true; 57 | subentry.entries.listAppend("Return to the meatsmith."); 58 | active_url = "shop.php?whichshop=meatsmith"; 59 | } 60 | 61 | if ($item[ring of telling skeletons what to do].item_amount() == 0) 62 | { 63 | if (!have_reason_to_add) 64 | subentry.header = "The Skeleton Store"; 65 | string line = "Could acquire a ring of telling skeletons what to do, by opening the chest at the NC"; 66 | if ($item[skeleton key].item_amount() == 0) 67 | line += HTMLGenerateSpanFont(" after acquiring a skeleton key", "red"); 68 | 69 | line += "."; 70 | subentry.entries.listAppend(line); 71 | have_reason_to_add = true; 72 | } 73 | 74 | if (!done) 75 | subentry.entries.listAppend("Non-combat appears every fourth adventure."); //except the first time for some reason? needs spading 76 | 77 | boolean [location] relevant_locations; 78 | relevant_locations[$location[the skeleton store]] = true; 79 | 80 | if (have_reason_to_add) 81 | optional_task_entries.listAppend(ChecklistEntryMake(base_quest_state.image_name, active_url, subentry, relevant_locations).ChecklistEntrySetIDTag("Meatsmith skeleton store quest")); 82 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Quests/Memories.ash: -------------------------------------------------------------------------------- 1 | //Currently disabled. Complicated. 2 | 3 | void QMemoriesInit() 4 | { 5 | if (true) 6 | return; 7 | if (true) 8 | { 9 | QuestState state; 10 | QuestStateParseMafiaQuestProperty(state, "questF01Primordial"); 11 | 12 | state.quest_name = "Primordial Fear Quest"; 13 | state.image_name = "__item empty agua de vida bottle"; 14 | 15 | 16 | __quest_state["Primordial Fear"] = state; 17 | } 18 | if (true) 19 | { 20 | QuestState state; 21 | QuestStateParseMafiaQuestProperty(state, "questF02Hyboria"); 22 | 23 | state.quest_name = "Hyboria Quest"; 24 | state.image_name = "__item empty agua de vida bottle"; 25 | 26 | 27 | __quest_state["Hyboria"] = state; 28 | } 29 | if (true) 30 | { 31 | QuestState state; 32 | QuestStateParseMafiaQuestProperty(state, "questF03Future"); 33 | 34 | state.quest_name = "Future Quest"; 35 | state.image_name = "__item empty agua de vida bottle"; 36 | 37 | 38 | __quest_state["Future"] = state; 39 | } 40 | } 41 | 42 | 43 | void QMemoriesPrimordialFearGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 44 | { 45 | QuestState base_quest_state = __quest_state["Primordial Fear"]; 46 | if (!base_quest_state.in_progress) 47 | return; 48 | string active_url = ""; 49 | 50 | ChecklistSubentry subentry; 51 | 52 | subentry.header = base_quest_state.quest_name; 53 | //FIXME implement this 54 | 55 | optional_task_entries.listAppend(ChecklistEntryMake(base_quest_state.image_name, active_url, subentry, $locations[the primordial soup]).ChecklistEntrySetIDTag("Memories quest primordial fear")); 56 | } 57 | 58 | void QMemoriesHyboriaGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 59 | { 60 | QuestState base_quest_state = __quest_state["Hyboria"]; 61 | if (!base_quest_state.in_progress) 62 | return; 63 | string active_url = ""; 64 | 65 | ChecklistSubentry subentry; 66 | 67 | subentry.header = base_quest_state.quest_name; 68 | //FIXME implement this 69 | 70 | 71 | optional_task_entries.listAppend(ChecklistEntryMake(base_quest_state.image_name, active_url, subentry, $locations[the jungles of ancient loathing]).ChecklistEntrySetIDTag("Memories quest hyboria")); 72 | } 73 | 74 | void QMemoriesFutureGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 75 | { 76 | QuestState base_quest_state = __quest_state["Future"]; 77 | if (!base_quest_state.in_progress) 78 | return; 79 | string active_url = ""; 80 | 81 | ChecklistSubentry subentry; 82 | 83 | subentry.header = base_quest_state.quest_name; 84 | //FIXME implement this 85 | 86 | 87 | optional_task_entries.listAppend(ChecklistEntryMake(base_quest_state.image_name, active_url, subentry, $locations[seaside megalopolis]).ChecklistEntrySetIDTag("Memories quest future")); 88 | } 89 | 90 | void QMemoriesGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 91 | { 92 | if (true) 93 | return; 94 | if (__quest_state["Primordial Fear"].in_progress) 95 | { 96 | QMemoriesPrimordialFearGenerateTasks(task_entries, optional_task_entries, future_task_entries); 97 | } 98 | else if (__quest_state["Hyboria"].in_progress) 99 | { 100 | QMemoriesHyboriaGenerateTasks(task_entries, optional_task_entries, future_task_entries); 101 | } 102 | else if (__quest_state["Future"].in_progress) 103 | { 104 | QMemoriesFutureGenerateTasks(task_entries, optional_task_entries, future_task_entries); 105 | } 106 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Quests/Old Landfill.ash: -------------------------------------------------------------------------------- 1 | 2 | void QOldLandfillInit() 3 | { 4 | QuestState state; 5 | 6 | QuestStateParseMafiaQuestProperty(state, "questM19Hippy"); 7 | 8 | state.quest_name = "Give a Hippy a Boat"; 9 | state.image_name = "__item junk junk"; 10 | 11 | state.startable = true; 12 | 13 | __quest_state["Old Landfill"] = state; 14 | } 15 | 16 | 17 | void QOldLandfillGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 18 | { 19 | QuestState base_quest_state = __quest_state["Old Landfill"]; 20 | //if (!base_quest_state.in_progress) //this isn't actively tracked, so the best we can do is checking the last adventure location 21 | //return; 22 | if ($item[junk junk].available_amount() > 0) //FIXME returning to the hippy 23 | return; 24 | if (__last_adventure_location != $location[the old landfill] && !base_quest_state.in_progress) 25 | return; 26 | if (__misc_state["mysterious island available"]) 27 | return; 28 | 29 | ChecklistSubentry subentry; 30 | subentry.entries.listAppend("Unlocks the Mysterious Island."); 31 | 32 | item [int] missing_boat_items = $items[old claw-foot bathtub,old clothesline pole,antique cigar sign].items_missing(); 33 | 34 | subentry.header = base_quest_state.quest_name; 35 | 36 | string active_url = "place.php?whichplace=woods"; 37 | 38 | if ($item[worse homes and gardens].available_amount() > 0 && missing_boat_items.count() == 0) 39 | { 40 | active_url = "shop.php?whichshop=junkmagazine"; 41 | subentry.entries.listAppend("Use worse homes and gardens, craft a junk junk."); 42 | } 43 | else 44 | { 45 | string [int] nc_instructions = listMake("Go left", "Flush a bunch of toilets"); 46 | 47 | if ($item[old claw-foot bathtub].available_amount() == 0) 48 | { 49 | nc_instructions = listMake("Go left", "Take the tub"); 50 | } 51 | else if ($item[old clothesline pole].available_amount() == 0) 52 | { 53 | nc_instructions = listMake("Go center", "Take the antenna"); 54 | } 55 | else if ($item[antique cigar sign].available_amount() == 0) 56 | { 57 | nc_instructions = listMake("Go right", "Take the sign"); 58 | } 59 | 60 | 61 | if (missing_boat_items.count() > $item[funky junk key].available_amount() || $item[worse homes and gardens].available_amount() == 0) 62 | { 63 | subentry.modifiers.listAppend("+item"); 64 | subentry.entries.listAppend("Adventure in the Old Landfill with +item."); 65 | } 66 | else 67 | subentry.entries.listAppend("Adventure in the Old Landfill."); 68 | 69 | subentry.entries.listAppend("At the choice adventure, choose:|*" + nc_instructions.listJoinComponents(__html_right_arrow_character) + "."); 70 | } 71 | 72 | 73 | optional_task_entries.listAppend(ChecklistEntryMake(base_quest_state.image_name, active_url, subentry, $locations[the old landfill]).ChecklistEntrySetIDTag("Old landfill hippy quest")); 74 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Quests/Quest import.ash: -------------------------------------------------------------------------------- 1 | import "relay/TourGuide/Quests/Level 2.ash"; 2 | import "relay/TourGuide/Quests/Level 3.ash"; 3 | import "relay/TourGuide/Quests/Level 4.ash"; 4 | import "relay/TourGuide/Quests/Level 5.ash"; 5 | import "relay/TourGuide/Quests/Level 6.ash"; 6 | import "relay/TourGuide/Quests/Level 7.ash"; 7 | import "relay/TourGuide/Quests/Level 8.ash"; 8 | import "relay/TourGuide/Quests/Level 9.ash"; 9 | import "relay/TourGuide/Quests/Level 10.ash"; 10 | import "relay/TourGuide/Quests/Level 11.ash"; 11 | import "relay/TourGuide/Quests/Level 12.ash"; 12 | import "relay/TourGuide/Quests/Level 13.ash"; 13 | import "relay/TourGuide/Quests/Manor.ash"; 14 | import "relay/TourGuide/Quests/Pirate.ash"; 15 | import "relay/TourGuide/Quests/Nemesis.ash"; 16 | import "relay/TourGuide/Quests/Sea.ash"; 17 | import "relay/TourGuide/Quests/Space Elves.ash"; 18 | import "relay/TourGuide/Quests/Azazel.ash"; 19 | import "relay/TourGuide/Quests/Untinker.ash"; 20 | import "relay/TourGuide/Quests/Artist.ash"; 21 | import "relay/TourGuide/Quests/Legendary Beat.ash"; 22 | import "relay/TourGuide/Quests/Memories.ash"; 23 | import "relay/TourGuide/Quests/White Citadel.ash"; 24 | import "relay/TourGuide/Quests/Wizard of Ego.ash"; 25 | import "relay/TourGuide/Quests/Spookyraven Lights Out.ash"; 26 | import "relay/TourGuide/Quests/Felonia.ash"; 27 | import "relay/TourGuide/Quests/Guild.ash"; 28 | import "relay/TourGuide/Quests/Airport.ash"; 29 | import "relay/TourGuide/Quests/Subject 37.ash"; 30 | import "relay/TourGuide/Quests/Marty.ash"; 31 | import "relay/TourGuide/Quests/Meatsmith.ash"; 32 | import "relay/TourGuide/Quests/Intergalaktik.ash"; 33 | import "relay/TourGuide/Quests/Old Landfill.ash"; 34 | import "relay/TourGuide/Quests/Madness Bakery.ash"; 35 | 36 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Quests/Untinker.ash: -------------------------------------------------------------------------------- 1 | 2 | void QUntinkerInit() 3 | { 4 | QuestState state; 5 | 6 | QuestStateParseMafiaQuestProperty(state, "questM01Untinker"); 7 | 8 | state.quest_name = "Untinker's Quest"; 9 | state.image_name = "rusty screwdriver"; 10 | 11 | state.startable = $location[the spooky forest].locationAvailable(); 12 | 13 | __quest_state["Untinker"] = state; 14 | } 15 | 16 | 17 | void QUntinkerGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 18 | { 19 | QuestState base_quest_state = __quest_state["Untinker"]; 20 | if (base_quest_state.finished || !base_quest_state.startable) 21 | return; 22 | 23 | if (my_path_id() == PATH_EXPLOSION || my_path_id() == PATH_GREY_GOO) return; 24 | ChecklistSubentry subentry; 25 | 26 | subentry.header = base_quest_state.quest_name; 27 | 28 | string url = ""; 29 | 30 | if ($item[rusty screwdriver].available_amount() > 0 || base_quest_state.mafia_internal_step == 0) 31 | { 32 | subentry.entries.listAppend("Speak to the Untinker."); 33 | url = "place.php?whichplace=forestvillage&action=fv_untinker_quest"; 34 | } 35 | else 36 | { 37 | //Acquire rusty screwdriver: 38 | if (knoll_available()) 39 | { 40 | subentry.entries.listAppend("Speak to Innabox in Degrassi Knoll."); 41 | url = "place.php?whichplace=knoll_friendly"; 42 | } 43 | else 44 | { 45 | url = "place.php?whichplace=knoll_hostile"; 46 | subentry.entries.listAppend("Retrieve screwdriver from the Degrassi Knoll Garage.|(25% superlikely)"); 47 | if (__misc_state["free runs available"]) 48 | { 49 | subentry.modifiers.listAppend("free runs"); 50 | } 51 | if (__misc_state["have hipster"]) 52 | { 53 | subentry.modifiers.listAppend(__misc_state_string["hipster name"]); 54 | } 55 | } 56 | } 57 | 58 | optional_task_entries.listAppend(ChecklistEntryMake(base_quest_state.image_name, url, subentry, $locations[the degrassi knoll garage]).ChecklistEntrySetIDTag("Untinker quest")); 59 | } 60 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Sections/Globals.ash: -------------------------------------------------------------------------------- 1 | //Runtime variables: 2 | location __last_adventure_location; 3 | 4 | 5 | //Runtime call functions: 6 | 7 | //Init functions happen after state and quest initialisation, so they can be referred to safely. 8 | string [int] __init_functions; 9 | 10 | void RegisterInitFunction(string function_name) 11 | { 12 | __init_functions.listAppend(function_name); 13 | } 14 | 15 | string [int] __checklist_generation_function_names; 16 | 17 | //Call function registration: 18 | void RegisterChecklistGenerationFunction(string function_name) 19 | { 20 | __checklist_generation_function_names.listAppend(function_name); 21 | } 22 | 23 | string [string][int] __specific_checklist_1_generation_function_names; 24 | void RegisterSpecificChecklistGenerationFunction1(string function_name, string checklist_name_1) 25 | { 26 | if (!(__specific_checklist_1_generation_function_names contains checklist_name_1)) { 27 | __specific_checklist_1_generation_function_names[checklist_name_1] = listMakeBlankString(); 28 | } 29 | __specific_checklist_1_generation_function_names[checklist_name_1].listAppend(function_name); 30 | } 31 | 32 | Record ChecklistGenerationFunctionRequest 33 | { 34 | string function_name; 35 | string [int] checklist_names; 36 | }; 37 | 38 | void listAppend(ChecklistGenerationFunctionRequest [int] list, ChecklistGenerationFunctionRequest entry) 39 | { 40 | int position = list.count(); 41 | while (list contains position) 42 | position += 1; 43 | list[position] = entry; 44 | } 45 | 46 | ChecklistGenerationFunctionRequest [int] __specific_checklist_generation_requests; 47 | 48 | void RegisterSpecificChecklistGenerationFunction3(string function_name, string checklist_name_1, string checklist_name_2, string checklist_name_3) 49 | { 50 | ChecklistGenerationFunctionRequest request; 51 | request.function_name = function_name; 52 | //Hardcoded to match call structure: 53 | request.checklist_names[0] = checklist_name_1; 54 | request.checklist_names[1] = checklist_name_2; 55 | request.checklist_names[2] = checklist_name_3; 56 | __specific_checklist_generation_requests.listAppend(request); 57 | } 58 | 59 | void RegisterTaskGenerationFunction(string function_name) { 60 | RegisterSpecificChecklistGenerationFunction3(function_name, "Tasks", "Optional Tasks", "Future Tasks"); 61 | } 62 | 63 | void RegisterResourceGenerationFunction(string function_name) { 64 | RegisterSpecificChecklistGenerationFunction1(function_name, "Resources"); 65 | } 66 | 67 | void RegisterLowKeyGenerationFunction(string function_name) { 68 | RegisterSpecificChecklistGenerationFunction1(function_name, "Keys"); 69 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Sections/Navigation Bar.ash: -------------------------------------------------------------------------------- 1 | buffer generateNavbar(Checklist [int] ordered_output_checklists) 2 | { 3 | buffer navbar; 4 | navbar.append(HTMLGenerateTagPrefix("div", mapMake("class", "r_bottom_outer_container", "style", "bottom:0px;"))); 5 | navbar.append(HTMLGenerateTagPrefix("div", mapMake("class", "r_bottom_inner_container", "style", "background:" + __setting_navbar_background_colour + ";"))); 6 | 7 | string [int] titles; 8 | foreach key in ordered_output_checklists 9 | titles.listAppend(ordered_output_checklists[key].title); 10 | 11 | if (titles.count() > 0) 12 | { 13 | int [int] each_width; 14 | //Calculate width of each title: 15 | if (__setting_navbar_has_proportional_widths) 16 | { 17 | int total_character_count = 0; 18 | foreach i in titles 19 | { 20 | string title = titles[i]; 21 | int title_length = title.length(); 22 | total_character_count += title_length; 23 | } 24 | if (total_character_count > 0) 25 | { 26 | foreach i in titles 27 | { 28 | string title = titles[i]; 29 | float title_length = title.length(); 30 | 31 | float calculating_value = (100.0 * title_length) / (to_float(total_character_count)); 32 | each_width[i] = floor(calculating_value); 33 | } 34 | } 35 | } 36 | else 37 | { 38 | float remaining_width = 100.0; 39 | int number_done = 0; 40 | foreach i in titles 41 | { 42 | int shared_width = to_int(remaining_width / to_float(titles.count() - number_done)); 43 | each_width[i] = shared_width; 44 | remaining_width -= shared_width; 45 | number_done += 1; 46 | } 47 | } 48 | boolean first = true; 49 | foreach i in titles 50 | { 51 | string title = titles[i]; 52 | 53 | string onclick_javascript = ""; 54 | 55 | //Cancel our usual link: 56 | onclick_javascript += "navbarClick(event,'" + HTMLConvertStringToAnchorID(title + " checklist container") + "')"; 57 | 58 | navbar.append(HTMLGenerateTagPrefix("a", mapMake("class", "r_a_undecorated", "href", "#" + HTMLConvertStringToAnchorID(title), "onclick", onclick_javascript))); 59 | navbar.append(HTMLGenerateTagPrefix("div", mapMake("class", "r_navbar_button_container", "style", "width:" + each_width[i] + "%;"))); 60 | 61 | //Vertical separator: 62 | if (first) 63 | first = false; 64 | else if (!__setting_gray_navbar) 65 | navbar.append(HTMLGenerateDivOfClass("", "r_navbar_line_separator")); 66 | 67 | string text_div = HTMLGenerateDivOfClass(title, "r_navbar_text"); 68 | if (true) 69 | { 70 | //Vertical centring with divs: 71 | //Which is to... tell the browser to act like a table. 72 | //Sorry. 73 | navbar.append(HTMLGenerateTagPrefix("div", mapMake("style", "padding-left:1px;padding-right:1px;margin-left:auto;margin-right:auto;display:table;height:100%;"))); 74 | navbar.append(HTMLGenerateTagWrap("div", text_div, mapMake("style", "display:table-cell;vertical-align:middle;"))); 75 | navbar.append(""); 76 | } 77 | navbar.append(""); 78 | navbar.append(""); 79 | } 80 | } 81 | navbar.append(""); 82 | navbar.append(""); 83 | return navbar; 84 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Sections/User Preferences.ash: -------------------------------------------------------------------------------- 1 | string [string] __user_preferences_private; 2 | boolean __read_user_preferences_initially = false; 3 | 4 | 5 | 6 | //File implementation: 7 | //Preferred, but not chosen in case this somehow triggers an HD read too often: 8 | /*string __user_preferences_file_name = "data/relay_ezandora_guide_preferences_" + my_id() + ".txt"; 9 | void readUserPreferences() 10 | { 11 | __read_user_preferences_initially = true; 12 | file_to_map(__user_preferences_file_name, __user_preferences_private); 13 | } 14 | 15 | void writeUserPreferences() 16 | { 17 | map_to_file(__user_preferences_private, __user_preferences_file_name); 18 | }*/ 19 | 20 | 21 | string __user_preferences_property_name = "ezandora_guide_preferences"; 22 | void readUserPreferences() 23 | { 24 | string [string] blank; 25 | __user_preferences_private = blank; 26 | string guide_value = get_property(__user_preferences_property_name); 27 | foreach key, pair in guide_value.split_string_alternate(";") 28 | { 29 | string [int] split = pair.split_string_alternate("="); 30 | if (split.count() != 2) 31 | continue; 32 | __user_preferences_private[split[0]] = split[1]; 33 | } 34 | __read_user_preferences_initially = true; 35 | } 36 | 37 | void writeUserPreferences() 38 | { 39 | if (!__read_user_preferences_initially) 40 | readUserPreferences(); 41 | buffer output_value; 42 | boolean first = true; 43 | foreach key, value in __user_preferences_private 44 | { 45 | if (!first) 46 | output_value.append(";"); 47 | else 48 | first = false; 49 | output_value.append(key); 50 | output_value.append("="); 51 | output_value.append(value); 52 | } 53 | set_property(__user_preferences_property_name, output_value); 54 | } 55 | 56 | 57 | string PreferenceGet(string name) 58 | { 59 | if (!__read_user_preferences_initially) 60 | readUserPreferences(); 61 | 62 | return __user_preferences_private[name]; 63 | } 64 | 65 | boolean PreferenceGetBoolean(string name) 66 | { 67 | return PreferenceGet(name).to_boolean(); 68 | } 69 | 70 | void PreferenceSet(string name, string value) 71 | { 72 | if (!__read_user_preferences_initially) 73 | readUserPreferences(); 74 | __user_preferences_private[name] = value; 75 | writeUserPreferences(); 76 | } 77 | 78 | 79 | void processSetUserPreferences(string [string] form_fields) 80 | { 81 | foreach key, value in form_fields 82 | { 83 | if (key == "set user preferences") 84 | continue; 85 | PreferenceSet(key, value); 86 | } 87 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Sets.ash: -------------------------------------------------------------------------------- 1 | 2 | import "relay/TourGuide/Support/Checklist.ash"; 3 | import "relay/TourGuide/Sets/Sets import.ash"; 4 | 5 | void SetsInit() 6 | { 7 | SCountersInit(); 8 | QHitsInit(); 9 | } 10 | 11 | 12 | void SetsGenerateResources(ChecklistEntry [int] resource_entries) 13 | { 14 | SFamiliarsGenerateResource(resource_entries); 15 | SSemirareGenerateResource(resource_entries); 16 | SSkillsGenerateResource(resource_entries); 17 | SMiscItemsGenerateResource(resource_entries); 18 | SCopiedMonstersGenerateResource(resource_entries); 19 | SPulveriseGenerateResource(resource_entries); 20 | SCountersGenerateResource(resource_entries); 21 | SFaxGenerateResource(resource_entries); 22 | SClassesGenerateResource(resource_entries); 23 | SEquipmentGenerateResource(resource_entries); 24 | S8bitRealmGenerateResource(resource_entries); 25 | SCalculateUniverseGenerateResource(resource_entries); 26 | SEventsGenerateResource(resource_entries); 27 | } 28 | 29 | void SetsGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 30 | { 31 | SFamiliarsGenerateTasks(task_entries, optional_task_entries, future_task_entries); 32 | SSemirareGenerateTasks(task_entries, optional_task_entries, future_task_entries); 33 | SDispensaryGenerateTasks(task_entries, optional_task_entries, future_task_entries); 34 | SCouncilGenerateTasks(task_entries, optional_task_entries, future_task_entries); 35 | SCopiedMonstersGenerateTasks(task_entries, optional_task_entries, future_task_entries); 36 | SAftercoreGenerateTasks(task_entries, optional_task_entries, future_task_entries); 37 | QHitsGenerateTasks(task_entries, optional_task_entries, future_task_entries); 38 | S8bitRealmGenerateTasks(task_entries, optional_task_entries, future_task_entries); 39 | SDailyDungeonGenerateTasks(task_entries, optional_task_entries, future_task_entries); 40 | SCountersGenerateTasks(task_entries, optional_task_entries, future_task_entries); 41 | SBountyHunterHunterGenerateTasks(task_entries, optional_task_entries, future_task_entries); 42 | SOldLevel9GenerateTasks(task_entries, optional_task_entries, future_task_entries); 43 | SFaxGenerateTasks(task_entries, optional_task_entries, future_task_entries); 44 | SDungeonsOfDoomGenerateTasks(task_entries, optional_task_entries, future_task_entries); 45 | SOlfactionGenerateTasks(task_entries, optional_task_entries, future_task_entries); 46 | SHolidayGenerateTasks(task_entries, optional_task_entries, future_task_entries); 47 | SRemindersGenerateTasks(task_entries, optional_task_entries, future_task_entries); 48 | SEventsGenerateTasks(task_entries, optional_task_entries, future_task_entries); 49 | SClassesGenerateTasks(task_entries, optional_task_entries, future_task_entries); 50 | SEquipmentGenerateTasks(task_entries, optional_task_entries, future_task_entries); 51 | SMiscItemsGenerateTasks(task_entries, optional_task_entries, future_task_entries); 52 | SPVPGenerateTasks(task_entries, optional_task_entries, future_task_entries); 53 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Sets/Council.ash: -------------------------------------------------------------------------------- 1 | 2 | void SCouncilGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 3 | { 4 | if (!__misc_state["in run"]) 5 | return; 6 | if (my_path_id() == PATH_COMMUNITY_SERVICE) 7 | return; 8 | boolean council_probably_wants_to_speak_to_you = false; 9 | string [int] reasons; 10 | boolean [string] seen_quest_name; 11 | foreach quest_name in __quest_state 12 | { 13 | QuestState state = __quest_state[quest_name]; 14 | if (state.quest_name == "Island War Quest" && my_path_id() == PATH_EXPLOSION) continue; 15 | if (state.startable && !state.in_progress && !state.finished && state.council_quest) 16 | { 17 | if (seen_quest_name[state.quest_name]) 18 | continue; 19 | seen_quest_name[state.quest_name] = true; 20 | reasons.listAppend(state.quest_name); 21 | council_probably_wants_to_speak_to_you = true; 22 | } 23 | } 24 | if (!council_probably_wants_to_speak_to_you) 25 | return; 26 | 27 | string [int] description; 28 | 29 | description.listAppend("Start the " + reasons.listJoinComponents(", ", "and") + "."); 30 | 31 | if (!have_outfit_components("War Hippy Fatigues") && !have_outfit_components("Frat Warrior Fatigues") && !have_outfit_components("Filthy Hippy Disguise") && __quest_state["Level 12"].startable && !__quest_state["Level 12"].in_progress && !__quest_state["Level 12"].finished && my_path_id() != PATH_EXPLOSIONS) 32 | description.listAppend(HTMLGenerateSpanFont("May want to wait", "red") + " until you've acquired a filthy hippy disguise for acquiring a war outfit?"); 33 | if (my_path_id() == PATH_EXPLOSIONS) 34 | description.listAppend("You might need to visit your quest log afterwards, to update mafia's tracking."); 35 | task_entries.listAppend(ChecklistEntryMake("council", "place.php?whichplace=town", ChecklistSubentryMake("Visit the Council of Loathing", "", description)).ChecklistEntrySetIDTag("Council visit")); 36 | } 37 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Sets/Demon Summon.ash: -------------------------------------------------------------------------------- 1 | //demonSummoned 2 | RegisterResourceGenerationFunction("SDemonSummonGenerateResource"); 3 | void SDemonSummonGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (!QuestState("questL11Manor").finished || my_path_id() == PATH_COMMUNITY_SERVICE || my_path_id() == PATH_GREY_GOO) 6 | return; 7 | if (get_property_boolean("demonSummoned")) 8 | return; 9 | //thin black candle >= 3 10 | //scroll of ancient forbidden unspeakable evil 11 | //FIXME suggest running intergnat? 12 | 13 | if ($item[thin black candle].available_amount() >= 3 && $item[scroll of ancient forbidden unspeakable evil].available_amount() + $item[scroll of ancient forbidden unspeakable evil].creatable_amount() > 0) 14 | { 15 | string [int] description; 16 | string url = "place.php?whichplace=manor4&action=manor4_chamber"; 17 | 18 | if ($item[thin black candle].item_amount() < 3 && $item[thin black candle].available_amount() >= 3) 19 | { 20 | description.listAppend("Pull 3 thin black candles."); 21 | url = ""; 22 | } 23 | if ($item[scroll of ancient forbidden unspeakable evil].available_amount() == 0 && $item[scroll of ancient forbidden unspeakable evil].creatable_amount() > 0) 24 | { 25 | description.listAppend("Create a scroll of ancient forbidden unspeakable evil."); 26 | url = ""; 27 | } 28 | 29 | string [int][int] john; 30 | //Prenatural greed. 31 | string [string] demons; 32 | demons["demonName2"] = "+100% meat"; 33 | if ($familiar[intergnat].familiar_is_usable() && in_ronin()) 34 | { 35 | if (!get_property("demonName12").contains_text("Neil")) //FIXME what if neil is on their friends list? 36 | { 37 | description.listAppend("Could run intergnat for demon name."); 38 | } 39 | else 40 | { 41 | if (my_level() == 11) 42 | { 43 | if (__dense_liana_machete_items.available_amount() == 0) 44 | demons["demonName12"] += "Antique machete, tomb ratchet, and cigarette lighter."; 45 | else 46 | demons["demonName12"] += "Tomb ratchet, and cigarette lighter."; 47 | } 48 | else if (my_level() == 12) 49 | { 50 | if ($items[richard's star key,star chart].available_amount() == 0) 51 | demons["demonName12"] += "Star chart."; 52 | } 53 | else if (my_level() == 13) 54 | demons["demonName12"] += "+50% init buff."; 55 | else 56 | demons["demonName12"] += "1000 meat."; 57 | if (demons["demonName12"] != "") 58 | demons["demonName12"] += "|"; 59 | demons["demonName12"] += "+10% item, +20% meat, +50% init, +spell/weapon damage buff."; 60 | if (my_familiar() != $familiar[intergnat]) 61 | demons["demonName12"] += "|Make sure to switch to your intergnat familiar before summoning."; 62 | } 63 | } 64 | //Intergnat. 65 | 66 | foreach property, description in demons 67 | { 68 | string property_value = get_property(property); 69 | if (property_value == "") 70 | continue; 71 | john.listAppend(listMake(property_value, description)); 72 | } 73 | 74 | if (john.count() > 0) 75 | description.listAppend(HTMLGenerateSimpleTableLines(john)); 76 | 77 | resource_entries.listAppend(ChecklistEntryMake("__item thin black candle", url, ChecklistSubentryMake("Demon summonable", "", description), 7).ChecklistEntrySetIDTag("Manor demon summoning")); 78 | } 79 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Sets/Dispensary.ash: -------------------------------------------------------------------------------- 1 | void SDispensaryGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 2 | { 3 | //Not sure how I feel about this. The dispensary is very useful, but not necessary to complete an ascension. 4 | if (dispensary_available()) 5 | return; 6 | //It's even less useful now that they've changed the buffs. Sorry, dispensary. 7 | if (true) 8 | return; 9 | if (!__misc_state["can equip just about any weapon"]) //need to wear KGE to learn the password 10 | return; 11 | 12 | if (!__quest_state["Level 5"].started || !$location[cobb's knob barracks].locationAvailable()) 13 | return; 14 | if (__quest_state["Level 5"].finished && !have_outfit_components("Knob Goblin Elite Guard Uniform")) //level 5 quest completed, but they don't have KGE - I think we'll close the suggestion here, as they probably don't want to go back? maybe? it'll still show up in semi-rare if they care to 15 | return; 16 | if (!have_outfit_components("Knob Goblin Elite Guard Uniform") && __misc_state["in run"]) //don't bother unless they have the uniform 17 | return; 18 | 19 | ChecklistSubentry subentry; 20 | subentry.header = "Unlock Cobb's Knob Dispensary"; 21 | 22 | string [int] dispensary_advantages; 23 | if (!black_market_available() && !__misc_state["MMJs buyable"]) 24 | dispensary_advantages.listAppend("MP Restorative"); 25 | dispensary_advantages.listAppend("+30% meat"); 26 | dispensary_advantages.listAppend("+15% items"); 27 | if (my_path_id() != PATH_BEES_HATE_YOU && !__misc_state["familiars temporarily blocked"]) 28 | dispensary_advantages.listAppend("+5 familiar weight"); 29 | dispensary_advantages.listAppend("+1 mainstat/fight"); 30 | 31 | if (dispensary_advantages.count() > 0) 32 | subentry.entries.listAppend("Access to " + dispensary_advantages.listJoinComponents(", ", "and") + " buff items."); 33 | 34 | if ($item[Cobb's Knob lab key].available_amount() == 0) 35 | subentry.entries.listAppend("Find the cobb's knob lab key either laying around, or defeat the goblin king."); 36 | else 37 | { 38 | if (have_outfit_components("Knob Goblin Elite Guard Uniform")) 39 | { 40 | if (!is_wearing_outfit("Knob Goblin Elite Guard Uniform")) 41 | subentry.entries.listAppend("Wear KGE outfit, adventure in Cobb's Knob Barracks."); 42 | else 43 | subentry.entries.listAppend("Adventure in Cobb's Knob Barracks."); 44 | } 45 | else 46 | subentry.entries.listAppend("Acquire KGE outfit"); 47 | } 48 | optional_task_entries.listAppend(ChecklistEntryMake("Dispensary", "cobbsknob.php", subentry, 10).ChecklistEntrySetIDTag("Dispensary cobb knob")); 49 | } 50 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Sets/Dungeons of Doom.ash: -------------------------------------------------------------------------------- 1 | 2 | void SDungeonsOfDoomGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 3 | { 4 | //Let's see... 5 | //Normally, we assume the best path is to fax a quantum mechanic (in HC) or pull a large box (in SC) 6 | //However, that won't work for paths without a fax machine, or for people without a VIP key, or for people who desire to open the dungeons of doom regardless. 7 | //So, we suggest it in those cases. 8 | //We also want to work in aftercore - if they haven't unlocked the DOD yet and they've started, give suggestions. 9 | 10 | //lastPlusSignUnlock is set by the oracle, not reading the book. 11 | string title = "Dungeons of Doom"; 12 | string image_name = "Dungeons of Doom"; 13 | string [int] description; 14 | string [int] modifiers; 15 | string url = "da.php"; 16 | 17 | boolean should_output = true; 18 | 19 | int turns_attempted = $location[The Enormous Greater-Than Sign].turnsAttemptedInLocation() + $location[the dungeons of doom].turnsAttemptedInLocation(); 20 | 21 | if (my_basestat(my_primestat()) < 45) //not yet 22 | return; 23 | if (turns_attempted == 0) //no, they haven't started yet 24 | return; 25 | 26 | if (get_property_ascension("lastPlusSignUnlock")) 27 | { 28 | should_output = false; 29 | //Dungeons of doom unlocked. 30 | if ($item[plus sign].available_amount() > 0) 31 | { 32 | should_output = true; 33 | //Read plus sign: 34 | title = "Read plus sign"; 35 | image_name = "__item plus sign"; 36 | url = "inventory.php?ftext=plus+sign"; 37 | } 38 | } 39 | else 40 | { 41 | boolean adventuring_in_sign = true; 42 | string [int] tasks; 43 | if (my_meat() < 1000) 44 | tasks.listAppend("acquire 1000 meat"); 45 | if ($item[plus sign].available_amount() == 0) 46 | tasks.listAppend("acquire plus sign from non-combat"); 47 | else if ($effect[Teleportitis].have_effect() == 0) 48 | tasks.listAppend("acquire teleportitis from non-combat or uppercase Q hitting you"); 49 | else 50 | { 51 | adventuring_in_sign = false; 52 | tasks.listAppend("find the oracle, pay for major consultation"); 53 | } 54 | 55 | title = "Unlock dungeons of doom"; 56 | if (adventuring_in_sign) 57 | { 58 | modifiers.listAppend("-combat"); 59 | description.listAppend("Run -combat in the enormous greater-than sign."); 60 | 61 | } 62 | description.listAppend(tasks.listJoinComponents(", ", "then").capitaliseFirstLetter() + "."); 63 | } 64 | 65 | if (should_output) 66 | optional_task_entries.listAppend(ChecklistEntryMake(image_name, url, ChecklistSubentryMake(title, modifiers, description), $locations[the enormous greater-than sign,the dungeons of doom]).ChecklistEntrySetIDTag("Dungeon of doom")); 67 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Sets/Equipment.ash: -------------------------------------------------------------------------------- 1 | 2 | string [int] SEquipmentGenerateXiblaxianHoloWristPuterDescription() 3 | { 4 | string [int] description; 5 | string [int][int] table; 6 | table.listAppend(listMake("Outdoor", "polymer")); 7 | table.listAppend(listMake("Indoor", "circuitry")); 8 | table.listAppend(listMake("Underground", "alloy")); 9 | table.listAppend(listMake("Underwater", "polymer")); 10 | //this is kind of a hack: 11 | int index_to_bold = -1; 12 | if (__last_adventure_location.environment == "outdoor") 13 | index_to_bold = 0; 14 | else if (__last_adventure_location.environment == "indoor") 15 | index_to_bold = 1; 16 | else if (__last_adventure_location.environment == "underground") 17 | index_to_bold = 2; 18 | if (__last_adventure_location.environment == "underwater") 19 | index_to_bold = 3; 20 | 21 | if (index_to_bold != -1) 22 | { 23 | foreach key, v in table[index_to_bold] 24 | table[index_to_bold][key] = HTMLGenerateSpanOfClass(v, "r_bold"); 25 | } 26 | description.listAppend(HTMLGenerateSimpleTableLines(table)); 27 | 28 | if (!get_property_boolean("_holoWristCrystal")) 29 | description.listAppend("Can acquire a crystal by mining. (once/day)"); 30 | 31 | string [int] items_owned; 32 | foreach it in $items[Xiblaxian alloy,Xiblaxian circuitry,Xiblaxian polymer,Xiblaxian crystal] 33 | { 34 | if (it.available_amount() > 0) 35 | items_owned.listAppend(it.available_amount() + " " + it); 36 | } 37 | 38 | description.listAppend("Own " + items_owned.listJoinComponents(", ", "and") + "."); 39 | return description; 40 | } 41 | 42 | void SEquipmentGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 43 | { 44 | if ($item[Xiblaxian holo-wrist-puter].equipped_amount() > 0) 45 | { 46 | int turns_left = XiblaxianHoloWristPuterTurnsUntilNextItem(); 47 | if (turns_left == 1 || turns_left == 0) 48 | { 49 | string [int] description = SEquipmentGenerateXiblaxianHoloWristPuterDescription(); 50 | task_entries.listAppend(ChecklistEntryMake("__item Xiblaxian holo-wrist-puter", "", ChecklistSubentryMake("Xiblaxian item next combat", "", description), -11).ChecklistEntrySetIDTag("Xiblaxian wrist now")); 51 | } 52 | } 53 | } 54 | 55 | void SEquipmentGenerateResource(ChecklistEntry [int] resource_entries) 56 | { 57 | if ($item[Xiblaxian holo-wrist-puter].equipped_amount() > 0) 58 | { 59 | int turns_left = XiblaxianHoloWristPuterTurnsUntilNextItem(); 60 | if (turns_left != -1 || true) 61 | { 62 | string [int] description = SEquipmentGenerateXiblaxianHoloWristPuterDescription(); 63 | //description.listAppend("_holoWristDrops = " + get_property_int("_holoWristDrops")); 64 | //description.listAppend("_holoWristProgress = " + get_property_int("_holoWristProgress")); 65 | 66 | string header = turns_left + " combats to Xiblaxian item"; 67 | if (turns_left <= 1) 68 | header = "Xiblaxian next turn"; 69 | resource_entries.listAppend(ChecklistEntryMake("__item Xiblaxian holo-wrist-puter", "", ChecklistSubentryMake(header, "", description), 8).ChecklistEntrySetIDTag("Xiblaxian wrist reminder")); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Sets/Events.ash: -------------------------------------------------------------------------------- 1 | import "relay/TourGuide/Support/Banishers.ash"; 2 | 3 | void SEventsGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 4 | { 5 | return; 6 | } 7 | 8 | void SCrimbo2015GenerateResource(ChecklistEntry [int] resource_entries) 9 | { 10 | string year_and_month = format_today_to_string("yyyyMM"); 11 | if (year_and_month != "201512") 12 | return; 13 | if (mafiaIsPastRevision(16544) && !in_ronin()) 14 | { 15 | int herb_uses_left = clampi(10 - get_property_int("_fragrantHerbsUsed"), 0, 10); 16 | if ($item[bundle of "fragrant" herbs].available_amount() > 0 && herb_uses_left > 0) 17 | { 18 | string [int] description; 19 | description.listAppend("Free run/banish three monsters at once."); 20 | monster [int] banished_monsters; 21 | foreach key, b in BanishesActive() 22 | { 23 | if (b.banish_source == "bundle of "fragrant" herbs") 24 | { 25 | banished_monsters.listAppend(b.banished_monster); 26 | } 27 | } 28 | if (banished_monsters.count() > 0) 29 | description.listAppend("Have " + banished_monsters.listJoinComponents(", ", "and") + " banished."); 30 | resource_entries.listAppend(ChecklistEntryMake("__item bundle of "fragrant" herbs", "", ChecklistSubentryMake(pluralise(herb_uses_left, "fragrant herb banish", "fragrant herb banishes"), "", description), 3).ChecklistEntrySetIDTag("Crimbo 2015 flagrant herbs")); 31 | } 32 | int stockpile_uses_left = clampi(10 - get_property_int("_nuclearStockpileUsed"), 0, 10); 33 | if ($item[nuclear stockpile].available_amount() > 0 && stockpile_uses_left > 0) 34 | { 35 | string [int] description; 36 | description.listAppend("Does not cost a turn."); 37 | resource_entries.listAppend(ChecklistEntryMake("__item nuclear stockpile", "", ChecklistSubentryMake(pluralise(stockpile_uses_left, "nuclear stockpile instakill", "nuclear stockpile instakills"), "", description), 3).ChecklistEntrySetIDTag("Crimbo 2015 nuclear stockpile")); 38 | } 39 | } 40 | } 41 | 42 | void SEventsGenerateResource(ChecklistEntry [int] resource_entries) 43 | { 44 | SCrimbo2015GenerateResource(resource_entries); 45 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Sets/Florist.ash: -------------------------------------------------------------------------------- 1 | import "relay/TourGuide/Plants.ash"; 2 | 3 | RegisterTaskGenerationFunction("SFloristGenerateTasks"); 4 | void SFloristGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 5 | { 6 | //Friar: 7 | if (__iotms_usable[$item[Order of the Green Thumb Order Form]]) 8 | { 9 | string image_name = "sunflower face"; 10 | ChecklistSubentry subentry; 11 | subentry.header = "Plant florist plants in " + __last_adventure_location; 12 | 13 | PlantSuggestion [int] area_relevant_suggestions; 14 | foreach key, suggestion in __plants_suggested_locations 15 | { 16 | 17 | if (suggestion.loc != __last_adventure_location) 18 | continue; 19 | 20 | area_relevant_suggestions.listAppend(suggestion); 21 | } 22 | 23 | boolean single_mode_only = false; 24 | if (area_relevant_suggestions.count() == 1) 25 | { 26 | single_mode_only = true; 27 | PlantSuggestion suggestion = area_relevant_suggestions[0]; 28 | string plant_name = suggestion.plant_name.capitaliseFirstLetter(); 29 | 30 | subentry.header = "Plant " + plant_name + " in " + __last_adventure_location; 31 | } 32 | 33 | foreach key, suggestion in area_relevant_suggestions 34 | { 35 | string plant_name = suggestion.plant_name.capitaliseFirstLetter(); 36 | Plant plant = __plant_properties[plant_name]; 37 | 38 | string line; 39 | 40 | if (single_mode_only) 41 | { 42 | line = plant.zone_effect + ", " + plant.terrain; 43 | if (plant.territorial) 44 | line = line + ", territorial"; 45 | 46 | if (suggestion.details != "") 47 | line += "|*" + suggestion.details; 48 | } 49 | else 50 | { 51 | line = plant_name + " (" + plant.zone_effect + ", " + plant.terrain; 52 | if (plant.territorial) 53 | line = line + ", territorial"; 54 | 55 | line += ")"; 56 | if (suggestion.details != "") 57 | line += "|*" + suggestion.details; 58 | } 59 | 60 | if (plant_name == "War Lily" || plant_name == "Rabid Dogwood" || plant_name == "Blustery Puffball") 61 | { 62 | if (monster_level_adjustment() + 30 > 150) 63 | { 64 | //subentry.header = "Optionally plant florist plants in " + __last_adventure_location; 65 | image_name = "__item pirate fledges"; 66 | 67 | subentry.header += "?"; 68 | line += "|" + HTMLGenerateSpanFont("Very dangerous", "red") + ", monsters "; 69 | if (monster_level_adjustment() > 150) 70 | line += "are"; 71 | else 72 | line += "will be"; 73 | line += " stagger immune."; 74 | } 75 | } 76 | 77 | subentry.entries.listAppend(line); 78 | } 79 | if (subentry.entries.count() > 0) 80 | task_entries.listAppend(ChecklistEntryMake(image_name, "place.php?whichplace=forestvillage&action=fv_friar", subentry, -11).ChecklistEntrySetIDTag("Florist friar plant suggestions")); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Sets/Holidays.ash: -------------------------------------------------------------------------------- 1 | import "relay/TourGuide/Support/Holiday.ash"; 2 | 3 | void SHolidayGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 4 | { 5 | boolean [string] todays_holidays = getHolidaysToday(); 6 | boolean [string] all_tomorrows_parties = getHolidaysTomorrow(); 7 | 8 | if (todays_holidays["Halloween"]) 9 | { 10 | if (__misc_state["in run"]) 11 | { 12 | string [int] description; 13 | description.listAppend("Free stats/items from monsters on the first block."); 14 | if (knoll_available() && !have_outfit_components("Filthy Hippy Disguise")) 15 | { 16 | item [int] missing_components = missing_outfit_components("Bugbear Costume"); 17 | if (missing_components.count() > 0) 18 | description.listAppend("If you need an outfit, buy a " + missing_components.listJoinComponents(", ", "and") + " from the knoll."); 19 | } 20 | optional_task_entries.listAppend(ChecklistEntryMake("__item plastic pumpkin bucket", "place.php?whichplace=town&action=town_trickortreat", ChecklistSubentryMake("Trick or treat for one block", "+" + my_primestat().to_lower_case(), description), $locations[trick-or-treating]).ChecklistEntrySetIDTag("Holiday halloween in-run")); 21 | } 22 | else 23 | { 24 | string [int] description; 25 | description.listAppend("Wear an outfit, go from house to house."); 26 | description.listAppend("Remember you can trick-or-treat while drunk."); 27 | optional_task_entries.listAppend(ChecklistEntryMake("__item plastic pumpkin bucket", "place.php?whichplace=town&action=town_trickortreat", ChecklistSubentryMake("Trick or treat", "", description), $locations[trick-or-treating]).ChecklistEntrySetIDTag("Holiday halloween aftercore")); 28 | } 29 | } 30 | if (all_tomorrows_parties["Halloween"] && !__misc_state["in run"]) 31 | optional_task_entries.listAppend(ChecklistEntryMake("__item plastic pumpkin bucket", "", ChecklistSubentryMake("Save turns for Halloween tomorrow", "", ""), 8).ChecklistEntrySetIDTag("Holiday halloween soon reminder")); 32 | 33 | if (todays_holidays["Arrrbor Day"]) 34 | { 35 | string [int] description; 36 | boolean [item] outfit_pieces_needed; 37 | foreach it in $items[crotchety pants,Saccharine Maple pendant,willowy bonnet] 38 | { 39 | if (!it.haveAtLeastXOfItemEverywhere(1)) 40 | outfit_pieces_needed[it] = true; 41 | } 42 | //FIXME detect collecting reward? 43 | if ($items[bag of Crotchety Pine saplings,bag of Saccharine Maple saplings,bag of Laughing Willow saplings].available_amount() == 0) 44 | { 45 | description.listAppend("Choose a sapling type."); 46 | string [int] suggestions; 47 | if (outfit_pieces_needed[$item[crotchety pants]]) 48 | suggestions.listAppend("Crotchety Pine"); 49 | if (outfit_pieces_needed[$item[Saccharine Maple pendant]]) 50 | suggestions.listAppend("Saccharine Maple"); 51 | if (outfit_pieces_needed[$item[willowy bonnet]]) 52 | suggestions.listAppend("Laughing Willow"); 53 | if (suggestions.count() > 0) 54 | description.listAppend("Could try " + suggestions.listJoinComponents(", ", "or") + " for the reward item" + (suggestions.count() > 1 ? "s" : "") + "."); 55 | } 56 | else 57 | { 58 | item [int] bag_types; 59 | boolean have_a_bag_equipped = false; 60 | foreach it in $items[bag of Crotchety Pine saplings,bag of Saccharine Maple saplings,bag of Laughing Willow saplings] 61 | { 62 | if (it.available_amount() > 0) 63 | bag_types.listAppend(it); 64 | if (it.equipped_amount() > 0) 65 | have_a_bag_equipped = true; 66 | } 67 | if (!have_a_bag_equipped) 68 | { 69 | description.listAppend("Equip your " + bag_types.listJoinComponents(", ", "or") + "."); 70 | } 71 | else if (outfit_pieces_needed.count() > 0) 72 | { 73 | description.listAppend("Adventure for at least one hundred adventures to collect the outfit piece next holiday."); 74 | } 75 | else 76 | { 77 | description.listAppend("Adventure for at least two adventures to collect the potion reward next holiday."); 78 | } 79 | } 80 | optional_task_entries.listAppend(ChecklistEntryMake("__item spooky sapling", "place.php?whichplace=woods", ChecklistSubentryMake("Plant trees", "", description), 8, $locations[The Arrrboretum]).ChecklistEntrySetIDTag("Holiday arrrbor day")); 81 | } 82 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Sets/Level 13 Door.ash: -------------------------------------------------------------------------------- 1 | 2 | void SLevel13DoorGenerateMissingItems(ChecklistEntry [int] tower_door_entries) 3 | { 4 | if (__quest_state["Level 13"].state_boolean["past keys"]) return; 5 | 6 | if ($item[skeleton key].available_amount() == 0 && !__quest_state["Level 13"].state_boolean["skeleton key used"]) { 7 | string line = "loose teeth (" + ($item[loose teeth].available_amount() == 0 ? "need" : "have") + ")"; 8 | line += " + skeleton bone (" + ($item[skeleton bone].available_amount() == 0 ? "need" : "have") + ")"; 9 | tower_door_entries.listAppend(ChecklistEntryMake("__item skeleton key", $location[the defiled nook].getClickableURLForLocation(), ChecklistSubentryMake("Skeleton key", "", line)).ChecklistEntrySetIDTag("Council L13 tower door skeleton key")); 10 | } 11 | 12 | S8bitRealmGenerateMissingItems(tower_door_entries); 13 | 14 | SDailyDungeonGenerateMissingItems(tower_door_entries); 15 | 16 | QHitsGenerateMissingItems(tower_door_entries); 17 | } 18 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Sets/Monorail.ash: -------------------------------------------------------------------------------- 1 | RegisterTaskGenerationFunction("SMonorailStationGenerateTasks"); 2 | void SMonorailStationGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 3 | { 4 | if (__misc_state["can eat just about anything"] && get_property("muffinOnOrder") == "earthenware muffin tin") 5 | optional_task_entries.listAppend(ChecklistEntryMake("__item earthenware muffin tin", "place.php?whichplace=monorail", ChecklistSubentryMake("Get your muffin tin back", "", "Vist the monorail's breakfast counter"), 8).ChecklistEntrySetIDTag("Monorail get muffin tin")); 6 | } 7 | 8 | RegisterResourceGenerationFunction("SMonorailStationBreakfastCounterGenerateResource"); 9 | void SMonorailStationBreakfastCounterGenerateResource(ChecklistEntry [int] resource_entries) 10 | { 11 | if (get_property_boolean("_muffinOrderedToday") || get_property("muffinOnOrder") == "earthenware muffin tin") 12 | return; 13 | 14 | item order = get_property("muffinOnOrder").lookupItem(); 15 | if (order != $item[none]) { 16 | resource_entries.listAppend(ChecklistEntryMake("__item " + order.to_string(), "place.php?whichplace=monorail", ChecklistSubentryMake("Go grab your " + order.to_string()), 5).ChecklistEntrySetIDTag("Monorail muffin resource")); 17 | } 18 | else if (lookupItem("earthenware muffin tin").available_amount() > 0) { 19 | resource_entries.listAppend(ChecklistEntryMake("__item earthenware muffin tin", "place.php?whichplace=monorail", ChecklistSubentryMake("Order a new muffin"), 5).ChecklistEntrySetIDTag("Monorail muffin resource")); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Sets/Old Level 9 quest.ash: -------------------------------------------------------------------------------- 1 | 2 | void SOldLevel9GenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 3 | { 4 | if ($location[The Valley of Rof L'm Fao].turnsAttemptedInLocation() == 0) 5 | return; 6 | //if (__misc_state["in run"]) 7 | //return; 8 | QuestState state; 9 | QuestStateParseMafiaQuestProperty(state, "questM15Lol", false); //don't issue a quest log load for this, no information gained 10 | if (!state.in_progress) 11 | return; 12 | 13 | string url = "place.php?whichplace=mountains"; 14 | 15 | string [int] description; 16 | 17 | if ($item[64735 scroll].item_amount() > 0) 18 | { 19 | description.listAppend("Use the 64735 scroll."); 20 | url = "inventory.php?ftext=64735+scroll"; 21 | } 22 | else 23 | { 24 | description.listAppend("Make the 64735 scroll using the rampaging adding machine."); 25 | 26 | item [int] components_testing; 27 | if ($item[64067 scroll].item_amount() == 0) 28 | { 29 | components_testing.listAppend($item[30669 scroll]); 30 | components_testing.listAppend($item[33398 scroll]); 31 | } 32 | if ($item[668 scroll].item_amount() == 0) 33 | { 34 | components_testing.listAppend($item[334 scroll]); 35 | components_testing.listAppend($item[334 scroll]); 36 | } 37 | string [int] components_needed; 38 | int [item] amount_used; 39 | foreach key in components_testing 40 | { 41 | item it = components_testing[key]; 42 | if (it.item_amount() - amount_used[it] <= 0) 43 | { 44 | components_needed.listAppend(it.to_string()); 45 | } 46 | else 47 | amount_used[it] += 1; 48 | } 49 | if (components_needed.count() > 0) 50 | description.listAppend("Need " + components_needed.listJoinComponents(", ", "and") + "."); 51 | 52 | //suggest faxing? 53 | if (__misc_state["fax equivalent accessible"]) 54 | description.listAppend("Possibly fax the rampaging adding machine (with all scroll components) for one-turn quest."); 55 | description.listAppend("Find rampaging adding machine, feed it 334 + 334, 30669 + 33398, 64067 + 668."); 56 | description.listAppend("31337 scroll is 30669 + 668. (334 + 334)"); 57 | } 58 | ChecklistSubentry [int] subentries; 59 | subentries.listAppend(ChecklistSubentryMake("A Quest, LOL", "", description)); 60 | optional_task_entries.listAppend(ChecklistEntryMake("__item 64735 scroll", url, subentries, 10, $locations[the valley of rof l'm fao]).ChecklistEntrySetIDTag("Valley rof l'm fao quest")); 61 | } 62 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Sets/Sets import.ash: -------------------------------------------------------------------------------- 1 | import "relay/TourGuide/Support/Library.ash"; 2 | import "relay/TourGuide/Sets/Semi-rare.ash"; 3 | import "relay/TourGuide/Sets/Hole in the Sky.ash"; 4 | import "relay/TourGuide/Sets/Familiars.ash"; 5 | import "relay/TourGuide/Sets/Dispensary.ash"; 6 | import "relay/TourGuide/Sets/Skills.ash"; 7 | import "relay/TourGuide/Sets/Misc Items.ash"; 8 | import "relay/TourGuide/Sets/Council.ash"; 9 | import "relay/TourGuide/Sets/Copied Monsters.ash"; 10 | import "relay/TourGuide/Sets/Pulverise.ash"; 11 | import "relay/TourGuide/Sets/Aftercore.ash"; 12 | import "relay/TourGuide/Sets/8-bit Realm.ash"; 13 | import "relay/TourGuide/Sets/Daily Dungeon.ash"; 14 | import "relay/TourGuide/Sets/Counters.ash"; 15 | import "relay/TourGuide/Sets/Bounty Hunter Hunter.ash"; 16 | import "relay/TourGuide/Sets/Old Level 9 quest.ash"; 17 | import "relay/TourGuide/Sets/Fax.ash"; 18 | import "relay/TourGuide/Sets/Dungeons of Doom.ash"; 19 | import "relay/TourGuide/Sets/Olfaction.ash"; 20 | import "relay/TourGuide/Sets/Holidays.ash"; 21 | import "relay/TourGuide/Sets/Reminders.ash"; 22 | import "relay/TourGuide/Sets/Events.ash"; 23 | import "relay/TourGuide/Sets/Classes.ash"; 24 | import "relay/TourGuide/Sets/Equipment.ash"; 25 | import "relay/TourGuide/Sets/Calculate Universe.ash"; 26 | import "relay/TourGuide/Sets/PVP.ash"; 27 | import "relay/TourGuide/Sets/Demon Summon.ash"; 28 | import "relay/TourGuide/Sets/Area Unlocks.ash"; 29 | import "relay/TourGuide/Sets/Powerlevel.ash"; 30 | import "relay/TourGuide/Sets/Florist.ash"; 31 | import "relay/TourGuide/Sets/Misc Tasks.ash"; 32 | import "relay/TourGuide/Sets/Sweet Synthesis.ash"; 33 | import "relay/TourGuide/Sets/Buff Upkeep.ash"; 34 | import "relay/TourGuide/Sets/Level 13 Door.ash"; 35 | import "relay/TourGuide/Sets/Monorail.ash"; 36 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Settings.ash: -------------------------------------------------------------------------------- 1 | //These settings are for development. Don't worry about editing them. 2 | string __version = "1.9.1"; 3 | 4 | //Path and name of the .js file. In case you change either. 5 | string __javascript = "TourGuide/TourGuide.js"; 6 | 7 | //Debugging: 8 | boolean __setting_debug_mode = false; 9 | boolean __setting_debug_enable_example_mode_in_aftercore = false; //for testing. Will give false information, so don't enable 10 | boolean __setting_debug_show_all_internal_states = false; //displays usable images/__misc_state/__misc_state_string/__misc_state_int/__quest_state 11 | 12 | //Display settings: 13 | boolean __setting_entire_area_clickable = false; 14 | boolean __setting_side_negative_space_is_dark = true; 15 | boolean __setting_fill_vertical = true; 16 | int __setting_image_width_large = 100; 17 | int __setting_image_width_medium = 70; 18 | int __setting_image_width_small = 30; 19 | 20 | boolean __show_importance_bar = true; 21 | boolean __setting_show_navbar = true; 22 | boolean __setting_navbar_has_proportional_widths = false; //doesn't look very good, remove? 23 | boolean __setting_gray_navbar = true; 24 | boolean __setting_use_kol_css = false; //images/styles.css 25 | boolean __setting_show_location_bar = true; 26 | boolean __setting_enable_location_popup_box = true; 27 | boolean __setting_location_bar_uses_last_location = false; //nextAdventure otherwise 28 | boolean __setting_location_bar_fixed_layout = true; 29 | boolean __setting_location_bar_limit_max_width = true; 30 | float __setting_location_bar_max_width_per_entry = 0.35; 31 | boolean __setting_enable_outputting_all_numberology_options = true; 32 | 33 | string __setting_unavailable_colour = "#7F7F7F"; 34 | string __setting_line_colour = "#B2B2B2"; 35 | string __setting_dark_colour = "#C0C0C0"; 36 | string __setting_modifier_colour = "#404040"; 37 | string __setting_navbar_background_colour = "#FFFFFF"; 38 | string __setting_page_background_colour = "#F7F7F7"; 39 | 40 | string __setting_media_query_large_size = "@media (min-width: 500px)"; 41 | string __setting_media_query_medium_size = "@media (min-width: 350px) and (max-width: 500px)"; 42 | string __setting_media_query_small_size = "@media (max-width: 350px) and (min-width: 225px)"; 43 | string __setting_media_query_tiny_size = "@media (max-width: 225px)"; 44 | 45 | float __setting_navbar_height_in_em = 2.3; 46 | string __setting_navbar_height = __setting_navbar_height_in_em + "em"; 47 | int __setting_horizontal_width = 600; 48 | boolean __setting_ios_appearance = false; //no don't 49 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Strategy.ash: -------------------------------------------------------------------------------- 1 | void generateStrategy(Checklist [int] checklists) 2 | { 3 | ChecklistEntry [int] entries; 4 | 5 | if (!__misc_state["in run"]) 6 | return; 7 | 8 | 9 | //What familiar to run. spleen items 10 | //Turn generation. 11 | //How to handle combat. 12 | //How to restore HP. 13 | //Where to get MP...? 14 | 15 | 16 | checklists.listAppend(ChecklistMake("Strategy", entries)); 17 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Support/AdventurePHP Locations.ash: -------------------------------------------------------------------------------- 1 | //This file isn't used in guide at all, currently, but I'd thought I'd release it anyways. 2 | //Classifies locations on whether they are adventure.php. Useful for scripts that need that information. Relevant for arrowing monsters, KOLHS, wandering monsters, semi-rare, etc. 3 | 4 | import "relay/TourGuide/Support/Math.ash"; 5 | 6 | static 7 | { 8 | int [location] __adventure_php_locations; 9 | void initialiseAdventurePHPLocations() 10 | { 11 | //Two methods: 12 | //Look up every snarfblat, and assign ones that have locations. (this is faster) 13 | //Load adventures.txt, find every adventure= entry, save those. (slower, but more accurate if they ever go past 1000 snarfblat) 14 | //Using the first method, because our parsing of adventures.txt isn't perfect, and it'll take a few years before we go over snarfblat=1000 15 | if (true) 16 | { 17 | //0.985093583 total, 0.663535898 net, 1000 invocations 18 | for i from 1 to 1000 //FIXME update this in a few years, we're nearing 500 or so right now 19 | { 20 | location l = i.to_location(); 21 | if (l != $location[none]) 22 | __adventure_php_locations[l] = i; 23 | } 24 | } 25 | else 26 | { 27 | //2.571006588 total, 0.791600414 net, 1000 invocations 28 | //Read from adventures.txt: 29 | //This doesn't accurately read the file. No idea how to use file_to_map here. 30 | string [string,string] adventures_txt; 31 | file_to_map("data/adventures.txt", adventures_txt); 32 | //print_html("adventures_txt = " + adventures_txt.to_json()); 33 | foreach key in adventures_txt 34 | { 35 | foreach key2 in adventures_txt[key] 36 | { 37 | if (key2.contains_text("adventure=")) 38 | { 39 | int snarfblat = key2.replace_string("adventure=", "").to_int_silent(); 40 | 41 | location l = snarfblat.to_location(); 42 | if (l != $location[none]) 43 | __adventure_php_locations[l] = snarfblat; 44 | } 45 | //print_html("found (" + key + ")(" + key2 + ") \"" + adventures_txt[key][key2] + "\""); 46 | } 47 | } 48 | } 49 | } 50 | initialiseAdventurePHPLocations(); 51 | } 52 | 53 | boolean locationVisitsAdventurePHP(location l) 54 | { 55 | if (l.to_url().contains_text("adventure.php")) 56 | return true; 57 | if (__adventure_php_locations contains l) 58 | return true; 59 | return false; 60 | } 61 | 62 | boolean locationAllowsWanderingMonsters(location l) 63 | { 64 | if ($locations[The Shore\, Inc. Travel Agency,Noob Cave,The Dire Warren] contains l) 65 | return false; 66 | if ($locations[The Daily Dungeon,An Overgrown Shrine (Northwest),An Overgrown Shrine (Southwest),An Overgrown Shrine (Northeast),An Overgrown Shrine (Southeast),A Massive Ziggurat] contains l) //warning: I have not personally verified these 67 | return false; 68 | if (l == $location[The X-32-F Combat Training Snowman]) 69 | return false; 70 | if ($locations[Gingerbread Industrial Zone,Gingerbread Train Station,Gingerbread Sewers,Gingerbread Upscale Retail District] contains l && l != $location[none]) 71 | return false; 72 | return l.locationVisitsAdventurePHP(); 73 | } 74 | 75 | int snarfblatForLocation(location l) 76 | { 77 | if (__adventure_php_locations contains l) 78 | return __adventure_php_locations[l]; 79 | return -1; 80 | } 81 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Support/Equipment Requirement.ash: -------------------------------------------------------------------------------- 1 | import "relay/TourGuide/Support/Library.ash"; 2 | 3 | Record EquipmentStatRequirement 4 | { 5 | stat requirement_stat; 6 | int requirement_amount; 7 | }; 8 | static 9 | { 10 | EquipmentStatRequirement [item] __equipment_stat_requirements; 11 | } 12 | 13 | void initialiseEquipmentRequirements() 14 | { 15 | if (__equipment_stat_requirements.count() > 0) 16 | return; 17 | Record equipment_txt_entry 18 | { 19 | int power; 20 | string requirement; 21 | string weapon_description; 22 | }; 23 | equipment_txt_entry [item] entries; 24 | file_to_map("data/equipment.txt", entries); 25 | 26 | foreach it, entry in entries 27 | { 28 | if (entry.requirement == "" || entry.requirement == "none") 29 | continue; 30 | int requirement_integer = entry.requirement.split_string(" ")[1].to_int_silent(); 31 | if (requirement_integer <= 0) 32 | continue; 33 | stat known_stat = $stat[none]; 34 | if (entry.requirement.contains_text("Mus: ")) 35 | { 36 | known_stat = $stat[muscle]; 37 | } 38 | else if (entry.requirement.contains_text("Mys: ")) 39 | { 40 | known_stat = $stat[mysticality]; 41 | } 42 | else if (entry.requirement.contains_text("Mox: ")) 43 | { 44 | known_stat = $stat[moxie]; 45 | } 46 | if (known_stat != $stat[none]) 47 | { 48 | EquipmentStatRequirement requirement; 49 | requirement.requirement_stat = known_stat; 50 | requirement.requirement_amount = requirement_integer; 51 | 52 | __equipment_stat_requirements[it] = requirement; 53 | //__equipment_stat_requirements[it][known_stat] = requirement_integer; 54 | } 55 | } 56 | } 57 | EquipmentStatRequirement StatRequirementForEquipment(item it) 58 | { 59 | initialiseEquipmentRequirements(); 60 | return __equipment_stat_requirements[it]; 61 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Support/Error.ash: -------------------------------------------------------------------------------- 1 | 2 | //Allows error checking. The intention behind this design is Errors are passed in to a method. The method then sets the error if anything went wrong. 3 | record Error 4 | { 5 | boolean was_error; 6 | string explanation; 7 | }; 8 | 9 | Error ErrorMake(boolean was_error, string explanation) 10 | { 11 | Error err; 12 | err.was_error = was_error; 13 | err.explanation = explanation; 14 | return err; 15 | } 16 | 17 | Error ErrorMake() 18 | { 19 | return ErrorMake(false, ""); 20 | } 21 | 22 | void ErrorSet(Error err, string explanation) 23 | { 24 | err.was_error = true; 25 | err.explanation = explanation; 26 | } 27 | 28 | void ErrorSet(Error err) 29 | { 30 | ErrorSet(err, "Unknown"); 31 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Support/Fold Groups.ash: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | static 5 | { 6 | boolean [item][item] __fold_groups; 7 | 8 | void generateFoldables() 9 | { 10 | string [int] foldgroups_file = file_to_array("data/foldgroups.txt"); 11 | 12 | foreach key, line in foldgroups_file 13 | { 14 | if (line.contains_text("#")) continue; //wrong, but I don't 15 | string [int] line_split = line.split_string("\t"); 16 | if (line_split.count() < 2) continue; 17 | for i from 1 to line_split.count() - 1 18 | { 19 | string v = line_split[i]; 20 | item it = v.to_item(); 21 | if (it == $item[none]) continue; 22 | 23 | foreach it2 in it.get_related("fold") 24 | { 25 | __fold_groups[it][it2] = true; 26 | } 27 | } 28 | } 29 | } 30 | generateFoldables(); 31 | } 32 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Support/Holiday.ash: -------------------------------------------------------------------------------- 1 | boolean [string] getHolidaysForDate(string realworld_date, int game_day) 2 | { 3 | boolean [string] holidays; 4 | 5 | if (realworld_date == "0202") 6 | holidays["Groundhog Day"] = true; 7 | //april fools 8 | else if (realworld_date == "0401") 9 | holidays["April Fool's Day"] = true; 10 | //Talk Like a Pirate Day - september 19th 11 | else if (realworld_date == "0919") 12 | holidays["Talk Like a Pirate Day"] = true; 13 | else if (realworld_date == "1031") 14 | holidays["Halloween"] = true; 15 | else if (realworld_date == "0214") 16 | holidays["Valentine's Day"] = true; 17 | else if (realworld_date == "0525") 18 | holidays["Towel Day"] = true; 19 | else if (realworld_date == "0704") 20 | holidays["Dependence Day"] = true; 21 | 22 | //Crimbo 23 | if (now_to_string("M").to_int_silent() == 12) 24 | holidays["Crimbo"] = true; 25 | 26 | //Friday the 13th 27 | if (format_today_to_string("EEE d") == "Fri 13") 28 | holidays["Friday the 13th"] = true; 29 | 30 | 31 | 32 | //Festival of Jarlsberg - acquire the party hat? - Jarlsuary 1 33 | if (game_day == 0) 34 | holidays["Festival of Jarlsberg"] = true; 35 | //Valentine's Day! - Frankuary 4 36 | else if (game_day == 11) 37 | holidays["Valentine's Day"] = true; 38 | //St. Sneaky Pete's Day - Starch 3 39 | else if (game_day == 18) 40 | holidays["St. Sneaky Pete's Day"] = true; 41 | //Oyster Egg Day - April 2 42 | else if (game_day == 25) 43 | holidays["Oyster Egg Day"] = true; 44 | //El Dia de Los Muertos Borrachos? just wandering monsters... - Martinus 2 45 | else if (game_day == 33) 46 | holidays["El Dia de Los Muertos Borrachos"] = true; 47 | //Generic Summer Holiday - Bill 3 48 | else if (game_day == 42) 49 | holidays["Generic Summer Holiday"] = true; 50 | //Dependence Day - Bor 4 51 | else if (game_day == 51) 52 | holidays["Dependence Day"] = true; 53 | //Arrrbor Day - Petember 4 54 | else if (game_day == 59) 55 | holidays["Arrrbor Day"] = true; 56 | //Labór Day - Carlvember 6 57 | else if (game_day == 69) 58 | holidays["Labór Day"] = true; 59 | //Halloween / halloween tomorrow, save adventures? - Porktober 8 60 | else if (game_day == 79) 61 | holidays["Halloween"] = true; 62 | //feast of boris...? - Boozember 7 63 | else if (game_day == 86) 64 | holidays["Feast of Boris"] = true; 65 | //Yuletide? - Dougtember 4 66 | else if (game_day == 91) 67 | holidays["Yuletide"] = true; 68 | 69 | 70 | return holidays; 71 | } 72 | 73 | boolean [string] getHolidaysToday() 74 | { 75 | boolean [string] holidays = getHolidaysForDate(format_today_to_string("MMdd"), gameday_to_int()); //FIXME Y10K error 76 | if (holiday() != "") 77 | holidays[holiday()] = true; 78 | return holidays; 79 | } 80 | 81 | boolean [string] getHolidaysTomorrow() 82 | { 83 | //FIXME support next real-world day 84 | return getHolidaysForDate("", ((gameday_to_int() + 1) % 96)); 85 | } 86 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Support/Item Filter.ash: -------------------------------------------------------------------------------- 1 | 2 | static 3 | { 4 | item [string][int] __if_potions_with_numeric_modifiers; 5 | 6 | 7 | /*void ItemFilterInitialise() 8 | { 9 | boolean [string] modifier_names = $strings[Meat Drop,Initiative,Muscle,Mysticality,Moxie,Muscle Percent,Mysticality Percent,Moxie Percent]; 10 | 11 | foreach modifier in modifier_names 12 | { 13 | __if_potions_with_numeric_modifiers[modifier] = listMakeBlankItem(); 14 | } 15 | foreach it in $items[] 16 | { 17 | if (it.inebriety > 0 || it.fullness > 0 || it.spleen > 0) continue; 18 | effect e = it.to_effect(); 19 | if (e == $effect[none]) continue; 20 | foreach modifier in modifier_names 21 | { 22 | if (e.numeric_modifier(modifier) > 0.0) 23 | { 24 | __if_potions_with_numeric_modifiers[modifier].listAppend(it); 25 | } 26 | } 27 | } 28 | } 29 | 30 | 31 | ItemFilterInitialise();*/ 32 | } 33 | 34 | 35 | void ItemFilterInitialisePotionsForModifier(string modifier) 36 | { 37 | if (__if_potions_with_numeric_modifiers contains modifier) 38 | return; 39 | __if_potions_with_numeric_modifiers[modifier] = listMakeBlankItem(); 40 | 41 | foreach it in $items[] 42 | { 43 | if (it.inebriety > 0 || it.fullness > 0 || it.spleen > 0) continue; 44 | effect e = it.to_effect(); 45 | if (e == $effect[none]) continue; 46 | if (e.numeric_modifier(modifier) != 0.0) 47 | { 48 | __if_potions_with_numeric_modifiers[modifier].listAppend(it); 49 | } 50 | } 51 | } 52 | 53 | 54 | item [int] ItemFilterGetPotionsWithNumericModifiers(string [int] modifiers) 55 | { 56 | item [int] potions; 57 | boolean [item] seen_potions; 58 | foreach key, modifier in modifiers 59 | { 60 | item [int] first_layer_list; 61 | if (!(__if_potions_with_numeric_modifiers contains modifier)) 62 | ItemFilterInitialisePotionsForModifier(modifier); 63 | 64 | first_layer_list = __if_potions_with_numeric_modifiers[modifier]; 65 | 66 | 67 | foreach key, it in first_layer_list 68 | { 69 | if (!it.is_unrestricted()) 70 | continue; 71 | if (seen_potions contains it) 72 | continue; 73 | potions.listAppend(it); 74 | seen_potions[it] = true; 75 | } 76 | } 77 | 78 | return potions; 79 | } 80 | 81 | item [int] ItemFilterGetPotionsCouldPullToAddToNumericModifier(string [int] modifiers, float minimum_modifier, boolean [item] blacklist) 82 | { 83 | item [int] relevant_potions_first_layer = ItemFilterGetPotionsWithNumericModifiers(modifiers); 84 | 85 | item [int] relevant_potions; 86 | foreach key, it in relevant_potions_first_layer 87 | { 88 | if (it.available_amount() > 0) continue; 89 | if (!it.tradeable && it.storage_amount() == 0) continue; 90 | if (!it.item_is_usable()) continue; 91 | effect e = it.to_effect(); 92 | if (e.have_effect() > 0) continue; 93 | if (!e.effect_is_usable()) continue; 94 | float v = 0; 95 | foreach key, modifier in modifiers 96 | v += e.numeric_modifier(modifier); 97 | if (v != 0.0 && v >= minimum_modifier && !(blacklist contains it)) 98 | { 99 | relevant_potions.listAppend(it); 100 | } 101 | } 102 | if (modifiers.count() == 2) 103 | sort relevant_potions by -(value.effect_modifier("effect").numeric_modifier(modifiers[0]) + value.effect_modifier("effect").numeric_modifier(modifiers[1])); 104 | else 105 | sort relevant_potions by -value.effect_modifier("effect").numeric_modifier(modifiers[0]); 106 | 107 | return relevant_potions; 108 | } 109 | 110 | 111 | item [int] ItemFilterGetPotionsCouldPullToAddToNumericModifier(string modifier, float minimum_modifier, boolean [item] blacklist) 112 | { 113 | return ItemFilterGetPotionsCouldPullToAddToNumericModifier(listMake(modifier), minimum_modifier, blacklist); 114 | } 115 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Support/Location Choice.ash: -------------------------------------------------------------------------------- 1 | record LocationChoice 2 | { 3 | location place; 4 | string [int] reasons; 5 | int importance; 6 | }; 7 | 8 | LocationChoice LocationChoiceMake(location place, string [int] reasons, int importance) 9 | { 10 | LocationChoice result; 11 | result.place = place; 12 | result.reasons = reasons; 13 | result.importance = importance; 14 | return result; 15 | } 16 | 17 | LocationChoice LocationChoiceMake(location place, string reason, int importance) 18 | { 19 | return LocationChoiceMake(place, listMake(reason), importance); 20 | } 21 | 22 | LocationChoice LocationChoiceMake(location place, string reason) 23 | { 24 | return LocationChoiceMake(place, reason, 0); 25 | } 26 | 27 | void listAppend(LocationChoice [int] list, LocationChoice entry) 28 | { 29 | int position = list.count(); 30 | while (list contains position) 31 | position += 1; 32 | list[position] = entry; 33 | } 34 | 35 | void LocationChoiceSort(LocationChoice [int] list) 36 | { 37 | sort list by value.importance; 38 | } 39 | 40 | string [int] LocationChoiceGenerateDescription(LocationChoice [int] list) 41 | { 42 | string [int] description; 43 | foreach key in list 44 | { 45 | LocationChoice lc = list[key]; 46 | string [int] explanation = lc.reasons; 47 | 48 | if (explanation.count() == 0) 49 | continue; 50 | string first = lc.place.to_string(); 51 | if (lc.place == $location[none]) 52 | first = ""; 53 | 54 | string line; 55 | if (explanation.count() > 1) 56 | { 57 | line = first + HTMLGenerateIndentedText(HTMLGenerateDiv(explanation.listJoinComponents("
"))); 58 | } 59 | else 60 | { 61 | line = listFirstObject(explanation); 62 | if (line.stringHasPrefix("|") || first == "") 63 | line = first + line; 64 | else 65 | line = first + ": " + line; 66 | } 67 | //string line = first + HTMLGenerateIndentedText(HTMLGenerateDiv(explanation.listJoinComponents(HTMLGenerateDivOfStyle("", "border-top:1px solid;width:30%;")))); 68 | if (!locationAvailable(lc.place) && lc.place != $location[none]) 69 | { 70 | line = HTMLGenerateDivOfClass(line, "r_future_option"); 71 | } 72 | description.listAppend(line); 73 | } 74 | return description; 75 | } -------------------------------------------------------------------------------- /Source/relay/TourGuide/Support/Numberology.ash: -------------------------------------------------------------------------------- 1 | static 2 | { 3 | int [string] __moon_sign_id_lookup; 4 | void initialiseMoonSignIDLookup() 5 | { 6 | __moon_sign_id_lookup[""] = 0; 7 | __moon_sign_id_lookup["None"] = 0; 8 | __moon_sign_id_lookup["Mongoose"] = 1; 9 | __moon_sign_id_lookup["Wallaby"] = 2; 10 | __moon_sign_id_lookup["Vole"] = 3; 11 | __moon_sign_id_lookup["Platypus"] = 4; 12 | __moon_sign_id_lookup["Opossum"] = 5; 13 | __moon_sign_id_lookup["Marmot"] = 6; 14 | __moon_sign_id_lookup["Wombat"] = 7; 15 | __moon_sign_id_lookup["Blender"] = 8; 16 | __moon_sign_id_lookup["Packrat"] = 9; 17 | __moon_sign_id_lookup["Bad Moon"] = 10; //confirmed 18 | } 19 | initialiseMoonSignIDLookup(); 20 | } 21 | 22 | Record NumberologyCacheState 23 | { 24 | int b; 25 | int c; 26 | int [int] input_to_outputs; 27 | int [int] input_deltas; 28 | }; 29 | 30 | NumberologyCacheState NumberologyCacheStateMake() 31 | { 32 | NumberologyCacheState r; 33 | r.b = -1; 34 | r.c = -1; 35 | return r; 36 | } 37 | 38 | static 39 | { 40 | NumberologyCacheState __numberology_cache = NumberologyCacheStateMake(); 41 | } 42 | 43 | void calculateNumberologyInputValuesForOutputs(boolean [int] desired_digits_in, int [int] digit_inputs_to_outputs_out, int [int] digit_inputs_to_deltas_out) 44 | { 45 | if (!(__moon_sign_id_lookup contains my_sign())) //not computable 46 | return; 47 | 48 | boolean [int] desired_digits_left; 49 | foreach digit in desired_digits_in 50 | { 51 | desired_digits_left[digit] = true; 52 | digit_inputs_to_deltas_out[digit] = 99; 53 | } 54 | int mood_sign_id = __moon_sign_id_lookup[my_sign()]; 55 | 56 | int b = my_spleen_use() + my_level(); 57 | int c = (my_ascensions() + mood_sign_id) * b + my_adventures(); 58 | 59 | if (__numberology_cache.b == b && __numberology_cache.c == c) 60 | { 61 | //Cache lookup: 62 | foreach digit in desired_digits_in 63 | { 64 | if (__numberology_cache.input_to_outputs contains digit) 65 | { 66 | digit_inputs_to_outputs_out[digit] = __numberology_cache.input_to_outputs[digit]; 67 | remove desired_digits_left[digit]; 68 | } 69 | else if (__numberology_cache.input_deltas contains digit) 70 | { 71 | digit_inputs_to_deltas_out[digit] = __numberology_cache.input_deltas[digit]; 72 | remove desired_digits_left[digit]; 73 | } 74 | } 75 | } 76 | if (desired_digits_left.count() == 0) 77 | return; 78 | 79 | int last_x = -1; 80 | //Brute force method: 81 | for x from 0 to 99 82 | { 83 | int v = x * b + c; 84 | int last_two_digits = v % 100; 85 | if (desired_digits_left contains last_two_digits) 86 | { 87 | remove desired_digits_left[last_two_digits]; 88 | remove digit_inputs_to_deltas_out[last_two_digits]; 89 | digit_inputs_to_outputs_out[last_two_digits] = x; 90 | if (desired_digits_left.count() == 0) 91 | { 92 | last_x = x; 93 | break; 94 | } 95 | } 96 | foreach digit in desired_digits_left 97 | { 98 | int delta = digit - last_two_digits; 99 | if (delta <= 0) 100 | digit_inputs_to_deltas_out[digit] = min(digit_inputs_to_deltas_out[digit], -delta); 101 | else 102 | { 103 | delta = digit - (last_two_digits + 100); 104 | if (delta <= 0) 105 | digit_inputs_to_deltas_out[digit] = min(digit_inputs_to_deltas_out[digit], -delta); 106 | } 107 | } 108 | } 109 | 110 | //Save cache: 111 | if (__numberology_cache.b != b || __numberology_cache.c != c) 112 | __numberology_cache = NumberologyCacheStateMake(); 113 | __numberology_cache.b = b; 114 | __numberology_cache.c = c; 115 | foreach input, output in digit_inputs_to_outputs_out 116 | __numberology_cache.input_to_outputs[input] = output; 117 | foreach input, delta in digit_inputs_to_deltas_out 118 | __numberology_cache.input_deltas[input] = delta; 119 | } 120 | 121 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Support/Statics 2.ash: -------------------------------------------------------------------------------- 1 | import "relay/TourGuide/Support/Library.ash"; 2 | 3 | static 4 | { 5 | //mr. fusion: 6 | boolean [item] __pvpable_food_and_drinks; 7 | void initialisePVPFoodAndDrinks() 8 | { 9 | foreach it in $items[] 10 | { 11 | if (it.fullness == 0 && it.inebriety == 0) continue; 12 | if (!it.item_is_pvp_stealable()) continue; 13 | __pvpable_food_and_drinks[it] = true; 14 | } 15 | } 16 | initialisePVPFoodAndDrinks(); 17 | } 18 | -------------------------------------------------------------------------------- /Source/relay/TourGuide/Tasks.ash: -------------------------------------------------------------------------------- 1 | import "relay/TourGuide/Support/Checklist.ash" 2 | import "relay/TourGuide/Support/Library.ash" 3 | import "relay/TourGuide/Plants.ash" 4 | import "relay/TourGuide/Support/HTML.ash" 5 | import "relay/TourGuide/Sets.ash" 6 | 7 | void generateTasks(Checklist [int] checklists) 8 | { 9 | ChecklistEntry [int] task_entries; 10 | 11 | ChecklistEntry [int] optional_task_entries; 12 | 13 | ChecklistEntry [int] future_task_entries; 14 | 15 | QuestsGenerateTasks(task_entries, optional_task_entries, future_task_entries); 16 | SetsGenerateTasks(task_entries, optional_task_entries, future_task_entries); 17 | 18 | checklists.listAppend(ChecklistMake("Tasks", task_entries)); 19 | checklists.listAppend(ChecklistMake("Optional Tasks", optional_task_entries)); 20 | checklists.listAppend(ChecklistMake("Future Tasks", future_task_entries)); 21 | } -------------------------------------------------------------------------------- /Source/relay/relay_TourGuide.ash: -------------------------------------------------------------------------------- 1 | //This script and its support scripts are in the public domain. 2 | 3 | since 20.6; //the earliest main release that supports the changes to the terrarium that came with the release of the Melodramedary 4 | import "relay/TourGuide/Main.ash" 5 | 6 | void main() 7 | { 8 | runMain(__FILE__); 9 | } 10 | --------------------------------------------------------------------------------