implement "crossover logic".

Makes it impossible that logical progression for a logic-having player is placed inside a no-logic world. All other placements remain available.
This commit is contained in:
Fabian Dill 2020-06-19 03:01:23 +02:00
parent cb1d4cc39e
commit f311d3a8b9
3 changed files with 29 additions and 2 deletions

View File

@ -116,6 +116,10 @@ class World(object):
set_player_attr('triforce_pieces_available', 30)
set_player_attr('triforce_pieces_required', 20)
@property
def player_ids(self):
yield from range(1, self.players + 1)
def get_name_string_for_object(self, obj) -> str:
return obj.name if self.players == 1 else f'{obj.name} ({self.get_player_names(obj.player)})'

View File

@ -208,3 +208,5 @@ for basename, substring in _simple_groups:
tempset.add(itemname)
del (_simple_groups)
progression_items = {name for name, data in item_table.items() if type(data[3]) == int and data[0]}

View File

@ -2,20 +2,24 @@ import collections
import logging
import OverworldGlitchRules
from BaseClasses import RegionType, World, Entrance
from Items import ItemFactory
from Items import ItemFactory, progression_items, item_name_groups
from OverworldGlitchRules import overworld_glitches_rules
def set_rules(world, player):
locality_rules(world, player)
if world.logic[player] == 'nologic':
logging.getLogger('').info('WARNING! Seeds generated under this logic often require major glitches and may be impossible!')
logging.getLogger('').info(
'WARNING! Seeds generated under this logic often require major glitches and may be impossible!')
world.get_region('Menu', player).can_reach_private = lambda state: True
for exit in world.get_region('Menu', player).exits:
exit.hide_path = True
return
crossover_logic(world, player)
global_rules(world, player)
if world.mode[player] != 'inverted':
default_rules(world, player)
@ -148,6 +152,23 @@ def locality_rules(world, player):
forbid_item(location, item, player)
def crossover_logic(world, player):
""" Simple and not graceful solution to logic loops if you mix no logic and logic.
Making it so that logical progression cannot be placed in no logic worlds."""
no_logic_players = set()
for other_player in world.player_ids:
if world.logic[other_player] == 'nologic':
no_logic_players.add(other_player)
if no_logic_players:
for location in world.get_locations():
if location.player in no_logic_players:
for item in progression_items:
forbid_item(location, item, player)
for item in item_name_groups["Small Keys"]:
forbid_item(location, item, player)
for item in item_name_groups["Big Keys"]:
forbid_item(location, item, player)
def global_rules(world, player):
# ganon can only carry triforce
add_item_rule(world.get_location('Ganon', player), lambda item: item.name == 'Triforce' and item.player == player)