├── Compile ASH script.rb ├── Images ├── Aftercore Small.png ├── Aftercore.png ├── BIG Day 2 End Small.png ├── BIG Day 2 End.png ├── Guide version 0.001.png ├── Inside Window.png ├── Instructions.png ├── Location Bar.png ├── No IOTM character Small.png ├── No IOTM character.png ├── Quest Example 1.png ├── Quest Example 2.png ├── Reminders 2.png ├── Reminders 3.png ├── Reminders.png ├── Resizing.png ├── Window picture Small.png ├── Window picture.png ├── absorbing.png ├── location popup bar.png ├── location_popup_bar_alpha.png └── spelunking.png ├── LICENSE ├── Matrix ├── glyphs.png ├── matrix.html └── matrix.js ├── README.md ├── Release └── relay │ ├── GuideBrowserSide.js │ └── relay_Guide.ash ├── Source └── relay │ ├── Guide │ ├── Daily Resources.ash │ ├── Items of the Month │ │ ├── Asdon Martin.ash │ │ ├── Backup Camera.ash │ │ ├── Barrel God.ash │ │ ├── Bastille Battalion.ash │ │ ├── Beach Comb.ash │ │ ├── Better Shrooms and Gardens catalog.ash │ │ ├── Bird-a-Day calendar.ash │ │ ├── BoomBox.ash │ │ ├── Boxing Daycare.ash │ │ ├── Cargo Cultist Shorts.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 Pill Keeper.ash │ │ ├── Emotion Chip.ash │ │ ├── Garbage Tote.ash │ │ ├── Gardens.ash │ │ ├── GenieBottle.ash │ │ ├── Getaway Campsite.ash │ │ ├── Gingerbread City.ash │ │ ├── God Lobster.ash │ │ ├── Grimstone.ash │ │ ├── Guzzlr tablet.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 │ │ ├── Miniature Crystal Ball.ash │ │ ├── Neverending Party.ash │ │ ├── New You.ash │ │ ├── Plastic Vampire Fangs.ash │ │ ├── Pocket Professor.ash │ │ ├── Portable Pantogram.ash │ │ ├── Potted Power Plant.ash │ │ ├── Powerful Glove.ash │ │ ├── Protonic Accelerator Pack.ash │ │ ├── Psychoanalytic.ash │ │ ├── Red-Nosed Snapper.ash │ │ ├── Retro Superhero Cape.ash │ │ ├── Rune Spoon.ash │ │ ├── Smithsness.ash │ │ ├── Snojo.ash │ │ ├── Source Terminal.ash │ │ ├── Space Jellyfish.ash │ │ ├── Spacegate.ash │ │ ├── Speakeasy.ash │ │ ├── Spinmaster Lathe.ash │ │ ├── Sugar.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 │ │ ├── Heavy Rains.ash │ │ ├── KOLHS.ash │ │ ├── License to Adventure.ash │ │ ├── Low Key.ash │ │ ├── Nuclear Autumn.ash │ │ ├── Paths import.ash │ │ ├── Quantum of Familiar.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 │ │ ├── Data.ash │ │ ├── Globals.ash │ │ ├── Location Bar Popup.ash │ │ ├── Location Bar.ash │ │ ├── Messages.ash │ │ ├── Navigation Bar.ash │ │ ├── Resource 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 │ │ ├── Bugs.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 │ │ ├── Holiday.ash │ │ ├── Misc Items.ash │ │ ├── Misc Tasks.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 │ │ ├── Checklist.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 │ │ ├── KOLImageData.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 │ │ └── Thanksgarden.ash │ └── Tasks.ash │ ├── GuideBrowserSide.js │ └── relay_Guide.ash └── manifest.json /Compile ASH script.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # Compile ASH script.rb 4 | # This script is in the public domain. 5 | # Compiles a collection of KoLMafia ASH scripts into one script, for distribution. 6 | # This isn't particularly robust. 7 | # Notable errors: 8 | # This script might miss import statements, and will import import statements that are commented out. 9 | # It will also not work on scripts outside of the KoLMafia directory that use absolute paths (relay/, scripts/) 10 | # And it won't understand certain aspects of KoLMafia's internal import mechanics. 11 | # Sorry! 12 | 13 | def readFileContentsAtPath(file_path) 14 | begin 15 | return File.read(file_path) 16 | rescue 17 | return '' 18 | end 19 | end 20 | 21 | def writeFileContentsAtPath(file_path, contents) 22 | File.write(file_path, contents) 23 | end 24 | 25 | # This is OS dependent. We need to know the base mafia directory, for relay/ and scripts/ paths. 26 | # So, we guess from the path we're given: 27 | def findPathOfSuperdirectory(file_path, directory_name) 28 | file_dir = File.dirname(file_path) 29 | if file_dir == file_path # reached base 30 | return '' 31 | elsif File.basename(file_dir) == directory_name # found it 32 | return file_dir 33 | else # go up one 34 | return findPathOfSuperdirectory(file_dir, directory_name) 35 | end 36 | end 37 | 38 | def compileFile(file_path, seen_file_paths, mafia_directory) 39 | file_path = File.absolute_path(file_path) # Eliminate ../ from paths, for our already-imported check 40 | 41 | if seen_file_paths.include?(file_path) # already imported. 42 | return '' 43 | end 44 | seen_file_paths << file_path 45 | file_dir = File.dirname(file_path) 46 | file_contents = readFileContentsAtPath(file_path) 47 | if file_contents == '' 48 | return '' 49 | end 50 | 51 | result_lines = [] 52 | file_lines = file_contents.split("\n") 53 | for line in file_lines 54 | if (not line.start_with?('import ')) 55 | result_lines << line 56 | else 57 | matches = line.match('import "([^"]*)"') 58 | if (matches != nil) 59 | importing_file = matches[1] 60 | if (importing_file.start_with?('relay/') or importing_file.start_with?('scripts/')) #assume absolute paths 61 | if (mafia_directory.empty?) 62 | puts "Absolute path found, halting compilation." 63 | exit(1) 64 | end 65 | importing_path = File.join(mafia_directory, importing_file) 66 | else 67 | importing_path = File.join(file_dir, importing_file) 68 | end 69 | result_lines << compileFile(importing_path, seen_file_paths, mafia_directory) 70 | end 71 | end 72 | end 73 | return result_lines.join("\n") 74 | end 75 | 76 | def main(arguments) 77 | if arguments.length < 1 78 | puts 'Usage: ' + $0 + ' input_file_path [output_file_path]' 79 | puts 'If no output file path is provided, results will be written to "Compiled [input_file_path]"' 80 | return 81 | end 82 | input_file_path = arguments[0] 83 | output_file_path = '' 84 | if arguments.length > 1 85 | output_file_path = arguments[1] 86 | else 87 | output_file_path = 'Compiled ' + File.basename(input_file_path) 88 | end 89 | mafia_directory = findPathOfSuperdirectory(input_file_path, 'KoLmafia') 90 | if mafia_directory.empty? 91 | puts 'Warning: KoLmafia directory not found. Absolute paths not supported.' 92 | end 93 | compilation = compileFile(input_file_path, [], mafia_directory) 94 | if (not compilation.empty?) 95 | puts 'Writing compiled "' + input_file_path + '" to "' + output_file_path + '"' 96 | writeFileContentsAtPath(output_file_path, compilation) 97 | else 98 | puts 'Empty or missing file, writing nothing.' 99 | end 100 | end 101 | 102 | if __FILE__ == $0 103 | main(ARGV) 104 | end 105 | -------------------------------------------------------------------------------- /Images/Aftercore Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/Aftercore Small.png -------------------------------------------------------------------------------- /Images/Aftercore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/Aftercore.png -------------------------------------------------------------------------------- /Images/BIG Day 2 End Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/BIG Day 2 End Small.png -------------------------------------------------------------------------------- /Images/BIG Day 2 End.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/BIG Day 2 End.png -------------------------------------------------------------------------------- /Images/Guide version 0.001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/Guide version 0.001.png -------------------------------------------------------------------------------- /Images/Inside Window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/Inside Window.png -------------------------------------------------------------------------------- /Images/Instructions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/Instructions.png -------------------------------------------------------------------------------- /Images/Location Bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/Location Bar.png -------------------------------------------------------------------------------- /Images/No IOTM character Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/No IOTM character Small.png -------------------------------------------------------------------------------- /Images/No IOTM character.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/No IOTM character.png -------------------------------------------------------------------------------- /Images/Quest Example 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/Quest Example 1.png -------------------------------------------------------------------------------- /Images/Quest Example 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/Quest Example 2.png -------------------------------------------------------------------------------- /Images/Reminders 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/Reminders 2.png -------------------------------------------------------------------------------- /Images/Reminders 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/Reminders 3.png -------------------------------------------------------------------------------- /Images/Reminders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/Reminders.png -------------------------------------------------------------------------------- /Images/Resizing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/Resizing.png -------------------------------------------------------------------------------- /Images/Window picture Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/Window picture Small.png -------------------------------------------------------------------------------- /Images/Window picture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/Window picture.png -------------------------------------------------------------------------------- /Images/absorbing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/absorbing.png -------------------------------------------------------------------------------- /Images/location popup bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/location popup bar.png -------------------------------------------------------------------------------- /Images/location_popup_bar_alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/location_popup_bar_alpha.png -------------------------------------------------------------------------------- /Images/spelunking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/Images/spelunking.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/Ezandora/Guide/13d7da6e609d97098cf84efa93eef5bcf2c4b25b/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 | Guide 2 | ===== 3 | 4 | How do I use it? 5 | ---------------- 6 | First, install it by running this command in KoLmafia's graphical CLI: 7 | 8 |
 9 | git checkout https://github.com/Ezandora/Guide.git
