163 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			163 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
|   | import typing | ||
|  | import random | ||
|  | 
 | ||
|  | from .Locations import location_table, lookup_name_to_id as locations_lookup_name_to_id | ||
|  | from .Items import (createResourcePackName, item_table, progressive_table, progressive_item_list, | ||
|  |     lookup_name_to_item, resourcepack_items as resourcePackItems, lookup_name_to_id as items_lookup_name_to_id) | ||
|  | 
 | ||
|  | from .Regions import create_regions, getConnectionName | ||
|  | from .Rules import set_rules | ||
|  | from .Options import raft_options | ||
|  | 
 | ||
|  | from BaseClasses import Region, RegionType, Entrance, Location, MultiWorld, Item | ||
|  | from ..AutoWorld import World | ||
|  | 
 | ||
|  | class RaftWorld(World): | ||
|  |     """
 | ||
|  |     Raft is a flooded world exploration game. You're stranded on a small raft in the middle of the | ||
|  |     ocean, and you must survive on trash floating by you on the top of the water and around/on any | ||
|  |     islands that you come across. | ||
|  |     """
 | ||
|  |     game: str = "Raft" | ||
|  | 
 | ||
|  |     item_name_to_id = items_lookup_name_to_id.copy() | ||
|  |     lastItemId = max(filter(lambda val: val is not None, item_name_to_id.values())) | ||
|  | 
 | ||
|  |     location_name_to_id = locations_lookup_name_to_id | ||
|  |     options = raft_options | ||
|  | 
 | ||
|  |     data_version = 1 | ||
|  | 
 | ||
|  |     def generate_basic(self): | ||
|  |         minRPSpecified = self.world.minimum_resource_pack_amount[self.player].value | ||
|  |         maxRPSpecified = self.world.maximum_resource_pack_amount[self.player].value | ||
|  |         minimumResourcePackAmount = min(minRPSpecified, maxRPSpecified) | ||
|  |         maximumResourcePackAmount = max(minRPSpecified, maxRPSpecified) | ||
|  |         # Generate item pool | ||
|  |         pool = [] | ||
|  |         for item in item_table: | ||
|  |             raft_item = self.create_item_replaceAsNecessary(item["name"]) | ||
|  |             pool.append(raft_item) | ||
|  | 
 | ||
|  |         extraItemNamePool = [] | ||
|  |         extras = len(location_table) - len(item_table) - 1 # Victory takes up 1 unaccounted-for slot | ||
|  |         if extras > 0: | ||
|  |             if (self.world.use_resource_packs[self.player].value): | ||
|  |                 for packItem in resourcePackItems: | ||
|  |                     for i in range(minimumResourcePackAmount, maximumResourcePackAmount + 1): | ||
|  |                         extraItemNamePool.append(createResourcePackName(i, packItem)) | ||
|  | 
 | ||
|  |             if self.world.duplicate_items[self.player].value != 0: | ||
|  |                 dupeItemPool = item_table.copy() | ||
|  |                 # Remove frequencies if necessary | ||
|  |                 if self.world.island_frequency_locations[self.player].value != 3: # Not completely random locations | ||
|  |                     dupeItemPool = (itm for itm in dupeItemPool if "Frequency" not in itm["name"]) | ||
|  |                  | ||
|  |                 # Remove progression or non-progression items if necessary | ||
|  |                 if (self.world.duplicate_items[self.player].value == 1): # Progression only | ||
|  |                     dupeItemPool = (itm for itm in dupeItemPool if itm["progression"] == True) | ||
|  |                 elif (self.world.duplicate_items[self.player].value == 2): # Non-progression only | ||
|  |                     dupeItemPool = (itm for itm in dupeItemPool if itm["progression"] == False) | ||
|  |                  | ||
|  |                 dupeItemPool = list(dupeItemPool) | ||
|  |                 # Finally, add items as necessary | ||
|  |                 if len(dupeItemPool) > 0: | ||
|  |                     for item in dupeItemPool: | ||
|  |                         extraItemNamePool.append(item["name"]) | ||
|  |              | ||
|  |             if (len(extraItemNamePool) > 0): | ||
|  |                 for randomItem in random.choices(extraItemNamePool, k=extras): | ||
|  |                     raft_item = self.create_item_replaceAsNecessary(randomItem) | ||
|  |                     pool.append(raft_item) | ||
|  | 
 | ||
|  |         self.world.itempool += pool | ||
|  | 
 | ||
|  |     def set_rules(self): | ||
|  |         set_rules(self.world, self.player) | ||
|  | 
 | ||
|  |     def create_regions(self): | ||
|  |         create_regions(self.world, self.player) | ||
|  | 
 | ||
