ALTTP: Updates to player-specific game tracker. (#3133)
This commit is contained in:
		
							parent
							
								
									a4acdb6ddf
								
							
						
					
					
						commit
						0a1ce5b7d8
					
				|  | @ -1,20 +0,0 @@ | |||
| window.addEventListener('load', () => { | ||||
|   const url = window.location; | ||||
|   setInterval(() => { | ||||
|     const ajax = new XMLHttpRequest(); | ||||
|     ajax.onreadystatechange = () => { | ||||
|       if (ajax.readyState !== 4) { return; } | ||||
| 
 | ||||
|       // Create a fake DOM using the returned HTML
 | ||||
|       const domParser = new DOMParser(); | ||||
|       const fakeDOM = domParser.parseFromString(ajax.responseText, 'text/html'); | ||||
| 
 | ||||
|       // Update item and location trackers
 | ||||
|       document.getElementById('inventory-table').innerHTML = fakeDOM.getElementById('inventory-table').innerHTML; | ||||
|       document.getElementById('location-table').innerHTML = fakeDOM.getElementById('location-table').innerHTML; | ||||
| 
 | ||||
|     }; | ||||
|     ajax.open('GET', url); | ||||
|     ajax.send(); | ||||
|   }, 15000) | ||||
| }); | ||||
|  | @ -1,75 +0,0 @@ | |||
| #player-tracker-wrapper{ | ||||
|     margin: 0; | ||||
|     font-family: LexendDeca-Light, sans-serif; | ||||
|     color: white; | ||||
|     font-size: 14px; | ||||
| } | ||||
| 
 | ||||
| #inventory-table{ | ||||
|     border-top: 2px solid #000000; | ||||
|     border-left: 2px solid #000000; | ||||
|     border-right: 2px solid #000000; | ||||
|     border-top-left-radius: 4px; | ||||
|     border-top-right-radius: 4px; | ||||
|     padding: 3px 3px 10px; | ||||
|     width: 284px; | ||||
|     background-color: #42b149; | ||||
| } | ||||
| 
 | ||||
| #inventory-table td{ | ||||
|     width: 40px; | ||||
|     height: 40px; | ||||
|     text-align: center; | ||||
|     vertical-align: middle; | ||||
| } | ||||
| 
 | ||||
| #inventory-table img{ | ||||
|     height: 100%; | ||||
|     max-width: 40px; | ||||
|     max-height: 40px; | ||||
|     filter: grayscale(100%) contrast(75%) brightness(75%); | ||||
| } | ||||
| 
 | ||||
| #inventory-table img.acquired{ | ||||
|     filter: none; | ||||
| } | ||||
| 
 | ||||
| #inventory-table img.powder-fix{ | ||||
|     width: 35px; | ||||
|     height: 35px; | ||||
| } | ||||
| 
 | ||||
| #location-table{ | ||||
|     width: 284px; | ||||
|     border-left: 2px solid #000000; | ||||
|     border-right: 2px solid #000000; | ||||
|     border-bottom: 2px solid #000000; | ||||
|     border-bottom-left-radius: 4px; | ||||
|     border-bottom-right-radius: 4px; | ||||
|     background-color: #42b149; | ||||
|     padding: 0 3px 3px; | ||||
| } | ||||
| 
 | ||||
| #location-table th{ | ||||
|     vertical-align: middle; | ||||
|     text-align: center; | ||||
|     padding-right: 10px; | ||||
| } | ||||
| 
 | ||||
| #location-table td{ | ||||
|     padding-top: 2px; | ||||
|     padding-bottom: 2px; | ||||
|     padding-right: 5px; | ||||
|     line-height: 20px; | ||||
| } | ||||
| 
 | ||||
| #location-table td.counter{ | ||||
|     padding-right: 8px; | ||||
|     text-align: right; | ||||
| } | ||||
| 
 | ||||
| #location-table img{ | ||||
|     height: 100%; | ||||
|     max-width: 30px; | ||||
|     max-height: 30px; | ||||
| } | ||||
|  | @ -0,0 +1,142 @@ | |||
| @import url('https://fonts.googleapis.com/css2?family=Lexend+Deca:wght@100..900&display=swap'); | ||||
| 
 | ||||
| .tracker-container { | ||||
|     width: 440px; | ||||
|     box-sizing: border-box; | ||||
|     font-family: "Lexend Deca", Arial, Helvetica, sans-serif; | ||||
|     border: 2px solid black; | ||||
|     border-radius: 4px; | ||||
|     resize: both; | ||||
| 
 | ||||
|     background-color: #42b149; | ||||
|     color: white; | ||||
| } | ||||
| 
 | ||||
| .hidden { | ||||
|     visibility: hidden; | ||||
| } | ||||
| 
 | ||||
| /** Inventory Grid ****************************************************************************************************/ | ||||
| .inventory-grid { | ||||
|     display: grid; | ||||
|     grid-template-columns: repeat(6, minmax(0, 1fr)); | ||||
|     padding: 1rem; | ||||
|     gap: 1rem; | ||||
| } | ||||
| 
 | ||||
| .inventory-grid .item { | ||||
|     position: relative; | ||||
|     display: flex; | ||||
|     justify-content: center; | ||||
|     height: 48px; | ||||
| } | ||||
| 
 | ||||
| .inventory-grid .dual-item { | ||||
|     display: flex; | ||||
|     justify-content: center; | ||||
| } | ||||
| 
 | ||||
| .inventory-grid .missing { | ||||
|     /* Missing items will be in full grayscale to signify "uncollected". */ | ||||
|     filter: grayscale(100%) contrast(75%) brightness(75%); | ||||
| } | ||||
| 
 | ||||
| .inventory-grid .item img, | ||||
| .inventory-grid .dual-item img { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     text-align: center; | ||||
|     font-size: 0.8rem; | ||||
|     text-shadow: 0 1px 2px black; | ||||
|     font-weight: bold; | ||||
|     image-rendering: crisp-edges; | ||||
|     background-size: contain; | ||||
|     background-repeat: no-repeat; | ||||
| } | ||||
| 
 | ||||
| .inventory-grid .dual-item img { | ||||
|     height: 48px; | ||||
|     margin: 0 -4px; | ||||
| } | ||||
| 
 | ||||
| .inventory-grid .dual-item img:first-child { | ||||
|     align-self: flex-end; | ||||
| } | ||||
| 
 | ||||
| .inventory-grid .item .quantity { | ||||
|     position: absolute; | ||||
|     bottom: 0; | ||||
|     right: 0; | ||||
|     text-align: right; | ||||
|     font-weight: 600; | ||||
|     font-size: 1.75rem; | ||||
|     line-height: 1.75rem; | ||||
|     text-shadow: | ||||
|         -1px -1px 0 #000, | ||||
|          1px -1px 0 #000, | ||||
|         -1px 1px 0 #000, | ||||
|          1px 1px 0 #000; | ||||
|     user-select: none; | ||||
| } | ||||
| 
 | ||||
