diff --git a/WebHostLib/templates/multiFactorioTracker.html b/WebHostLib/templates/multiFactorioTracker.html
new file mode 100644
index 00000000..bc0a977a
--- /dev/null
+++ b/WebHostLib/templates/multiFactorioTracker.html
@@ -0,0 +1,44 @@
+{% extends "multiTracker.html" %}
+{% block custom_table_headers %}
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+{% endblock %}
+{% block custom_table_row scoped %}
+{% if games[player] == "Factorio" %}
+{% if inventory[team][player][131161] or inventory[team][player][131281] %}✔{% endif %} |
+{% if inventory[team][player][131172] or inventory[team][player][131281] > 1%}✔{% endif %} |
+{% if inventory[team][player][131195] or inventory[team][player][131281] > 2%}✔{% endif %} |
+{% if inventory[team][player][131240] or inventory[team][player][131281] > 3%}✔{% endif %} |
+{% if inventory[team][player][131240] or inventory[team][player][131281] > 4%}✔{% endif %} |
+{% if inventory[team][player][131220] or inventory[team][player][131281] > 5%}✔{% endif %} |
+{% else %}
+❌ |
+❌ |
+❌ |
+❌ |
+❌ |
+❌ |
+{% endif %}
+{% endblock%}
diff --git a/WebHostLib/templates/multiTracker.html b/WebHostLib/templates/multiTracker.html
index 3c6b09d1..c6defff0 100644
--- a/WebHostLib/templates/multiTracker.html
+++ b/WebHostLib/templates/multiTracker.html
@@ -30,6 +30,10 @@
# |
Name |
+ Game |
+ {% block custom_table_headers %}
+ {# implement this block in game-specific multi trackers #}
+ {% endblock %}
Checks |
% |
Last Activity |
@@ -41,6 +45,10 @@
{{ loop.index }} |
{{ player_names[(team, loop.index)]|e }} |
+ {{ games[player] }} |
+ {% block custom_table_row scoped %}
+ {# implement this block in game-specific multi trackers #}
+ {% endblock %}
{{ checks["Total"] }}/{{ checks_in_area[player]["Total"] }} |
{{ percent_total_checks_done[team][player] }} |
{%- if activity_timers[(team, player)] -%}
diff --git a/WebHostLib/templates/multiTrackerNavigation.html b/WebHostLib/templates/multiTrackerNavigation.html
index c6498fc6..f712f336 100644
--- a/WebHostLib/templates/multiTrackerNavigation.html
+++ b/WebHostLib/templates/multiTrackerNavigation.html
@@ -2,11 +2,8 @@
{%- endif -%}
diff --git a/WebHostLib/tracker.py b/WebHostLib/tracker.py
index c2a44324..8d9311fc 100644
--- a/WebHostLib/tracker.py
+++ b/WebHostLib/tracker.py
@@ -666,7 +666,6 @@ def __renderOoTTracker(multisave: Dict[str, Any], room: Room, locations: Dict[in
}
for item_name, item_id in multi_items.items():
base_name = item_name.split()[-1].lower()
- count = inventory[item_id]
display_data[base_name+"_count"] = inventory[item_id]
# Gather dungeon locations
@@ -1323,24 +1322,22 @@ def get_enabled_multiworld_trackers(room: Room, current: str):
"current": current == "Generic"
}
]
-
- if any(slot.game == "A Link to the Past" for slot in room.seed.slots) or current == "A Link to the Past":
- enabled.append({
- "name": "A Link to the Past",
- "endpoint": "get_LttP_multiworld_tracker",
- "current": current == "A Link to the Past"}
- )
-
+ for game_name, endpoint in multi_trackers.items():
+ if any(slot.game == game_name for slot in room.seed.slots) or current == game_name:
+ enabled.append({
+ "name": game_name,
+ "endpoint": endpoint.__name__,
+ "current": current == game_name}
+ )
return enabled
-@app.route('/tracker/')
-@cache.memoize(timeout=60) # multisave is currently created at most every minute
-def get_multiworld_tracker(tracker: UUID):
+def _get_multiworld_tracker_data(tracker: UUID) -> typing.Optional[typing.Dict[str, typing.Any]]:
room: Room = Room.get(tracker=tracker)
if not room:
- abort(404)
- locations, names, use_door_tracker, seed_checks_in_area, player_location_to_area, \
+ return None
+
+ locations, names, use_door_tracker, checks_in_area, player_location_to_area, \
precollected_items, games, slot_data, groups, saving_second, custom_locations, custom_items = \
get_static_room_data(room)
@@ -1366,7 +1363,9 @@ def get_multiworld_tracker(tracker: UUID):
continue
player_locations = locations[player]
checks_done[team][player]["Total"] = sum(1 for loc in locations_checked if loc in player_locations)
- percent_total_checks_done[team][player] = int(checks_done[team][player]["Total"] / seed_checks_in_area[player]["Total"] * 100) if seed_checks_in_area[player]["Total"] else 100
+ percent_total_checks_done[team][player] = int(checks_done[team][player]["Total"] /
+ checks_in_area[player]["Total"] * 100) \
+ if checks_in_area[player]["Total"] else 100
activity_timers = {}
now = datetime.datetime.utcnow()
@@ -1386,15 +1385,61 @@ def get_multiworld_tracker(tracker: UUID):
for (team, player), data in multisave.get("video", []):
video[(team, player)] = data
- enabled_multiworld_trackers = get_enabled_multiworld_trackers(room, "Generic")
-
- return render_template("multiTracker.html", player_names=player_names, room=room, checks_done=checks_done,
- percent_total_checks_done=percent_total_checks_done, checks_in_area=seed_checks_in_area,
- activity_timers=activity_timers, video=video, hints=hints,
- long_player_names=long_player_names, enabled_multiworld_trackers=enabled_multiworld_trackers)
+ return dict(player_names=player_names, room=room, checks_done=checks_done,
+ percent_total_checks_done=percent_total_checks_done, checks_in_area=checks_in_area,
+ activity_timers=activity_timers, video=video, hints=hints,
+ long_player_names=long_player_names,
+ multisave=multisave, precollected_items=precollected_items, groups=groups,
+ locations=locations, games=games)
-@app.route('/tracker//lttp')
+def _get_inventory_data(data: typing.Dict[str, typing.Any]) -> typing.Dict[int, typing.Dict[int, int]]:
+ inventory = {teamnumber: {playernumber: collections.Counter() for playernumber in team_data}
+ for teamnumber, team_data in data["checks_done"].items()}
+
+ groups = data["groups"]
+
+ for (team, player), locations_checked in data["multisave"].get("location_checks", {}).items():
+ if player in data["groups"]:
+ continue
+ player_locations = data["locations"][player]
+ precollected = data["precollected_items"][player]
+ for item_id in precollected:
+ inventory[team][player][item_id] += 1
+ for location in locations_checked:
+ item_id, recipient, flags = player_locations[location]
+ recipients = groups.get(recipient, [recipient])
+ for recipient in recipients:
+ inventory[team][recipient][item_id] += 1
+ return inventory
+
+
+@app.route('/tracker/')
+@cache.memoize(timeout=60) # multisave is currently created at most every minute
+def get_multiworld_tracker(tracker: UUID):
+ data = _get_multiworld_tracker_data(tracker)
+ if not data:
+ abort(404)
+
+ data["enabled_multiworld_trackers"] = get_enabled_multiworld_trackers(data["room"], "Generic")
+
+ return render_template("multiTracker.html", **data)
+
+
+@app.route('/tracker//Factorio')
+@cache.memoize(timeout=60) # multisave is currently created at most every minute
+def get_Factorio_multiworld_tracker(tracker: UUID):
+ data = _get_multiworld_tracker_data(tracker)
+ if not data:
+ abort(404)
+
+ data["inventory"] = _get_inventory_data(data)
+ data["enabled_multiworld_trackers"] = get_enabled_multiworld_trackers(data["room"], "Factorio")
+
+ return render_template("multiFactorioTracker.html", **data)
+
+
+@app.route('/tracker//A Link to the Past')
@cache.memoize(timeout=60) # multisave is currently created at most every minute
def get_LttP_multiworld_tracker(tracker: UUID):
room: Room = Room.get(tracker=tracker)
@@ -1518,3 +1563,8 @@ game_specific_trackers: typing.Dict[str, typing.Callable] = {
"Super Metroid": __renderSuperMetroidTracker,
"Starcraft 2 Wings of Liberty": __renderSC2WoLTracker
}
+
+multi_trackers: typing.Dict[str, typing.Callable] = {
+ "A Link to the Past": get_LttP_multiworld_tracker,
+ "Factorio": get_Factorio_multiworld_tracker,
+}