10 | 
11 | 12 | Once it's installed, look in the relay browser. In the upper-right, there will be a "-run script-" menu: 13 | 14 | ![Instructions](https://raw.github.com/Ezandora/Guide/master/Images/Instructions.png) 15 | 16 | Select Guide. Guide will install itself into the window, and will automatically update as you go along. 17 | 18 | To update the script itself, run this command in the graphical CLI: 19 | 20 |
21 | git update
22 | 
23 | 24 | What does it do? 25 | ---------------- 26 | Guide.ash is a relay script which will give advice on playing the web game [Kingdom of Loathing](http://www.kingdomofloathing.com) within [KoLmafia, a third-party tool](http://kolmafia.sourceforge.net). It details how to complete quests you're on, and what resources you have available. 27 | 28 | During an ascension, it will inform you what you need to know to complete your ascension as quickly as possible. Faxing, the daily dungeon, acquiring a wand, where to go next. 29 | 30 | The script runs side-by-side with KOL. Leave the window open, and it'll update as you go along. 31 | 32 | Quest advice: 33 | 34 | ![Quest Example 1](https://raw.github.com/Ezandora/Guide/master/Images/Quest%20Example%201.png) 35 | ![Quest Example 2](https://raw.github.com/Ezandora/Guide/master/Images/Quest%20Example%202.png) 36 | 37 | Reminders: 38 | 39 | ![Reminders](https://raw.github.com/Ezandora/Guide/master/Images/Reminders.png) 40 | ![Reminders 2](https://raw.github.com/Ezandora/Guide/master/Images/Reminders 2.png) 41 | ![Reminders 3](https://raw.github.com/Ezandora/Guide/master/Images/Reminders 3.png) 42 | 43 | The script will inform you of many resources you have - free runaways, hipster fights, semi-rares, etc. - and ideas on what to use them on. 44 | There is preliminary support for the florist friar and what to pull. It also works in aftercore. 45 | 46 | Screenshots: 47 | 48 | [![Window picture](https://raw.github.com/Ezandora/Guide/master/Images/Window%20picture%20Small.png)](https://raw.github.com/Ezandora/Guide/master/Images/Window%20picture.png) 49 | [![Aftercore](https://raw.github.com/Ezandora/Guide/master/Images/Aftercore%20Small.png)](https://raw.github.com/Ezandora/Guide/master/Images/Aftercore.png) 50 | [![No IOTM character](https://raw.github.com/Ezandora/Guide/master/Images/No%20IOTM%20character%20Small.png)](https://raw.github.com/Ezandora/Guide/master/Images/No%20IOTM%20character.png) 51 | [![BIG Day 2 end](https://raw.github.com/Ezandora/Guide/master/Images/BIG%20Day%202%20End%20Small.png)](https://raw.github.com/Ezandora/Guide/master/Images/BIG%20Day%202%20End.png) 52 | 53 | 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. 54 | 55 | Development guidelines 56 | --------------------- 57 | The release above is a compiled version of the development version, which can be found by checking out https://github.com/Ezandora/Guide/trunk/Source/ instead. If you wish to edit the script easily, start there. 58 | The release is compiled via Compile ASH script.rb, which collects the seventy or so scripts into one for ease of release. 59 | Currently, the only guidelines are avoid visit_url(), as well as any connection to KOL's servers. This is meant to be a local application. 60 | 61 | This script, as well as its support scripts, are in the public domain. 62 | 63 | Contact me in-game: Ezandora (#1557284) 64 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Backup Camera.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterGenerationFunction("IOTMBackupCameraGenerate"); 3 | void IOTMBackupCameraGenerate(ChecklistCollection checklists) 4 | { 5 | item camera = lookupItem("backup camera"); 6 | if (!camera.have()) return; 7 | 8 | 9 | int times_backed_up = get_property_int("_backUpUses"); 10 | int backup_limit = 11; 11 | if (my_path_id_legacy() == PATH_ROBOT) //from reports 12 | backup_limit = 16; 13 | int backups_left = MAX(0, backup_limit - times_backed_up); 14 | if (backups_left > 0) 15 | { 16 | string [int] description; 17 | string url = ""; 18 | 19 | monster lm = last_monster(); 20 | string last_monster_description = lm; 21 | if (lm == $monster[none] || !lm.monsterCanBeCopied()) 22 | last_monster_description = "a monster"; 23 | 24 | 25 | description.listAppend("Fight " + last_monster_description + " in another zone.|Burns delay."); 26 | description.listAppend("In combat, cast Back-Up to your Last Enemy."); 27 | 28 | 29 | if (!camera.equipped()) 30 | { 31 | url = "inventory.php?which=2&ftext=backup+camera"; 32 | description.listAppend("Equip the backup camera first."); 33 | } 34 | string title = pluralise(backups_left, "camera backup", "camera backups"); 35 | checklists.add(C_RESOURCES, ChecklistEntryMake(616, "__item backup camera", url, ChecklistSubentryMake(title, "", description), 1)).ChecklistEntryTag("backup camera").ChecklistEntrySetAbridgedHeader(title); 36 | } 37 | 38 | if (true) 39 | { 40 | string [int] description; 41 | string url = ""; 42 | if (!camera.equipped()) 43 | url = "inventory.php?which=2&ftext=backup+camera"; 44 | else 45 | url = "inventory.php?which=2"; 46 | 47 | string camera_mode = get_property("backupCameraMode"); //meat, 48 | 49 | string [string] camera_mode_descriptions = 50 | { 51 | "meat":"+50% meat", 52 | "init":"+100% init", 53 | "ml":"+" + min(50, my_level() * 3) + " ML", 54 | }; 55 | 56 | 57 | if (camera_mode_descriptions contains camera_mode) 58 | description.listAppend(camera_mode_descriptions[camera_mode] + " enchantment."); 59 | 60 | string [int] other_options; 61 | foreach mode_name, mode_description in camera_mode_descriptions 62 | { 63 | if (mode_name == camera_mode) continue; 64 | other_options.listAppend(mode_description); 65 | } 66 | description.listAppend("Could switch to " + other_options.listJoinComponents(", ", "or") + "."); 67 | 68 | if (!get_property_boolean("backupCameraReverserEnabled")) 69 | description.listAppend("You may want to enable the reverser in the mode settings."); 70 | 71 | checklists.add(C_RESOURCES, ChecklistEntryMake(617, "__item backup camera", url, ChecklistSubentryMake("Backup Camera", "", description), 1)).ChecklistEntryTag("backup camera"); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /Source/relay/Guide/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 ($item[Bastille Battalion control rig].available_amount() == 0) return; 7 | 8 | if ($item[Draftsman's driving gloves].available_amount() > 0 || $item[Nouveau nosering].available_amount() > 0 || $item[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 ($item[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(545, "__item Bastille Battalion control rig", url, ChecklistSubentryMake("Collect Bastille rewards", "", description), 8)); 80 | } 81 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Beach Comb.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("IOTMBeachCombGenerateResource"); 3 | void IOTMBeachCombGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if ($item[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 | { 9 | boolean [int] beach_heads_used = get_property("_beachHeadsUsed").stringToIntIntList(",").listInvert(); 10 | 11 | string [int] description; 12 | string [int] buffs; 13 | 14 | string [int] elemental_buffs; 15 | boolean in_run = __misc_state["in run"]; 16 | if (!beach_heads_used[1]) 17 | elemental_buffs.listAppend(HTMLGenerateSpanOfClass("Hot-Headed", "r_element_hot")); 18 | if (!beach_heads_used[2]) 19 | elemental_buffs.listAppend(HTMLGenerateSpanOfClass("Cold as Nice", "r_element_cold")); 20 | if (!beach_heads_used[3]) 21 | elemental_buffs.listAppend(HTMLGenerateSpanOfClass("A Brush with Grossness", "r_element_stench")); 22 | if (!beach_heads_used[4]) 23 | elemental_buffs.listAppend(HTMLGenerateSpanOfClass("Does It Have a Skull In There??", "r_element_spooky")); 24 | if (!beach_heads_used[5]) 25 | elemental_buffs.listAppend(HTMLGenerateSpanOfClass("Oiled\, Slick", "r_element_sleaze")); 26 | 27 | if (elemental_buffs.count() > 0 && in_run) 28 | buffs.listAppend("" + elemental_buffs.listJoinComponents(" / ") + ": +3 X resistance, +15 X damage, +15 X spell damage."); 29 | if (!beach_heads_used[6] && in_run) 30 | buffs.listAppend("Lack of Body-Building: +50% muscle, +25% weapon damage."); // hah 31 | if (!beach_heads_used[7] && in_run) 32 | buffs.listAppend("We're All Made of Starfish: +50% myst, +25% spell damage."); 33 | if (!beach_heads_used[8] && in_run) 34 | buffs.listAppend("Pomp & Circumsands: +50% moxie, +25% ranged damage."); 35 | if (!beach_heads_used[9] && in_run) 36 | buffs.listAppend("Resting Beach Face: +50% init."); 37 | if (!beach_heads_used[10]) 38 | buffs.listAppend("Do I Know You From Somewhere?: +5 familiar weight."); 39 | if (!beach_heads_used[11] && in_run) 40 | buffs.listAppend("You Learned Something Maybe!: +5 stats/fight."); 41 | 42 | if (buffs.count() > 0) 43 | description.listAppend("Buffs:
" + buffs.listJoinComponents("
")); 44 | if (free_walks_left >= 10) 45 | description.listAppend((description.count() > 0 ? "Or collect" : "Collect") + " a bunch of items? (10 walks)"); 46 | description.listAppend("Or farm the beach."); 47 | resource_entries.listAppend(ChecklistEntryMake(544, "__item beach comb", "main.php?comb=1", ChecklistSubentryMake(pluralise(free_walks_left, "beach comb", "beach combs"), "", description), 3).ChecklistEntrySetCategory("buff")); //moving it over to buff from equipment. we thought about doing the same to powerful glove, but no 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Better Shrooms and Gardens catalog.ash: -------------------------------------------------------------------------------- 1 | //bad 2 | /*RegisterTaskGenerationFunction("IOTMBetterShroomsAndGardensGenerateTasks"); 3 | void IOTMBetterShroomsAndGardensGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 4 | { 5 | if (!(get_campground() contains $item[packet of mushroom spores])) return; 6 | 7 | int fights = get_property_int("_mushroomGardenFights"); 8 | int fight_limit = 1; 9 | if (my_path_id_legacy() == PATH_LUIGI) 10 | fight_limit = 5; 11 | int fights_left = clampi(0, fight_limit - fights, fight_limit); 12 | 13 | if (fights_left > 0) 14 | { 15 | string title = "Fight in your mushroom garden"; 16 | string [int] description; 17 | if (fights_left > 1) 18 | description.listAppend(fights_left + " free fights left."); 19 | else 20 | description.listAppend("Free fight."); 21 | description.listAppend("Pick the mushroom afterwards."); 22 | if (!__misc_state["in run"]) //rewards do not seem practical in-run 23 | description.listAppend("Or fertilise it for long-term rewards."); 24 | 25 | optional_task_entries.listAppend(ChecklistEntryMake(611, "__item colossal free-range mushroom", "campground.php", ChecklistSubentryMake(title, "", description), 8)); 26 | } 27 | }*/ 28 | 29 | RegisterGenerationFunction("IOTMBetterShroomsAndGardensGenerate"); 30 | void IOTMBetterShroomsAndGardensGenerate(ChecklistCollection checklists) 31 | { 32 | if (get_campground()[$item[packet of mushroom spores]] == 0) return; 33 | 34 | int max_fights = 1; 35 | if (my_path_id_legacy() == PATH_LUIGI) 36 | max_fights = 5; 37 | int fights_left = clampi(max_fights - get_property_int("_mushroomGardenFights"), 0, max_fights); 38 | if (fights_left > 0) 39 | { 40 | string title = "Free mushroom fight"; 41 | if (fights_left > 1) 42 | title = pluralise(fights_left, "mushroom fight", "mushroom fights"); 43 | string description; 44 | 45 | checklists.add(C_RESOURCES, ChecklistEntryMake(612, "__item immense free-range mushroom", "campground.php", ChecklistSubentryMake(title, "", description), 4).ChecklistEntryTag("daily free fight")); 46 | } 47 | if (!get_property_boolean("_mushroomGardenVisited") && fights_left <= 0) 48 | { 49 | string title = "Pick mushroom garden"; 50 | string description = "Or fertilise it for long-term rewards"; 51 | checklists.add(C_OPTIONAL_TASKS, ChecklistEntryMake(613, "__item immense free-range mushroom", "campground.php", ChecklistSubentryMake(title, "", description), 4)); 52 | 53 | } 54 | } 55 | 56 | 57 | 58 | 59 | RegisterResourceGenerationFunction("IOTMBetterShroomsAndGardensGenerateResource"); 60 | void IOTMBetterShroomsAndGardensGenerateResource(ChecklistEntry [int] resource_entries) 61 | { 62 | if (in_ronin()) 63 | { 64 | item [int] mushrooms; 65 | foreach it in $items[free-range mushroom,plump free-range mushroom,bulky free-range mushroom,giant free-range mushroom,immense free-range mushroom,colossal free-range mushroom] 66 | { 67 | if (!it.have()) continue; 68 | mushrooms.listAppend(it); 69 | } 70 | //we would use ChecklistEntryTag here, except I am not sure if it's stable and I only want the last entry to have the description 71 | ChecklistSubentry [int] subentries; 72 | string image_name; 73 | foreach key, it in mushrooms 74 | { 75 | if (image_name == "") image_name = "__item " + it; 76 | string [int] description; 77 | if (key == mushrooms.count() - 1) 78 | description.listAppend("Use for mushroom filets."); 79 | subentries.listAppend(ChecklistSubentryMake(pluralise(it), "", description)); 80 | //resource_entries.listAppend(ChecklistEntryMake(614, "__item " + it, "campground.php", ChecklistSubentryMake(pluralise(it), "", description), 8).ChecklistEntryTag("using shroom and garden item")); 81 | } 82 | if (subentries.count() > 0) 83 | resource_entries.listAppend(ChecklistEntryMake(615, image_name, "inventory.php?which=3&ftext=mushroom", subentries, 8)); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Bird-a-Day calendar.ash: -------------------------------------------------------------------------------- 1 | string [int] convertMafiaModifierStringToOurStyle(string modifier_string) 2 | { 3 | string [int] modifiers; 4 | foreach key, s in modifier_string.split_string(", ") 5 | { 6 | if (s == "") continue; 7 | string [int] line = s.split_string(": "); 8 | if (line.count() == 2) 9 | { 10 | string value = line[1]; 11 | string modifier = line[0].to_lower_case(); 12 | 13 | string [string] short_name_for_modifiers = { 14 | "muscle percent":"muscle", 15 | "mysticality percent":"mysticality", 16 | "moxie percent":"moxie", 17 | "item drop":"item", 18 | "food drop":"food", 19 | "damage absorption":"DA", 20 | "damage reduction":"DR", 21 | "combat rate":"combat", 22 | }; 23 | 24 | if (modifier == "muscle percent" || modifier == "mysticality percent" || modifier == "moxie percent" || modifier == "item drop" || modifier == "food drop" || modifier == "combat rate") 25 | { 26 | value += "%"; 27 | } 28 | if (short_name_for_modifiers contains modifier) 29 | modifier = short_name_for_modifiers[modifier]; 30 | modifiers.listAppend(value + " " + modifier); 31 | } 32 | else 33 | modifiers.listAppend(s); 34 | } 35 | return modifiers; 36 | } 37 | 38 | RegisterResourceGenerationFunction("IOTMBirdADayCalendarGenerateResource"); 39 | void IOTMBirdADayCalendarGenerateResource(ChecklistEntry [int] resource_entries) 40 | { 41 | if (!$item[bird-a-day calendar].have()) return; 42 | 43 | //_birdOfTheDay: unknown 44 | //_birdOfTheDayMods: 45 | //_birdsSoughtToday: unknown 46 | //_canSeekBirds: boolean 47 | 48 | int birds_sought_today = get_property_int("_birdsSoughtToday"); 49 | int skill_mp_cost = 5 * powi(2, birds_sought_today); 50 | string bird_of_the_day = get_property("_birdOfTheDay"); 51 | 52 | if (true) 53 | { 54 | string [int] modifiers; 55 | if (bird_of_the_day != "") 56 | modifiers = convertMafiaModifierStringToOurStyle(get_property("_birdOfTheDayMods")); 57 | string [int] description; 58 | string url = "skillz.php"; 59 | if (modifiers.count() == 0) 60 | modifiers.listAppend("Unknown"); 61 | description.listAppend(modifiers.listJoinComponents(", ") + " buff. (10 turns, " + skill_mp_cost + " mp)"); 62 | if (!get_property_boolean("_canSeekBirds")) 63 | { 64 | description.listAppend("Use your bird-a-day calendar first."); 65 | url = "inventory.php?which=3&ftext=bird-a-day+calendar"; 66 | } 67 | 68 | if (birds_sought_today == 6 && bird_of_the_day != get_property("yourFavoriteBird")) 69 | { 70 | description.listAppend(HTMLGenerateSpanFont("Warning: casting this skill again will make it your favourite bird, which stays across ascension.", "red")); 71 | } 72 | 73 | resource_entries.listAppend(ChecklistEntryMake(539, "__skill " + $skill[Seek out a bird], url, ChecklistSubentryMake("Seek out a Bird", "", description), 5).ChecklistEntryTag("bird-a-day calendar").ChecklistEntrySetCategory("buff").ChecklistEntrySetShortDescription(skill_mp_cost + "mp")); 74 | } 75 | //_favoriteBirdVisited: boolean 76 | //yourFavoriteBird: string, name 77 | //yourFavoriteBirdMods: what the birds does. format: "Moxie Percent: +75, Spooky Resistance: +2, Item Drop: +20, Damage Absorption: +100, Damage Reduction: 5" 78 | 79 | //thought about putting this in skills.ash, but it's here instead 80 | if ($skill[Visit your Favorite Bird].skill_is_usable() && !get_property_boolean("_favoriteBirdVisited")) 81 | { 82 | string [int] modifiers = convertMafiaModifierStringToOurStyle(get_property("yourFavoriteBirdMods")); 83 | string [int] description; 84 | description.listAppend(modifiers.listJoinComponents(", ") + " buff. (20 turns)"); 85 | resource_entries.listAppend(ChecklistEntryMake(540, "__skill Visit your Favorite Bird", "skillz.php", ChecklistSubentryMake("Visit your favourite bird", "", description), 5).ChecklistEntryTag("bird-a-day calendar").ChecklistEntrySetCategory("buff")); 86 | } 87 | } 88 | 89 | 90 | -------------------------------------------------------------------------------- /Source/relay/Guide/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 (!$item[SongBoom™ BoomBox].have()) 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_legacy() != 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(606, "__item SongBoom™ BoomBox", "inv_use.php?pwd=" + my_hash() + "&whichitem=9919", ChecklistSubentryMake("Set BoomBox song", "", description), 8)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Source/relay/Guide/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_legacy() == PATH_G_LOVER) 10 | return; 11 | 12 | //if (get_property_boolean("_floundryFabricated")) 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(499, "__item fishy fish", "clan_viplounge.php?action=floundry", ChecklistSubentryMake("Rentable floundry equipment", "", description), 8)); 53 | } 54 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Comprehensive Cartography.ash: -------------------------------------------------------------------------------- 1 | RegisterGenerationFunction("IOTMComprehensiveCartographyGenerate"); 2 | void IOTMComprehensiveCartographyGenerate(ChecklistCollection checklists) 3 | { 4 | if (!lookupSkill("Comprehensive Cartography").skill_is_usable()) return; 5 | 6 | 7 | int monster_maps_remaining = clampi(3 - get_property_int("_monstersMapped"), 0, 3); 8 | 9 | 10 | boolean currently_mapping_monsters = get_property_boolean("mappingMonsters"); 11 | 12 | if (monster_maps_remaining > 0) 13 | { 14 | string title = pluralise(monster_maps_remaining, "Map the Monster", "Map the Monsters"); 15 | string [int] description; 16 | description.listAppend("Allows picking which monster to encounter next adventure."); 17 | if (currently_mapping_monsters) 18 | description.listAppend("Skill is up; choice will appear next adventure"); 19 | 20 | checklists.add(C_RESOURCES, ChecklistEntryMake(454, "__skill Map the Monsters", "skillz.php", ChecklistSubentryMake(title, "", description), 0)).ChecklistEntrySetCategory("skill"); 21 | } 22 | 23 | if (currently_mapping_monsters) 24 | { 25 | string title = "Monster Map Active"; 26 | string [int] description; 27 | description.listAppend("Pick a monster to fight, when you adventure."); 28 | checklists.add(C_TASKS, ChecklistEntryMake(455, "__skill Map the Monsters", "main.php", ChecklistSubentryMake(title, "", description), -11)); 29 | } 30 | 31 | //FIXME other half: the special adventures. have we seen them yet? how should we output this? 32 | //billiards room especially 33 | } 34 | -------------------------------------------------------------------------------- /Source/relay/Guide/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 (!__iotms_usable[$item[detective school application]]) 5 | return; 6 | 7 | //Should we always mention this in aftercore? 8 | //Hmm... I suppose. 9 | int cases_remaining = clampi(3 - get_property_int("_detectiveCasesCompleted"), 0, 3); 10 | if (cases_remaining > 0) 11 | { 12 | optional_task_entries.listAppend(ChecklistEntryMake(530, "__item noir fedora", "place.php?whichplace=town_wrong&action=townwrong_precinct", ChecklistSubentryMake("Solve " + pluraliseWordy(cases_remaining, "more case", "more cases"), "", "Gives cop dollars."), 5)); 13 | } 14 | if ($items[plastic detective badge,bronze detective badge,silver detective badge,gold detective badge].available_amount() == 0) 15 | { 16 | optional_task_entries.listAppend(ChecklistEntryMake(531, "__item plastic detective badge", "place.php?whichplace=town_wrong&action=townwrong_precinct", ChecklistSubentryMake("Collect your Precinct badge", "", ""), 5)); 17 | 18 | } 19 | } 20 | 21 | RegisterResourceGenerationFunction("IOTMDetectiveSchoolGenerateResource"); 22 | void IOTMDetectiveSchoolGenerateResource(ChecklistEntry [int] resource_entries) 23 | { 24 | if (!__iotms_usable[$item[detective school application]]) 25 | return; 26 | 27 | //FIXME mention how much more they need to upgrade to the next badge? 28 | if (__misc_state["in run"] && in_ronin()) 29 | { 30 | int cop_dollars_have = $item[cop dollar].available_amount(); 31 | if (cop_dollars_have > 0) 32 | { 33 | string [int] description; 34 | 35 | string [int] buyables; 36 | 37 | string [int] ml_types_can_eat_drink; 38 | if (__misc_state["can eat just about anything"]) 39 | ml_types_can_eat_drink.listAppend("food"); 40 | if (__misc_state["can drink just about anything"]) 41 | ml_types_can_eat_drink.listAppend("drink"); 42 | if (ml_types_can_eat_drink.count() > 0 && cop_dollars_have >= 4) 43 | buyables.listAppend(ml_types_can_eat_drink.listJoinComponents("/")); 44 | if (cop_dollars_have >= 10) 45 | { 46 | buyables.listAppend("a -combat potion (50 turns)"); 47 | } 48 | if (buyables.count() > 0) 49 | description.listAppend("Buy " + buyables.listJoinComponents(", ", "or") + "."); 50 | resource_entries.listAppend(ChecklistEntryMake(532, "__item cop dollar", "shop.php?whichshop=detective", ChecklistSubentryMake(pluralise($item[cop dollar]), "", description), 7)); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Eight Days a Week Pill Keeper.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("IOTMEightDaysAweekPillKeeperGenerateResource"); 3 | void IOTMEightDaysAweekPillKeeperGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (!$item[Eight Days a Week Pill Keeper].have()) return; 6 | 7 | 8 | boolean first_one_is_free = !get_property_boolean("_freePillKeeperUsed"); 9 | if (first_one_is_free || availableSpleen() >= 3) 10 | { 11 | string [int] description; 12 | description.listAppend("Surprise Me: force semi-rare next turn."); 13 | description.listAppend("Sneakisol: Next adventure will be a non-combat."); 14 | description.listAppend("Explodinall: yellow ray monster, next fight you win."); 15 | 16 | string [int] marginals; 17 | marginals.listAppend("Extendicillin: double next potion's effect length."); 18 | marginals.listAppend("Rainbowolin: +4 all res buff. (30 turns)"); 19 | marginals.listAppend("Hulkien: +100% all stats buff. (30 turns)."); 20 | marginals.listAppend("Fidoxene: +familiar weight buff, up to 20lb base. (30 turns)"); 21 | description.listAppend("Marginal:|*" + marginals.listJoinComponents("|*")); 22 | //description.listAppend("Telecybin: teleportitis."); //technically optimal if you want to unlock the DoD 23 | //generateEquipmentLink($item[eight days a week pill keeper]) 24 | string short_desc = ""; 25 | if (first_one_is_free) 26 | { 27 | description.listAppend("First one's free."); 28 | short_desc = "free"; 29 | } 30 | else 31 | { 32 | description.listAppend("Costs three spleen."); 33 | short_desc = "3spn"; 34 | } 35 | 36 | resource_entries.listAppend(ChecklistEntryMake(547, "__item eight days a week pill keeper", "main.php?eowkeeper=1", ChecklistSubentryMake("Pill keeper", "", description), 4).ChecklistEntrySetShortDescription(short_desc)); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Garbage Tote.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterGenerationFunction("IOTMGarbageToteGenerate"); 3 | void IOTMGarbageToteGenerate(ChecklistCollection checklists) 4 | { 5 | if (!$item[January's Garbage Tote].have()) return; 6 | boolean [item] relevant_items; 7 | if (get_property_int("garbageTreeCharge") > 0) 8 | relevant_items[$item[deceased crimbo tree]] = true; 9 | if (get_property_int("garbageShirtCharge") > 0 && __misc_state["Torso aware"]) 10 | relevant_items[$item[makeshift garbage shirt]] = true; 11 | if (get_property_int("garbageChampagneCharge") > 0) 12 | relevant_items[$item[broken champagne bottle]] = true; 13 | relevant_items[$item[tinsel tights]] = true; 14 | relevant_items[$item[wad of used tape]] = true; 15 | if (relevant_items.available_amount() == 0) 16 | { 17 | string [int] description; 18 | if (my_level() < 13 && get_property_int("garbageShirtCharge") > 0 && __misc_state["Torso aware"]) 19 | { 20 | description.listAppend("Makeshift garbage shirt (double statgain for " + pluralise(get_property_int("garbageShirtCharge"), "more turn", "more turns") + ".)"); 21 | } 22 | else if (my_level() < 13) 23 | description.listAppend("Tinsel tights (+25 ML)"); 24 | description.listAppend("Wad of used tape (+15% item, +30% meat)"); 25 | if (get_property_int("garbageChampagneCharge") > 0) 26 | description.listAppend("Broken champagne bottle (double +item for " + pluralise(get_property_int("garbageChampagneCharge"), "more turn", "more turns") + ".)"); 27 | 28 | 29 | checklists.add(C_OPTIONAL_TASKS, ChecklistEntryMake(552, "__item January's Garbage Tote", "inv_use.php?pwd=" + my_hash() + "&whichitem=9690", ChecklistSubentryMake("Collect a garbage tote item", "", description), 1)); 30 | } 31 | 32 | 33 | //resources: 34 | 35 | string [item] item_effect_description; 36 | string [item] item_charge_property; 37 | 38 | if (__misc_state["Torso aware"]) 39 | item_charge_property[$item[makeshift garbage shirt]] = "garbageShirtCharge"; 40 | item_charge_property[$item[broken champagne bottle]] = "garbageChampagneCharge"; 41 | item_charge_property[$item[deceased crimbo tree]] = "garbageTreeCharge"; 42 | 43 | 44 | if (__misc_state["Torso aware"]) 45 | item_effect_description[$item[makeshift garbage shirt]] = "Doubles statgain"; 46 | item_effect_description[$item[broken champagne bottle]] = "Doubles +item"; 47 | item_effect_description[$item[deceased crimbo tree]] = "Absorbs damage"; 48 | 49 | foreach it, property_name in item_charge_property 50 | { 51 | int charge = get_property_int(property_name); 52 | boolean have = it.available_amount() > 0; 53 | if (!have && charge == 0) continue; 54 | if (!have && !($items[makeshift garbage shirt,broken champagne bottle] contains it)) continue; 55 | string title; 56 | string [int] description; 57 | string url = generateEquipmentLink(it); 58 | if (charge > 0) 59 | { 60 | title = pluralise(charge, "charge", "charges") + " of " + it; 61 | description.listAppend(item_effect_description[it] + "." + (!have ? " Not active." : "")); 62 | } 63 | else 64 | { 65 | title = HTMLGenerateSpanFont("No charges of " + it, "red"); 66 | description.listAppend("Switch out for something else."); 67 | url = "inv_use.php?pwd=" + my_hash() + "&whichitem=9690"; 68 | } 69 | checklists.add(C_RESOURCES, ChecklistEntryMake(553, "__item " + it, url, ChecklistSubentryMake(title, "", description), 8).ChecklistEntryTag("garbage tote")); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/GenieBottle.ash: -------------------------------------------------------------------------------- 1 | RegisterResourceGenerationFunction("IOTMGenieBottleGenerateResource"); 2 | void IOTMGenieBottleGenerateResource(ChecklistEntry [int] resource_entries) 3 | { 4 | if ($item[genie bottle].item_amount() + $item[pocket wish].item_amount() == 0) return; 5 | 6 | int wishes_left = 0; 7 | if (__misc_state["in run"] && in_ronin()) 8 | wishes_left += $item[pocket wish].item_amount(); 9 | if ($item[genie bottle].item_amount() > 0 && my_path_id_legacy() != 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 ($item[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(462, "__item genie bottle", url, ChecklistSubentryMake(pluralise(wishes_left, "wish", "wishes"), "", description), 1)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Getaway Campsite.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("IOTMGetawayCampsiteGenerateResource"); 3 | void IOTMGetawayCampsiteGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (!__iotms_usable[$item[Distant Woods Getaway Brochure]]) return; 6 | 7 | item firewood = $item[stick of firewood]; 8 | int cloud_buffs_left = clampi(1 - get_property_int("_campAwayCloudBuffs"), 0, 1); 9 | int smile_buffs_left = clampi(3 - get_property_int("_campAwaySmileBuffs"), 0, 3); 10 | 11 | if (cloud_buffs_left > 0)// && $effect[That's Just Cloud-Talk, Man].have_effect() == 0) 12 | { 13 | string [int] description; 14 | description.listAppend("Large +stat buff. Gaze at the stars."); 15 | if (firewood.have() || $item[campfire smoke].have()) 16 | description.listAppend("If you don't see it, you could make and use campfire smoke, first."); 17 | resource_entries.listAppend(ChecklistEntryMake(535, "__item Newbiesport™ tent", "place.php?whichplace=campaway", ChecklistSubentryMake("Cloud-talk buff obtainable", "", description), 0).ChecklistEntryTag("getaway campsite").ChecklistEntrySetCategory("buff").ChecklistEntrySetSpecificImage("__effect That's Just Cloud-Talk, Man")); 18 | } 19 | if (smile_buffs_left > 0)// && $effect[That's Just Cloud-Talk, Man].have_effect() == 0) 20 | { 21 | resource_entries.listAppend(ChecklistEntryMake(536, "__item Newbiesport™ tent", "place.php?whichplace=campaway", ChecklistSubentryMake(pluralise(smile_buffs_left, "smile buff", "smile buffs") + " obtainable", "", "Various minor effects. Gaze at the stars."), 5).ChecklistEntryTag("getaway campsite").ChecklistEntrySetCategory("buff").ChecklistEntrySetSpecificImage("__effect Smile of the " + my_sign())); 22 | } 23 | if (firewood.have() && __misc_state["in run"]) 24 | { 25 | string [int] description; 26 | 27 | string [int] various_options; 28 | if (__misc_state["can eat just about anything"]) 29 | various_options.listAppend("food"); 30 | if (firewood.available_amount() >= 5 && my_path_id_legacy() != PATH_GELATINOUS_NOOB) 31 | { 32 | if (!$item[whittled tiara].have()) 33 | various_options.listAppend("whittled tiara for +elemental damage"); 34 | if (!$item[whittled shorts].have()) 35 | various_options.listAppend("whittled shorts for +2 all res"); 36 | if (!$item[whittled flute].have()) 37 | various_options.listAppend("whittled flute for +25% meat"); 38 | if (firewood.available_amount() >= 10) 39 | { 40 | if (!$item[whittled bear figurine].have() && !__misc_state["familiars temporarily blocked"]) 41 | various_options.listAppend("whittled bear figurine for +5 familiar weight"); 42 | if (!$item[whittled owl figurine].have()) 43 | various_options.listAppend("whittled owl figurine for +20 ML"); 44 | if (!$item[whittled fox figurine].have()) 45 | various_options.listAppend("whittled fox figurine figurine for +50% init"); 46 | } 47 | if (firewood.available_amount() >= 100 && !$item[whittled walking stick].have()) 48 | various_options.listAppend("whittled walking stick for a bunch of stuff"); 49 | } 50 | if (various_options.count() > 0) 51 | description.listAppend(various_options.listJoinComponents(", ", "or").capitaliseFirstLetter() + "."); 52 | resource_entries.listAppend(ChecklistEntryMake(537, "__item Newbiesport™ tent", "shop.php?whichshop=campfire", ChecklistSubentryMake(pluralise(firewood), "", description), 5).ChecklistEntryTag("getaway campsite").ChecklistEntrySetSpecificImage("__item " + firewood)); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Source/relay/Guide/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(570, "__skill Ceci N'Est Pas Un Chapeau", "skillz.php", ChecklistSubentryMake("Ceci N'Est Pas Un Chapeau", "", "Random enchantment hat, 300MP."), 10)); 10 | } 11 | 12 | if ($skill[Gingerbread Mob Hit].skill_is_usable()) 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(571, "__familiar Penguin Goodfella", "", ChecklistSubentryMake("Gingerbread mob hit", "", description), 0).ChecklistEntryTag("free instakill")); 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 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/Guide/Items of the Month/Guzzlr tablet.ash: -------------------------------------------------------------------------------- 1 | RegisterGenerationFunction("IOTMGuzzlrTabletGenerate"); 2 | void IOTMGuzzlrTabletGenerate(ChecklistCollection checklists) 3 | { 4 | if (!$item[guzzlr tablet].have()) return; 5 | 6 | QuestState guzzlr_quest_state = QuestState("questGuzzlr"); 7 | if (guzzlr_quest_state.in_progress) 8 | { 9 | location target_location = get_property_location("guzzlrQuestLocation"); 10 | string target_item_string = get_property("guzzlrQuestBooze"); 11 | item target_item = target_item_string.to_item(); 12 | 13 | if (target_item_string == "special personalized cocktail") 14 | target_item = $item[Guzzlr cocktail set]; 15 | 16 | string target_item_description = target_item; 17 | boolean have_target_item = target_item.item_amount() > 0; 18 | 19 | if (target_item == $item[Guzzlr cocktail set]) 20 | { 21 | boolean [item] potential_drinks = $items[Steamboat,Ghiaccio Colada,Nog-on-the-Cob,Sourfinger,Buttery Boy]; 22 | have_target_item = false; 23 | foreach it in potential_drinks 24 | { 25 | if (it.item_amount() > 0) 26 | { 27 | target_item = it; 28 | target_item_description = target_item; 29 | have_target_item = true; 30 | break; 31 | } 32 | } 33 | if (!have_target_item) 34 | { 35 | target_item_description = potential_drinks.listInvert().listJoinComponents(", ", "or"); 36 | } 37 | } 38 | 39 | string [int] description; 40 | 41 | description.listAppend("Adventure in " + target_location + " to deliever a " + target_item + "."); 42 | if (target_item != $item[none] && !have_target_item) 43 | description.listAppend(HTMLGenerateSpanFont("Acquire a " + target_item_description + " first.", "red")); 44 | 45 | 46 | boolean [item] all_relevant_items = $items[Guzzlr pants,Guzzlr shoes]; 47 | 48 | boolean [item] items_to_equip; 49 | foreach it in all_relevant_items 50 | { 51 | if (!it.equipped() && it.have()) 52 | items_to_equip[it] = true; 53 | } 54 | 55 | if (items_to_equip.count() > 0) 56 | description.listAppend(HTMLGenerateSpanFont("Equip " + items_to_equip.listInvert().listJoinComponents(", ", "and") + " first.", "red")); 57 | checklists.add(C_AFTERCORE_TASKS, ChecklistEntryMake(456, "__item guzzlr tablet", target_location.getClickableURLForLocation(), ChecklistSubentryMake("Guzzlr quest", "", description), 8, locationToLocationMap(target_location))); 58 | } 59 | //I think "_guzzlrPlatinumDeliveries" will tell you how many deliveries you started today 60 | //did a platinum from the previous day, _guzzlrPlatinumDeliveries was zero, started a new one today, went up to one 61 | if (!guzzlr_quest_state.started && get_property_int("_guzzlrPlatinumDeliveries") == 0 && get_property_int("guzzlrGoldDeliveries") >= 5) 62 | { 63 | checklists.add(C_OPTIONAL_TASKS, ChecklistEntryMake(457, "__item guzzlr tablet", "inventory.php?tap=guzzlr", ChecklistSubentryMake("Start platinum guzzlr quest", "", "Daily collectable."), 8)); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Source/relay/Guide/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(523, "__item tennis ball", "", ChecklistSubentryMake(pluralise($item[tennis ball]), "", "Free run/banish."), 6).ChecklistEntryTag("free 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/Guide/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[$item[Horsery contract]]) return; 5 | if (get_property("_horsery") == "" && my_meat() >= 500) 6 | { 7 | optional_task_entries.listAppend(ChecklistEntryMake(451, "__item magical pony: Spectrum Dash", "place.php?whichplace=town_right&action=town_horsery", ChecklistSubentryMake("Bring along a horse!", "", "Probably the dark horse."))); 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/KGBriefcase.ash: -------------------------------------------------------------------------------- 1 | RegisterResourceGenerationFunction("IOTMKGBriefcaseGenerateResource"); 2 | void IOTMKGBriefcaseGenerateResource(ChecklistEntry [int] resource_entries) 3 | { 4 | if (!__iotms_usable[$item[kremlin's greatest briefcase]]) return; 5 | ChecklistEntry entry = ChecklistEntryMake(509); 6 | entry.image_lookup_name = "__item Kremlin's Greatest Briefcase"; 7 | entry.importance_level = 5; 8 | entry.url = "place.php?whichplace=kgb"; 9 | if (get_property_int("_kgbTranquilizerDartUses") < 3 && my_path_id_legacy() != PATH_POCKET_FAMILIARS) 10 | { 11 | string [int] description; 12 | description.listAppend("Free run/banishes for twenty turns.|Use the KGB tranquilizer dart skill in-combat."); 13 | if ($item[kremlin's greatest briefcase].equipped_amount() == 0) 14 | { 15 | description.listAppend("Equip the briefcase first."); 16 | //entry.url = "inventory.php?which=2"; 17 | } 18 | resource_entries.listAppend(ChecklistEntryMake(510, "__item Kremlin's Greatest Briefcase", entry.url, ChecklistSubentryMake(pluralise(3 - get_property_int("_kgbTranquilizerDartUses"), "briefcase dart", "briefcase darts"), "", description)).ChecklistEntryTag("free banish")); 19 | } 20 | int clicks_remaining = clampi(22 - get_property_int("_kgbClicksUsed"), 0, 22); 21 | if (clicks_remaining > 0) 22 | { 23 | string [int] description; 24 | description.listAppend("All sorts of things. Buffs, martinis, cigars!"); 25 | 26 | entry.subentries.listAppend(ChecklistSubentryMake(pluralise(clicks_remaining, "click", "clicks"), "", description)); 27 | } 28 | if (entry.subentries.count() > 0) 29 | resource_entries.listAppend(entry); 30 | } 31 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Latte.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("IOTMLatteGenerateResource"); 3 | void IOTMLatteGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if ($item[latte lovers member's mug].available_amount() == 0) return; 6 | if (!__misc_state["can equip just about any off-hand"]) return; 7 | 8 | int refills_remaining = clampi(3 - get_property_int("_latteRefillsUsed"), 0, 3); 9 | boolean banish_used = get_property_boolean("_latteBanishUsed"); 10 | boolean copy_used = get_property_boolean("_latteCopyUsed"); //more of an olfact than a copy 11 | boolean drink_used = get_property_boolean("_latteDrinkUsed"); 12 | 13 | int banishes_available = refills_remaining + (!banish_used ? 1 : 0); 14 | int copies_available = refills_remaining + (!copy_used ? 1 : 0); 15 | 16 | string url; 17 | boolean latte_needs_equipping = false; 18 | if ($item[latte lovers member's mug].equipped_amount() == 0) 19 | { 20 | url = generateEquipmentLink($item[latte lovers member's mug]); 21 | latte_needs_equipping = true; 22 | } 23 | if (banishes_available > 0) 24 | { 25 | string banish_url = url; 26 | string [int] description; 27 | description.listAppend("Free run/banish." + (latte_needs_equipping ? " Equip latte first." : "") + "|Throw Latte on Opponent in combat."); 28 | 29 | if (banish_used) 30 | { 31 | banish_url = "main.php?latte=1"; 32 | description.listAppend(HTMLGenerateSpanFont("Must refill latte first.", "red")); 33 | } 34 | resource_entries.listAppend(ChecklistEntryMake(533, "__item latte lovers member's mug", banish_url, ChecklistSubentryMake(pluralise(banishes_available, "latte banish", "latte banishes"), "", description), 0).ChecklistEntryTag("free banish").ChecklistEntrySetSpecificImage("__skill Throw Latte on Opponent")); 35 | } 36 | 37 | ChecklistEntry entry = ChecklistEntryMake(534); 38 | entry.image_lookup_name = "__item latte lovers member's mug"; 39 | entry.url = "main.php?latte=1"; 40 | 41 | if (refills_remaining > 0) 42 | { 43 | string [int] description; 44 | if (!banish_used && __misc_state["in run"]) 45 | description.listAppend(HTMLGenerateSpanFont("Use banish first.", "red")); 46 | entry.subentries.listAppend(ChecklistSubentryMake(pluralise(refills_remaining, "latte refill", "latte refills"), "", description)); 47 | } 48 | if (copies_available > 0) 49 | { 50 | string [int] description; 51 | description.listAppend("Offer Latte to Opponent in combat."); 52 | if (copy_used) 53 | { 54 | description.listAppend(HTMLGenerateSpanFont("Must refill latte first.", "red")); 55 | } 56 | if ($skill[Transcendent Olfaction].have_skill()) 57 | description.listAppend("Stack with Transcendent Olfaction."); 58 | entry.subentries.listAppend(ChecklistSubentryMake(pluralise(copies_available, "latte olfaction", "latte olfactions"), "", description)); 59 | } 60 | if (!drink_used && my_path_id_legacy() != PATH_VAMPIRE) 61 | { 62 | entry.subentries.listAppend(ChecklistSubentryMake("Gulp Latte available", "", "Restores half your HP and MP. Cast in combat.")); 63 | } 64 | entry.ChecklistEntrySetAbridgedHeader("Latte lovers member's mug"); 65 | if (entry.subentries.count() > 0) 66 | resource_entries.listAppend(entry); 67 | } 68 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Lil Doctor Bag.ash: -------------------------------------------------------------------------------- 1 | RegisterGenerationFunction("IOTMLilDoctorBagGenerate"); 2 | void IOTMLilDoctorBagGenerate(ChecklistCollection checklists) 3 | { 4 | if (!$item[Lil' Doctor™ bag].have()) return; 5 | //Quest: 6 | 7 | if (QuestState("questDoctorBag").in_progress) 8 | { 9 | item required_item = get_property_item("doctorBagQuestItem"); 10 | location target_location = get_property_location("doctorBagQuestLocation"); 11 | 12 | string [int] description; 13 | description.listAppend("Adventure in " + target_location + ". Free runs/delay burning helps."); 14 | if (required_item.item_amount() == 0) 15 | description.listAppend("Acquire a " + required_item + " first."); 16 | 17 | description.listAppend("Reward is marginal."); 18 | checklists.add(C_AFTERCORE_TASKS, ChecklistEntryMake(554, "__item Lil' Doctor™ bag", target_location.getClickableURLForLocation(), ChecklistSubentryMake("Lil' Doctor quest", "", description), 11, locationToLocationMap(target_location))); 19 | } 20 | 21 | //Otoscope: +200% item 22 | int otoscopes_left = clampi(3 - get_property_int("_otoscopeUsed"), 0, 3); 23 | if (otoscopes_left > 0 && __misc_state["in run"]) 24 | { 25 | string url; 26 | string [int] description; 27 | description.listAppend("+200% item for one turn, cast in combat."); 28 | 29 | url = generateEquipmentLink($item[Lil' Doctor™ bag]); 30 | if ($item[Lil' Doctor™ bag].equipped_amount() == 0) 31 | { 32 | description.listAppend("Equip the Lil'l Doctor™ bag first."); 33 | } 34 | //if (snojo_skill_entry.image_lookup_name == "") 35 | //snojo_skill_entry.image_lookup_name = "__skill shattering punch"; 36 | checklists.add(C_RESOURCES, ChecklistEntryMake(555, "__item Lil' Doctor™ bag", url, ChecklistSubentryMake(pluralise(otoscopes_left, "otoscope", "otoscopes"), "", description), 8).ChecklistEntrySetSpecificImage("__skill otoscope")); 37 | } 38 | //Chest X-Ray: instakill 39 | int instakills_left = clampi(3 - get_property_int("_chestXRayUsed"), 0, 3); 40 | if (instakills_left > 0) 41 | { 42 | string url; 43 | string [int] description; 44 | description.listAppend("Win a fight without taking a turn."); 45 | 46 | url = generateEquipmentLink($item[Lil' Doctor™ bag]); 47 | if ($item[Lil' Doctor™ bag].equipped_amount() == 0) 48 | { 49 | description.listAppend("Equip the Lil'l Doctor™ bag first."); 50 | } 51 | //if (snojo_skill_entry.image_lookup_name == "") 52 | //snojo_skill_entry.image_lookup_name = "__skill shattering punch"; 53 | checklists.add(C_RESOURCES, ChecklistEntryMake(556, "__item Lil' Doctor™ bag", url, ChecklistSubentryMake(pluralise(instakills_left, "chest x-ray", "chest x-rays"), "", description), 0).ChecklistEntryTag("free instakill").ChecklistEntrySetSpecificImage("__skill chest x-ray")); 54 | 55 | } 56 | //Reflex Hammer: Banish 57 | int banishes_left = clampi(3 - get_property_int("_reflexHammerUsed"), 0, 3); 58 | if (banishes_left > 0) 59 | { 60 | string url; 61 | string [int] description; 62 | description.listAppend("Free run/banish."); 63 | Banish banish_entry = BanishByName("Reflex Hammer"); 64 | int turns_left_of_banish = banish_entry.BanishTurnsLeft(); 65 | if (turns_left_of_banish > 0) 66 | { 67 | //is this relevant? we don't describe this for pantsgiving 68 | description.listAppend("Currently used on " + banish_entry.banished_monster + " for " + pluralise(turns_left_of_banish, "more turn", "more turns") + "."); 69 | } 70 | url = generateEquipmentLink($item[Lil' Doctor™ bag]); 71 | if ($item[Lil' Doctor™ bag].equipped_amount() == 0) 72 | { 73 | description.listAppend("Equip the Lil'l Doctor™ bag first."); 74 | } 75 | checklists.add(C_RESOURCES, ChecklistEntryMake(557, "__item Lil' Doctor™ bag", url, ChecklistSubentryMake(pluralise(banishes_left, "reflex hammer", "reflex hammers"), "", description), 0).ChecklistEntryTag("free banish").ChecklistEntrySetSpecificImage("__skill reflex hammer")); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Source/relay/Guide/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 ($item[Fourth of May Cosplay Saber].available_amount() == 0) return; 5 | if (!__misc_state["can equip just about any weapon"]) return; 6 | if (get_property_int("_saberMod") == 0) 7 | { 8 | string [int] options; 9 | if (in_ronin()) 10 | { 11 | options.listAppend("Regen ~17 MP/adventure."); 12 | options.listAppend("+20 ML."); 13 | options.listAppend("+3 all resistances."); 14 | } 15 | options.listAppend("+10 familiar weight."); 16 | 17 | string [int] description; 18 | if (options.count() > 1) 19 | description.listAppend("Choose one of:|*" + options.listJoinComponents("|*")); 20 | else 21 | description.listAppend(options.listJoinComponents("|")); 22 | optional_task_entries.listAppend(ChecklistEntryMake(500, "__item Fourth of May Cosplay Saber", "main.php?action=may4", ChecklistSubentryMake("Modify your lightsaber", "", description), 8)); 23 | } 24 | monster saber_monster = get_property_monster("_saberForceMonster"); 25 | if (saber_monster != $monster[none] && get_property_int("_saberForceMonsterCount") > 0) 26 | { 27 | string [int] description; 28 | int fights_left = clampi(get_property_int("_saberForceMonsterCount"), 0, 3); 29 | string url = ""; 30 | location [int] possible_appearance_locations = saber_monster.getPossibleLocationsMonsterCanAppearInNaturally().listInvert(); 31 | 32 | description.listAppend("Will appear when you adventure in " + possible_appearance_locations.listJoinComponents(", ", "or") + "."); 33 | if (possible_appearance_locations.count() > 0) 34 | url = possible_appearance_locations[0].getClickableURLForLocation(); 35 | optional_task_entries.listAppend(ChecklistEntryMake(501, "__monster " + saber_monster, url, ChecklistSubentryMake("Fight " + pluralise(fights_left, "more " + saber_monster, "more " + saber_monster + "s"), "", description), -1)); 36 | } 37 | } 38 | 39 | RegisterResourceGenerationFunction("IOTMMaySaberGenerateResource"); 40 | void IOTMMaySaberGenerateResource(ChecklistEntry [int] resource_entries) 41 | { 42 | if ($item[Fourth of May Cosplay Saber].available_amount() == 0) return; 43 | if (!__misc_state["can equip just about any weapon"]) return; 44 | if (get_property_int("_saberForceUses") < 5) 45 | { 46 | int uses_remaining = clampi(5 - get_property_int("_saberForceUses"), 0, 5); 47 | string url = generateEquipmentLink($item[Fourth of May Cosplay Saber]); 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 in the zone."); 52 | description.listAppend("Or collect all* their items."); 53 | if (my_path_id_legacy() == PATH_COMMUNITY_SERVICE && $skill[Meteor Lore].have_skill()) 54 | { 55 | description.listAppend("Bonus! Use Meteor Shower + lightsaber skill to save a bunch of turns on weapon damage/spell damage/familiar weight tests."); 56 | } 57 | //description.listAppend("Choose one of:|*" + options.listJoinComponents("|*")); 58 | resource_entries.listAppend(ChecklistEntryMake(502, "__item Fourth of May Cosplay Saber", url, ChecklistSubentryMake(pluralise(uses_remaining, "force use", "forces uses"), "", description), 0)); 59 | 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Melodramedary.ash: -------------------------------------------------------------------------------- 1 | 2 | 3 | RegisterGenerationFunction("IOTMMelodramedaryGenerate"); 4 | void IOTMMelodramedaryGenerate(ChecklistCollection checklists) 5 | { 6 | familiar melodramedary = lookupFamiliar("Melodramedary"); 7 | if (!melodramedary.have_familiar() || __misc_state["familiars temporarily blocked"]) return; 8 | 9 | item melodramedary_helmet = lookupItem("dromedary drinking helmet"); 10 | /*√-desert 11 | -han on hoth 12 | -whatever else this does 13 | -spit: 14 | spit on me: +100% weapon/spell damage, +100% all stats (community service alert) 15 | spit on them: doubles the amount of items dropped 16 | */ 17 | 18 | boolean avoid_adding_main = false; 19 | 20 | int spit_level = get_property_int("camelSpit"); //starts at 100 21 | 22 | string title;// = spit_level + " Melodramedary spit"; 23 | string [int] description; 24 | string url_main; 25 | string short_desc; 26 | 27 | if (my_familiar() != melodramedary) 28 | { 29 | url_main = "familiar.php"; 30 | description.listAppend("Bring melodramedary along."); 31 | } 32 | if (spit_level < 100) 33 | { 34 | float spit_per_combat = 3.33; 35 | if (melodramedary.familiar_equipped_equipment() == melodramedary_helmet) 36 | { 37 | spit_per_combat += 3.33 * 0.3; 38 | } 39 | else if (melodramedary_helmet.available_amount() > 0 && melodramedary_helmet.can_equip()) 40 | { 41 | description.listAppend("Should equip the dromedary drinking helmet."); 42 | } 43 | if (spit_level == 0 && my_familiar() != melodramedary) 44 | avoid_adding_main = true; 45 | float remaining_spit = 100 - spit_level; 46 | 47 | float remaining_turns = remaining_spit / spit_per_combat; 48 | 49 | int estimated_turns = remaining_turns.floor(); 50 | title = pluralise(estimated_turns, "combat", "combats") + " until melodramedary skill"; 51 | //description.listAppend(pluralise(remaining_turns.round(), "turn", "turns") + " to next use."); 52 | 53 | short_desc = estimated_turns.to_string(); 54 | } 55 | else 56 | { 57 | title = "Melodramedary combat skill ready"; 58 | short_desc = "now"; 59 | string target_text; 60 | 61 | string [int] targets; 62 | //FIXME write this 63 | if (targets.count() > 0) 64 | target_text = "|Potential Targets:|*-" + targets.listJoinComponents("|*-"); 65 | description.listAppend(melodramedary.name + ", spit on me: +100% weapon/spell damage/stats buff. (15 turns)"); 66 | description.listAppend(melodramedary.name + ", spit on them: doubles all items dropped from combat. " + target_text); 67 | } 68 | if (!avoid_adding_main) 69 | checklists.add(C_RESOURCES, ChecklistEntryMake(458, "__familiar Melodramedary", url_main, ChecklistSubentryMake(title, "", description), 1)).ChecklistEntryTag("Melodramedary").ChecklistEntrySetCategory("familiar").ChecklistEntrySetShortDescription(short_desc); 70 | 71 | //There might not be any tracking for this? 72 | if (lookupItem("Fourth of May Cosplay Saber").have() && !get_property_boolean("_tauntaunTaunted") && false) 73 | { 74 | string url = "inventory.php?which=2"; 75 | int cold_level = clampi(melodramedary.familiar_weight(), 1, 20); 76 | 77 | string [int] tauntaun_description; 78 | tauntaun_description.listAppend("+" + cold_level + " cold res. (10 turns)"); 79 | tauntaun_description.listAppend("Will reset Melodramedary familiar weight."); 80 | string [int] tasks; 81 | if (!lookupItem("Fourth of May Cosplay Saber").equipped()) 82 | { 83 | tasks.listAppend("equip Fourth of May Cosplay Saber"); 84 | } 85 | if (my_familiar() != melodramedary) 86 | { 87 | url = "familiar.php"; 88 | tasks.listAppend("change familiar to Melodramedary"); 89 | } 90 | if (tasks.count() > 0) 91 | tauntaun_description.listAppend(tasks.listJoinComponents(", ", "and").capitaliseFirstLetter() + "."); 92 | checklists.add(C_RESOURCES, ChecklistEntryMake(459, "__familiar Melodramedary", url, ChecklistSubentryMake("Melodramedary buff", "", tauntaun_description), 1)).ChecklistEntryTag("Melodramedary"); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Miniature Crystal Ball.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterGenerationFunction("IOTMMiniatureCrystalBallGenerate"); 3 | void IOTMMiniatureCrystalBallGenerate(ChecklistCollection checklists) 4 | { 5 | item crystal_ball = lookupItem("miniature crystal ball"); 6 | if (!crystal_ball.have() || __misc_state["familiars temporarily blocked"]) return; 7 | 8 | 9 | 10 | monster next_monster = get_property_monster("crystalBallMonster"); 11 | location next_location = get_property_location("crystalBallLocation"); 12 | string [int] description; 13 | 14 | boolean is_equipped = crystal_ball.equipped(); 15 | if (!is_equipped) 16 | description.listAppend("Equip to predict the next monster fought in zone."); 17 | else 18 | description.listAppend("Predicts the next monster fought in zone."); 19 | 20 | 21 | string image_name = "__item miniature crystal ball"; 22 | 23 | string url = "familiar.php"; 24 | 25 | if (next_monster != $monster[none]) 26 | { 27 | string line = "Next monster is " + next_monster + " in " + next_location + "."; 28 | string warning; 29 | if (!is_equipped) 30 | { 31 | warning = HTMLGenerateSpanFont("|Will not appear unless miniature crystal ball is equipped.", "red"); 32 | if (crystal_ball.item_amount() == 0) 33 | { 34 | //Find the familiar: 35 | //FIXME: only use familiars we have? but static is badhere I think.. 36 | foreach f in $familiars[] 37 | { 38 | if (f.familiar_equipped_equipment() == crystal_ball) 39 | { 40 | warning += "|*Currently held by " + f + "."; 41 | break; 42 | } 43 | } 44 | } 45 | } 46 | else 47 | { 48 | url = next_location.getClickableURLForLocation(); 49 | } 50 | description.listAppend(line); 51 | description.listAppend(warning); 52 | 53 | //Debate here: should the popup be item size? 54 | //Pros: the smaller size makes it take up less space, and it is a pop up. On retina displays, looks good. 55 | //Minuses: the "normal" size looks much nicer on non-retina displays, more "recognisable." 56 | //For now, regular size. This is important info we want to draw attention to. 57 | string popup_image_name = "__half __monster " + next_monster; 58 | image_name = "__monster " + next_monster; 59 | 60 | 61 | 62 | 63 | string popup_header = next_monster.capitaliseFirstLetter(); 64 | string popup_description = "Next adventure in " + next_location + "."; 65 | popup_description += warning; 66 | checklists.add(C_TASKS, ChecklistEntryMake(513, popup_image_name, url, ChecklistSubentryMake(popup_header, "", popup_description), -11)); 67 | } 68 | 69 | //tried inventory.php?which=2&ftext=miniature+crystal+ball but mafia's tracking with familiar equipment in inventory.php is wonky? 70 | checklists.add(C_RESOURCES, ChecklistEntryMake(514, image_name, url, ChecklistSubentryMake("Minature crystal ball", "", description), 1)); 71 | } 72 | -------------------------------------------------------------------------------- /Source/relay/Guide/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[$item[Daily Affirmation: Adapt to Change Eventually]] = "+4 stats/fight, +50% init"; 9 | if (!__misc_state["need to level"]) 10 | affirmation_effects[$item[Daily Affirmation: Adapt to Change Eventually]] = "+50% init"; 11 | affirmation_effects[$item[Daily Affirmation: Always be Collecting]] = "+50% item, +100% meat"; 12 | affirmation_effects[$item[Daily Affirmation: Be a Mind Master]] = "+100% spell damage, 15 MP regen"; 13 | affirmation_effects[$item[Daily Affirmation: Be Superficially interested]] = "-combat / +combat (togglable)"; 14 | affirmation_effects[$item[Daily Affirmation: Keep Free Hate in your Heart]] = "+30 ML"; 15 | affirmation_effects[$item[Daily Affirmation: Think Win-Lose]] = "+50% all stats"; 16 | affirmation_effects[$item[Daily Affirmation: Work For Hours a Week]] = "+5 familiar weight, 15 HP regen"; 17 | if (__misc_state["familiars temporarily blocked"]) 18 | affirmation_effects[$item[Daily Affirmation: Work For Hours a Week]] = "15 HP regen"; 19 | 20 | 21 | affirmation_combat_uses[$item[Daily Affirmation: Adapt to Change Eventually]] = "reroll monster"; //monster change 22 | affirmation_combat_uses[$item[Daily Affirmation: Always be Collecting]] = "duplicate item drops"; 23 | affirmation_combat_uses[$item[Daily Affirmation: Be a Mind Master]] = "banish for 80 turns"; 24 | if (!__misc_state["have reusable olfaction equivalent"]) 25 | affirmation_combat_uses[$item[Daily Affirmation: Be Superficially interested]] = "olfact weakly"; 26 | if (hippy_stone_broken()) 27 | affirmation_combat_uses[$item[Daily Affirmation: Keep Free Hate in your Heart]] = "gain 3 PVP fights"; 28 | affirmation_combat_uses[$item[Daily Affirmation: Think Win-Lose]] = "instakill"; 29 | affirmation_combat_uses[$item[Daily Affirmation: Work For Hours a Week]] = "earn some meat"; 30 | 31 | ChecklistEntry entry = ChecklistEntryMake(496); 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 == $item[Daily Affirmation: Think Win-Lose]) 44 | { 45 | resource_entries.listAppend(ChecklistEntryMake(497, "__item " + it, "", subentry).ChecklistEntryTag("free instakill")); 46 | } 47 | else if (it == $item[Daily Affirmation: Be a Mind Master]) 48 | { 49 | resource_entries.listAppend(ChecklistEntryMake(498, "__item " + it, "", subentry).ChecklistEntryTag("free banish")); 50 | } 51 | else 52 | entry.subentries.listAppend(subentry); 53 | } 54 | if (entry.subentries.count() > 0) 55 | { 56 | entry.url = "inventory.php?which=3"; 57 | entry.importance_level = 6; 58 | resource_entries.listAppend(entry); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Source/relay/Guide/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[$item[portable pantogram]]) return; 6 | if ($item[pantogram pants].available_amount() > 0) return; 7 | 8 | if (my_path_id_legacy() == 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_legacy() == 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_legacy() == 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_legacy() != 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(573, "__item portable pantogram", "inv_use.php?pwd=" + my_hash() + "&whichitem=9573", ChecklistSubentryMake("Summon pants", "", description), 1)); 69 | } 70 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Potted Power Plant.ash: -------------------------------------------------------------------------------- 1 | 2 | // 3 | RegisterGenerationFunction("IOTMPottedPowerPlantGenerate"); 4 | void IOTMPottedPowerPlantGenerate(ChecklistCollection checklists) 5 | { 6 | //_pottedPowerPlant, shockingLickCharges 7 | 8 | if (lookupItem("potted power plant").have() && mafiaIsPastRevision(20657)) 9 | { 10 | int plant_picks_remaining = 0; 11 | string [int] plant_pick_state = get_property("_pottedPowerPlant").split_string_alternate(","); 12 | foreach key, pick in plant_pick_state 13 | { 14 | if (pick == "") continue; 15 | if (pick == "0") continue; 16 | if (is_integer(pick)) plant_picks_remaining += 1; 17 | } 18 | if (plant_pick_state.count() == 0) 19 | plant_picks_remaining = 7; //guess 20 | if (plant_picks_remaining > 0) 21 | { 22 | checklists.add(C_RESOURCES, ChecklistEntryMake(519, "__item potted power plant", "inv_use.php?pwd=" + my_hash() + "&whichitem=10738", ChecklistSubentryMake(pluralise(plant_picks_remaining, "potted power plant pick", "potted power plant picks"), "", ""), 2)).ChecklistEntryTag("Potted Power Plant"); 23 | } 24 | } 25 | if (in_ronin()) 26 | { 27 | string [item] battery_descriptions = { 28 | lookupItem("battery (AAA)"):"+50% spell damage, regen ~7MP/adv (30 turns), 30 MP", 29 | lookupItem("battery (AA)"):"+50% spell damage, +50% init, regen ~7MP/adv (30 turns), 40 MP", 30 | lookupItem("battery (D)"):"+50% spell damage, +50% init, +3 stats/fight, regen ~7MP/adv (30 turns), 50 MP", 31 | lookupItem("battery (9-Volt)"):"1 freekill charge, +50% spell damage, +50% init, +3 stats/fight, regen ~7MP/adv (30 turns), 60 MP", 32 | lookupItem("battery (lantern)"):"1 freekill charge, +100% item, +50% spell damage, +50% init, +3 stats/fight, regen ~7MP/adv (30 turns), 70 MP", 33 | lookupItem("battery (car)"):"1 freekill charge, +100% item, +100% meat, +50% spell damage, +50% init, +3 stats/fight, regen ~7MP/adv (30 turns), 80 MP", 34 | }; 35 | if (my_path_id_legacy() == PATH_ROBOT) 36 | { 37 | battery_descriptions[lookupItem("battery (AAA)")] += ", 15 energy"; 38 | battery_descriptions[lookupItem("battery (AA)")] += ", 20 energy"; 39 | battery_descriptions[lookupItem("battery (D)")] += ", 25 energy"; 40 | battery_descriptions[lookupItem("battery (9-Volt)")] += ", 30 energy"; 41 | battery_descriptions[lookupItem("battery (lantern)")] += ", 35 energy"; 42 | battery_descriptions[lookupItem("battery (car)")] += ", 40 energy"; 43 | } 44 | string [int] creatables; 45 | string url = "inventory.php?which=3&ftext=battery"; 46 | foreach it, item_description in battery_descriptions 47 | { 48 | if (it.have()) 49 | { 50 | checklists.add(C_RESOURCES, ChecklistEntryMake(520, "__item " + it, url, ChecklistSubentryMake(pluralise(it), "", item_description), 2)).ChecklistEntryTag("Potted Power Plant"); 51 | } 52 | int creatable_amount = it.creatable_amount(); 53 | if (creatable_amount > 0) 54 | { 55 | creatables.listAppend("" + pluralise(creatable_amount, it) + ": " + item_description); 56 | } 57 | } 58 | if (creatables.count() > 0) 59 | { 60 | checklists.add(C_RESOURCES, ChecklistEntryMake(521, "__item potted power plant", url, ChecklistSubentryMake("Creatable batteries", "", creatables), 2)).ChecklistEntryTag("Potted Power Plant"); 61 | } 62 | } 63 | int shocking_lick_charges = get_property_int("shockingLickCharges"); 64 | if (shocking_lick_charges > 0) 65 | { 66 | checklists.add(C_RESOURCES, ChecklistEntryMake(522, "__skill Shocking Lick", "", ChecklistSubentryMake(pluralise(shocking_lick_charges, "Shocking Lick", "Shocking Licks"), "", "Free instakill."), 1).ChecklistEntryTag("free instakill")); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Powerful Glove.ash: -------------------------------------------------------------------------------- 1 | 2 | import "relay/Guide/Items of the Month/Meteor Lore.ash"; 3 | 4 | RegisterResourceGenerationFunction("IOTMPowerfulGloveGenerateResource"); 5 | void IOTMPowerfulGloveGenerateResource(ChecklistEntry [int] resource_entries) 6 | { 7 | if (!$item[powerful glove].have()) return; 8 | 9 | int battery_left = clampi(100 - get_property_int("_powerfulGloveBatteryPowerUsed"), 0, 100); 10 | 11 | if (battery_left >= 5) 12 | { 13 | //invisible avatar - -10% combat rate 14 | //shrink enemy - should we even bother to mention this? reduces a single foe's HP/attack/def by 50%, I am not sure this is useful anywhere except maaaaaybe the war boss and duriel? 15 | //triple size - +200% stats for twenty adventures 16 | 17 | string [int] description; 18 | 19 | if (battery_left >= 10) 20 | { 21 | //replace enemy - macrometeorite reroll 22 | string [int] useful_places = generateUsefulPlacesToRerollMonsters(); 23 | description.listAppend("Replace enemy:|Reroll a monster in combat, -10 energy:|*-" + useful_places.listJoinComponents("|*-")); 24 | } 25 | 26 | description.listAppend("Invisible avatar: -10% combat rate buff. (10 adv, -5 energy)"); 27 | description.listAppend("Triple size: +200% all stats buff. (20 adv, -5 energy)"); 28 | 29 | string url = "skillz.php"; 30 | if (!$item[powerful glove].equipped()) 31 | { 32 | url = generateEquipmentLink($item[powerful glove]); 33 | description.listAppend("Equip first to use."); 34 | } 35 | resource_entries.listAppend(ChecklistEntryMake(480, "__item powerful glove", url, ChecklistSubentryMake(battery_left + " Powerful Glove energy", "", description), 2)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Rune Spoon.ash: -------------------------------------------------------------------------------- 1 | 2 | //moonTuned 3 | RegisterResourceGenerationFunction("IOTMRuneSpoonGenerateResource"); 4 | void IOTMRuneSpoonGenerateResource(ChecklistEntry [int] resource_entries) 5 | { 6 | item spoon = $item[hewn moon-rune spoon]; 7 | if (!spoon.have() && spoon.closet_amount() == 0) 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_legacy() == PATH_SLOW_AND_STEADY)) continue; 65 | if (sign == "Blender" && (!__misc_state["can drink just about anything"] || my_path_id_legacy() == 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(461, "__item " + spoon, url, ChecklistSubentryMake("Moon sign tunable", "", description), 10)); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Spacegate.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("IOTMSpacegateGenerateResource"); 3 | void IOTMSpacegateGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (!__iotms_usable[$item[Spacegate access badge]]) 6 | return; 7 | if (!get_property_boolean("_spacegateVaccine") && my_path_id_legacy() != 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 && $item[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(603, "__item plus sign", "place.php?whichplace=spacegate&action=sg_vaccinator", ChecklistSubentryMake("Vaccination", "", description), 8).ChecklistEntrySetCategory("buff")); 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(604, "__item portable spacegate", "place.php?whichplace=spacegate&action=sg_Terminal", ChecklistSubentryMake("Spacegate dial", "", description), 8)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Source/relay/Guide/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 | 24 | string image_name = ""; 25 | 26 | if ($item[sugar sheet].available_amount() > 0 && __misc_state["in run"] && in_ronin()) 27 | { 28 | string [int] suggestions; 29 | SugarGenerateSuggestions(suggestions); 30 | subentries.listAppend(ChecklistSubentryMake(pluralise($item[sugar sheet]), "", suggestions)); 31 | 32 | image_name = "sugar sheet"; 33 | } 34 | foreach key in sugar_crafted_items 35 | { 36 | item it = sugar_crafted_items[key]; 37 | if (it.available_amount() == 0) 38 | continue; 39 | int counter = get_property_int("sugarCounter" + it.to_int()); 40 | if (counter == 0 && (!__misc_state["in run"] || !in_ronin())) //in aftercore, probably not as relevant 41 | continue; 42 | int combats_left = 31 - counter; 43 | subentries.listAppend(ChecklistSubentryMake(pluralise(it), "", pluralise(combats_left, "combat", "combats") + " left.")); 44 | if (image_name.length() == 0) 45 | image_name = it; 46 | } 47 | if (subentries.count() > 0) 48 | { 49 | resource_entries.listAppend(ChecklistEntryMake(605, image_name, "", subentries, 10)); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Time-Spinner.ash: -------------------------------------------------------------------------------- 1 | RegisterResourceGenerationFunction("IOTMTimeSpinnerGenerateResource"); 2 | void IOTMTimeSpinnerGenerateResource(ChecklistEntry [int] resource_entries) 3 | { 4 | //Warn about eating if they're low on turns - you can't use the time spinner when you're out of adventures. 5 | if ($item[Time-Spinner].available_amount() == 0) 6 | return; 7 | if (my_path_id_legacy() == PATH_G_LOVER) 8 | return; 9 | int minutes_left = clampi(10 - get_property_int("_timeSpinnerMinutesUsed"), 0, 10); 10 | if (minutes_left <= 0) 11 | return; 12 | 13 | string [int] description; 14 | 15 | if (minutes_left >= 3) 16 | { 17 | //Recent fight - 3 minutes - fight something past. Umm... hmm... same as any monster you copy? Though with restrictions. Plus olfaction-lite in NA. 18 | int amount = minutes_left / 3; 19 | description.listAppend(HTMLGenerateSpanOfClass(pluralise(amount, "recent fight", "recent fights"), "r_bold") + ": Re-fight a monster this ascension."); 20 | //Delicious meal - 3 minutes 21 | if (__misc_state["can eat just about anything"] && availableFullness() > 0) 22 | { 23 | description.listAppend(HTMLGenerateSpanOfClass(pluralise(amount, "meal", "meals"), "r_bold") + ": Re-eat something else today."); 24 | } 25 | } 26 | //Way back in time - 1 minute, stats, costs a turn(?) 27 | if (minutes_left >= 2) 28 | { 29 | //Visit the far future - 2 minutes, star-trek mini-game, lets you replicate things. Script fodder. 30 | if (!get_property_boolean("_timeSpinnerReplicatorUsed")) 31 | { 32 | string [int] options; 33 | if (__misc_state["can eat just about anything"] && availableFullness() > 0) 34 | options.listAppend("epic food"); 35 | if (__misc_state["can drink just about anything"] && availableDrunkenness() > 0) 36 | options.listAppend("drink"); 37 | if (!in_ronin()) 38 | options.listAppend("something to sell"); 39 | if (my_path_id_legacy() == PATH_GELATINOUS_NOOB && !$skill[Pathological Greed].have_skill() && $item[shot of Kardashian Gin].available_amount() == 0) 40 | { 41 | options.listAppend("Kardashian Gin for +meat skill"); 42 | } 43 | if (options.count() == 0) 44 | options.listAppend("item"); 45 | description.listAppend(HTMLGenerateSpanOfClass("Future", "r_bold") + ": once/day " + options.listJoinComponents(" / ") + "."); 46 | } 47 | } 48 | //Play a time prank - 1 minute, heart 49 | 50 | resource_entries.listAppend(ChecklistEntryMake(579, "Hourglass", "inv_use.php?whichitem=9104&pwd=" + my_hash(), ChecklistSubentryMake(pluralise(minutes_left, "Time-Spinner minute", "Time-Spinner minutes"), "", description), 4).ChecklistEntrySetCategory("equipment")); 51 | } 52 | -------------------------------------------------------------------------------- /Source/relay/Guide/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 (!__iotms_usable[$item[heart-shaped crate]]) 6 | return; 7 | if (get_property_boolean("_loveTunnelUsed")) 8 | return; 9 | 10 | string [int] description; 11 | //equipment: LOV Eardigan (+25% muscle exp, +25 ML), LOV Epaulettes (+25% myst exp), LOV Earrings (+25% moxie exp, +50% meat, +3 all res) 12 | //50-turn buffs: Lovebotamy (10 stats/fight), Open Heart Surgery (+10 familiar weight), Wandering Eye Surgery (+50% item) 13 | //item: boomerang (arrow), toy dart gun (???), chocolate (adventures), flowers (???), elephant (???), TOAST! (toasty!) 14 | 15 | description.listAppend("Three free fights. Attack, spell, and pickpocket respectively for elixirs."); 16 | if (my_path_id_legacy() == PATH_GELATINOUS_NOOB) 17 | description.listAppend("Equipment choice unimportant."); 18 | else 19 | { 20 | string [int] equipment_choices; 21 | equipment_choices.listAppend(HTMLBoldIfTrue("Eardigan", my_primestat() == $stat[muscle] && __misc_state["in run"] && my_level() < 13) + " (+25% muscle exp, +25 ML)"); 22 | if (my_path_id_legacy() != PATH_G_LOVER) 23 | equipment_choices.listAppend(HTMLBoldIfTrue("Epaulettes", my_primestat() == $stat[mysticality] && __misc_state["in run"] && my_level() < 13) + " (+25% myst exp)"); 24 | 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)"); 25 | description.listAppend("Equipment choice:|*" + equipment_choices.listJoinComponents(", ", "or")); 26 | } 27 | string [int] buff_choices; 28 | if (my_path_id_legacy() != PATH_G_LOVER) 29 | buff_choices.listAppend("+10 stats/fight"); 30 | buff_choices.listAppend("+10 familiar weight"); 31 | buff_choices.listAppend("+50% item"); 32 | description.listAppend("Buff choice: (50 turns)|*" + buff_choices.listJoinComponents(", ", "or")); 33 | 34 | string [int] usable_items; 35 | if (my_path_id_legacy() != PATH_LIVE_ASCEND_REPEAT) 36 | usable_items.listAppend("single-use wandering copier"); 37 | usable_items.listAppend("chat hearts"); 38 | if (my_path_id_legacy() != PATH_SLOW_AND_STEADY && my_path_id_legacy() != PATH_G_LOVER) 39 | usable_items.listAppend("chocolate (adventures)"); 40 | if ($familiar[space jellyfish].familiar_is_usable()) 41 | usable_items.listAppend("toast"); 42 | description.listAppend("Item choice:|*" + usable_items.listJoinComponents(", ", "or").capitaliseFirstLetter() + "."); 43 | 44 | optional_task_entries.listAppend(ChecklistEntryMake(580, "__item pink candy heart", "place.php?whichplace=town_wrong", ChecklistSubentryMake("Take a love trip", "", description))); 45 | } 46 | 47 | RegisterResourceGenerationFunction("IOTMTunnelOfLoveGenerateResource"); 48 | void IOTMTunnelOfLoveGenerateResource(ChecklistEntry [int] resource_entries) 49 | { 50 | //mostly the boomerang 51 | //what does sokka throw? a boomeraang! 52 | 53 | if (__misc_state["in run"] && in_ronin()) 54 | { 55 | /*item enamorang = $item[LOV Enamorang]; 56 | if (enamorang.available_amount() > 0) 57 | { 58 | resource_entries.listAppend(ChecklistEntryMake(581, "__item LOV Enamorang", "", ChecklistSubentryMake(pluralise(enamorang), "", "Copies the monster once as an arrow."), 5)); 59 | 60 | }*/ 61 | item chocolate = $item[LOV Extraterrestrial Chocolate]; 62 | if (chocolate.available_amount() > 0 && my_path_id_legacy() != PATH_SLOW_AND_STEADY) 63 | { 64 | //FIXME list other chocolates? 65 | resource_entries.listAppend(ChecklistEntryMake(582, "__item LOV Extraterrestrial Chocolate", "", ChecklistSubentryMake(pluralise(chocolate), "", "Adventures!"), 5)); 66 | 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Source/relay/Guide/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_legacy() != PATH_POCKET_FAMILIARS) 11 | { 12 | string [int] skills; 13 | skills.listAppend("Wolf: +50% muscle, +50% meat"); 14 | skills.listAppend("Mist: +2 all res"); 15 | skills.listAppend("Bat: +50% item"); 16 | 17 | string url = generateEquipmentLink($item[vampyric cloake]); 18 | string [int] description; 19 | description.listAppend("In-combat cast one of the Become skills, to gain a buff for that fight:|*" + skills.listJoinComponents("|*")); 20 | resource_entries.listAppend(ChecklistEntryMake(589, "__item vampyric cloake", url, ChecklistSubentryMake(pluralise(uses_left, "vampyric skill use", "vampyric skill uses"), "", description), 5)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Source/relay/Guide/Items of the Month/Zutara.ash: -------------------------------------------------------------------------------- 1 | 2 | 3 | RegisterGenerationFunction("IOTMZutaraGenerate"); 4 | void IOTMZutaraGenerate(ChecklistCollection checklists) 5 | { 6 | if (!__misc_state["VIP available"] || !$item[Clan Carnival Game].is_unrestricted()) 7 | return; 8 | if (!get_property_boolean("_clanFortuneBuffUsed")) 9 | { 10 | string [int] description; 11 | if (!__misc_state["familiars temporarily blocked"] && __misc_state["in run"]) 12 | 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. 13 | if (my_path_id_legacy() != PATH_G_LOVER) 14 | description.listAppend(HTMLGenerateSpanOfClass("Hagnk:", "r_bold") + " +50% item/booze/food."); 15 | if (my_path_id_legacy() != PATH_G_LOVER) 16 | description.listAppend(HTMLGenerateSpanOfClass("Meatsmith:", "r_bold") + " +100% meat, +50% gear drop."); 17 | 18 | if (__misc_state["in run"]) 19 | { 20 | if (my_primestat() == $stat[muscle] || my_path_id_legacy() == PATH_COMMUNITY_SERVICE) 21 | description.listAppend(HTMLGenerateSpanOfClass("Gunther:", "r_bold") + " +5 muscle stats/fight, +100% muscle, +50% HP."); 22 | if (my_primestat() == $stat[moxie] || my_path_id_legacy() == PATH_COMMUNITY_SERVICE) 23 | description.listAppend(HTMLGenerateSpanOfClass("Gorgonzola:", "r_bold") + " +5 myst stats/fight, +100% myst, +50% MP."); 24 | //always show moxie, since I'm sure that +50% init will be super important to someone. maybe they have a bad lair test? 25 | if (my_path_id_legacy() != PATH_G_LOVER) 26 | description.listAppend(HTMLGenerateSpanOfClass("Shifty:", "r_bold") + " +5 moxie stats/fight, +100% moxie, +50% init."); 27 | } 28 | checklists.add(C_RESOURCES, ChecklistEntryMake(587, "__item genie's turbane", "clan_viplounge.php?preaction=lovetester", ChecklistSubentryMake("Fortune buff (100 turns)", "", description), 8).ChecklistEntryTag("zutara").ChecklistEntrySetCategory("buff").ChecklistEntrySetShortDescription("blank")); 29 | } 30 | if (get_property_int("_clanFortuneConsultUses") < 3) 31 | { 32 | string [int] description; 33 | checklists.add(C_RESOURCES, ChecklistEntryMake(588, "__item genie's turbane", "clan_viplounge.php?preaction=lovetester", ChecklistSubentryMake(pluralise(3 - get_property_int("_clanFortuneConsultUses"), "fortune clan consult", "fortune clan consults"), "", description), 8).ChecklistEntryTag("zutara")); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Source/relay/Guide/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_legacy() != PATH_AVATAR_OF_JARLSBERG) 44 | return; 45 | 46 | ChecklistEntry entry = ChecklistEntryMake(183); 47 | entry.url = ""; 48 | entry.image_lookup_name = ""; 49 | 50 | 51 | //wizard staff: 52 | //Show uses: 53 | //_jiggleCheesedMonsters split by | 54 | 55 | PathJarlsbergGenerateStaff(entry, $item[Staff of the All-Steak], "_jiggleSteak", "+300% items.", false); 56 | 57 | if (true) 58 | { 59 | string olfacted_monster = get_property("_jiggleCreamedMonster"); 60 | boolean always_output = false; 61 | string cream_line = "Monster olfaction"; 62 | if (olfacted_monster != "") 63 | { 64 | always_output = true; 65 | cream_line += "|Following a " + olfacted_monster.HTMLEscapeString() + "."; 66 | } 67 | PathJarlsbergGenerateStaff(entry, $item[Staff of the Cream of the Cream], "_jiggleCream", cream_line, always_output); 68 | } 69 | if (true) 70 | { 71 | //I must capture the avatar (of jarlsberg) to regain my honor 72 | string [int] banished_monsters = split_string_alternate(get_property("_jiggleCheesedMonsters"), "\\|"); 73 | boolean always_output = false; 74 | string cheese_line = ""; 75 | if (get_property("_jiggleCheesedMonsters") != "") 76 | { 77 | cheese_line += "Monsters banished: " + banished_monsters.listJoinComponents(", ", "and").HTMLEscapeString() + "."; 78 | always_output = true; 79 | } 80 | 81 | ChecklistEntry entry2; 82 | boolean should_add = PathJarlsbergGenerateStaff(entry2, $item[Staff of the Standalone Cheese], "_jiggleCheese", cheese_line, always_output); 83 | entry2.ChecklistEntryTag("banish"); 84 | if (should_add) 85 | resource_entries.listAppend(entry2); 86 | } 87 | PathJarlsbergGenerateStaff(entry, $item[Staff of the Staff of Life], "_jiggleLife", "Restores all HP.", false); 88 | 89 | if (entry.subentries.count() > 0) 90 | resource_entries.listAppend(entry); 91 | } 92 | -------------------------------------------------------------------------------- /Source/relay/Guide/Paths/Dark Gift.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("PathDarkGiftGenerateResource"); 3 | void PathDarkGiftGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (my_path_id_legacy() != PATH_VAMPIRE) 6 | return; 7 | 8 | int banishes_left = clampi(10 - get_property_int("_balefulHowlUses"), 0, 10); 9 | if (banishes_left > 0 && $skill[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(140, "__skill Baleful Howl", url, ChecklistSubentryMake(pluralise(banishes_left, "baleful howl", "baleful howls"), "", description), 0).ChecklistEntryTag("free banish")); 23 | } 24 | -------------------------------------------------------------------------------- /Source/relay/Guide/Paths/Explosions.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("PathExplosionsGenerateResource"); 3 | void PathExplosionsGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (my_path_id_legacy() != PATH_EXPLOSIONS) 6 | return; 7 | item isotopes = $item[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-ish pill].available_amount()) 20 | description.listAppend("lucky-ish pill - extra clovers, super useful.");*/ 21 | if (isotope_amount >= 25 && !$item[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 && !$item[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 && !$item[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(141, "__item rare Meat isotope", "shop.php?whichshop=exploathing", ChecklistSubentryMake(pluralise(isotopes), "", description), 5)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Source/relay/Guide/Paths/G-Lover.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterResourceGenerationFunction("PathGLoverGenerateResource"); 3 | void PathGLoverGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (my_path_id_legacy() != PATH_G_LOVER) 6 | return; 7 | 8 | item g = $item[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 && $items[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(196, "__item g", "shop.php?whichshop=glover", ChecklistSubentryMake(pluralise(g) + " available", "", description), 3)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Source/relay/Guide/Paths/Paths import.ash: -------------------------------------------------------------------------------- 1 | import "relay/Guide/Paths/Actually Ed the Undying.ash"; 2 | import "relay/Guide/Paths/Avatar of Jarlsberg.ash"; 3 | import "relay/Guide/Paths/Avatar of Sneaky Pete.ash"; 4 | import "relay/Guide/Paths/Avatar of West of Loathing.ash"; 5 | import "relay/Guide/Paths/Bad Moon.ash"; 6 | import "relay/Guide/Paths/Bugbear Invasion.ash"; 7 | import "relay/Guide/Paths/Community Service.ash"; 8 | import "relay/Guide/Paths/Heavy Rains.ash"; 9 | import "relay/Guide/Paths/KOLHS.ash"; 10 | import "relay/Guide/Paths/Way of the Surprising Fist.ash"; 11 | import "relay/Guide/Paths/The Source.ash"; 12 | import "relay/Guide/Paths/Zombie Slayer.ash"; 13 | import "relay/Guide/Paths/Nuclear Autumn.ash"; 14 | import "relay/Guide/Paths/Gelatinous Noob.ash"; 15 | import "relay/Guide/Paths/License to Adventure.ash"; 16 | import "relay/Guide/Paths/G-Lover.ash"; 17 | import "relay/Guide/Paths/Explosions.ash"; 18 | import "relay/Guide/Paths/Low Key.ash"; 19 | import "relay/Guide/Paths/Quantum of Familiar.ash"; 20 | 21 | -------------------------------------------------------------------------------- /Source/relay/Guide/Paths/Quantum of Familiar.ash: -------------------------------------------------------------------------------- 1 | 2 | RegisterGenerationFunction("PathQuantumOfFamiliarGenerate"); 3 | void PathQuantumOfFamiliarGenerate(ChecklistCollection checklists) 4 | { 5 | if (my_path_id_legacy() != PATH_QUANTUM) return; 6 | int current_turn = total_turns_played(); 7 | int next_quantum_alignment = get_property_int("_nextQuantumAlignment"); 8 | //nextQuantumFamiliarTurn? 9 | 10 | if (current_turn >= next_quantum_alignment) 11 | { 12 | int turns_until_next_familiar_switch = clampi(get_property_int("nextQuantumFamiliarTurn") - current_turn, -1, 11); 13 | string [int] description; 14 | string turns_usable_in = pluralise(turns_until_next_familiar_switch, "turn", "turns"); 15 | if (turns_until_next_familiar_switch == -1) 16 | turns_usable_in = "unknown turns"; 17 | description.listAppend("Will be usable in " + turns_usable_in + "."); 18 | if (get_property_int("_banderRunaways") < 11) 19 | description.listAppend("Maybe a pair of stomping boots?"); 20 | checklists.add(C_OPTIONAL_TASKS, ChecklistEntryMake(0, "__familiar pair of stomping boots", "qterrarium.php", ChecklistSubentryMake("Can align your next familiar", "", description), 0)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Source/relay/Guide/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_legacy() != 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(194, "meat", "cobbsknob.php", ChecklistSubentryMake("Cobb's Knob treasury meat", "", "Wear harem girl disguise, adventure once for 500 meat."), 5)); 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(195, "__item Teachings of the Fist", "", ChecklistSubentryMake("Teachings of the Fist", "", "Found in " + missing_areas.listJoinComponents(", ", "and") + "."), 5)); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /Source/relay/Guide/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_legacy() != 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(171, "__item hunter brain", "inventory.php?which=1", ChecklistSubentryMake("Eat a hunter brain", "", "Gain a skill point."), -1)); 23 | } 24 | } 25 | 26 | } 27 | 28 | RegisterResourceGenerationFunction("PathZombieSlayerGenerateResource"); 29 | void PathZombieSlayerGenerateResource(ChecklistEntry [int] resource_entries) 30 | { 31 | if (my_path_id_legacy() != PATH_ZOMBIE_SLAYER) 32 | return; 33 | 34 | if ($item[right bear arm].available_amount() > 0 && $item[left bear arm].available_amount() > 0) 35 | { 36 | int bear_hugs_remaining = clampi(10 - get_property_int("_bearHugs"), 0, 10); 37 | 38 | if (bear_hugs_remaining > 0) 39 | { 40 | string url; 41 | string [int] description; 42 | description.listAppend("Converts monster to zombies. Ideally, use against group monsters."); 43 | string [int] items_to_equip; 44 | foreach it in $items[right bear arm,left bear arm] 45 | { 46 | if (it.equipped_amount() == 0) 47 | items_to_equip.listAppend(it); 48 | } 49 | if (items_to_equip.count() > 0) 50 | { 51 | url = "inventory.php?which=2"; 52 | description.listAppend("Equip " + items_to_equip.listJoinComponents(", ", "and") + "."); 53 | } 54 | resource_entries.listAppend(ChecklistEntryMake(172, "__item right bear arm", url, ChecklistSubentryMake(pluralise(bear_hugs_remaining, "bear hug", "bear hugs"), "", description), 8)); 55 | 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Source/relay/Guide/QuestState.ash: -------------------------------------------------------------------------------- 1 | import "relay/Guide/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/Guide/Quests.ash: -------------------------------------------------------------------------------- 1 | import "relay/Guide/Support/Checklist.ash" 2 | import "relay/Guide/Support/LocationAvailable.ash" 3 | import "relay/Guide/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 | 40 | //has to happen after level 13 init... or not? 41 | QManorInit(); 42 | } 43 | 44 | 45 | void QuestsGenerateTasks(ChecklistEntry [int] task_entries, ChecklistEntry [int] optional_task_entries, ChecklistEntry [int] future_task_entries) 46 | { 47 | //ideally, remove this entirely: 48 | QLevel2GenerateTasks(task_entries, optional_task_entries, future_task_entries); 49 | QLevel3GenerateTasks(task_entries, optional_task_entries, future_task_entries); 50 | QLevel4GenerateTasks(task_entries, optional_task_entries, future_task_entries); 51 | QLevel5GenerateTasks(task_entries, optional_task_entries, future_task_entries); 52 | QLevel6GenerateTasks(task_entries, optional_task_entries, future_task_entries); 53 | QLevel7GenerateTasks(task_entries, optional_task_entries, future_task_entries); 54 | QLevel8GenerateTasks(task_entries, optional_task_entries, future_task_entries); 55 | QLevel9GenerateTasks(task_entries, optional_task_entries, future_task_entries); 56 | QLevel10GenerateTasks(task_entries, optional_task_entries, future_task_entries); 57 | QLevel11GenerateTasks(task_entries, optional_task_entries, future_task_entries); 58 | QLevel12GenerateTasks(task_entries, optional_task_entries, future_task_entries); 59 | QLevel13GenerateTasks(task_entries, optional_task_entries, future_task_entries); 60 | 61 | QManorGenerateTasks(task_entries, optional_task_entries, future_task_entries); 62 | QPirateGenerateTasks(task_entries, optional_task_entries, future_task_entries); 63 | QSeaGenerateTasks(task_entries, optional_task_entries, future_task_entries); 64 | QSpaceElvesGenerateTasks(task_entries, optional_task_entries, future_task_entries); 65 | QAzazelGenerateTasks(task_entries, optional_task_entries, future_task_entries); 66 | QGuildGenerateTasks(task_entries, optional_task_entries, future_task_entries); 67 | 68 | QUntinkerGenerateTasks(task_entries, optional_task_entries, future_task_entries); 69 | QArtistGenerateTasks(task_entries, optional_task_entries, future_task_entries); 70 | QLegendaryBeatGenerateTasks(task_entries, optional_task_entries, future_task_entries); 71 | QMemoriesGenerateTasks(task_entries, optional_task_entries, future_task_entries); 72 | QWhiteCitadelGenerateTasks(task_entries, optional_task_entries, future_task_entries); 73 | QWizardOfEgoGenerateTasks(task_entries, optional_task_entries, future_task_entries); 74 | QSpookyravenLightsOutGenerateTasks(task_entries, optional_task_entries, future_task_entries); 75 | QFeloniaGenerateTasks(task_entries, optional_task_entries, future_task_entries); 76 | 77 | QSubject37GenerateTasks(task_entries, optional_task_entries, future_task_entries); 78 | QMartyGenerateTasks(task_entries, optional_task_entries, future_task_entries); 79 | } 80 | 81 | void QuestsGenerateResources(ChecklistEntry [int] resource_entries) 82 | { 83 | QSpookyravenLightsOutGenerateResource(resource_entries); 84 | } 85 | -------------------------------------------------------------------------------- /Source/relay/Guide/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_legacy() == PATH_ZOMBIE_SLAYER) //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(71, base_quest_state.image_name, active_url, subentry, $locations[the sleazy back alley, the outskirts of cobb's knob, the haunted pantry])); 80 | } 81 | -------------------------------------------------------------------------------- /Source/relay/Guide/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 | RegisterGenerationFunction("QGalaktikGenerate"); 18 | void QGalaktikGenerate(ChecklistCollection checklists) 19 | { 20 | QuestState base_quest_state = __quest_state["Galaktik"]; 21 | if (!base_quest_state.in_progress) 22 | return; 23 | 24 | ChecklistSubentry subentry; 25 | 26 | subentry.header = base_quest_state.quest_name; 27 | 28 | string active_url = "place.php?whichplace=town_wrong"; 29 | string image_name = base_quest_state.image_name; 30 | 31 | string [int] missing_item_descriptions; 32 | foreach it in $items[swindleblossom,fraudwort,shysterweed] 33 | { 34 | if (it.available_amount() >= 3) 35 | continue; 36 | missing_item_descriptions.listAppend(pluraliseWordy(3 - it.available_amount(), "more " + it, "more " + it.plural)); 37 | } 38 | 39 | if (missing_item_descriptions.count() > 0) 40 | { 41 | subentry.entries.listAppend("Collect " + missing_item_descriptions.listJoinComponents(", ", "and") + " in the overgrown lot."); 42 | if ($item[brown paper bag mask].available_amount() > 0 && $item[brown paper bag mask].equipped_amount() == 0) 43 | subentry.entries.listAppend("Could equip the brown paper bag mask to meet the Lot's wife, if you haven't already."); 44 | 45 | //if (__misc_state["in run"] && __last_adventure_location != $location[the overgrown lot] && !in_bad_moon()) 46 | //return; 47 | } 48 | else 49 | { 50 | //shop.php?whichshop=doc&action=talk 51 | active_url = "shop.php?whichshop=doc&action=talk"; 52 | subentry.entries.listAppend("Return to Doc Galaktik."); 53 | //image_name = "__familiar o.a.f."; 54 | } 55 | 56 | checklists.add(C_AFTERCORE_TASKS, ChecklistEntryMake(35, image_name, active_url, subentry, $locations[the overgrown lot])); 57 | } 58 | -------------------------------------------------------------------------------- /Source/relay/Guide/Quests/Level 2.ash: -------------------------------------------------------------------------------- 1 | 2 | void QLevel2Init() 3 | { 4 | //questL02Larva 5 | QuestState state; 6 | 7 | QuestStateParseMafiaQuestProperty(state, "questL02Larva"); 8 | if (my_path_id_legacy() == 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_legacy() == 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_legacy() == 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(80, base_quest_state.image_name, url, subentry, $locations[the spooky forest])); 90 | } 91 | -------------------------------------------------------------------------------- /Source/relay/Guide/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 | RegisterGenerationFunction("QMadnessBakeryGenerate"); 17 | void QMadnessBakeryGenerate(ChecklistCollection checklists) 18 | { 19 | QuestState base_quest_state = __quest_state["Madness Bakery"]; 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 url = "place.php?whichplace=town_right"; 28 | 29 | if ($item[no-handed pie].available_amount() > 0 || base_quest_state.mafia_internal_step >= 5) 30 | { 31 | subentry.entries.listAppend("Talk to the leggerer."); 32 | url = "place.php?whichplace=town_market"; 33 | } 34 | else 35 | { 36 | //step1 seems to exist, but no information on office visits left 37 | //step2 - cake lord 38 | //step3 - in the progress of talking to madeline 39 | //step4 - acquire cake 40 | //step5 - melon lord? 41 | subentry.entries.listAppend("Adventure in the Madness Bakery|Choose the first option in the non-combat repeatedly."); 42 | } 43 | 44 | checklists.add(C_AFTERCORE_TASKS, ChecklistEntryMake(1, base_quest_state.image_name, url, subentry, $locations[Madness Bakery])); 45 | } 46 | -------------------------------------------------------------------------------- /Source/relay/Guide/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 | RegisterGenerationFunction("QMeatsmithGenerate"); 18 | void QMeatsmithGenerate(ChecklistCollection checklists) 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 | if (have_reason_to_add) 78 | checklists.add(C_AFTERCORE_TASKS, ChecklistEntryMake(11, base_quest_state.image_name, active_url, subentry, locationToLocationMap($location[the skeleton store]))); 79 | } 80 | -------------------------------------------------------------------------------- /Source/relay/Guide/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(8, base_quest_state.image_name, active_url, subentry, $locations[the primordial soup])); 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(9, base_quest_state.image_name, active_url, subentry, $locations[the jungles of ancient loathing])); 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(10, base_quest_state.image_name, active_url, subentry, $locations[seaside megalopolis])); 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 | } 107 | -------------------------------------------------------------------------------- /Source/relay/Guide/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 | RegisterGenerationFunction("QOldLandfillGenerate"); 18 | void QOldLandfillGenerate(ChecklistCollection collection) 19 | { 20 | QuestState base_quest_state = __quest_state["Old Landfill"]; 21 | //if (!base_quest_state.in_progress) //this isn't actively tracked, so the best we can do is checking the last adventure location 22 | //return; 23 | if ($item[junk junk].available_amount() > 0) //FIXME returning to the hippy 24 | return; 25 | if (__last_adventure_location != $location[the old landfill] && !base_quest_state.in_progress) 26 | return; 27 | if (__misc_state["mysterious island available"]) 28 | return; 29 | 30 | ChecklistSubentry subentry; 31 | subentry.entries.listAppend("Unlocks the Mysterious Island."); 32 | 33 | item [int] missing_boat_items = $items[old claw-foot bathtub,old clothesline pole,antique cigar sign].items_missing(); 34 | 35 | subentry.header = base_quest_state.quest_name; 36 | 37 | string active_url = "place.php?whichplace=woods"; 38 | 39 | if ($item[worse homes and gardens].available_amount() > 0 && missing_boat_items.count() == 0) 40 | { 41 | active_url = "shop.php?whichshop=junkmagazine"; 42 | subentry.entries.listAppend("Use worse homes and gardens, craft a junk junk."); 43 | } 44 | else 45 | { 46 | string [int] nc_instructions = listMake("Go left", "Flush a bunch of toilets"); 47 | 48 | if ($item[old claw-foot bathtub].available_amount() == 0) 49 | { 50 | nc_instructions = listMake("Go left", "Take the tub"); 51 | } 52 | else if ($item[old clothesline pole].available_amount() == 0) 53 | { 54 | nc_instructions = listMake("Go center", "Take the antenna"); 55 | } 56 | else if ($item[antique cigar sign].available_amount() == 0) 57 | { 58 | nc_instructions = listMake("Go right", "Take the sign"); 59 | } 60 | 61 | 62 | if (missing_boat_items.count() > $item[funky junk key].available_amount() || $item[worse homes and gardens].available_amount() == 0) 63 | { 64 | subentry.modifiers.listAppend("+item"); 65 | subentry.entries.listAppend("Adventure in the Old Landfill with +item."); 66 | } 67 | else 68 | subentry.entries.listAppend("Adventure in the Old Landfill."); 69 | 70 | subentry.entries.listAppend("At the choice adventure, choose:|*" + nc_instructions.listJoinComponents(__html_right_arrow_character) + "."); 71 | } 72 | 73 | 74 | collection.add(C_OPTIONAL_TASKS, ChecklistEntryMake(93, base_quest_state.image_name, active_url, subentry, $locations[the old landfill])); 75 | } 76 | -------------------------------------------------------------------------------- /Source/relay/Guide/Quests/Quest import.ash: -------------------------------------------------------------------------------- 1 | import "relay/Guide/Quests/Level 2.ash"; 2 | import "relay/Guide/Quests/Level 3.ash"; 3 | import "relay/Guide/Quests/Level 4.ash"; 4 | import "relay/Guide/Quests/Level 5.ash"; 5 | import "relay/Guide/Quests/Level 6.ash"; 6 | import "relay/Guide/Quests/Level 7.ash"; 7 | import "relay/Guide/Quests/Level 8.ash"; 8 | import "relay/Guide/Quests/Level 9.ash"; 9 | import "relay/Guide/Quests/Level 10.ash"; 10 | import "relay/Guide/Quests/Level 11.ash"; 11 | import "relay/Guide/Quests/Level 12.ash"; 12 | import "relay/Guide/Quests/Level 13.ash"; 13 | import "relay/Guide/Quests/Manor.ash"; 14 | import "relay/Guide/Quests/Pirate.ash"; 15 | import "relay/Guide/Quests/Nemesis.ash"; 16 | import "relay/Guide/Quests/Sea.ash"; 17 | import "relay/Guide/Quests/Space Elves.ash"; 18 | import "relay/Guide/Quests/Azazel.ash"; 19 | import "relay/Guide/Quests/Untinker.ash"; 20 | import "relay/Guide/Quests/Artist.ash"; 21 | import "relay/Guide/Quests/Legendary Beat.ash"; 22 | import "relay/Guide/Quests/Memories.ash"; 23 | import "relay/Guide/Quests/White Citadel.ash"; 24 | import "relay/Guide/Quests/Wizard of Ego.ash"; 25 | import "relay/Guide/Quests/Spookyraven Lights Out.ash"; 26 | import "relay/Guide/Quests/Felonia.ash"; 27 | import "relay/Guide/Quests/Guild.ash"; 28 | import "relay/Guide/Quests/Airport.ash"; 29 | import "relay/Guide/Quests/Subject 37.ash"; 30 | import "relay/Guide/Quests/Marty.ash"; 31 | import "relay/Guide/Quests/Meatsmith.ash"; 32 | import "relay/Guide/Quests/Intergalaktik.ash"; 33 | import "relay/Guide/Quests/Old Landfill.ash"; 34 | import "relay/Guide/Quests/Madness Bakery.ash"; 35 | 36 | -------------------------------------------------------------------------------- /Source/relay/Guide/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_legacy() == PATH_EXPLOSION) 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(29, base_quest_state.image_name, url, subentry, 8, $locations[the degrassi knoll garage])); 59 | } 60 | -------------------------------------------------------------------------------- /Source/relay/Guide/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 | 24 | string [string][int] __specific_checklist_1_generation_function_names; 25 | void RegisterSpecificChecklistGenerationFunction1(string function_name, string checklist_name_1) 26 | { 27 | if (!(__specific_checklist_1_generation_function_names contains checklist_name_1)) 28 | { 29 | __specific_checklist_1_generation_function_names[checklist_name_1] = listMakeBlankString(); 30 | } 31 | __specific_checklist_1_generation_function_names[checklist_name_1].listAppend(function_name); 32 | } 33 | 34 | Record ChecklistGenerationFunctionRequest 35 | { 36 | string function_name; 37 | string [int] checklist_names; 38 | }; 39 | 40 | void listAppend(ChecklistGenerationFunctionRequest [int] list, ChecklistGenerationFunctionRequest entry) 41 | { 42 | int position = list.count(); 43 | while (list contains position) 44 | position += 1; 45 | list[position] = entry; 46 | } 47 | 48 | ChecklistGenerationFunctionRequest [int] __specific_checklist_generation_requests; 49 | 50 | void RegisterSpecificChecklistGenerationFunction3(string function_name, string checklist_name_1, string checklist_name_2, string checklist_name_3) 51 | { 52 | ChecklistGenerationFunctionRequest request; 53 | request.function_name = function_name; 54 | //Hardcoded to match call structure: 55 | request.checklist_names[0] = checklist_name_1; 56 | request.checklist_names[1] = checklist_name_2; 57 | request.checklist_names[2] = checklist_name_3; 58 | __specific_checklist_generation_requests.listAppend(request); 59 | } 60 | 61 | void RegisterResourceGenerationFunction(string function_name) 62 | { 63 | RegisterSpecificChecklistGenerationFunction1(function_name, "Resources"); 64 | } 65 | 66 | void RegisterTaskGenerationFunction(string function_name) 67 | { 68 | RegisterSpecificChecklistGenerationFunction3(function_name, "Tasks", "Optional Tasks", "Future Tasks"); 69 | } 70 | 71 | 72 | string [int] __generation_function_names; 73 | void RegisterGenerationFunction(string function_name) 74 | { 75 | __generation_function_names.listAppend(function_name); 76 | } 77 | -------------------------------------------------------------------------------- /Source/relay/Guide/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 | //print_html("PreferenceSet(" + name + ", " + value + ")"); 73 | if (!__read_user_preferences_initially) 74 | readUserPreferences(); 75 | __user_preferences_private[name] = value; 76 | writeUserPreferences(); 77 | } 78 | 79 | 80 | void processSetUserPreferences(string [string] form_fields) 81 | { 82 | foreach key, value in form_fields 83 | { 84 | if (key == "set user preferences") 85 | continue; 86 | PreferenceSet(key, value); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Source/relay/Guide/Sets.ash: -------------------------------------------------------------------------------- 1 | 2 | import "relay/Guide/Support/Checklist.ash"; 3 | import "relay/Guide/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 | } 54 | 55 | 56 | void SetsGenerateMissingItems(ChecklistEntry [int] items_needed_entries) 57 | { 58 | QHitsGenerateMissingItems(items_needed_entries); 59 | } -------------------------------------------------------------------------------- /Source/relay/Guide/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_legacy() == 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_legacy() == 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_legacy() != 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_legacy() == PATH_EXPLOSIONS) 34 | description.listAppend("You might need to visit your quest log afterwards, to update mafia's tracking."); 35 | task_entries.listAppend(ChecklistEntryMake(384, "council", "place.php?whichplace=town", ChecklistSubentryMake("Visit the Council of Loathing", "", description))); 36 | } 37 | -------------------------------------------------------------------------------- /Source/relay/Guide/Sets/Demon Summon.ash: -------------------------------------------------------------------------------- 1 | //demonSummoned 2 | RegisterResourceGenerationFunction("SDemonSummonGenerateResource"); 3 | void SDemonSummonGenerateResource(ChecklistEntry [int] resource_entries) 4 | { 5 | if (!QuestState("questL11Manor").finished) 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 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(219, "__item thin black candle", url, ChecklistSubentryMake("Demon summonable", "", description), 7)); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Source/relay/Guide/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_legacy() != 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(218, "Dispensary", "cobbsknob.php", subentry, 10)); 49 | } 50 | -------------------------------------------------------------------------------- /Source/relay/Guide/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?which=3"; 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(282, image_name, url, ChecklistSubentryMake(title, modifiers, description), $locations[the enormous greater-than sign,the dungeons of doom])); 67 | } 68 | -------------------------------------------------------------------------------- /Source/relay/Guide/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(385, "__item Xiblaxian holo-wrist-puter", "", ChecklistSubentryMake("Xiblaxian item next combat", "", description), -11)); 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(386, "__item Xiblaxian holo-wrist-puter", "", ChecklistSubentryMake(header, "", description), 8)); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Source/relay/Guide/Sets/Events.ash: -------------------------------------------------------------------------------- 1 | import "relay/Guide/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 (!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(381, "__item bundle of "fragrant" herbs", "", ChecklistSubentryMake(pluralise(herb_uses_left, "fragrant herb banish", "fragrant herb banishes"), "", description), 3)); 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(382, "__item nuclear stockpile", "", ChecklistSubentryMake(pluralise(stockpile_uses_left, "nuclear stockpile instakill", "nuclear stockpile instakills"), "", description), 3)); 38 | } 39 | } 40 | } 41 | 42 | void SEventsGenerateResource(ChecklistEntry [int] resource_entries) 43 | { 44 | SCrimbo2015GenerateResource(resource_entries); 45 | } 46 | -------------------------------------------------------------------------------- /Source/relay/Guide/Sets/Florist.ash: -------------------------------------------------------------------------------- 1 | import "relay/Guide/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(402, image_name, "place.php?whichplace=forestvillage&action=fv_friar", subentry, -11)); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Source/relay/Guide/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?which=3"; 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(226, "__item 64735 scroll", url, subentries, 10, $locations[the valley of rof l'm fao])); 61 | } 62 | -------------------------------------------------------------------------------- /Source/relay/Guide/Sets/Sets import.ash: -------------------------------------------------------------------------------- 1 | import "relay/Guide/Support/Library.ash"; 2 | import "relay/Guide/Sets/Semi-rare.ash"; 3 | import "relay/Guide/Sets/Hole in the Sky.ash"; 4 | import "relay/Guide/Sets/Familiars.ash"; 5 | import "relay/Guide/Sets/Dispensary.ash"; 6 | import "relay/Guide/Sets/Skills.ash"; 7 | import "relay/Guide/Sets/Misc Items.ash"; 8 | import "relay/Guide/Sets/Council.ash"; 9 | import "relay/Guide/Sets/Copied Monsters.ash"; 10 | import "relay/Guide/Sets/Pulverise.ash"; 11 | import "relay/Guide/Sets/Aftercore.ash"; 12 | import "relay/Guide/Sets/8-bit Realm.ash"; 13 | import "relay/Guide/Sets/Daily Dungeon.ash"; 14 | import "relay/Guide/Sets/Counters.ash"; 15 | import "relay/Guide/Sets/Bounty Hunter Hunter.ash"; 16 | import "relay/Guide/Sets/Old Level 9 quest.ash"; 17 | import "relay/Guide/Sets/Fax.ash"; 18 | import "relay/Guide/Sets/Dungeons of Doom.ash"; 19 | import "relay/Guide/Sets/Olfaction.ash"; 20 | import "relay/Guide/Sets/Holiday.ash"; 21 | import "relay/Guide/Sets/Reminders.ash"; 22 | import "relay/Guide/Sets/Events.ash"; 23 | import "relay/Guide/Sets/Classes.ash"; 24 | import "relay/Guide/Sets/Equipment.ash"; 25 | import "relay/Guide/Sets/Calculate Universe.ash"; 26 | import "relay/Guide/Sets/PVP.ash"; 27 | import "relay/Guide/Sets/Demon Summon.ash"; 28 | import "relay/Guide/Sets/Area Unlocks.ash"; 29 | import "relay/Guide/Sets/Powerlevel.ash"; 30 | import "relay/Guide/Sets/Florist.ash"; 31 | import "relay/Guide/Sets/Misc Tasks.ash"; 32 | import "relay/Guide/Sets/Sweet Synthesis.ash"; 33 | import "relay/Guide/Sets/Buff Upkeep.ash"; 34 | import "relay/Guide/Sets/Bugs.ash"; 35 | -------------------------------------------------------------------------------- /Source/relay/Guide/Settings.ash: -------------------------------------------------------------------------------- 1 | //These settings are for development. Don't worry about editing them. 2 | string __version = "2.0.7"; 3 | 4 | //Debugging: 5 | boolean __setting_debug_mode = false; 6 | boolean debug = __setting_debug_mode; //if (debug) 7 | boolean __setting_debug_enable_example_mode_in_aftercore = false; //for testing. Will give false information, so don't enable 8 | boolean __setting_debug_show_all_internal_states = false; //displays usable images/__misc_state/__misc_state_string/__misc_state_int/__quest_state 9 | 10 | //Display settings: 11 | boolean __setting_entire_area_clickable = false; 12 | boolean __setting_side_negative_space_is_dark = true; 13 | boolean __setting_newstyle_navbars = true; 14 | boolean __setting_fill_vertical = true; 15 | int __setting_image_width_large = 50; 16 | int __setting_image_width_medium = 50; 17 | int __setting_image_width_small = 30; 18 | 19 | boolean __show_importance_bar = true; 20 | boolean __setting_show_navbar = true; 21 | boolean __setting_navbar_has_proportional_widths = false; //doesn't look very good, remove? 22 | boolean __setting_gray_navbar = true; 23 | boolean __use_table_based_layouts = false; //backup implementation. not compatible with media queries. consider removing? 24 | boolean __use_flexbox_on_checklists = true; 25 | boolean __enable_showhide_feature = true; 26 | 27 | boolean __setting_use_kol_css = false; //images/styles.css 28 | boolean __setting_show_location_bar = true; 29 | boolean __setting_enable_location_popup_box = true; 30 | boolean __setting_location_bar_uses_last_location = false; //nextAdventure otherwise 31 | boolean __setting_location_bar_fixed_layout = true; 32 | boolean __setting_location_bar_limit_max_width = true; 33 | float __setting_location_bar_max_width_per_entry = 0.35; 34 | boolean __setting_small_size_uses_full_width = false; //implemented, but disabled - doesn't look amazing. reduced indention width instead to compensate 35 | boolean __setting_enable_outputting_all_numberology_options = true; 36 | 37 | //Do not use directly; use var() calls 38 | string __setting_unavailable_colour = "#7F7F7F"; //var(--unavailable_colour) 39 | string __setting_line_colour = "#B2B2B2"; //var(--line_colour) 40 | string __setting_dark_colour = "#C0C0C0"; //var(--dark_colour) 41 | string __setting_modifier_colour = "#404040"; //var(--modifier_colour) 42 | string __setting_navbar_background_colour = "#FFFFFF"; //var(--navbar_background_colour) 43 | string __setting_page_background_colour = "#F7F7F7"; //var(--page_background_colour) 44 | string __setting_main_content_background_colour = "#FFFFFF"; //var(--main_content_background_colour) 45 | string __setting_main_content_text_colour = "#000000"; //var(--main_content_text_colour) 46 | string __setting_hover_alternate_colour = "#CCCCCC"; //var(--hover_alternate_colour) 47 | 48 | //Inverted, dark mode versions of above: 49 | string __setting_unavailable_colour_dark = "#7F7F7F"; //var(--unavailable_colour) 50 | string __setting_line_colour_dark = "#4D4D4D"; //var(--line_colour) 51 | string __setting_dark_colour_dark = "#3F3F3F"; //var(--dark_colour) 52 | string __setting_modifier_colour_dark = "#BFBFBF"; //var(--modifier_colour) 53 | string __setting_navbar_background_colour_dark = "#000000"; //var(--navbar_background_colour) 54 | string __setting_page_background_colour_dark = "#3F3F3F"; //var(--page_background_colour) 55 | string __setting_main_content_background_colour_dark = "#000000"; //var(--main_content_background_colour) 56 | string __setting_main_content_text_colour_dark = "#FFFFFF"; //var(--main_content_text_colour) 57 | string __setting_hover_alternate_colour_dark = "#333333"; //var(--hover_alternate_colour) 58 | 59 | string __setting_media_query_large_size = "@media (min-width: 500px)"; 60 | string __setting_media_query_medium_size = "@media (min-width: 350px) and (max-width: 500px)"; 61 | string __setting_media_query_small_size = "@media (max-width: 350px) and (min-width: 225px)"; 62 | string __setting_media_query_tiny_size = "@media (max-width: 225px)"; 63 | 64 | float __setting_navbar_height_in_em = 2.3; 65 | string __setting_navbar_height = __setting_navbar_height_in_em + "em"; 66 | int __setting_horizontal_width = 600; 67 | boolean __setting_ios_appearance = false; //no don't 68 | string __relay_filename; 69 | -------------------------------------------------------------------------------- /Source/relay/Guide/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/Guide/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/Guide/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/Guide/Support/Equipment Requirement.ash: -------------------------------------------------------------------------------- 1 | import "relay/Guide/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/Guide/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 | } 32 | -------------------------------------------------------------------------------- /Source/relay/Guide/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/Guide/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/Guide/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] blocklist) 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 && !(blocklist 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] blocklist) 112 | { 113 | return ItemFilterGetPotionsCouldPullToAddToNumericModifier(listMake(modifier), minimum_modifier, blocklist); 114 | } 115 | -------------------------------------------------------------------------------- /Source/relay/Guide/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/Guide/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/Guide/Support/Statics 2.ash: -------------------------------------------------------------------------------- 1 | import "relay/Guide/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/Guide/Tasks.ash: -------------------------------------------------------------------------------- 1 | import "relay/Guide/Support/Checklist.ash" 2 | import "relay/Guide/Support/Library.ash" 3 | import "relay/Guide/Plants.ash" 4 | import "relay/Guide/Support/HTML.ash" 5 | import "relay/Guide/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_Guide.ash: -------------------------------------------------------------------------------- 1 | //This script and its support scripts are in the public domain. 2 | 3 | since 20.6; 4 | import "relay/Guide/Main.ash" 5 | 6 | void main() 7 | { 8 | __relay_filename = __FILE__; 9 | runMain(); 10 | } 11 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "root_directory":"Release" 3 | } 4 | --------------------------------------------------------------------------------