LttP & Factorio: fix item state removal for progressive items.

This commit is contained in:
Fabian Dill 2021-08-21 06:55:08 +02:00
parent 4aeb3cd3dc
commit 6a3d1fcaf4
4 changed files with 92 additions and 48 deletions

View File

@ -58,7 +58,7 @@ def uploads():
game="Minecraft")) game="Minecraft"))
elif file.filename.endswith(".zip"): elif file.filename.endswith(".zip"):
# Factorio mods needs a specific name or they do no function # Factorio mods needs a specific name or they do not function
_, seed_name, slot_id, slot_name = file.filename.rsplit("_", 1)[0].split("-") _, seed_name, slot_id, slot_name = file.filename.rsplit("_", 1)[0].split("-")
slots.add(Slot(data=zfile.open(file, "r").read(), player_name=slot_name, slots.add(Slot(data=zfile.open(file, "r").read(), player_name=slot_name,
player_id=int(slot_id[1:]), game="Factorio")) player_id=int(slot_id[1:]), game="Factorio"))

View File

@ -150,9 +150,10 @@ class World(metaclass=AutoWorldRegister):
# end of Main.py calls # end of Main.py calls
def collect_item(self, state: CollectionState, item: Item) -> Optional[str]: def collect_item(self, state: CollectionState, item: Item, remove=False) -> Optional[str]:
"""Collect an item name into state. For speed reasons items that aren't logically useful get skipped. """Collect an item name into state. For speed reasons items that aren't logically useful get skipped.
Collect None to skip item.""" Collect None to skip item.
:param remove: indicate if this is meant to remove from state instead of adding."""
if item.advancement: if item.advancement:
return item.name return item.name
@ -170,7 +171,7 @@ class World(metaclass=AutoWorldRegister):
return False return False
def remove(self, state: CollectionState, item: Item) -> bool: def remove(self, state: CollectionState, item: Item) -> bool:
name = self.collect_item(state, item) name = self.collect_item(state, item, True)
if name: if name:
state.prog_items[name, item.player] -= 1 state.prog_items[name, item.player] -= 1
if state.prog_items[name, item.player] < 1: if state.prog_items[name, item.player] < 1:
@ -178,6 +179,7 @@ class World(metaclass=AutoWorldRegister):
return True return True
return False return False
# any methods attached to this can be used as part of CollectionState, # any methods attached to this can be used as part of CollectionState,
# please use a prefix as all of them get clobbered together # please use a prefix as all of them get clobbered together
class LogicMixin(metaclass=AutoLogicRegister): class LogicMixin(metaclass=AutoLogicRegister):

View File

