219 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			HTML
		
	
	
	
			
		
		
	
	
			219 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)"),
 | 
						|
    "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/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, 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>
 |