| /** Regions List ******************************************************************************************************/ | ||||
| .regions-list { | ||||
|     padding: 1rem; | ||||
| } | ||||
| 
 | ||||
| .regions-list summary { | ||||
|     list-style: none; | ||||
|     display: flex; | ||||
|     gap: 0.5rem; | ||||
|     cursor: pointer; | ||||
| } | ||||
| 
 | ||||
| .regions-list summary::before { | ||||
|     content: "⯈"; | ||||
|     width: 1em; | ||||
|     flex-shrink: 0; | ||||
| } | ||||
| 
 | ||||
| .regions-list details { | ||||
|     font-weight: 300; | ||||
| } | ||||
| 
 | ||||
| .regions-list details[open] > summary::before { | ||||
|     content: "⯆"; | ||||
| } | ||||
| 
 | ||||
| .regions-list .region { | ||||
|     width: 100%; | ||||
|     display: grid; | ||||
|     grid-template-columns: 20fr 8fr 2fr 2fr; | ||||
|     align-items: center; | ||||
|     gap: 4px; | ||||
|     text-align: center; | ||||
|     font-weight: 300; | ||||
|     box-sizing: border-box; | ||||
| } | ||||
| 
 | ||||
| .regions-list .region :first-child { | ||||
|     text-align: left; | ||||
|     font-weight: 500; | ||||
| } | ||||
| 
 | ||||
| .regions-list .region.region-header { | ||||
|     margin-left: 24px; | ||||
|     width: calc(100% - 24px); | ||||
|     padding: 2px; | ||||
| } | ||||
| 
 | ||||
| .regions-list .location-rows { | ||||
|     border-top: 1px solid white; | ||||
|     display: grid; | ||||
|     grid-template-columns: auto 32px; | ||||
|     font-weight: 300; | ||||
|     padding: 2px 8px; | ||||
|     margin-top: 4px; | ||||
|     font-size: 0.8rem; | ||||
| } | ||||
| 
 | ||||
| .regions-list .location-rows :nth-child(even) { | ||||
|     text-align: right; | ||||
| } | ||||
|  | @ -1,86 +0,0 @@ | |||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <title>{{ player_name }}'s Tracker</title> | ||||
|     <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename="styles/globalStyles.css") }}"/> | ||||
|     <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename="styles/lttp-tracker.css") }}"/> | ||||
|     <script type="application/ecmascript" src="{{ url_for('static', filename="assets/lttp-tracker.js") }}"></script> | ||||
| </head> | ||||
| 
 | ||||