|  |     def fill_slot_data(self): | ||
|  |         slot_data = {} | ||
|  |         return slot_data | ||
|  |      | ||
|  |     def create_item_replaceAsNecessary(self, name: str) -> Item: | ||
|  |         isFrequency = "Frequency" in name | ||
|  |         shouldUseProgressive = ((isFrequency and self.world.island_frequency_locations[self.player].value == 2) | ||
|  |             or (not isFrequency and self.world.progressive_items[self.player].value)) | ||
|  |         if shouldUseProgressive and name in progressive_table: | ||
|  |             name = progressive_table[name] | ||
|  |         return self.create_item(name) | ||
|  | 
 | ||
|  |     def create_item(self, name: str) -> Item: | ||
|  |         item = lookup_name_to_item[name] | ||
|  |         return RaftItem(name, item["progression"], self.item_name_to_id[name], player=self.player) | ||
|  |      | ||
|  |     def create_resourcePack(self, rpName: str) -> Item: | ||
|  |         return RaftItem(rpName, False, self.item_name_to_id[rpName], player=self.player) | ||
|  |      | ||
|  |     def collect_item(self, state, item, remove=False): | ||
|  |         if item.name in progressive_item_list: | ||
|  |             prog_table = progressive_item_list[item.name] | ||
|  |             if remove: | ||
|  |                 for item_name in reversed(prog_table): | ||
|  |                     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(RaftWorld, self).collect_item(state, item, remove) | ||
|  | 
 | ||
|  |     def get_required_client_version(self) -> typing.Tuple[int, int, int]: | ||
|  |         return max((0, 2, 0), super(RaftWorld, self).get_required_client_version()) | ||
|  |      | ||
|  |     def pre_fill(self): | ||
|  |         if self.world.island_frequency_locations[self.player] == 0: | ||
|  |             self.setLocationItem("Radio Tower Frequency to Vasagatan", "Vasagatan Frequency") | ||
|  |             self.setLocationItem("Vasagatan Frequency to Balboa", "Balboa Island Frequency") | ||
|  |             self.setLocationItem("Relay Station quest", "Caravan Island Frequency") | ||
|  |             self.setLocationItem("Caravan Island Frequency to Tangaroa", "Tangaroa Frequency") | ||
|  |         elif self.world.island_frequency_locations[self.player] == 1: | ||
|  |             self.setLocationItemFromRegion("RadioTower", "Vasagatan Frequency") | ||
|  |             self.setLocationItemFromRegion("Vasagatan", "Balboa Island Frequency") | ||
|  |             self.setLocationItemFromRegion("BalboaIsland", "Caravan Island Frequency") | ||
|  |             self.setLocationItemFromRegion("CaravanIsland", "Tangaroa Frequency") | ||
|  |         # Victory item | ||
|  |         self.world.get_location("Tangaroa Next Frequency", self.player).place_locked_item( | ||
|  |             RaftItem("Victory", True, None, player=self.player)) | ||
|  |      | ||
|  |     def setLocationItem(self, location: str, itemName: str): | ||
|  |         itemToUse = next(filter(lambda itm: itm.name == itemName, self.world.itempool)) | ||
|  |         self.world.itempool.remove(itemToUse) | ||
|  |         self.world.get_location(location, self.player).place_locked_item(itemToUse) | ||
|  |      | ||
|  |     def setLocationItemFromRegion(self, region: str, itemName: str): | ||
|  |         itemToUse = next(filter(lambda itm: itm.name == itemName, self.world.itempool)) | ||
|  |         self.world.itempool.remove(itemToUse) | ||
|  |         location = random.choice(list(loc for loc in location_table if loc["region"] == region)) | ||
|  |         self.world.get_location(location["name"], self.player).place_locked_item(itemToUse) | ||
|  | 
 | ||
|  | def create_region(world: MultiWorld, player: int, name: str, locations=None, exits=None): | ||
|  |     ret = Region(name, RegionType.Generic, name, player) | ||
|  |     ret.world = world | ||
|  |     if locations: | ||
|  |         for location in locations: | ||
|  |             loc_id = locations_lookup_name_to_id.get(location, 0) | ||
|  |             locationObj = RaftLocation(player, location, loc_id, ret) | ||
|  |             ret.locations.append(locationObj) | ||
|  |     if exits: | ||
|  |         for exit in exits: | ||
|  |             ret.exits.append(Entrance(player, getConnectionName(name, exit), ret)) | ||
|  | 
 | ||
|  |     return ret | ||
|  | 
 | ||
|  | class RaftLocation(Location): | ||
|  |     game = "Raft" | ||
|  | 
 | ||
|  | 
 | ||
|  | class RaftItem(Item): | ||
|  |     game = "Raft" |