164 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			164 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Python
		
	
	
	
| import csv
 | |
| import enum
 | |
| import math
 | |
| from dataclasses import dataclass, field
 | |
| from random import Random
 | |
| from typing import Dict, List, Set
 | |
| 
 | |
| from BaseClasses import Item, ItemClassification
 | |
| from . import Options, data
 | |
| 
 | |
| 
 | |
| class DLCQuestItem(Item):
 | |
|     game: str = "DLCQuest"
 | |
|     coins: int = 0
 | |
|     coin_suffix: str = ""
 | |
| 
 | |
| 
 | |
| offset = 120_000
 | |
| 
 | |
| 
 | |
| class Group(enum.Enum):
 | |
|     DLC = enum.auto()
 | |
|     DLCQuest = enum.auto()
 | |
|     Freemium = enum.auto()
 | |
|     Item = enum.auto()
 | |
|     Coin = enum.auto()
 | |
|     Trap = enum.auto()
 | |
|     Twice = enum.auto()
 | |
|     Piece = enum.auto()
 | |
|     Deprecated = enum.auto()
 | |
| 
 | |
| 
 | |
| 
 | |
| @dataclass(frozen=True)
 | |
| class ItemData:
 | |
|     code_without_offset: offset
 | |
|     name: str
 | |
|     classification: ItemClassification
 | |
|     groups: Set[Group] = field(default_factory=frozenset)
 | |
| 
 | |
|     def __post_init__(self):
 | |
|         if not isinstance(self.groups, frozenset):
 | |
|             super().__setattr__("groups", frozenset(self.groups))
 | |
| 
 | |
|     @property
 | |
|     def code(self):
 | |
|         return offset + self.code_without_offset if self.code_without_offset is not None else None
 | |
| 
 | |
|     def has_any_group(self, *group: Group) -> bool:
 | |
|         groups = set(group)
 | |
|         return bool(groups.intersection(self.groups))
 | |
| 
 | |
| 
 | |
| def load_item_csv():
 | |
|     try:
 | |
|         from importlib.resources import files
 | |
|     except ImportError:
 | |
|         from importlib_resources import files  # noqa
 | |
| 
 | |
|     items = []
 | |
|     with files(data).joinpath("items.csv").open() as file:
 | |
|         item_reader = csv.DictReader(file)
 | |
|         for item in item_reader:
 | |
|             id = int(item["id"]) if item["id"] else None
 | |
|             classification = ItemClassification[item["classification"]]
 | |
|             groups = {Group[group] for group in item["groups"].split(",") if group}
 | |
|             items.append(ItemData(id, item["name"], classification, groups))
 | |
|     return items
 | |
| 
 | |
| 
 | |
| all_items: List[ItemData] = load_item_csv()
 | |
| item_table: Dict[str, ItemData] = {}
 | |
| items_by_group: Dict[Group, List[ItemData]] = {}
 | |
| 
 | |
| 
 | |
| def initialize_item_table():
 | |
|     item_table.update({item.name: item for item in all_items})
 | |
| 
 | |
| 
 | |
| def initialize_groups():
 | |
|     for item in all_items:
 | |
|         for group in item.groups:
 | |
|             item_group = items_by_group.get(group, list())
 | |
|             item_group.append(item)
 | |
|             items_by_group[group] = item_group
 | |
| 
 | |
| 
 | |
| initialize_item_table()
 | |
| initialize_groups()
 | |
| 
 | |
| 
 | |
| def create_trap_items(world, world_options: Options.DLCQuestOptions, trap_needed: int, random: Random) -> List[Item]:
 | |
|     traps = []
 | |
|     for i in range(trap_needed):
 | |
|         trap = random.choice(items_by_group[Group.Trap])
 | |
|         traps.append(world.create_item(trap, ItemClassification.trap))
 | |
| 
 | |
|     return traps
 | |
| 
 | |
| 
 | |
| def create_items(world, world_options: Options.DLCQuestOptions, locations_count: int, random: Random):
 | |
|     created_items = []
 | |
|     if world_options.campaign == Options.Campaign.option_basic or world_options.campaign == Options.Campaign.option_both:
 | |
|         create_items_basic(world_options, created_items, world)
 | |
| 
 | |
|     if (world_options.campaign == Options.Campaign.option_live_freemium_or_die or
 | |
|             world_options.campaign == Options.Campaign.option_both):
 | |
|         create_items_lfod(world_options, created_items, world)
 | |
| 
 | |
|     trap_items = create_trap_items(world, world_options, locations_count - len(created_items), random)
 | |
|     created_items += trap_items
 | |
| 
 | |
|     return created_items
 | |
| 
 | |
| 
 | |
| def create_items_lfod(world_options, created_items, world):
 | |
|     for item in items_by_group[Group.Freemium]:
 | |
|         if item.has_any_group(Group.DLC):
 | |
|             created_items.append(world.create_item(item))
 | |
|         if item.has_any_group(Group.Item) and world_options.item_shuffle == Options.ItemShuffle.option_shuffled:
 | |
|             created_items.append(world.create_item(item))
 | |
|             if item.has_any_group(Group.Twice):
 | |
|                 created_items.append(world.create_item(item))
 | |
|     if world_options.coinsanity == Options.CoinSanity.option_coin:
 | |
|         if world_options.coinbundlequantity == -1:
 | |
|             create_coin_piece(created_items, world, 889, 200, Group.Freemium)
 | |
|             return
 | |
|         create_coin(world_options, created_items, world, 889, 200, Group.Freemium)
 | |
| 
 | |
| 
 | |
| def create_items_basic(world_options, created_items, world):
 | |
|     for item in items_by_group[Group.DLCQuest]:
 | |
|         if item.has_any_group(Group.DLC):
 | |
|             created_items.append(world.create_item(item))
 | |
|         if item.has_any_group(Group.Item) and world_options.item_shuffle == Options.ItemShuffle.option_shuffled:
 | |
|             created_items.append(world.create_item(item))
 | |
|             if item.has_any_group(Group.Twice):
 | |
|                 created_items.append(world.create_item(item))
 | |
|     if world_options.coinsanity == Options.CoinSanity.option_coin:
 | |
|         if world_options.coinbundlequantity == -1:
 | |
|             create_coin_piece(created_items, world, 825, 250, Group.DLCQuest)
 | |
|             return
 | |
|         create_coin(world_options, created_items, world, 825, 250, Group.DLCQuest)
 | |
| 
 | |
| 
 | |
| def create_coin(world_options, created_items, world, total_coins, required_coins, group):
 | |
|     coin_bundle_required = math.ceil(required_coins / world_options.coinbundlequantity)
 | |
|     coin_bundle_useful = math.ceil((total_coins - coin_bundle_required * world_options.coinbundlequantity) / world_options.coinbundlequantity)
 | |
|     for item in items_by_group[group]:
 | |
|         if item.has_any_group(Group.Coin):
 | |
|             for i in range(coin_bundle_required):
 | |
|                 created_items.append(world.create_item(item))
 | |
|             for i in range(coin_bundle_useful):
 | |
|                 created_items.append(world.create_item(item, ItemClassification.useful))
 | |
| 
 | |
| 
 | |
| def create_coin_piece(created_items, world, total_coins, required_coins, group):
 | |
|     for item in items_by_group[group]:
 | |
|         if item.has_any_group(Group.Piece):
 | |
|             for i in range(required_coins*10):
 | |
|                 created_items.append(world.create_item(item))
 | |
|             for i in range((total_coins - required_coins) * 10):
 | |
|                 created_items.append(world.create_item(item, ItemClassification.useful))
 |