| <body> | ||||
|     <div id="player-tracker-wrapper" data-tracker="{{ room.tracker|suuid }}"> | ||||
|         <table id="inventory-table"> | ||||
|             <tr> | ||||
|                 <td><img src="{{ bow_url }}" class="{{ 'acquired' if bow_acquired }}" /></td> | ||||
|                 <td><img src="{{ icons["Blue Boomerang"] }}" class="{{ 'acquired' if 'Blue Boomerang' in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Red Boomerang"] }}" class="{{ 'acquired' if 'Red Boomerang' in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Hookshot"] }}" class="{{ 'acquired' if 'Hookshot' in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Magic Powder"] }}" class="powder-fix {{ 'acquired' if 'Magic Powder' in acquired_items }}" /></td> | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <td><img src="{{ icons["Fire Rod"] }}" class="{{ 'acquired' if "Fire Rod" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Ice Rod"] }}" class="{{ 'acquired' if "Ice Rod" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Bombos"] }}" class="{{ 'acquired' if "Bombos" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Ether"] }}" class="{{ 'acquired' if "Ether" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Quake"] }}" class="{{ 'acquired' if "Quake" in acquired_items }}" /></td> | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <td><img src="{{ icons["Lamp"] }}" class="{{ 'acquired' if "Lamp" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Hammer"] }}" class="{{ 'acquired' if "Hammer" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Flute"] }}" class="{{ 'acquired' if "Flute" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Bug Catching Net"] }}" class="{{ 'acquired' if "Bug Catching Net" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Book of Mudora"] }}" class="{{ 'acquired' if "Book of Mudora" in acquired_items }}" /></td> | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <td><img src="{{ icons["Bottle"] }}" class="{{ 'acquired' if "Bottle" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Cane of Somaria"] }}" class="{{ 'acquired' if "Cane of Somaria" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Cane of Byrna"] }}" class="{{ 'acquired' if "Cane of Byrna" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Cape"] }}" class="{{ 'acquired' if "Cape" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Magic Mirror"] }}" class="{{ 'acquired' if "Magic Mirror" in acquired_items }}" /></td> | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <td><img src="{{ icons["Pegasus Boots"] }}" class="{{ 'acquired' if "Pegasus Boots" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ glove_url }}" class="{{ 'acquired' if glove_acquired }}" /></td> | ||||
|                 <td><img src="{{ icons["Flippers"] }}" class="{{ 'acquired' if "Flippers" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Moon Pearl"] }}" class="{{ 'acquired' if "Moon Pearl" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Mushroom"] }}" class="{{ 'acquired' if "Mushroom" in acquired_items }}" /></td> | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <td><img src="{{ sword_url }}" class="{{ 'acquired' if sword_acquired }}" /></td> | ||||
|                 <td><img src="{{ shield_url }}" class="{{ 'acquired' if shield_acquired }}" /></td> | ||||
|                 <td><img src="{{ mail_url }}" class="acquired" /></td> | ||||
|                 <td><img src="{{ icons["Shovel"] }}" class="{{ 'acquired' if "Shovel" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Triforce"] }}" class="{{ 'acquired' if "Triforce" in acquired_items }}" /></td> | ||||
|             </tr> | ||||
|         </table> | ||||
|         <table id="location-table"> | ||||
|             <tr> | ||||
|                 <th></th> | ||||
|                 <th class="counter"><img src="{{ icons["Chest"] }}" /></th> | ||||
|                 {% if key_locations and "Universal" not in key_locations %} | ||||
|                     <th class="counter"><img src="{{ icons["Small Key"] }}" /></th> | ||||
|                 {% endif %} | ||||
|                 {% if big_key_locations %} | ||||
|                     <th><img src="{{ icons["Big Key"] }}" /></th> | ||||
|                 {% endif %} | ||||
|             </tr> | ||||
|             {% for area in sp_areas %} | ||||
|                 <tr> | ||||
|                     <td>{{ area }}</td> | ||||
|                     <td class="counter">{{ checks_done[area] }} / {{ checks_in_area[area] }}</td> | ||||
|                     {% if key_locations and "Universal" not in key_locations %} | ||||
|                         <td class="counter"> | ||||
|                             {{ inventory[small_key_ids[area]] if area in key_locations else '—' }} | ||||
|                         </td> | ||||
|                     {% endif %} | ||||
|                     {% if big_key_locations %} | ||||
|                         <td> | ||||
|                             {{ '✔' if area in big_key_locations and inventory[big_key_ids[area]] else ('—' if area not in big_key_locations else '') }} | ||||
|                         </td> | ||||
|                     {% endif %} | ||||
|                 </tr> | ||||
|             {% endfor %} | ||||
|         </table> | ||||
|     </div> | ||||
| </body> | ||||
| </html> | ||||
|  | @ -1,73 +1,89 @@ | |||
| {%- set icons = { | ||||
|     "Blue Shield": "https://www.zeldadungeon.net/wiki/images/8/85/Fighters-Shield.png", | ||||
|     "Red Shield": "https://www.zeldadungeon.net/wiki/images/5/55/Fire-Shield.png", | ||||
|     "Mirror Shield": "https://www.zeldadungeon.net/wiki/images/8/84/Mirror-Shield.png", | ||||
|     "Fighter Sword": "https://oyster.ignimgs.com/mediawiki/apis.ign.com/the-legend-of-zelda-a-link-to-the-past/4/40/SFighterSword.png?width=1920", | ||||
|     "Master Sword": "https://oyster.ignimgs.com/mediawiki/apis.ign.com/the-legend-of-zelda-a-link-to-the-past/6/65/SMasterSword.png?width=1920", | ||||
|     "Tempered Sword": "https://oyster.ignimgs.com/mediawiki/apis.ign.com/the-legend-of-zelda-a-link-to-the-past/9/92/STemperedSword.png?width=1920", | ||||
|     "Golden Sword": "https://oyster.ignimgs.com/mediawiki/apis.ign.com/the-legend-of-zelda-a-link-to-the-past/2/28/SGoldenSword.png?width=1920", | ||||
|     "Bow": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/b/bc/ALttP_Bow_%26_Arrows_Sprite.png?version=5f85a70e6366bf473544ef93b274f74c", | ||||
|     "Silver Bow": "https://oyster.ignimgs.com/mediawiki/apis.ign.com/the-legend-of-zelda-a-link-to-the-past/6/65/Bow.png?width=1920", | ||||
|     "Green Mail": "https://oyster.ignimgs.com/mediawiki/apis.ign.com/the-legend-of-zelda-a-link-to-the-past/c/c9/SGreenTunic.png?width=1920", | ||||
|     "Blue Mail": "https://oyster.ignimgs.com/mediawiki/apis.ign.com/the-legend-of-zelda-a-link-to-the-past/9/98/SBlueTunic.png?width=1920", | ||||
|     "Red Mail": "https://oyster.ignimgs.com/mediawiki/apis.ign.com/the-legend-of-zelda-a-link-to-the-past/7/74/SRedTunic.png?width=1920", | ||||
|     "Power Glove": "https://oyster.ignimgs.com/mediawiki/apis.ign.com/the-legend-of-zelda-a-link-to-the-past/f/f5/SPowerGlove.png?width=1920", | ||||
|     "Titan Mitts": "https://oyster.ignimgs.com/mediawiki/apis.ign.com/the-legend-of-zelda-a-link-to-the-past/c/c1/STitanMitt.png?width=1920", | ||||
|     "Progressive Sword": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/c/cc/ALttP_Master_Sword_Sprite.png?version=55869db2a20e157cd3b5c8f556097725", | ||||
|     "Pegasus Boots": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/e/ed/ALttP_Pegasus_Shoes_Sprite.png?version=405f42f97240c9dcd2b71ffc4bebc7f9", | ||||
|     "Progressive Glove": "https://oyster.ignimgs.com/mediawiki/apis.ign.com/the-legend-of-zelda-a-link-to-the-past/c/c1/STitanMitt.png?width=1920", | ||||
|     "Flippers": "https://oyster.ignimgs.com/mediawiki/apis.ign.com/the-legend-of-zelda-a-link-to-the-past/4/4c/ZoraFlippers.png?width=1920", | ||||
|     "Moon Pearl": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/6/63/ALttP_Moon_Pearl_Sprite.png?version=d601542d5abcc3e006ee163254bea77e", | ||||
|     "Progressive Bow": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/b/bc/ALttP_Bow_%26_Arrows_Sprite.png?version=cfb7648b3714cccc80e2b17b2adf00ed", | ||||
|     "Blue Boomerang": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/c/c3/ALttP_Boomerang_Sprite.png?version=96127d163759395eb510b81a556d500e", | ||||
|     "Red Boomerang": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/b/b9/ALttP_Magical_Boomerang_Sprite.png?version=47cddce7a07bc3e4c2c10727b491f400", | ||||
|     "Hookshot": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/2/24/Hookshot.png?version=c90bc8e07a52e8090377bd6ef854c18b", | ||||
|     "Mushroom": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/3/35/ALttP_Mushroom_Sprite.png?version=1f1acb30d71bd96b60a3491e54bbfe59", | ||||
|     "Magic Powder": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/e/e5/ALttP_Magic_Powder_Sprite.png?version=c24e38effbd4f80496d35830ce8ff4ec", | ||||
|     "Fire Rod": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/d/d6/FireRod.png?version=6eabc9f24d25697e2c4cd43ddc8207c0", | ||||
|     "Ice Rod": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/d/d7/ALttP_Ice_Rod_Sprite.png?version=1f944148223d91cfc6a615c92286c3bc", | ||||
|     "Bombos": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/8/8c/ALttP_Bombos_Medallion_Sprite.png?version=f4d6aba47fb69375e090178f0fc33b26", | ||||
|     "Ether": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/3/3c/Ether.png?version=34027651a5565fcc5a83189178ab17b5", | ||||
|     "Quake": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/5/56/ALttP_Quake_Medallion_Sprite.png?version=efd64d451b1831bd59f7b7d6b61b5879", | ||||
|     "Lamp": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/6/63/ALttP_Lantern_Sprite.png?version=e76eaa1ec509c9a5efb2916698d5a4ce", | ||||
|     "Hammer": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/d/d1/ALttP_Hammer_Sprite.png?version=e0adec227193818dcaedf587eba34500", | ||||
|     "Shovel": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/c/c4/ALttP_Shovel_Sprite.png?version=e73d1ce0115c2c70eaca15b014bd6f05", | ||||
|     "Flute": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/d/db/Flute.png?version=ec4982b31c56da2c0c010905c5c60390", | ||||
|     "Bug Catching Net": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/5/54/Bug-CatchingNet.png?version=4d40e0ee015b687ff75b333b968d8be6", | ||||
|     "Book of Mudora": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/2/22/ALttP_Book_of_Mudora_Sprite.png?version=11e4632bba54f6b9bf921df06ac93744", | ||||
|     "Bottle": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/e/ef/ALttP_Magic_Bottle_Sprite.png?version=fd98ab04db775270cbe79fce0235777b", | ||||
|     "Cane of Somaria": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/e/e1/ALttP_Cane_of_Somaria_Sprite.png?version=8cc1900dfd887890badffc903bb87943", | ||||
|     "Cane of Byrna": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/b/bc/ALttP_Cane_of_Byrna_Sprite.png?version=758b607c8cbe2cf1900d42a0b3d0fb54", | ||||
|     "Cape": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/1/1c/ALttP_Magic_Cape_Sprite.png?version=6b77f0d609aab0c751307fc124736832", | ||||
|     "Magic Mirror": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/e/e5/ALttP_Magic_Mirror_Sprite.png?version=e035dbc9cbe2a3bd44aa6d047762b0cc", | ||||
|     "Triforce": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/4/4e/TriforceALttPTitle.png?version=dc398e1293177581c16303e4f9d12a48", | ||||
| {% 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", | ||||
|     "Small Key": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/f/f1/ALttP_Small_Key_Sprite.png?version=4f35d92842f0de39d969181eea03774e", | ||||
|     "Big Key": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/3/33/ALttP_Big_Key_Sprite.png?version=136dfa418ba76c8b4e270f466fc12f4d", | ||||
|     "Chest": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/7/73/ALttP_Treasure_Chest_Sprite.png?version=5f530ecd98dcb22251e146e8049c0dda", | ||||
|     "Light World": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/e/e7/ALttP_Soldier_Green_Sprite.png?version=d650d417934cd707a47e496489c268a6", | ||||
|     "Dark World": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/9/94/ALttP_Moblin_Sprite.png?version=ebf50e33f4657c377d1606bcc0886ddc", | ||||
|     "Hyrule Castle": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/d/d3/ALttP_Ball_and_Chain_Trooper_Sprite.png?version=1768a87c06d29cc8e7ddd80b9fa516be", | ||||
|     "Agahnims Tower": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/1/1e/ALttP_Agahnim_Sprite.png?version=365956e61b0c2191eae4eddbe591dab5", | ||||
|     "Desert Palace": "https://www.zeldadungeon.net/wiki/images/2/25/Lanmola-ALTTP-Sprite.png", | ||||
|     "Eastern Palace": "https://www.zeldadungeon.net/wiki/images/d/dc/RedArmosKnight.png", | ||||
|     "Tower of Hera": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/3/3c/ALttP_Moldorm_Sprite.png?version=c588257bdc2543468e008a6b30f262a7", | ||||
|     "Palace of Darkness": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/e/ed/ALttP_Helmasaur_King_Sprite.png?version=ab8a4a1cfd91d4fc43466c56cba30022", | ||||
|     "Swamp Palace": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/7/73/ALttP_Arrghus_Sprite.png?version=b098be3122e53f751b74f4a5ef9184b5", | ||||
|     "Skull Woods": "https://alttp-wiki.net/images/6/6a/Mothula.png", | ||||
|     "Thieves Town": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/8/86/ALttP_Blind_the_Thief_Sprite.png?version=3833021bfcd112be54e7390679047222", | ||||
|     "Ice Palace": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/3/33/ALttP_Kholdstare_Sprite.png?version=e5a1b0e8b2298e550d85f90bf97045c0", | ||||
|     "Misery Mire": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/8/85/ALttP_Vitreous_Sprite.png?version=92b2e9cb0aa63f831760f08041d8d8d8", | ||||
|     "Turtle Rock": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/9/91/ALttP_Trinexx_Sprite.png?version=0cc867d513952aa03edd155597a0c0be", | ||||
|     "Ganons Tower": "https://gamepedia.cursecdn.com/zelda_gamepedia_en/b/b9/ALttP_Ganon_Sprite.png?version=956f51f054954dfff53c1a9d4f929c74", | ||||
| } -%} | ||||
|     "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", | ||||
| } %} | ||||
| 
 | ||||
