 532cff1334
			
		
	
	532cff1334
	
	
	
		
			
			* ALTTP: Massive game tracker update. * Adds dropdowns separated by region for each location and its checked status. * Adds Bombs for bombless start seeds. * Adds Triforce Pieces to track. * Update icon image URLs to match in-game closer. * Fix issue with grouped progressive items. * Couple missed points. * Another edge case with details being refreshed. * Remove old commented out CSS * Consolidate a table and move an erroneous location in wrong region. * ALTTP: Updates and refactors to multi-tracker and player tracker. * Removed some missed commented out code. * Add triforce to prepare inventory logic.
		
			
				
	
	
		
			220 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			220 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| {% set icons = {
 | |
|     "Blue Shield": "https://www.zeldadungeon.net/wiki/images/thumb/c/c3/FightersShield-ALttP-Sprite.png/100px-FightersShield-ALttP-Sprite.png",
 | |
|     "Red Shield": "https://www.zeldadungeon.net/wiki/images/thumb/9/9e/FireShield-ALttP-Sprite.png/111px-FireShield-ALttP-Sprite.png",
 | |
|     "Mirror Shield": "https://www.zeldadungeon.net/wiki/images/thumb/e/e3/MirrorShield-ALttP-Sprite.png/105px-MirrorShield-ALttP-Sprite.png",
 | |
|     "Fighter Sword": "https://upload.wikimedia.org/wikibooks/en/8/8e/Zelda_ALttP_item_L-1_Sword.png",
 | |
|     "Master Sword": "https://upload.wikimedia.org/wikibooks/en/8/87/BS_Zelda_AST_item_L-2_Sword.png",
 | |
|     "Tempered Sword": "https://upload.wikimedia.org/wikibooks/en/c/cc/BS_Zelda_AST_item_L-3_Sword.png",
 | |
|     "Golden Sword": "https://upload.wikimedia.org/wikibooks/en/4/40/BS_Zelda_AST_item_L-4_Sword.png",
 | |
|     "Bow": "https://www.zeldadungeon.net/wiki/images/thumb/8/8c/BowArrows-ALttP-Sprite.png/120px-BowArrows-ALttP-Sprite.png",
 | |
|     "Silver Bow": "https://upload.wikimedia.org/wikibooks/en/6/69/Zelda_ALttP_item_Silver_Arrows.png",
 | |
|     "Green Mail": "https://upload.wikimedia.org/wikibooks/en/d/dd/Zelda_ALttP_item_Green_Mail.png",
 | |
|     "Blue Mail": "https://upload.wikimedia.org/wikibooks/en/b/b5/Zelda_ALttP_item_Blue_Mail.png",
 | |
|     "Red Mail": "https://upload.wikimedia.org/wikibooks/en/d/db/Zelda_ALttP_item_Red_Mail.png",
 | |
|     "Power Glove": "https://www.zeldadungeon.net/wiki/images/thumb/4/41/PowerGlove-ALttP-Sprite.png/105px-PowerGlove-ALttP-Sprite.png",
 | |
|     "Titan Mitts": "https://www.zeldadungeon.net/wiki/images/thumb/7/75/TitanMitt-ALttP-Sprite.png/105px-TitanMitt-ALttP-Sprite.png",
 | |
|     "Pegasus Boots": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/e/ed/ALttP_Pegasus_Shoes_Sprite.png",
 | |
|     "Flippers": "https://www.zeldadungeon.net/wiki/images/thumb/b/bc/ZoraFlippers-ALttP-Sprite.png/112px-ZoraFlippers-ALttP-Sprite.png",
 | |
|     "Moon Pearl": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/6/63/ALttP_Moon_Pearl_Sprite.png",
 | |
|     "Blue Boomerang": "https://www.zeldadungeon.net/wiki/images/thumb/f/f0/Boomerang-ALttP-Sprite.png/86px-Boomerang-ALttP-Sprite.png",
 | |
|     "Red Boomerang": "https://www.zeldadungeon.net/wiki/images/thumb/3/3c/MagicalBoomerang-ALttP-Sprite.png/86px-MagicalBoomerang-ALttP-Sprite.png",
 | |
|     "Hookshot": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/2/24/Hookshot.png",
 | |
|     "Mushroom": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/3/35/ALttP_Mushroom_Sprite.png",
 | |
|     "Magic Powder": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/e/e5/ALttP_Magic_Powder_Sprite.png",
 | |
|     "Fire Rod": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/d/d6/FireRod.png",
 | |
|     "Ice Rod": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/d/d7/ALttP_Ice_Rod_Sprite.png",
 | |
|     "Bombos": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/8/8c/ALttP_Bombos_Medallion_Sprite.png",
 | |
|     "Ether": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/3/3c/Ether.png",
 | |
|     "Quake": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/5/56/ALttP_Quake_Medallion_Sprite.png",
 | |
|     "Lamp": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/6/63/ALttP_Lantern_Sprite.png",
 | |
|     "Hammer": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/d/d1/ALttP_Hammer_Sprite.png",
 | |
|     "Shovel": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/c/c4/ALttP_Shovel_Sprite.png",
 | |
|     "Flute": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/d/db/Flute.png",
 | |
|     "Bug Catching Net": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/5/54/Bug-CatchingNet.png",
 | |
|     "Book of Mudora": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/2/22/ALttP_Book_of_Mudora_Sprite.png",
 | |
|     "Bottles": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/e/ef/ALttP_Magic_Bottle_Sprite.png",
 | |
|     "Cane of Somaria": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/e/e1/ALttP_Cane_of_Somaria_Sprite.png",
 | |
|     "Cane of Byrna": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/b/bc/ALttP_Cane_of_Byrna_Sprite.png",
 | |
|     "Cape": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/1/1c/ALttP_Magic_Cape_Sprite.png",
 | |
|     "Magic Mirror": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/e/e5/ALttP_Magic_Mirror_Sprite.png",
 | |
|     "Triforce": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/4/4e/TriforceALttPTitle.png",
 | |
|     "Triforce Piece": "https://www.zeldadungeon.net/wiki/images/thumb/5/54/Triforce_Fragment_-_BS_Zelda.png/62px-Triforce_Fragment_-_BS_Zelda.png",
 | |
|     "Bombs": "https://static.wikia.nocookie.net/zelda_gamepedia_en/images/3/38/ALttP_Bomb_Sprite.png",
 | |
|     "Small Key": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/f/f1/ALttP_Small_Key_Sprite.png",
 | |
|     "Big Key": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/3/33/ALttP_Big_Key_Sprite.png",
 | |
| } %}
 | |
