| 
									
										
										
										
											2024-05-17 04:13:40 -06:00
										 |  |  | from typing import Any, Dict | 
					
						
							|  |  |  | from BaseClasses import MultiWorld, Region, Location, Item, Tutorial, ItemClassification, CollectionState | 
					
						
							|  |  |  | from worlds.AutoWorld import World, WebWorld | 
					
						
							|  |  |  | from .Items import base_id, item_table, group_table, BRCType | 
					
						
							|  |  |  | from .Locations import location_table, event_table | 
					
						
							|  |  |  | from .Regions import region_exits | 
					
						
							|  |  |  | from .Rules import rules | 
					
						
							|  |  |  | from .Options import BombRushCyberfunkOptions, StartStyle | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BombRushCyberfunkWeb(WebWorld): | 
					
						
							|  |  |  |     theme = "ocean" | 
					
						
							|  |  |  |     tutorials = [Tutorial( | 
					
						
							|  |  |  |         "Multiworld Setup Guide", | 
					
						
							|  |  |  |         "A guide to setting up Bomb Rush Cyberfunk randomizer and connecting to an Archipelago Multiworld", | 
					
						
							|  |  |  |         "English", | 
					
						
							|  |  |  |         "setup_en.md", | 
					
						
							|  |  |  |         "setup/en", | 
					
						
							|  |  |  |         ["TRPG"] | 
					
						
							|  |  |  |     )] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BombRushCyberfunkWorld(World): | 
					
						
							|  |  |  |     """Bomb Rush Cyberfunk is 1 second per second of advanced funkstyle. Battle rival crews and dispatch militarized 
 | 
					
						
							|  |  |  |     police to conquer the five boroughs of New Amsterdam. Become All City."""
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     game = "Bomb Rush Cyberfunk" | 
					
						
							|  |  |  |     web = BombRushCyberfunkWeb() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     item_name_to_id = {item["name"]: (base_id + index) for index, item in enumerate(item_table)} | 
					
						
							|  |  |  |     item_name_to_type = {item["name"]: item["type"] for item in item_table} | 
					
						
							|  |  |  |     location_name_to_id = {loc["name"]: (base_id + index) for index, loc in enumerate(location_table)} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     item_name_groups = group_table | 
					
						
							|  |  |  |     options_dataclass = BombRushCyberfunkOptions | 
					
						
							|  |  |  |     options: BombRushCyberfunkOptions | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, multiworld: MultiWorld, player: int): | 
					
						
							|  |  |  |         super(BombRushCyberfunkWorld, self).__init__(multiworld, player) | 
					
						
							|  |  |  |         self.item_classification: Dict[BRCType, ItemClassification] = { | 
					
						
							|  |  |  |             BRCType.Music: ItemClassification.filler, | 
					
						
							|  |  |  |             BRCType.GraffitiM: ItemClassification.progression, | 
					
						
							|  |  |  |             BRCType.GraffitiL: ItemClassification.progression, | 
					
						
							|  |  |  |             BRCType.GraffitiXL: ItemClassification.progression, | 
					
						
							|  |  |  |             BRCType.Outfit: ItemClassification.filler, | 
					
						
							|  |  |  |             BRCType.Character: ItemClassification.progression, | 
					
						
							|  |  |  |             BRCType.REP: ItemClassification.progression_skip_balancing, | 
					
						
							|  |  |  |             BRCType.Camera: ItemClassification.progression | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def collect(self, state: "CollectionState", item: "Item") -> bool: | 
					
						
							|  |  |  |         change = super().collect(state, item) | 
					
						
							|  |  |  |         if change and "REP" in item.name: | 
					
						
							|  |  |  |             rep: int = int(item.name[0:len(item.name)-4]) | 
					
						
							|  |  |  |             state.prog_items[item.player]["rep"] += rep | 
					
						
							|  |  |  |         return change | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def remove(self, state: "CollectionState", item: "Item") -> bool: | 
					
						
							|  |  |  |         change = super().remove(state, item) | 
					
						
							|  |  |  |         if change and "REP" in item.name: | 
					
						
							|  |  |  |             rep: int = int(item.name[0:len(item.name)-4]) | 
					
						
							|  |  |  |             state.prog_items[item.player]["rep"] -= rep | 
					
						
							|  |  |  |         return change | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_rules(self): | 
					
						
							|  |  |  |         rules(self) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_item_classification(self, item_type: BRCType) -> ItemClassification: | 
					
						
							|  |  |  |         classification = ItemClassification.filler | 
					
						
							|  |  |  |         if item_type in self.item_classification.keys(): | 
					
						
							|  |  |  |             classification = self.item_classification[item_type] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return classification | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_item(self, name: str) -> "BombRushCyberfunkItem": | 
					
						
							|  |  |  |         item_id: int = self.item_name_to_id[name] | 
					
						
							|  |  |  |         item_type: BRCType = self.item_name_to_type[name] | 
					
						
							|  |  |  |         classification = self.get_item_classification(item_type) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return BombRushCyberfunkItem(name, classification, item_id, self.player) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_event(self, event: str) -> "BombRushCyberfunkItem": | 
					
						
							|  |  |  |         return BombRushCyberfunkItem(event, ItemClassification.progression_skip_balancing, None, self.player) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_filler_item_name(self) -> str: | 
					
						
							|  |  |  |         item = self.random.choice(item_table) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         while self.get_item_classification(item["type"]) == ItemClassification.progression: | 
					
						
							|  |  |  |             item = self.random.choice(item_table) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return item["name"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def generate_early(self): | 
					
						
							|  |  |  |         if self.options.starting_movestyle == StartStyle.option_skateboard: | 
					
						
							|  |  |  |             self.item_classification[BRCType.Skateboard] = ItemClassification.filler | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.item_classification[BRCType.Skateboard] = ItemClassification.progression | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if self.options.starting_movestyle == StartStyle.option_inline_skates: | 
					
						
							|  |  |  |             self.item_classification[BRCType.InlineSkates] = ItemClassification.filler | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.item_classification[BRCType.InlineSkates] = ItemClassification.progression | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         if self.options.starting_movestyle == StartStyle.option_bmx: | 
					
						
							|  |  |  |             self.item_classification[BRCType.BMX] = ItemClassification.filler | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.item_classification[BRCType.BMX] = ItemClassification.progression | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_items(self): | 
					
						
							|  |  |  |         rep_locations: int = 87 | 
					
						
							|  |  |  |         if self.options.skip_polo_photos: | 
					
						
							| 
									
										
										
										
											2024-06-07 11:11:35 -06:00
										 |  |  |             rep_locations -= 17 | 
					
						
							| 
									
										
										
										
											2024-05-17 04:13:40 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.options.total_rep.round_to_nearest_step() | 
					
						
							|  |  |  |         rep_counts = self.options.total_rep.get_rep_item_counts(self.random, rep_locations) | 
					
						
							|  |  |  |         #print(sum([8*rep_counts[0], 16*rep_counts[1], 24*rep_counts[2], 32*rep_counts[3], 48*rep_counts[4]]), \ | 
					
						
							|  |  |  |         #    rep_counts) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         pool = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for item in item_table: | 
					
						
							|  |  |  |             if "REP" in item["name"]: | 
					
						
							|  |  |  |                 count: int = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if item["name"] == "8 REP": | 
					
						
							|  |  |  |                     count = rep_counts[0] | 
					
						
							|  |  |  |                 elif item["name"] == "16 REP": | 
					
						
							|  |  |  |                     count = rep_counts[1] | 
					
						
							|  |  |  |                 elif item["name"] == "24 REP": | 
					
						
							|  |  |  |                     count = rep_counts[2] | 
					
						
							|  |  |  |                 elif item["name"] == "32 REP": | 
					
						
							|  |  |  |                     count = rep_counts[3] | 
					
						
							|  |  |  |                 elif item["name"] == "48 REP": | 
					
						
							|  |  |  |                     count = rep_counts[4] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if count > 0: | 
					
						
							|  |  |  |                     for _ in range(count): | 
					
						
							|  |  |  |                         pool.append(self.create_item(item["name"])) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 pool.append(self.create_item(item["name"])) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.multiworld.itempool += pool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_regions(self): | 
					
						
							|  |  |  |         multiworld = self.multiworld | 
					
						
							|  |  |  |         player = self.player | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         menu = Region("Menu", player, multiworld) | 
					
						
							|  |  |  |         multiworld.regions.append(menu) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for n in region_exits: | 
					
						
							|  |  |  |             multiworld.regions += [Region(n, player, multiworld)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         menu.add_exits({"Hideout": "New Game"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for n in region_exits: | 
					
						
							|  |  |  |             self.get_region(n).add_exits(region_exits[n]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for index, loc in enumerate(location_table): | 
					
						
							| 
									
										
										
										
											2024-06-07 11:11:35 -06:00
										 |  |  |             if self.options.skip_polo_photos and "Polo" in loc["game_id"]: | 
					
						
							| 
									
										
										
										
											2024-05-17 04:13:40 -06:00
										 |  |  |                 continue | 
					
						
							|  |  |  |             stage: Region = self.get_region(loc["stage"]) | 
					
						
							|  |  |  |             stage.add_locations({loc["name"]: base_id + index}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for e in event_table: | 
					
						
							|  |  |  |             stage: Region = self.get_region(e["stage"]) | 
					
						
							|  |  |  |             event = BombRushCyberfunkLocation(player, e["name"], None, stage) | 
					
						
							|  |  |  |             event.show_in_spoiler = False | 
					
						
							|  |  |  |             event.place_locked_item(self.create_event(e["item"])) | 
					
						
							|  |  |  |             stage.locations += [event] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         multiworld.completion_condition[player] = lambda state: state.has("Victory", player) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def fill_slot_data(self) -> Dict[str, Any]: | 
					
						
							|  |  |  |         options = self.options | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         slot_data: Dict[str, Any] = { | 
					
						
							|  |  |  |             "locations": {loc["game_id"]: (base_id + index) for index, loc in enumerate(location_table)}, | 
					
						
							|  |  |  |             "logic": options.logic.value, | 
					
						
							|  |  |  |             "skip_intro": bool(options.skip_intro.value), | 
					
						
							|  |  |  |             "skip_dreams": bool(options.skip_dreams.value), | 
					
						
							|  |  |  |             "skip_statue_hands": bool(options.skip_statue_hands.value), | 
					
						
							|  |  |  |             "total_rep": options.total_rep.value, | 
					
						
							|  |  |  |             "extra_rep_required": bool(options.extra_rep_required.value), | 
					
						
							|  |  |  |             "starting_movestyle": options.starting_movestyle.value, | 
					
						
							|  |  |  |             "limited_graffiti": bool(options.limited_graffiti.value), | 
					
						
							|  |  |  |             "small_graffiti_uses": options.small_graffiti_uses.value, | 
					
						
							|  |  |  |             "skip_polo_photos": bool(options.skip_polo_photos.value), | 
					
						
							|  |  |  |             "dont_save_photos": bool(options.dont_save_photos.value), | 
					
						
							|  |  |  |             "score_difficulty": int(options.score_difficulty.value), | 
					
						
							|  |  |  |             "damage_multiplier": options.damage_multiplier.value, | 
					
						
							|  |  |  |             "death_link": bool(options.death_link.value) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return slot_data | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BombRushCyberfunkItem(Item): | 
					
						
							|  |  |  |     game: str = "Bomb Rush Cyberfunk" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BombRushCyberfunkLocation(Location): | 
					
						
							| 
									
										
										
										
											2024-05-17 13:24:32 -04:00
										 |  |  |     game: str = "Bomb Rush Cyberfunk" |