| <!DOCTYPE html> | ||||
| {% 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)"), | ||||
|     "Thieves' Town": ("Small Key (Thieves Town)", "Big Key (Thieves Town)"), | ||||
|     "Skull Woods": ("Small Key (Skull Woods)", "Big Key (Skull Woods)"), | ||||
|     "Swamp Palace": ("Small Key (Swamp Palace)", "Big Key (Swamp Palace)"), | ||||
|     "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/lttp-tracker.css") }}"/> | ||||
|     <script type="application/ecmascript" src="{{ url_for('static', filename="assets/lttp-tracker.js") }}"></script> | ||||
|     <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='styles/tracker__ALinkToThePast.css') }}"> | ||||
| </head> | ||||
| 
 | ||||
| <body> | ||||
|  | @ -76,79 +92,127 @@ | |||
|         <a href="{{ url_for("get_generic_game_tracker", tracker=room.tracker, tracked_team=team, tracked_player=player) }}">Switch To Generic Tracker</a> | ||||
|     </div> | ||||
| 
 | ||||
|     <div id="player-tracker-wrapper" data-tracker="{{ room.tracker|suuid }}"> | ||||
|         <table id="inventory-table"> | ||||
|             <tr> | ||||
|                 <td><img src="{{ icons[bow_icon] }}" class="{{ 'acquired' if bow_acquired }}" /></td> | ||||
|                 <td><img src="{{ icons["Blue Boomerang"] }}" class="{{ 'acquired' if 'Blue Boomerang' in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Red Boomerang"] }}" class="{{ 'acquired' if 'Red Boomerang' in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Hookshot"] }}" class="{{ 'acquired' if 'Hookshot' in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Magic Powder"] }}" class="powder-fix {{ 'acquired' if 'Magic Powder' in acquired_items }}" /></td> | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <td><img src="{{ icons["Fire Rod"] }}" class="{{ 'acquired' if "Fire Rod" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Ice Rod"] }}" class="{{ 'acquired' if "Ice Rod" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Bombos"] }}" class="{{ 'acquired' if "Bombos" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Ether"] }}" class="{{ 'acquired' if "Ether" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Quake"] }}" class="{{ 'acquired' if "Quake" in acquired_items }}" /></td> | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <td><img src="{{ icons["Lamp"] }}" class="{{ 'acquired' if "Lamp" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Hammer"] }}" class="{{ 'acquired' if "Hammer" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Flute"] }}" class="{{ 'acquired' if "Flute" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Bug Catching Net"] }}" class="{{ 'acquired' if "Bug Catching Net" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Book of Mudora"] }}" class="{{ 'acquired' if "Book of Mudora" in acquired_items }}" /></td> | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <td><img src="{{ icons["Bottle"] }}" class="{{ 'acquired' if "Bottle" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Cane of Somaria"] }}" class="{{ 'acquired' if "Cane of Somaria" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Cane of Byrna"] }}" class="{{ 'acquired' if "Cane of Byrna" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Cape"] }}" class="{{ 'acquired' if "Cape" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Magic Mirror"] }}" class="{{ 'acquired' if "Magic Mirror" in acquired_items }}" /></td> | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <td><img src="{{ icons["Pegasus Boots"] }}" class="{{ 'acquired' if "Pegasus Boots" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons[glove_icon] }}" class="{{ 'acquired' if glove_acquired }}" /></td> | ||||
|                 <td><img src="{{ icons["Flippers"] }}" class="{{ 'acquired' if "Flippers" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Moon Pearl"] }}" class="{{ 'acquired' if "Moon Pearl" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Mushroom"] }}" class="{{ 'acquired' if "Mushroom" in acquired_items }}" /></td> | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <td><img src="{{ icons[sword_icon] }}" class="{{ 'acquired' if sword_acquired }}" /></td> | ||||
|                 <td><img src="{{ icons[shield_icon] }}" class="{{ 'acquired' if shield_acquired }}" /></td> | ||||
|                 <td><img src="{{ icons[mail_icon] }}" class="acquired" /></td> | ||||
|                 <td><img src="{{ icons["Shovel"] }}" class="{{ 'acquired' if "Shovel" in acquired_items }}" /></td> | ||||
|                 <td><img src="{{ icons["Triforce"] }}" class="{{ 'acquired' if "Triforce" in acquired_items }}" /></td> | ||||
|             </tr> | ||||
|         </table> | ||||
|         <table id="location-table"> | ||||
|             <tr> | ||||
|                 <th></th> | ||||
|                 <th class="counter"><img src="{{ icons["Chest"] }}" /></th> | ||||
|                 {% if key_locations and "Universal" not in key_locations %} | ||||
|                     <th class="counter"><img src="{{ icons["Small Key"] }}" /></th> | ||||
|     <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 %} | ||||
|                 {% if big_key_locations %} | ||||
|                     <th><img src="{{ icons["Big Key"] }}" /></th> | ||||
|                 {% endif %} | ||||
|             </tr> | ||||
|             {% for area in sp_areas %} | ||||
|                 <tr> | ||||
|                     <td>{{ area }}</td> | ||||
|                     <td class="counter">{{ checks_done[area] }} / {{ checks_in_area[area] }}</td> | ||||
|                     {% if key_locations and "Universal" not in key_locations %} | ||||
|                         <td class="counter"> | ||||
|                             {{ inventory[small_key_ids[area]] if area in key_locations else '—' }} | ||||
|                         </td> | ||||
|                     {% endif %} | ||||
|                     {% if big_key_locations %} | ||||
|                         <td> | ||||
|                             {{ '✔' if area in big_key_locations and inventory[big_key_ids[area]] else ('—' if area not in big_key_locations else '') }} | ||||
|                         </td> | ||||
|                     {% endif %} | ||||
|                 </tr> | ||||
|             {% endfor %} | ||||
|         </table> | ||||
|         </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, region_data in regions.items() %} | ||||
|                 {% 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> | ||||
|  |  | |||
|  | @ -695,196 +695,169 @@ if "A Link to the Past" in network_data_package["games"]: | |||
|         ) | ||||
| 
 | ||||