@ -86,46 +86,83 @@ class ALTTPWorld(World):
world.random = old_random world.random = old_random
plando_connect(world, player) plando_connect(world, player)
def collect_item(self, state: CollectionState, item: Item): def collect_item(self, state: CollectionState, item: Item, remove=False):
if item.name.startswith('Progressive '): item_name = item.name
if 'Sword' in item.name: if item_name.startswith('Progressive '):
if state.has('Golden Sword', item.player): if remove:
pass if 'Sword' in item_name:
elif state.has('Tempered Sword', item.player) and self.world.difficulty_requirements[ if state.has('Golden Sword', item.player):
item.player].progressive_sword_limit >= 4: return 'Golden Sword'
return 'Golden Sword' elif state.has('Tempered Sword', item.player):
elif state.has('Master Sword', item.player) and self.world.difficulty_requirements[ return 'Tempered Sword'
item.player].progressive_sword_limit >= 3: elif state.has('Master Sword', item.player):
return 'Tempered Sword' return 'Master Sword'
elif state.has('Fighter Sword', item.player) and self.world.difficulty_requirements[item.player].progressive_sword_limit >= 2: elif state.has('Fighter Sword', item.player):
return 'Master Sword' return 'Fighter Sword'
elif self.world.difficulty_requirements[item.player].progressive_sword_limit >= 1: else:
return 'Fighter Sword' return None
elif 'Glove' in item.name: elif 'Glove' in item.name:
if state.has('Titans Mitts', item.player): if state.has('Titans Mitts', item.player):
return return 'Titans Mitts'
elif state.has('Power Glove', item.player): elif state.has('Power Glove', item.player):
return 'Titans Mitts' return 'Power Glove'
else: else:
return 'Power Glove' return None
elif 'Shield' in item.name: elif 'Shield' in item_name:
if state.has('Mirror Shield', item.player): if state.has('Mirror Shield', item.player):
return return 'Mirror Shield'
elif state.has('Red Shield', item.player) and self.world.difficulty_requirements[item.player].progressive_shield_limit >= 3: elif state.has('Red Shield', item.player):
return 'Mirror Shield' return 'Red Shield'
elif state.has('Blue Shield', item.player) and self.world.difficulty_requirements[item.player].progressive_shield_limit >= 2: elif state.has('Blue Shield', item.player):
return 'Red Shield' return 'Blue Shield'
elif self.world.difficulty_requirements[item.player].progressive_shield_limit >= 1: else:
return 'Blue Shield' return None
elif 'Bow' in item.name: elif 'Bow' in item_name:
if state.has('Silver', item.player): if state.has('Silver Bow', item.player):
return return 'Silver Bow'
elif state.has('Bow', item.player) and self.world.difficulty_requirements[item.player].progressive_bow_limit >= 2: elif state.has('Bow', item.player):
return 'Silver Bow' return 'Bow'
elif self.world.difficulty_requirements[item.player].progressive_bow_limit >= 1: else:
return 'Bow' return None
else:
if 'Sword' in item_name:
if state.has('Golden Sword', item.player):
pass
elif state.has('Tempered Sword', item.player) and self.world.difficulty_requirements[
item.player].progressive_sword_limit >= 4:
return 'Golden Sword'
elif state.has('Master Sword', item.player) and self.world.difficulty_requirements[
item.player].progressive_sword_limit >= 3:
return 'Tempered Sword'
elif state.has('Fighter Sword', item.player) and self.world.difficulty_requirements[item.player].progressive_sword_limit >= 2:
return 'Master Sword'
elif self.world.difficulty_requirements[item.player].progressive_sword_limit >= 1:
return 'Fighter Sword'
elif 'Glove' in item_name:
if state.has('Titans Mitts', item.player):
return
elif state.has('Power Glove', item.player):
return 'Titans Mitts'
else:
return 'Power Glove'
elif 'Shield' in item_name:
if state.has('Mirror Shield', item.player):
return
elif state.has('Red Shield', item.player) and self.world.difficulty_requirements[item.player].progressive_shield_limit >= 3:
return 'Mirror Shield'
elif state.has('Blue Shield', item.player) and self.world.difficulty_requirements[item.player].progressive_shield_limit >= 2:
return 'Red Shield'
elif self.world.difficulty_requirements[item.player].progressive_shield_limit >= 1:
return 'Blue Shield'
elif 'Bow' in item_name:
if state.has('Silver', item.player):
return
elif state.has('Bow', item.player) and self.world.difficulty_requirements[item.player].progressive_bow_limit >= 2:
return 'Silver Bow'
elif self.world.difficulty_requirements[item.player].progressive_bow_limit >= 1:
return 'Bow'
elif item.advancement: elif item.advancement:
return item.name return item_name
def pre_fill(self): def pre_fill(self):
from Fill import fill_restrictive, FillError from Fill import fill_restrictive, FillError

View File

@ -140,14 +140,19 @@ class Factorio(World):
world.completion_condition[player] = lambda state: state.has('Victory', player) world.completion_condition[player] = lambda state: state.has('Victory', player)
def collect_item(self, state, item): def collect_item(self, state, item, remove=False):
if item.advancement and item.name in progressive_technology_table: if item.advancement and item.name in progressive_technology_table:
prog_table = progressive_technology_table[item.name].progressive prog_table = progressive_technology_table[item.name].progressive
for item_name in prog_table: if remove:
if not state.has(item_name, item.player): for item_name in reversed(prog_table):
return item_name if state.has(item_name, item.player):
return item_name
else:
for item_name in prog_table:
if not state.has(item_name, item.player):
return item_name
return super(Factorio, self).collect_item(state, item) return super(Factorio, self).collect_item(state, item, remove)
def get_required_client_version(self) -> tuple: def get_required_client_version(self) -> tuple:
return max((0, 1, 6), super(Factorio, self).get_required_client_version()) return max((0, 1, 6), super(Factorio, self).get_required_client_version())