 cae1e683e2
			
		
	
	cae1e683e2
	
	
	
		
			
			## Adding in Explore Mode: Features include: * Added in `environments` to be items. * `Location checks` are now `environment based` instead of being able to get them from anywhere. * Added in support for the `DLC Survivors of the void` which include `Void Items` and `3 new maps` that come with it. (option added to use DLC) --------- Co-authored-by: Dogpetkid <dogpetkid@gmail.com>
		
			
				
	
	
		
			120 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from typing import Tuple
 | |
| from BaseClasses import Location
 | |
| from .Options import TotalLocations
 | |
| from .Options import ChestsPerEnvironment
 | |
| from .Options import ShrinesPerEnvironment
 | |
| from .Options import ScavengersPerEnvironment
 | |
| from .Options import ScannersPerEnvironment
 | |
| from .Options import AltarsPerEnvironment
 | |
| from .RoR2Environments import *
 | |
| 
 | |
| 
 | |
| class RiskOfRainLocation(Location):
 | |
|     game: str = "Risk of Rain 2"
 | |
| 
 | |
| 
 | |
| ror2_locations_start_id = 38000
 | |
| 
 | |
| 
 | |
| def get_classic_item_pickups(n: int) -> Dict[str, int]:
 | |
|     """Get n ItemPickups, capped at the max value for TotalLocations"""
 | |
|     n = max(n, 0)
 | |
|     n = min(n, TotalLocations.range_end)
 | |
|     return { f"ItemPickup{i+1}": ror2_locations_start_id+i for i in range(n) }
 | |
| 
 | |
| 
 | |
| item_pickups = get_classic_item_pickups(TotalLocations.range_end)
 | |
| location_table = item_pickups
 | |
| 
 | |
| 
 | |
| def environment_abreviation(long_name:str) -> str:
 | |
|     """convert long environment names to initials"""
 | |
|     abrev = ""
 | |
|     # go through every word finding a letter (or number) for an initial
 | |
|     for word in long_name.split():
 | |
|         initial = word[0]
 | |
|         for letter in word:
 | |
|             if letter.isalnum():
 | |
|                 initial = letter
 | |
|                 break
 | |
|         abrev+= initial
 | |
|     return abrev
 | |
| 
 | |
| # highest numbered orderedstages (this is so we can treat the easily caculate the check ids based on the environment and location "offset")
 | |
| highest_orderedstage: int= max(compress_dict_list_horizontal(environment_orderedstages_table).values())
 | |
| 
 | |
| ror2_locations_start_orderedstage = ror2_locations_start_id + TotalLocations.range_end
 | |
| 
 | |
| class orderedstage_location:
 | |
|     """A class to behave like a struct for storing the offsets of location types in the allocated space per orderedstage environments."""
 | |
|     # TODO is there a better, more generic way to do this?
 | |
|     offset_ChestsPerEnvironment     = 0
 | |
|     offset_ShrinesPerEnvironment    = offset_ChestsPerEnvironment       + ChestsPerEnvironment.range_end
 | |
|     offset_ScavengersPerEnvironment = offset_ShrinesPerEnvironment      + ShrinesPerEnvironment.range_end
 | |
|     offset_ScannersPerEnvironment   = offset_ScavengersPerEnvironment   + ScavengersPerEnvironment.range_end
 | |
|     offset_AltarsPerEnvironment     = offset_ScannersPerEnvironment     + ScannersPerEnvironment.range_end
 | |
| 
 | |
|     # total space allocated to the locations in a single orderedstage environment
 | |
|     allocation = offset_AltarsPerEnvironment + AltarsPerEnvironment.range_end
 | |
| 
 | |
|     def get_environment_locations(chests:int, shrines:int, scavengers:int, scanners:int, altars:int, environment: Tuple[str, int]) -> Dict[str, int]:
 | |
|         """Get the locations within a specific environment"""
 | |