|     def render_ALinkToThePast_tracker(tracker_data: TrackerData, team: int, player: int) -> str: | ||||
|         # Helper objects. | ||||
|         alttp_id_lookup = tracker_data.item_name_to_id["A Link to the Past"] | ||||
|         inventory = collections.Counter({ | ||||
|             tracker_data.item_id_to_name["A Link to the Past"][code]: count | ||||
|             for code, count in tracker_data.get_player_inventory_counts(team, player).items() | ||||
|         }) | ||||
| 
 | ||||
|         links = { | ||||
|             "Bow":                   "Progressive Bow", | ||||
|             "Silver Arrows":         "Progressive Bow", | ||||
|             "Silver Bow":            "Progressive Bow", | ||||
|             "Progressive Bow (Alt)": "Progressive Bow", | ||||
|             "Bottle (Red Potion)":   "Bottle", | ||||
|             "Bottle (Green Potion)": "Bottle", | ||||
|             "Bottle (Blue Potion)":  "Bottle", | ||||
|             "Bottle (Fairy)":        "Bottle", | ||||
|             "Bottle (Bee)":          "Bottle", | ||||
|             "Bottle (Good Bee)":     "Bottle", | ||||
|             "Fighter Sword":         "Progressive Sword", | ||||
|             "Master Sword":          "Progressive Sword", | ||||
|             "Tempered Sword":        "Progressive Sword", | ||||
|             "Golden Sword":          "Progressive Sword", | ||||
|             "Power Glove":           "Progressive Glove", | ||||
|             "Titans Mitts":          "Progressive Glove", | ||||
|         # Mapping from non-progressive item to progressive name and max level. | ||||
|         non_progressive_items = { | ||||
|             "Fighter Sword":  ("Progressive Sword",  1), | ||||
|             "Master Sword":   ("Progressive Sword",  2), | ||||
|             "Tempered Sword": ("Progressive Sword",  3), | ||||
|             "Golden Sword":   ("Progressive Sword",  4), | ||||
|             "Power Glove":    ("Progressive Glove",  1), | ||||
|             "Titans Mitts":   ("Progressive Glove",  2), | ||||
|             "Bow":            ("Progressive Bow",    1), | ||||
|             "Silver Bow":     ("Progressive Bow",    2), | ||||
|             "Blue Mail":      ("Progressive Mail",   1), | ||||
|             "Red Mail":       ("Progressive Mail",   2), | ||||
|             "Blue Shield":    ("Progressive Shield", 1), | ||||
|             "Red Shield":     ("Progressive Shield", 2), | ||||
|             "Mirror Shield":  ("Progressive Shield", 3), | ||||
|         } | ||||
|         links = {alttp_id_lookup[key]: alttp_id_lookup[value] for key, value in links.items()} | ||||
|         levels = { | ||||
|             "Fighter Sword":   1, | ||||
|             "Master Sword":    2, | ||||
|             "Tempered Sword":  3, | ||||
|             "Golden Sword":    4, | ||||
|             "Power Glove":     1, | ||||
|             "Titans Mitts":    2, | ||||
|             "Bow":             1, | ||||
|             "Silver Bow":      2, | ||||
|             "Triforce Piece": 90, | ||||
| 
 | ||||
|         progressive_item_max = { | ||||
|             "Progressive Sword":  4, | ||||
|             "Progressive Glove":  2, | ||||
|             "Progressive Bow":    2, | ||||
|             "Progressive Mail":   2, | ||||
|             "Progressive Shield": 3, | ||||
|         } | ||||
|         tracking_names = [ | ||||
|             "Progressive Sword", "Progressive Bow", "Book of Mudora", "Hammer", "Hookshot", "Magic Mirror", "Flute", | ||||
|             "Pegasus Boots", "Progressive Glove", "Flippers", "Moon Pearl", "Blue Boomerang", "Red Boomerang", | ||||
|             "Bug Catching Net", "Cape", "Shovel", "Lamp", "Mushroom", "Magic Powder", "Cane of Somaria", | ||||
|             "Cane of Byrna", "Fire Rod", "Ice Rod", "Bombos", "Ether", "Quake", "Bottle", "Triforce Piece", "Triforce", | ||||
| 
 | ||||
|         bottle_items = [ | ||||
|             "Bottle", | ||||
|             "Bottle (Bee)", | ||||
|             "Bottle (Blue Potion)", | ||||
|             "Bottle (Fairy)", | ||||
|             "Bottle (Good Bee)", | ||||
|             "Bottle (Green Potion)", | ||||
|             "Bottle (Red Potion)", | ||||
|         ] | ||||
|         default_locations = { | ||||
| 
 | ||||
|         # Translate non-progression items to progression items for tracker simplicity. | ||||
|         for item, (prog_item, level) in non_progressive_items.items(): | ||||
|             if item in inventory: | ||||
|                 inventory[prog_item] = min(max(inventory[prog_item], level), progressive_item_max[prog_item]) | ||||
| 
 | ||||
|         for bottle in bottle_items: | ||||
|             inventory["Bottles"] = min(inventory["Bottles"] + inventory[bottle], 4) | ||||
| 
 | ||||
|         if "Progressive Bow (Alt)" in inventory: | ||||
|             inventory["Progressive Bow"] += inventory["Progressive Bow (Alt)"] | ||||
|             inventory["Progressive Bow"] = min(inventory["Progressive Bow"], progressive_item_max["Progressive Bow"]) | ||||
| 
 | ||||
|         # Highlight 'bombs' if we received any bomb upgrades in bombless start. | ||||
|         # In race mode, we'll just assume bombless start for simplicity. | ||||
|         if tracker_data.get_slot_data(team, player).get("bombless_start", True): | ||||
|             inventory["Bombs"] = sum(count for item, count in inventory.items() if item.startswith("Bomb Upgrade")) | ||||
|         else: | ||||
|             inventory["Bombs"] = 1 | ||||
| 
 | ||||
|         known_regions = { | ||||
|             "Light World": { | ||||
|                 1572864, 1572865, 60034, 1572867, 1572868, 60037, 1572869, 1572866, 60040, 59788, 60046, 60175, | ||||
|                 1572880, 60049, 60178, 1572883, 60052, 60181, 1572885, 60055, 60184, 191256, 60058, 60187, 1572884, | ||||
|                 1572886, 1572887, 1572906, 60202, 60205, 59824, 166320, 1010170, 60208, 60211, 60214, 60217, 59836, | ||||
|                 60220, 60223, 59839, 1573184, 60226, 975299, 1573188, 1573189, 188229, 60229, 60232, 1573193, | ||||
|                 1573194, 60235, 1573187, 59845, 59854, 211407, 60238, 59857, 1573185, 1573186, 1572882, 212328, | ||||
|                 59881, 59761, 59890, 59770, 193020, 212605 | ||||
|                 0x180013, 0x02eb18, 0x18014a, 0x180145, 0x033d68, 0x00eb0f, 0x00eb12, 0x00eb15, 0x00eb18, 0x00eb1b, | ||||
|                 0x02df45, 0x00e971, 0x0ee1c3, 0x180149, 0x00e9b0, 0x00e9d1, 0x00e97a, 0x00e98c, 0x00e9bc, 0x00e9ce, | ||||
|                 0x00e9e9, 0x00e9f2, 0x00ea82, 0x00ea85, 0x00ea88, 0x02f1fc, 0x00ea8e, 0x00ea91, 0x00ea94, 0x00ea97, | ||||
|                 0x00ea9a, 0x18002a, 0x180015, 0x0339cf, 0x033e7d, 0x180000, 0x180001, 0x180003, 0x180004, 0x180005, | ||||
|                 0x00eb42, 0x00eb45, 0x00eb48, 0x00eb4b, 0x180010, 0x00eb4e, 0x00eb3f, 0x180012, 0x180014, 0x180144, | ||||
|                 0x180142, 0x180143, 0x0289b0, 0x0f69fa, 0x180002, 0x00eb2a, 0x00eb2d, 0x00eb30, 0x00eb33, 0x00eb36, | ||||
|                 0x00eb39, 0x00eb3c, 0x00e9bf, 0x180016, 0x180017, 0x180140, 0x180141, 0x00e9c5, 0x400018, 0x400019, | ||||
|                 0x40001a, 0x400015, 0x400016, 0x400017, 0x400012, 0x400013, 0x400014, 0x40001b, 0x40001c, 0x40001d, | ||||
|                 0x400022, 0x400023, 0x400024, 0x400025, 0x400021, 0x40001e, 0x40001f, | ||||
|             }, | ||||
|             "Dark World": { | ||||
|                 59776, 59779, 975237, 1572870, 60043, 1572881, 60190, 60193, 60196, 60199, 60840, 1573190, 209095, | ||||
|                 1573192, 1573191, 60241, 60244, 60247, 60250, 59884, 59887, 60019, 60022, 60028, 60031 | ||||
|                 0x180147, 0x0ee185, 0x0330c7, 0x180148, 0x00eb1e, 0x00eb21, 0x00eb24, 0x00eb27, 0x180011, 0x180006, | ||||
|                 0x00e980, 0x00e983, 0x00e9ec, 0x00e9ef, 0x00eda8, 0x180146, 0x00ea73, 0x00ea76, 0x00ea7c, 0x00ea7f, | ||||
|                 0x00ea8b, 0x00eb51, 0x00eb54, 0x00eb5a, 0x00eb57, 0x400000, 0x400001, 0x400002, 0x400006, 0x400007, | ||||
|                 0x400008, 0x400009, 0x40000a, 0x40000b, 0x40000f, 0x400010, 0x400011, 0x400003, 0x400004, 0x400005, | ||||
|                 0x40000c, 0x40000d, 0x40000e, | ||||
|             }, | ||||
|             "Hyrule Castle": { | ||||
|                 0x00e974, 0x00eb0c, 0x00eb09, 0x00e96e, 0x00eb5d, 0x00eb60, 0x00eb63, 0x00ea79, 0x140037, 0x140034, | ||||
|                 0x14000d, 0x14003d, | ||||
|             }, | ||||
|             "Agahnims Tower": { | ||||
|                 0x00eab5, 0x00eab2, 0x140061, 0x140052, | ||||
|             }, | ||||
|             "Eastern Palace": { | ||||
|                 0x00e977, 0x00e97d, 0x00e9b3, 0x00e9b9, 0x00e9f5, 0x180150, 0x14005b, 0x140049, | ||||
|             }, | ||||
|             "Desert Palace": { | ||||
|                 0x00e98f, 0x180160, 0x00e9b6, 0x00e9cb, 0x00e9c2, 0x180151, 0x140031, 0x14002b, 0x140028, | ||||
|             }, | ||||
|             "Tower of Hera": { | ||||
|                 0x180162, 0x00e9ad, 0x00e9e6, 0x00e9fb, 0x00e9f8, 0x180152 | ||||
|             }, | ||||
|             "Desert Palace": {1573216, 59842, 59851, 59791, 1573201, 59830}, | ||||
|             "Eastern Palace": {1573200, 59827, 59893, 59767, 59833, 59773}, | ||||
|             "Hyrule Castle": {60256, 60259, 60169, 60172, 59758, 59764, 60025, 60253}, | ||||
|             "Agahnims Tower": {60082, 60085}, | ||||
|             "Tower of Hera": {1573218, 59878, 59821, 1573202, 59896, 59899}, | ||||
|             "Swamp Palace": {60064, 60067, 60070, 59782, 59785, 60073, 60076, 60079, 1573204, 60061}, | ||||
|             "Thieves Town": {59905, 59908, 59911, 59914, 59917, 59920, 59923, 1573206}, | ||||
|             "Skull Woods": {59809, 59902, 59848, 59794, 1573205, 59800, 59803, 59806}, | ||||
|             "Ice Palace": {59872, 59875, 59812, 59818, 59860, 59797, 1573207, 59869}, | ||||
|             "Misery Mire": {60001, 60004, 60007, 60010, 60013, 1573208, 59866, 59998}, | ||||
|             "Turtle Rock": {59938, 59941, 59944, 1573209, 59947, 59950, 59953, 59956, 59926, 59929, 59932, 59935}, | ||||
|             "Palace of Darkness": { | ||||
|                 59968, 59971, 59974, 59977, 59980, 59983, 59986, 1573203, 59989, 59959, 59992, 59962, 59995, | ||||
|                 59965 | ||||
|                 0x00ea5b, 0x00ea3d, 0x00ea49, 0x00ea37, 0x00ea3a, 0x00ea52, 0x00ea43, 0x00ea4c, 0x00ea4f, 0x00ea55, | ||||
|                 0x00ea58, 0x00ea40, 0x00ea46, 0x180153, | ||||
|             }, | ||||
|             "Swamp Palace": { | ||||
|                 0x00ea9d, 0x00e986, 0x00e989, 0x00eaa0, 0x00eaa6, 0x00eaa3, 0x00eaa9, 0x00eaac, 0x00eaaf, 0x180154, | ||||
|                 0x140019, 0x140016, 0x140013, 0x140010, 0x14000a, | ||||
|             }, | ||||
|             "Thieves' Town": { | ||||
|                 0x00ea04, 0x00ea01, 0x00ea07, 0x00ea0a, 0x00ea0d, 0x00ea10, 0x00ea13, 0x180156, 0x14005e, 0x14004f, | ||||
|             }, | ||||
|             "Skull Woods": { | ||||
|                 0x00e992, 0x00e99b, 0x00e998, 0x00e9a1, 0x00e9c8, 0x00e99e, 0x00e9fe, 0x180155, 0x14002e, 0x14001c, | ||||
|             }, | ||||
|             "Ice Palace": { | ||||
|                 0x00e9d4, 0x00e995, 0x00e9aa, 0x00e9e3, 0x00e9e0, 0x00e9a4, 0x00e9dd, 0x180157, 0x140004, 0x140022, | ||||
|                 0x140025, 0x140046, | ||||
|             }, | ||||
|             "Misery Mire": { | ||||
|                 0x00ea67, 0x00ea6a, 0x00ea5e, 0x00ea61, 0x00e9da, 0x00ea64, 0x00ea6d, 0x180158, 0x140055, 0x14004c, | ||||
|                 0x140064, | ||||
|             }, | ||||
|             "Turtle Rock": { | ||||
|                 0x00ea22, 0x00ea1c, 0x00ea1f, 0x00ea16, 0x00ea25, 0x00ea19, 0x00ea34, 0x00ea31, 0x00ea2e, 0x00ea2b, | ||||
|                 0x00ea28, 0x180159, 0x140058, 0x140007, | ||||
|             }, | ||||
|             "Ganons Tower": { | ||||
|                 60160, 60163, 60166, 60088, 60091, 60094, 60097, 60100, 60103, 60106, 60109, 60112, 60115, 60118, | ||||
|                 60121, 60124, 60127, 1573217, 60130, 60133, 60136, 60139, 60142, 60145, 60148, 60151, 60157 | ||||
|                 0x180161, 0x00ead9, 0x00eadc, 0x00eae2, 0x00eae5, 0x00eae8, 0x00eaeb, 0x00eaee, 0x00eab8, 0x00eabb, | ||||
|                 0x00eabe, 0x00eac1, 0x00ead3, 0x00ead0, 0x00eac4, 0x00eac7, 0x00eaca, 0x00eacd, 0x00eadf, 0x00eadf, | ||||
|                 0x00ead6, 0x00eaf4, 0x00eaf7, 0x00eaf1, 0x00eafd, 0x00eb00, 0x00eb03, 0x00eb06, 0x140040, 0x140043, | ||||
|                 0x14003a, 0x14001f, | ||||
|             }, | ||||
|             "Total": set() | ||||
|         } | ||||
|         key_only_locations = { | ||||
|             "Light World": set(), | ||||
|             "Dark World": set(), | ||||
|             "Desert Palace": {0x140031, 0x14002b, 0x140061, 0x140028}, | ||||
|             "Eastern Palace": {0x14005b, 0x140049}, | ||||
|             "Hyrule Castle": {0x140037, 0x140034, 0x14000d, 0x14003d}, | ||||
|             "Agahnims Tower": {0x140061, 0x140052}, | ||||
|             "Tower of Hera": set(), | ||||
|             "Swamp Palace": {0x140019, 0x140016, 0x140013, 0x140010, 0x14000a}, | ||||
|             "Thieves Town": {0x14005e, 0x14004f}, | ||||
|             "Skull Woods": {0x14002e, 0x14001c}, | ||||
|             "Ice Palace": {0x140004, 0x140022, 0x140025, 0x140046}, | ||||
|             "Misery Mire": {0x140055, 0x14004c, 0x140064}, | ||||
|             "Turtle Rock": {0x140058, 0x140007}, | ||||
|             "Palace of Darkness": set(), | ||||
|             "Ganons Tower": {0x140040, 0x140043, 0x14003a, 0x14001f}, | ||||
|             "Total": set() | ||||
| 
 | ||||
|         regions = { | ||||
|             "Light World":        {"checked": 0, "locations": []}, | ||||
|             "Dark World":         {"checked": 0, "locations": []}, | ||||
|             "Hyrule Castle":      {"checked": 0, "locations": []}, | ||||
|             "Agahnims Tower":     {"checked": 0, "locations": []}, | ||||
|             "Eastern Palace":     {"checked": 0, "locations": []}, | ||||
|             "Desert Palace":      {"checked": 0, "locations": []}, | ||||
|             "Tower of Hera":      {"checked": 0, "locations": []}, | ||||
|             "Palace of Darkness": {"checked": 0, "locations": []}, | ||||
|             "Skull Woods":        {"checked": 0, "locations": []}, | ||||
|             "Thieves' Town":      {"checked": 0, "locations": []}, | ||||
|             "Swamp Palace":       {"checked": 0, "locations": []}, | ||||
|             "Ice Palace":         {"checked": 0, "locations": []}, | ||||
|             "Misery Mire":        {"checked": 0, "locations": []}, | ||||
|             "Turtle Rock":        {"checked": 0, "locations": []}, | ||||
|             "Ganons Tower":       {"checked": 0, "locations": []}, | ||||
|             "Unknown":            {"checked": 0, "locations": []}, | ||||
|         } | ||||
|         location_to_area = {} | ||||
|         for area, locations in default_locations.items(): | ||||
|             for checked_location in locations: | ||||
|                 location_to_area[checked_location] = area | ||||
|         for area, locations in key_only_locations.items(): | ||||
|             for checked_location in locations: | ||||
|                 location_to_area[checked_location] = area | ||||
| 
 | ||||
|         checks_in_area = {area: len(checks) for area, checks in default_locations.items()} | ||||
|         checks_in_area["Total"] = 216 | ||||
|         ordered_areas = ( | ||||
|             "Light World", "Dark World", "Hyrule Castle", "Agahnims Tower", "Eastern Palace", "Desert Palace", | ||||
|             "Tower of Hera", "Palace of Darkness", "Swamp Palace", "Skull Woods", "Thieves Town", "Ice Palace", | ||||
|             "Misery Mire", "Turtle Rock", "Ganons Tower", "Total" | ||||
|         ) | ||||
| 
 | ||||
|         tracking_ids = [] | ||||
|         for item in tracking_names: | ||||
|             tracking_ids.append(alttp_id_lookup[item]) | ||||
| 
 | ||||
|         # Can't wait to get this into the apworld. Oof. | ||||
|         from worlds.alttp import Items | ||||
| 
 | ||||
|         small_key_ids = {} | ||||
|         big_key_ids = {} | ||||
|         ids_small_key = {} | ||||
|         ids_big_key = {} | ||||
|         for item_name, data in Items.item_table.items(): | ||||
|             if "Key" in item_name: | ||||
|                 area = item_name.split("(")[1][:-1] | ||||
|                 if "Small" in item_name: | ||||
|                     small_key_ids[area] = data[2] | ||||
|                     ids_small_key[data[2]] = area | ||||
|                 else: | ||||
|                     big_key_ids[area] = data[2] | ||||
|                     ids_big_key[data[2]] = area | ||||
| 
 | ||||
|         inventory = collections.Counter() | ||||
|         checks_done = {loc_name: 0 for loc_name in default_locations} | ||||
|         player_big_key_locations = set() | ||||
|         player_small_key_locations = set() | ||||
| 
 | ||||
|         player_locations = tracker_data.get_player_locations(team, player) | ||||
|         for checked_location in tracker_data.get_player_checked_locations(team, player): | ||||
|             if checked_location in player_locations: | ||||
|                 area_name = location_to_area.get(checked_location, None) | ||||
|                 if area_name: | ||||
|                     checks_done[area_name] += 1 | ||||
| 
 | ||||
|                 checks_done["Total"] += 1 | ||||
| 
 | ||||
|         for received_item in tracker_data.get_player_received_items(team, player): | ||||
|             target_item = links.get(received_item.item, received_item.item) | ||||
|             if received_item.item in levels:  # non-progressive | ||||
|                 inventory[target_item] = max(inventory[target_item], levels[received_item.item]) | ||||
|         for location in tracker_data.get_player_locations(team, player): | ||||
|             location_name = tracker_data.location_id_to_name["A Link to the Past"][location] | ||||
|             location_checked = location in tracker_data.get_player_checked_locations(team, player) | ||||
|             for region, region_locations in known_regions.items(): | ||||
|                 if location in region_locations: | ||||
|                     regions[region]["locations"].append((location_name, location_checked)) | ||||
|                     regions[region]["checked"] += 1 if location_checked else 0 | ||||
|                     break | ||||
|             else: | ||||
|                 inventory[target_item] += 1 | ||||
|                 # New or missed location in the tables above. Add it to an "unknown region", so it's not forgotten. | ||||
|                 regions["Unknown"]["locations"].append((location_name, location_checked)) | ||||
|                 regions["Unknown"]["checked"] += 1 if location_checked else 0 | ||||
| 
 | ||||
|         for location, (item_id, _, _) in player_locations.items(): | ||||
|             if item_id in ids_big_key: | ||||
|                 player_big_key_locations.add(ids_big_key[item_id]) | ||||
|             elif item_id in ids_small_key: | ||||
|                 player_small_key_locations.add(ids_small_key[item_id]) | ||||
| 
 | ||||
|         # Note the presence of the triforce item | ||||
|         if tracker_data.get_player_client_status(team, player) == ClientStatus.CLIENT_GOAL: | ||||
|             inventory[106] = 1  # Triforce | ||||
| 
 | ||||
|         # Progressive items need special handling for icons and class | ||||
|         progressive_items = { | ||||
|             "Progressive Sword":  94, | ||||
|             "Progressive Glove":  97, | ||||
|             "Progressive Bow":    100, | ||||
|             "Progressive Mail":   96, | ||||
|             "Progressive Shield": 95, | ||||
|         } | ||||
|         progressive_names = { | ||||
|             "Progressive Sword":  [None, "Fighter Sword", "Master Sword", "Tempered Sword", "Golden Sword"], | ||||
|             "Progressive Glove":  [None, "Power Glove", "Titan Mitts"], | ||||
|             "Progressive Bow":    [None, "Bow", "Silver Bow"], | ||||
|             "Progressive Mail":   ["Green Mail", "Blue Mail", "Red Mail"], | ||||
|             "Progressive Shield": [None, "Blue Shield", "Red Shield", "Mirror Shield"] | ||||
|         } | ||||
| 
 | ||||
|         # Determine which icon to use | ||||
|         display_data = {} | ||||
|         for item_name, item_id in progressive_items.items(): | ||||
|             level = min(inventory[item_id], len(progressive_names[item_name]) - 1) | ||||
|             display_name = progressive_names[item_name][level] | ||||
|             acquired = True | ||||
|             if not display_name: | ||||
|                 acquired = False | ||||
|                 display_name = progressive_names[item_name][level + 1] | ||||
|             base_name = item_name.split(maxsplit=1)[1].lower() | ||||
|             display_data[base_name + "_acquired"] = acquired | ||||
|             display_data[base_name + "_icon"] = display_name | ||||
| 
 | ||||
|         # The single player tracker doesn't care about overworld, underworld, and total checks. Maybe it should? | ||||
|         sp_areas = ordered_areas[2:15] | ||||
|         # Sort locations in regions by name | ||||
|         for region in regions: | ||||
|             regions[region]["locations"].sort() | ||||
| 
 | ||||
|         return render_template( | ||||
|             template_name_or_list="tracker__ALinkToThePast.html", | ||||
|  | @ -893,15 +866,7 @@ if "A Link to the Past" in network_data_package["games"]: | |||
|             player=player, | ||||
|             inventory=inventory, | ||||
|             player_name=tracker_data.get_player_name(team, player), | ||||
|             checks_done=checks_done, | ||||
|             checks_in_area=checks_in_area, | ||||
|             acquired_items={tracker_data.item_id_to_name["A Link to the Past"][id] for id in inventory}, | ||||
|             sp_areas=sp_areas, | ||||
|             small_key_ids=small_key_ids, | ||||
|             key_locations=player_small_key_locations, | ||||
|             big_key_ids=big_key_ids, | ||||
|             big_key_locations=player_big_key_locations, | ||||
|             **display_data, | ||||
|             regions=regions, | ||||
|         ) | ||||
| 
 | ||||
|     _multiworld_trackers["A Link to the Past"] = render_ALinkToThePast_multiworld_tracker | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue