mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 20:21:32 -06:00
354 lines
10 KiB
Python
354 lines
10 KiB
Python
![]() |
from enum import Enum
|
||
|
from typing import Dict, Optional, TYPE_CHECKING, List
|
||
|
from BaseClasses import Item, ItemClassification
|
||
|
from .Data import (
|
||
|
GoodyHutRewardData,
|
||
|
get_era_required_items_data,
|
||
|
get_existing_civics_data,
|
||
|
get_existing_techs_data,
|
||
|
get_goody_hut_rewards_data,
|
||
|
get_progressive_districts_data,
|
||
|
)
|
||
|
from .Enum import CivVICheckType, EraType
|
||
|
from .ProgressiveDistricts import get_flat_progressive_districts
|
||
|
|
||
|
if TYPE_CHECKING:
|
||
|
from . import CivVIWorld
|
||
|
|
||
|
|
||
|
CIV_VI_AP_ITEM_ID_BASE = 5041000
|
||
|
|
||
|
NON_PROGRESSION_DISTRICTS = ["PROGRESSIVE_PRESERVE", "PROGRESSIVE_NEIGHBORHOOD"]
|
||
|
|
||
|
|
||
|
# Items required as progression for boostsanity mode
|
||
|
BOOSTSANITY_PROGRESSION_ITEMS = [
|
||
|
"TECH_THE_WHEEL",
|
||
|
"TECH_MASONRY",
|
||
|
"TECH_ARCHERY",
|
||
|
"TECH_ENGINEERING",
|
||
|
"TECH_CONSTRUCTION",
|
||
|
"TECH_GUNPOWDER",
|
||
|
"TECH_MACHINERY",
|
||
|
"TECH_SIEGE_TACTICS",
|
||
|
"TECH_STIRRUPS",
|
||
|
"TECH_ASTRONOMY",
|
||
|
"TECH_BALLISTICS",
|
||
|
"TECH_STEAM_POWER",
|
||
|
"TECH_SANITATION",
|
||
|
"TECH_COMPUTERS",
|
||
|
"TECH_COMBUSTION",
|
||
|
"TECH_TELECOMMUNICATIONS",
|
||
|
"TECH_ROBOTICS",
|
||
|
"CIVIC_FEUDALISM",
|
||
|
"CIVIC_GUILDS",
|
||
|
"CIVIC_THE_ENLIGHTENMENT",
|
||
|
"CIVIC_MERCANTILISM",
|
||
|
"CIVIC_CONSERVATION",
|
||
|
"CIVIC_CIVIL_SERVICE",
|
||
|
"CIVIC_GLOBALIZATION",
|
||
|
"CIVIC_COLD_WAR",
|
||
|
"CIVIC_URBANIZATION",
|
||
|
"CIVIC_NATIONALISM",
|
||
|
"CIVIC_MOBILIZATION",
|
||
|
"PROGRESSIVE_NEIGHBORHOOD",
|
||
|
"PROGRESSIVE_PRESERVE",
|
||
|
]
|
||
|
|
||
|
|
||
|
class FillerItemRarity(Enum):
|
||
|
COMMON = "COMMON"
|
||
|
UNCOMMON = "UNCOMMON"
|
||
|
RARE = "RARE"
|
||
|
|
||
|
|
||
|
FILLER_DISTRIBUTION: Dict[FillerItemRarity, float] = {
|
||
|
FillerItemRarity.RARE: 0.025,
|
||
|
FillerItemRarity.UNCOMMON: 0.2,
|
||
|
FillerItemRarity.COMMON: 0.775,
|
||
|
}
|
||
|
|
||
|
|
||
|
class FillerItemData:
|
||
|
name: str
|
||
|
type: str
|
||
|
rarity: FillerItemRarity
|
||
|
civ_name: str
|
||
|
|
||
|
def __init__(self, data: GoodyHutRewardData):
|
||
|
self.name = data["Name"]
|
||
|
self.rarity = FillerItemRarity(data["Rarity"])
|
||
|
self.civ_name = data["Type"]
|
||
|
|
||
|
|
||
|
filler_data: Dict[str, FillerItemData] = {
|
||
|
item["Name"]: FillerItemData(item) for item in get_goody_hut_rewards_data()
|
||
|
}
|
||
|
|
||
|
|
||
|
class CivVIItemData:
|
||
|
civ_vi_id: int
|
||
|
classification: ItemClassification
|
||
|
name: str
|
||
|
code: int
|
||
|
cost: int
|
||
|
item_type: CivVICheckType
|
||
|
progressive_name: Optional[str]
|
||
|
civ_name: Optional[str]
|
||
|
era: Optional[EraType]
|
||
|
|
||
|
def __init__(
|
||
|
self,
|
||
|
name: str,
|
||
|
civ_vi_id: int,
|
||
|
cost: int,
|
||
|
item_type: CivVICheckType,
|
||
|
id_offset: int,
|
||
|
classification: ItemClassification,
|
||
|
progressive_name: Optional[str],
|
||
|
civ_name: Optional[str] = None,
|
||
|
era: Optional[EraType] = None,
|
||
|
):
|
||
|
self.classification = classification
|
||
|
self.civ_vi_id = civ_vi_id
|
||
|
self.name = name
|
||
|
self.code = civ_vi_id + CIV_VI_AP_ITEM_ID_BASE + id_offset
|
||
|
self.cost = cost
|
||
|
self.item_type = item_type
|
||
|
self.progressive_name = progressive_name
|
||
|
self.civ_name = civ_name
|
||
|
self.era = era
|
||
|
|
||
|
|
||
|
class CivVIEvent(Item):
|
||
|
game: str = "Civilization VI"
|
||
|
|
||
|
|
||
|
class CivVIItem(Item):
|
||
|
game: str = "Civilization VI"
|
||
|
civ_vi_id: int
|
||
|
item_type: CivVICheckType
|
||
|
|
||
|
def __init__(
|
||
|
self,
|
||
|
item: CivVIItemData,
|
||
|
player: int,
|
||
|
classification: Optional[ItemClassification] = None,
|
||
|
):
|
||
|
super().__init__(
|
||
|
item.name, classification or item.classification, item.code, player
|
||
|
)
|
||
|
self.civ_vi_id = item.civ_vi_id
|
||
|
self.item_type = item.item_type
|
||
|
|
||
|
|
||
|
def format_item_name(name: str) -> str:
|
||
|
name_parts = name.split("_")
|
||
|
return " ".join([part.capitalize() for part in name_parts])
|
||
|
|
||
|
|
||
|
_items_by_civ_name: Dict[str, CivVIItemData] = {}
|
||
|
|
||
|
|
||
|
def get_item_by_civ_name(
|
||
|
item_name: str, item_table: Dict[str, "CivVIItemData"]
|
||
|
) -> "CivVIItemData":
|
||
|
"""Gets the names of the items in the item_table"""
|
||
|
if not _items_by_civ_name:
|
||
|
for item in item_table.values():
|
||
|
if item.civ_name:
|
||
|
_items_by_civ_name[item.civ_name] = item
|
||
|
|
||
|
try:
|
||
|
return _items_by_civ_name[item_name]
|
||
|
except KeyError as e:
|
||
|
raise KeyError(f"Item {item_name} not found in item_table") from e
|
||
|
|
||
|
|
||
|
def _generate_tech_items(
|
||
|
id_base: int, required_items: List[str], progressive_items: Dict[str, str]
|
||
|
) -> Dict[str, CivVIItemData]:
|
||
|
# Generate Techs
|
||
|
existing_techs = get_existing_techs_data()
|
||
|
tech_table: Dict[str, CivVIItemData] = {}
|
||
|
|
||
|
tech_id = 0
|
||
|
for tech in existing_techs:
|
||
|
classification = ItemClassification.useful
|
||
|
name = tech["Name"]
|
||
|
civ_name = tech["Type"]
|
||
|
if civ_name in required_items:
|
||
|
classification = ItemClassification.progression
|
||
|
progressive_name = None
|
||
|
check_type = CivVICheckType.TECH
|
||
|
if civ_name in progressive_items.keys():
|
||
|
progressive_name = format_item_name(progressive_items[civ_name])
|
||
|
|
||
|
tech_table[name] = CivVIItemData(
|
||
|
name=name,
|
||
|
civ_vi_id=tech_id,
|
||
|
cost=tech["Cost"],
|
||
|
item_type=check_type,
|
||
|
id_offset=id_base,
|
||
|
classification=classification,
|
||
|
progressive_name=progressive_name,
|
||
|
civ_name=civ_name,
|
||
|
era=EraType(tech["EraType"]),
|
||
|
)
|
||
|
|
||
|
tech_id += 1
|
||
|
|
||
|
return tech_table
|
||
|
|
||
|
|
||
|
def _generate_civics_items(
|
||
|
id_base: int, required_items: List[str], progressive_items: Dict[str, str]
|
||
|
) -> Dict[str, CivVIItemData]:
|
||
|
civic_id = 0
|
||
|
civic_table: Dict[str, CivVIItemData] = {}
|
||
|
existing_civics = get_existing_civics_data()
|
||
|
|
||
|
for civic in existing_civics:
|
||
|
name = civic["Name"]
|
||
|
civ_name = civic["Type"]
|
||
|
progressive_name = None
|
||
|
check_type = CivVICheckType.CIVIC
|
||
|
|
||
|
if civ_name in progressive_items.keys():
|
||
|
progressive_name = format_item_name(progressive_items[civ_name])
|
||
|
|
||
|
classification = ItemClassification.useful
|
||
|
if civ_name in required_items:
|
||
|
classification = ItemClassification.progression
|
||
|
|
||
|
civic_table[name] = CivVIItemData(
|
||
|
name=name,
|
||
|
civ_vi_id=civic_id,
|
||
|
cost=civic["Cost"],
|
||
|
item_type=check_type,
|
||
|
id_offset=id_base,
|
||
|
classification=classification,
|
||
|
progressive_name=progressive_name,
|
||
|
civ_name=civ_name,
|
||
|
era=EraType(civic["EraType"]),
|
||
|
)
|
||
|
|
||
|
civic_id += 1
|
||
|
|
||
|
return civic_table
|
||
|
|
||
|
|
||
|
def _generate_progressive_district_items(id_base: int) -> Dict[str, CivVIItemData]:
|
||
|
progressive_table: Dict[str, CivVIItemData] = {}
|
||
|
progressive_id_base = 0
|
||
|
progressive_items = get_progressive_districts_data()
|
||
|
for item_name in progressive_items.keys():
|
||
|
classification = (
|
||
|
ItemClassification.useful
|
||
|
if item_name in NON_PROGRESSION_DISTRICTS
|
||
|
else ItemClassification.progression
|
||
|
)
|
||
|
name = format_item_name(item_name)
|
||
|
progressive_table[name] = CivVIItemData(
|
||
|
name=name,
|
||
|
civ_vi_id=progressive_id_base,
|
||
|
cost=0,
|
||
|
item_type=CivVICheckType.PROGRESSIVE_DISTRICT,
|
||
|
id_offset=id_base,
|
||
|
classification=classification,
|
||
|
progressive_name=None,
|
||
|
civ_name=item_name,
|
||
|
)
|
||
|
progressive_id_base += 1
|
||
|
return progressive_table
|
||
|
|
||
|
|
||
|
def _generate_progressive_era_items(id_base: int) -> Dict[str, CivVIItemData]:
|
||
|
"""Generates the single progressive district item"""
|
||
|
era_table: Dict[str, CivVIItemData] = {}
|
||
|
# Generate progressive eras
|
||
|
progressive_era_name = format_item_name("PROGRESSIVE_ERA")
|
||
|
era_table[progressive_era_name] = CivVIItemData(
|
||
|
name=progressive_era_name,
|
||
|
civ_vi_id=0,
|
||
|
cost=0,
|
||
|
item_type=CivVICheckType.ERA,
|
||
|
id_offset=id_base,
|
||
|
classification=ItemClassification.progression,
|
||
|
progressive_name=None,
|
||
|
civ_name="PROGRESSIVE_ERA",
|
||
|
)
|
||
|
return era_table
|
||
|
|
||
|
|
||
|
def _generate_goody_hut_items(id_base: int) -> Dict[str, CivVIItemData]:
|
||
|
# Generate goody hut items
|
||
|
goody_huts = {
|
||
|
item["Name"]: FillerItemData(item) for item in get_goody_hut_rewards_data()
|
||
|
}
|
||
|
goody_table: Dict[str, CivVIItemData] = {}
|
||
|
goody_base = 0
|
||
|
for value in goody_huts.values():
|
||
|
goody_table[value.name] = CivVIItemData(
|
||
|
name=value.name,
|
||
|
civ_vi_id=goody_base,
|
||
|
cost=0,
|
||
|
item_type=CivVICheckType.GOODY,
|
||
|
id_offset=id_base,
|
||
|
classification=ItemClassification.filler,
|
||
|
progressive_name=None,
|
||
|
civ_name=value.civ_name,
|
||
|
)
|
||
|
goody_base += 1
|
||
|
return goody_table
|
||
|
|
||
|
|
||
|
def generate_item_table() -> Dict[str, CivVIItemData]:
|
||
|
era_required_items = get_era_required_items_data()
|
||
|
required_items: List[str] = []
|
||
|
for value in era_required_items.values():
|
||
|
required_items += value
|
||
|
|
||
|
progressive_items = get_flat_progressive_districts()
|
||
|
|
||
|
item_table: Dict[str, CivVIItemData] = {}
|
||
|
|
||
|
def get_id_base():
|
||
|
return len(item_table.keys())
|
||
|
|
||
|
item_table.update(
|
||
|
**_generate_tech_items(get_id_base(), required_items, progressive_items)
|
||
|
)
|
||
|
item_table.update(
|
||
|
**_generate_civics_items(get_id_base(), required_items, progressive_items)
|
||
|
)
|
||
|
item_table.update(**_generate_progressive_district_items(get_id_base()))
|
||
|
item_table.update(**_generate_progressive_era_items(get_id_base()))
|
||
|
item_table.update(**_generate_goody_hut_items(get_id_base()))
|
||
|
|
||
|
return item_table
|
||
|
|
||
|
|
||
|
def get_items_by_type(
|
||
|
item_type: CivVICheckType, item_table: Dict[str, CivVIItemData]
|
||
|
) -> List[CivVIItemData]:
|
||
|
"""
|
||
|
Returns a list of items that match the given item type
|
||
|
"""
|
||
|
return [item for item in item_table.values() if item.item_type == item_type]
|
||
|
|
||
|
|
||
|
fillers_by_rarity: Dict[FillerItemRarity, List[FillerItemData]] = {
|
||
|
rarity: [item for item in filler_data.values() if item.rarity == rarity]
|
||
|
for rarity in FillerItemRarity
|
||
|
}
|
||
|
|
||
|
|
||
|
def get_random_filler_by_rarity(
|
||
|
world: "CivVIWorld", rarity: FillerItemRarity
|
||
|
) -> FillerItemData:
|
||
|
"""
|
||
|
Returns a random filler item by rarity
|
||
|
"""
|
||
|
return world.random.choice(fillers_by_rarity[rarity])
|