106 lines
3.5 KiB
Python
106 lines
3.5 KiB
Python
"""Building / unit catalog ids and costs — docs/FACTIONS.md + docs/GAMEPLAY.md.
|
||
|
||
Ids are stable snake_case (FACTIONS.md). Display names stay out of the sim wire.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from dataclasses import dataclass
|
||
from typing import Final
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class BuildSpec:
|
||
id: str
|
||
pitch: float
|
||
build_s: float
|
||
role: str # hq | dropoff | housing | producer | turret | hall
|
||
tier: int
|
||
pop_bonus: int = 0 # housing only
|
||
hp: float = 1000.0
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class UnitSpec:
|
||
id: str
|
||
pitch: float
|
||
build_s: float
|
||
role: str # worker | scout | melee | ranged | siege | air
|
||
armor: str # Hide | Plate | Ward | Air
|
||
hp: float
|
||
dps: float
|
||
pop: int = 1
|
||
|
||
|
||
# Shared economy numbers (GAMEPLAY.md)
|
||
START_PITCH: Final[float] = 500.0
|
||
START_POP_CAP: Final[int] = 10
|
||
POP_CAP_MAX: Final[int] = 80
|
||
WORKER_PITCH: Final[float] = 50.0
|
||
WORKER_BUILD_S: Final[float] = 12.0
|
||
TURRET_PITCH: Final[float] = 150.0
|
||
HZ: Final[int] = 20
|
||
|
||
# Faction harvest modifiers on well seep into the pool (GAMEPLAY.md)
|
||
STAFF_HARVEST: Final[float] = 0.85 # −15%
|
||
HOST_HARVEST: Final[float] = 1.10 # +10%
|
||
|
||
FACTION_STAFF: Final[str] = "crooked_staff"
|
||
FACTION_HOST: Final[str] = "rust_host"
|
||
|
||
HQ_BY_FACTION: Final[dict[str, str]] = {
|
||
FACTION_STAFF: "bent_keep",
|
||
FACTION_HOST: "scrap_spire",
|
||
}
|
||
WORKER_BY_FACTION: Final[dict[str, str]] = {
|
||
FACTION_STAFF: "well_walker",
|
||
FACTION_HOST: "sump_rig",
|
||
}
|
||
DROPOFF_BY_FACTION: Final[dict[str, str]] = {
|
||
FACTION_STAFF: "pitch_font",
|
||
FACTION_HOST: "sump_press",
|
||
}
|
||
HOUSING_BY_FACTION: Final[dict[str, str]] = {
|
||
FACTION_STAFF: "cot_hall",
|
||
FACTION_HOST: "frame_rack",
|
||
}
|
||
T1_HALL_BY_FACTION: Final[dict[str, str]] = {
|
||
FACTION_STAFF: "coven_yard",
|
||
FACTION_HOST: "bolt_hall",
|
||
}
|
||
T1_MELEE_BY_FACTION: Final[dict[str, str]] = {
|
||
FACTION_STAFF: "acolyte",
|
||
FACTION_HOST: "bolt_hand",
|
||
}
|
||
|
||
BUILDINGS: Final[dict[str, BuildSpec]] = {
|
||
"bent_keep": BuildSpec("bent_keep", 0, 0, "hq", 1, hp=5000.0),
|
||
"scrap_spire": BuildSpec("scrap_spire", 0, 0, "hq", 1, hp=5000.0),
|
||
"pitch_font": BuildSpec("pitch_font", 120, 15, "dropoff", 1, hp=800.0),
|
||
"sump_press": BuildSpec("sump_press", 120, 15, "dropoff", 1, hp=800.0),
|
||
"cot_hall": BuildSpec("cot_hall", 80, 12, "housing", 1, pop_bonus=8, hp=600.0),
|
||
"frame_rack": BuildSpec("frame_rack", 80, 12, "housing", 1, pop_bonus=8, hp=600.0),
|
||
"coven_yard": BuildSpec("coven_yard", 180, 20, "producer", 1, hp=1000.0),
|
||
"bolt_hall": BuildSpec("bolt_hall", 180, 20, "producer", 1, hp=1000.0),
|
||
"ward_post": BuildSpec("ward_post", TURRET_PITCH, 18, "turret", 1, hp=700.0),
|
||
"can_turret": BuildSpec("can_turret", TURRET_PITCH, 18, "turret", 1, hp=700.0),
|
||
"hex_circle": BuildSpec("hex_circle", 250, 25, "hall", 2, hp=1200.0),
|
||
"dynamo": BuildSpec("dynamo", 250, 25, "hall", 2, hp=1200.0),
|
||
}
|
||
|
||
UNITS: Final[dict[str, UnitSpec]] = {
|
||
"well_walker": UnitSpec("well_walker", WORKER_PITCH, WORKER_BUILD_S, "worker", "Hide", 60, 0),
|
||
"sump_rig": UnitSpec("sump_rig", WORKER_PITCH, WORKER_BUILD_S, "worker", "Plate", 70, 0),
|
||
"acolyte": UnitSpec("acolyte", 75, 8, "ranged", "Hide", 40, 4.0),
|
||
"bolt_hand": UnitSpec("bolt_hand", 80, 9, "ranged", "Plate", 55, 3.5),
|
||
"crookhound": UnitSpec("crookhound", 100, 10, "scout", "Hide", 45, 5.0),
|
||
"rattle_scout": UnitSpec("rattle_scout", 110, 11, "scout", "Plate", 50, 4.5),
|
||
}
|
||
|
||
|
||
def harvest_mod(faction: str) -> float:
|
||
if faction == FACTION_STAFF:
|
||
return STAFF_HARVEST
|
||
if faction == FACTION_HOST:
|
||
return HOST_HARVEST
|
||
return 1.0
|