| 
 | |
| {% set inventory_order = [
 | |
|     "Progressive Bow", "Boomerangs",      "Hookshot",          "Bombs",            "Mushroom",       "Magic Powder",
 | |
|     "Fire Rod",        "Ice Rod",         "Bombos",            "Ether",            "Quake",          "Progressive Mail",
 | |
|     "Lamp",            "Hammer",          "Flute",             "Bug Catching Net", "Book of Mudora", "Progressive Shield",
 | |
|     "Bottles",         "Cane of Somaria", "Cane of Byrna",     "Cape",             "Magic Mirror",   "Progressive Sword",
 | |
|     "Shovel",          "Pegasus Boots",   "Progressive Glove", "Flippers",         "Moon Pearl",     "Triforce Piece",
 | |
| ] %}
 | |
| 
 | |
| {# Most have a duplicated 0th entry for when we have none of that item to still load the correct icon/name. #}
 | |
| {% set progressive_order = {
 | |
|     "Progressive Bow":    ["Bow", "Bow", "Silver Bow"],
 | |
|     "Progressive Mail":   ["Green Mail", "Blue Mail", "Red Mail"],
 | |
|     "Progressive Shield": ["Blue Shield", "Blue Shield", "Red Shield", "Mirror Shield"],
 | |
|     "Progressive Sword":  ["Fighter Sword", "Fighter Sword", "Master Sword", "Tempered Sword", "Golden Sword"],
 | |
|     "Progressive Glove":  ["Power Glove", "Power Glove", "Titan Mitts"],
 | |
| } %}
 | |
| 
 | |
| {% set dungeon_keys = {
 | |
|     "Hyrule Castle": ("Small Key (Hyrule Castle)", "Big Key (Hyrule Castle)"),
 | |
|     "Agahnims Tower": ("Small Key (Agahnims Tower)", "Big Key (Agahnims Tower)"),
 | |
|     "Eastern Palace": ("Small Key (Eastern Palace)", "Big Key (Eastern Palace)"),
 | |
|     "Desert Palace": ("Small Key (Desert Palace)", "Big Key (Desert Palace)"),
 | |
|     "Tower of Hera": ("Small Key (Tower of Hera)", "Big Key (Tower of Hera)"),
 | |
|     "Palace of Darkness": ("Small Key (Palace of Darkness)", "Big Key (Palace of Darkness)"),
 | |
|     "Swamp Palace": ("Small Key (Swamp Palace)", "Big Key (Swamp Palace)"),
 | |
|     "Thieves Town": ("Small Key (Thieves Town)", "Big Key (Thieves Town)"),
 | |
|     "Skull Woods": ("Small Key (Skull Woods)", "Big Key (Skull Woods)"),
 | |
|     "Ice Palace": ("Small Key (Ice Palace)", "Big Key (Ice Palace)"),
 | |
|     "Misery Mire": ("Small Key (Misery Mire)", "Big Key (Misery Mire)"),
 | |
|     "Turtle Rock": ("Small Key (Turtle Rock)", "Big Key (Turtle Rock)"),
 | |
|     "Ganons Tower": ("Small Key (Ganons Tower)", "Big Key (Ganons Tower)"),
 | |
| } %}
 | |
| 
 | |
| <!doctype html>
 | |
| <html lang="en">
 | |
| <head>
 | |
|     <meta charset="UTF-8">
 | |
|     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | |
|     <title>{{ player_name }}'s Tracker</title>
 | |
|     <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='styles/tracker__ALinkToThePast.css') }}">
 | |