|         environment_name = environment[0]
 | |
|         environment_index = environment[1]
 | |
|         locations = {}
 | |
| 
 | |
|         # due to this mapping, since environment ids are not consecutive, there are lots of "wasted" id numbers
 | |
|         # TODO perhaps a hashing algorithm could be used to compress this range and save "wasted" ids
 | |
|         environment_start_id = environment_index * orderedstage_location.allocation + ror2_locations_start_orderedstage
 | |
|         for n in range(chests):
 | |
|             locations.update({f"{environment_name}: Chest {n+1}":            n + orderedstage_location.offset_ChestsPerEnvironment       + environment_start_id})
 | |
|         for n in range(shrines):
 | |
|             locations.update({f"{environment_name}: Shrine {n+1}":           n + orderedstage_location.offset_ShrinesPerEnvironment      + environment_start_id})
 | |
|         for n in range(scavengers):
 | |
|             locations.update({f"{environment_name}: Scavenger {n+1}":        n + orderedstage_location.offset_ScavengersPerEnvironment   + environment_start_id})
 | |
|         for n in range(scanners):
 | |
|             locations.update({f"{environment_name}: Radio Scanner {n+1}":    n + orderedstage_location.offset_ScannersPerEnvironment     + environment_start_id})
 | |
|         for n in range(altars):
 | |
|             locations.update({f"{environment_name}: Newt Altar {n+1}":       n + orderedstage_location.offset_AltarsPerEnvironment       + environment_start_id})
 | |
|         return locations
 | |
| 
 | |
|     def get_locations(chests:int, shrines:int, scavengers:int, scanners:int, altars:int, dlc_sotv:bool) -> Dict[str, int]:
 | |
|         """Get a dictionary of locations for the ordedstage environments with the locations from the parameters."""
 | |
|         locations = {}
 | |
|         orderedstages = compress_dict_list_horizontal(environment_vanilla_orderedstages_table)
 | |
|         if(dlc_sotv): orderedstages.update(compress_dict_list_horizontal(environment_sotv_orderedstages_table))
 | |
|         # for every environment, generate the respective locations
 | |
|         for environment_name, environment_index in orderedstages.items():
 | |
|             # locations = locations | orderedstage_location.get_environment_locations(
 | |
|             locations.update(orderedstage_location.get_environment_locations(
 | |
|                 chests=chests,
 | |
|                 shrines=shrines,
 | |
|                 scavengers=scavengers,
 | |
|                 scanners=scanners,
 | |
|                 altars=altars,
 | |
|                 environment=(environment_name, environment_index)
 | |
|             ))
 | |
|         return locations
 | |
| 
 | |
|     def getall_locations(dlc_sotv:bool=True) -> Dict[str, int]:
 | |
|         """
 | |
|         Get all locations in ordered stages.
 | |
|         Set dlc_sotv to true for the SOTV DLC to be included.
 | |
|         """
 | |
|         # to get all locations, attempt using as many locations as possible
 | |
|         return orderedstage_location.get_locations(
 | |
|             chests=ChestsPerEnvironment.range_end,
 | |
|             shrines=ShrinesPerEnvironment.range_end,
 | |
|             scavengers=ScavengersPerEnvironment.range_end,
 | |
|             scanners=ScannersPerEnvironment.range_end,
 | |
|             altars=AltarsPerEnvironment.range_end,
 | |
|             dlc_sotv=dlc_sotv
 | |
|         )
 | |
| 
 | |
| 
 | |
| ror2_location_post_orderedstage = ror2_locations_start_orderedstage + highest_orderedstage*orderedstage_location.allocation
 | |
| location_table.update(orderedstage_location.getall_locations())
 | |
| # use the sotv dlc in the lookup table so that all ids can be looked up regardless of use
 | |
| 
 | |
| lookup_id_to_name: Dict[int, str] = {id: name for name, id in location_table.items()}
 |