Skip to content

Commit 915c38f

Browse files
authored
Merge pull request ArchipelagoMW#9 from silasary/requests
A few small enhancements
2 parents 3b53aa9 + 6004f3d commit 915c38f

File tree

5 files changed

+77
-29
lines changed

5 files changed

+77
-29
lines changed

ManualClient.py

+36-17
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,11 @@ def get_location_by_name(self, name):
9090
if location:
9191
return location
9292
return AutoWorldRegister.world_types[self.game].location_name_to_location[name]
93-
93+
94+
def get_location_by_id(self, id):
95+
name = self.location_names[id]
96+
return self.get_location_by_name(name)
97+
9498
def get_item_by_name(self, name):
9599
item = self.item_table.get(name)
96100
if item:
@@ -159,10 +163,10 @@ class ManualManager(GameManager):
159163
("Manual", "Manual"),
160164
]
161165
base_title = "Archipelago Manual Client"
162-
listed_items = {"(no category)": []}
163-
item_categories = ["(no category)"]
164-
listed_locations = {"(no category)": []}
165-
location_categories = ["(no category)"]
166+
listed_items = {"(No Category)": []}
167+
item_categories = ["(No Category)"]
168+
listed_locations = {"(No Category)": []}
169+
location_categories = ["(No Category)"]
166170

167171
active_item_accordion = 0
168172
active_location_accordion = 0
@@ -197,13 +201,13 @@ def build(self) -> Layout:
197201
self.ctx.build_gui(self)
198202

199203
return self.container
200-
204+
201205
def clear_lists(self):
202-
self.listed_items = {"(no category)": []}
203-
self.item_categories = ["(no category)"]
204-
self.listed_locations = {"(no category)": []}
205-
self.location_categories = ["(no category)"]
206-
206+
self.listed_items = {"(No Category)": []}
207+
self.item_categories = ["(No Category)"]
208+
self.listed_locations = {"(No Category)": [], "(Hinted)": []}
209+
self.location_categories = ["(No Category)", "(Hinted)"]
210+
207211
def set_active_item_accordion(self, instance):
208212
index = 0
209213

@@ -224,6 +228,21 @@ def set_active_location_accordion(self, instance):
224228

225229
index += 1
226230

231+
def update_hints(self):
232+
super().update_hints()
233+
rebuild = False
234+
for hint in self.ctx.stored_data.get(f"_read_hints_{self.ctx.team}_{self.ctx.slot}", []):
235+
if hint["finding_player"] == self.ctx.slot:
236+
if hint["location"] in self.ctx.missing_locations:
237+
location = self.ctx.get_location_by_id(hint["location"])
238+
if "(Hinted)" not in location["category"]:
239+
location["category"].append("(Hinted)")
240+
rebuild = True
241+
242+
if rebuild:
243+
self.build_tracker_and_locations_table()
244+
self.update_tracker_and_locations_table()
245+
227246
def build_tracker_and_locations_table(self):
228247
self.tracker_and_locations_panel.clear_widgets()
229248

@@ -268,7 +287,7 @@ def build_tracker_and_locations_table(self):
268287

269288
self.listed_locations[category].append(location_id)
270289
else: # leave it in the generic category
271-
self.listed_locations["(no category)"].append(location_id)
290+
self.listed_locations["(No Category)"].append(location_id)
272291

273292
victory_location = self.ctx.get_location_by_name("__Manual Game Complete__")
274293

@@ -310,7 +329,7 @@ def build_tracker_and_locations_table(self):
310329
locations_in_category = len(self.listed_locations[location_category])
311330

312331
if ("category" in victory_location_data and location_category in victory_location_data["category"]) or \
313-
("category" not in victory_location_data and location_category == "(no category)"):
332+
("category" not in victory_location_data and location_category == "(No Category)"):
314333
locations_in_category += 1
315334