| </head>
 | |
| 
 | |
| <body>
 | |
|     {# TODO: Replace this with a proper wrapper for each tracker when developing TrackerAPI. #}
 | |
|     <div style="margin-bottom: 0.5rem">
 | |
|         <a href="{{ url_for("get_generic_game_tracker", tracker=room.tracker, tracked_team=team, tracked_player=player) }}">Switch To Generic Tracker</a>
 | |
|     </div>
 | |
| 
 | |
|     <div class="tracker-container">
 | |
|         {# Inventory Grid #}
 | |
|         <div class="inventory-grid">
 | |
|             {% for item in inventory_order %}
 | |
|                 {% if item in progressive_order %}
 | |
|                     {% set non_prog_item = progressive_order[item][inventory[item]] %}
 | |
|                     <div class="item">
 | |
|                         <img
 | |
|                             src="{{ icons[non_prog_item] }}"
 | |
|                             alt="{{ non_prog_item }}"
 | |
|                             title="{{ non_prog_item }}"
 | |
|                             {# Progressive Mail gets a special exception, since it starts displaying green mail. #}
 | |
|                             class="{{ 'missing' if (item not in inventory or inventory[item] == 0) and item != 'Progressive Mail' }}"
 | |
|                         >
 | |
|                     </div>
 | |
|                 {% elif item == "Boomerangs" %}
 | |
|                     <div class="dual-item">
 | |
|                         <img
 | |
|                             src="{{ icons['Blue Boomerang'] }}"
 | |
|                             alt="Blue Boomerang"
 | |
|                             title="Blue Boomerang"
 | |
|                             class="{{ 'missing' if 'Blue Boomerang' not in inventory }}"
 | |
|                         >
 | |
|                         <img
 | |
|                             src="{{ icons['Red Boomerang'] }}"
 | |
|                             alt="Red Boomerang"
 | |
|                             title="Red Boomerang"
 | |
|                             class="{{ 'missing' if 'Red Boomerang' not in inventory }}"
 | |
|                         >
 | |
|                     </div>
 | |
|                 {% else %}
 | |
|                     <div class="item {{ 'hidden' if item == 'Triforce Piece' and inventory['Triforce Piece'] == 0 }}">
 | |
|                         <img
 | |
|                             src="{{ icons[item] }}"
 | |
|                             alt="{{ item }}"
 | |
|                             title="{{ item }}"
 | |
|                             class="{{ 'missing' if item not in inventory or inventory[item] == 0 }}"
 | |
|                         >
 | |
|                         {% if item == "Bottles" or item == "Triforce Piece" %}
 | |
|                             <div class="quantity">{{ inventory[item] }}</div>
 | |
|                         {% endif %}
 | |
|                     </div>
 | |
|                 {% endif %}
 | |
|             {% endfor %}
 | |
|         </div>
 | |
| 
 | |
|         <div class="regions-list">
 | |
|             <div class="region region-header">
 | |
|                 <div></div>
 | |
|                 <div></div>
 | |
|                 <div><img src="{{ icons['Small Key'] }}" alt="SK" title="Small Keys"></div>
 | |
|                 <div><img src="{{ icons['Big Key'] }}" alt="BK" title="Big Keys"></div>
 | |
|             </div>
 | |
| 
 | |
|             {% for region_name in known_regions %}
 | |
|                 {% set region_data = regions[region_name] %}
 | |
|                 {% if region_data["locations"] | length > 0 %}
 | |
|                     <details class="region-details">
 | |
|                         <summary>
 | |
|                             {% if region_name in dungeon_keys %}
 | |
|                                 <div class="region">
 | |
|                                     <span>{{ region_name }}</span>
 | |
|                                     <span>{{ region_data["checked"] }} / {{ region_data["locations"] | length }}</span>
 | |
|                                     <span>{{ inventory[dungeon_keys[region_name][0]] }}</span>
 | |
|                                     <span>
 | |
|                                         {% if region_name == "Agahnims Tower" %}
 | |
|                                             —
 | |
|                                         {% elif inventory[dungeon_keys[region_name][1]] %}
 | |
|                                             ✔
 | |
|                                         {% endif %}
 | |
|                                     </span>
 | |
|                                 </div>
 | |
|                             {% else %}
 | |
|                                 <div class="region">
 | |
|                                     <span>{{ region_name }}</span>
 | |
|                                     <span>{{ region_data["checked"] }} / {{ region_data["locations"] | length }}</span>
 | |
|                                     <span>—</span>
 | |
|                                     <span>—</span>
 | |
|                                 </div>
 | |
|                             {% endif %}
 | |
|                         </summary>
 | |
| 
 | |
|                         <div class="location-rows">
 | |
|                             {% for location, checked in region_data["locations"] %}
 | |
|                                 <div>{{ location }}</div>
 | |
|                                 <div>{% if checked %}✔{% endif %}</div>
 | |
|                             {% endfor %}
 | |
|                         </div>
 | |
|                     </details>
 | |
|                 {% endif %}
 | |
|             {% endfor %}
 | |
|         </div>
 | |
|     </div>
 | |
| 
 | |
|     <script>
 | |
|         const parser = new DOMParser();
 | |
|         const interval = 15_000;
 | |
| 
 | |
|         window.addEventListener("load", () => {
 | |
|             setInterval(() => updateTracker()
 | |
|                 .then(() => console.log("Refreshed tracker."))
 | |
|                 .catch(console.error), interval);
 | |
|         });
 | |
| 
 | |
|         async function updateTracker() {
 | |
|             const response = await fetch(`${window.location}`);
 | |
|             if (!response.ok) {
 | |
|                 throw new Error(`Failed to fetch tracker update from ${window.location}. Received response: ${response.statusText}`);
 | |
|             }
 | |
| 
 | |
|             const fakeDOM = parser.parseFromString(await response.text(), "text/html");
 | |
|             document.querySelector(".inventory-grid").innerHTML = fakeDOM.querySelector(".inventory-grid").innerHTML;
 | |
| 
 | |
|             const regionDetailElements = document.querySelectorAll(".region-details");
 | |
|             const fakeDetailElements = fakeDOM.querySelectorAll(".region-details");
 | |
| 
 | |
|             for (let i = 0; i < regionDetailElements.length; ++i) {
 | |
|                 const isOpen = regionDetailElements[i].open;
 | |
|                 regionDetailElements[i].innerHTML = fakeDetailElements[i].innerHTML;
 | |
|                 regionDetailElements[i].open = isOpen;
 | |
|             }
 | |
|         }
 | |
|     </script>
 | |
| </body>
 | |
| </html>
 |