316335
category_tree = locations_panel.add_node(
@@ -329,8 +348,8 @@ def build_tracker_and_locations_table(self):
329348

330349
# if this is the category that Victory is in, display the Victory button
331350
# if ("category" in victory_location_data and location_category in victory_location_data["category"]) or \
332-
# ("category" not in victory_location_data and location_category == "(no category)"):
333-
if (location_category == "(no category)"):
351+
# ("category" not in victory_location_data and location_category == "(No Category)"):
352+
if (location_category == "(No Category)"):
334353

335354
# Add the Victory location to be marked at any point, which is why locations length has 1 added to it above
336355
location_button = TreeViewButton(text="VICTORY! (seed finished)", size_hint=(None, None), height=30, width=400)
@@ -398,12 +417,12 @@ def update_tracker_and_locations_table(self, update_highlights=False):
398417
item_data = self.ctx.get_item_by_name(item_name)
399418

400419
if "category" not in item_data or not item_data["category"]:
401-
item_data["category"] = ["(no category)"]
420+
item_data["category"] = ["(No Category)"]
402421

403422
if category_name in item_data["category"] and network_item.item not in self.listed_items[category_name]:
404423
item_name_parts = self.ctx.item_names[network_item.item].split(":")
405424
item_count = len(list(i for i in self.ctx.items_received if i.item == network_item.item))
406-
item_text = Label(text="%s (%s)" % (item_name_parts[0], item_count),
425+
item_text = Label(text="%s (%s)" % (item_name_parts[0], item_count),
407426
size_hint=(None, None), height=30, width=400, bold=True)
408427

409428
category_grid.add_widget(item_text)

worlds/_manual/Items.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
item_id_to_name = {}
1414
item_name_to_item = {}
15+
item_name_groups = {}
1516
advancement_item_names = set()
1617
lastItemId = -1
1718

@@ -35,10 +36,15 @@
3536
item_name_to_item[item_name] = item
3637
if item["progression"]:
3738
advancement_item_names.add(item_name)
38-
39-
if item["id"] != None:
39+
40+
if item["id"] is not None:
4041
lastItemId = max(lastItemId, item["id"])
4142

43+
for c in item.get("category", []):
44+
if c not in item_name_groups:
45+
item_name_groups[c] = []
46+
item_name_groups[c].append(item_name)
47+
4248
progressive_item_list = {}
4349

4450
for item in progressive_item_table:
@@ -59,6 +65,7 @@
5965
item_id_to_name[None] = "__Victory__"
6066
item_name_to_id = {name: id for id, name in item_id_to_name.items()}
6167

68+
6269
######################
6370
# Item classes
6471
######################

worlds/_manual/Locations.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
if "victory" in location_table[key] and location_table[key]["victory"]:
1919
custom_victory_location = location_table[key]
2020
victory_key = key # store the victory location to be removed later
21-
21+
2222
continue
2323

2424
location_table[key]["id"] = count
@@ -42,11 +42,18 @@
4242

4343
location_id_to_name = {}
4444
location_name_to_location = {}
45+
location_name_groups = {}
4546

4647
for item in location_table:
4748
location_id_to_name[item["id"]] = item["name"]
4849
location_name_to_location[item["name"]] = item
4950

51+
for c in item.get("category", []):
52+
if c not in location_name_groups:
53+
location_name_groups[c] = []
54+
location_name_groups[c].append(item["name"])
55+
56+
5057
# location_id_to_name[None] = "__Manual Game Complete__"
5158
location_name_to_id = {name: id for id, name in location_id_to_name.items()}
5259

worlds/_manual/Rules.py

+20-7
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def infix_to_postfix(expr, location):
2828
while stack:
2929
postfix += stack.pop()
3030
except Exception:
31-
raise KeyError("Invalid logic format for location/region {}.".format(location))
31+
raise KeyError("Invalid logic format for location/region {}.".format(location))
3232
return postfix
3333

3434

@@ -52,8 +52,8 @@ def evaluate_postfix(expr, location):
5252
op = stack.pop()
5353
stack.append(not op)
5454
except Exception:
55-
raise KeyError("Invalid logic format for location/region {}.".format(location))
56-
55+
raise KeyError("Invalid logic format for location/region {}.".format(location))
56+
5757
if len(stack) != 1:
5858
raise KeyError("Invalid logic format for location/region {}.".format(location))
5959
return stack.pop()
@@ -80,19 +80,32 @@ def checkRequireStringForArea(state, area):
8080

8181
if len(item_parts) > 1:
8282
item_name = item_parts[0]
83-
item_count = int(item_parts[1])
83+
item_count = item_parts[1]
8484

8585
total = 0
8686

8787
if require_type == 'category':
88-
category_items = [item["name"] for item in base.item_name_to_item.values() if "category" in item and item_name in item["category"]]
88+
category_items = [item for item in base.item_name_to_item.values() if "category" in item and item_name in item["category"]]
89+
if item_count.lower() == 'all':
90+
item_count = sum([base.item_name_to_item[category_item["name"]]['count'] for category_item in category_items])
91+
elif item_count.lower() == 'half':
92+
item_count = sum([base.item_name_to_item[category_item["name"]]['count'] for category_item in category_items]) / 2
93+
else:
94+
item_count = int(item_count)
8995

9096
for category_item in category_items:
91-
total += state.count(category_item, player)
97+
total += state.count(category_item["name"], player)
9298

9399
if total >= item_count:
94100
requires_list = requires_list.replace(item_base, "1")
95101
elif require_type == 'item':
102+
if item_count.lower() == 'all':
103+
item_count = base.item_name_to_item[item_name]['count']
104+
elif item_count.lower() == 'half':
105+
item_count = base.item_name_to_item[item_name]['count'] / 2
106+
else:
107+
item_count = int(item_count)
108+
96109
total = state.count(item_name, player)
97110

98111
if total >= item_count:
@@ -116,7 +129,7 @@ def checkRequireDictForArea(state, area):
116129
if (isinstance(item, dict) and "or" in item and isinstance(item["or"], list)) or (isinstance(item, list)):
117130
canAccessOr = True
118131
or_items = item
119-
132+
120133
if isinstance(item, dict):
121134
or_items = item["or"]
122135

worlds/_manual/__init__.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
from .Data import item_table, progressive_item_table, location_table, region_table
77
from .Game import game_name, filler_item_name, starting_items
8-
from .Locations import location_id_to_name, location_name_to_id, location_name_to_location
9-
from .Items import item_id_to_name, item_name_to_id, item_name_to_item, advancement_item_names
8+
from .Locations import location_id_to_name, location_name_to_id, location_name_to_location, location_name_groups
9+
from .Items import item_id_to_name, item_name_to_id, item_name_to_item, advancement_item_names, item_name_groups
1010

1111
from .Regions import create_regions
1212
from .Items import ManualItem
@@ -57,11 +57,13 @@ class ManualWorld(World):
5757
item_id_to_name = item_id_to_name
5858
item_name_to_id = item_name_to_id
5959
item_name_to_item = item_name_to_item
60+
item_name_groups = item_name_groups
6061
advancement_item_names = advancement_item_names
6162
location_table = location_table # this is likely imported from Data instead of Locations because the Game Complete location should not be in here, but is used for lookups
6263
location_id_to_name = location_id_to_name
6364
location_name_to_id = location_name_to_id
6465
location_name_to_location = location_name_to_location
66+
location_name_groups = location_name_groups
6567

6668
def pre_fill(self):
6769
before_pre_fill(self, self.multiworld, self.player)

0 commit comments

Comments
 (0)