Compare commits
No commits in common. "dev" and "main" have entirely different histories.
6 changed files with 27 additions and 309 deletions
10
README.md
10
README.md
|
|
@ -32,10 +32,8 @@ is saved after each edit or result, so you can stop and resume later.
|
|||
|
||||
The main menu also has a fully randomized one-off show (choose a game first) and
|
||||
Season Mode. Seasons save separately under `seasons/` and book Raw → Thursday
|
||||
Night SmackDown! → WWF PPV repeatedly. New season champions can be selected,
|
||||
randomized, or left vacant. Built-in seasons ask which wrestlers are eligible
|
||||
for the Light-Heavyweight division; that selection is saved with the season.
|
||||
Semi-random cards use division rankings and repeat-match rivalries;
|
||||
Night SmackDown! → WWF PPV repeatedly. New season champions can be selected, randomized, or left
|
||||
vacant. Semi-random cards use division rankings and repeat-match rivalries;
|
||||
title defenses are possible on any show and are weighted more heavily on PPVs.
|
||||
PPV cards may feature up to two title defenses, while weekly shows may feature
|
||||
one. Mark each season match with a ranking division, and separately mark title
|
||||
|
|
@ -71,8 +69,8 @@ federation, not just the built-in WWF games:
|
|||
- **Create a new game and federation** — name the game, pick the federation and
|
||||
platform (PlayStation 1, PlayStation 2, or other), name the federation's
|
||||
three shows, list the roster, edit the suggested match types, and add any
|
||||
championship/ranking divisions (singles, tag team, women's, or
|
||||
Light-Heavyweight). Restricted divisions let you choose eligible wrestlers.
|
||||
championship/ranking divisions (singles, tag team, or women's). A women's
|
||||
division asks which roster members are eligible.
|
||||
- **Copy a built-in WWF game to edit** — clones any built-in game into your own
|
||||
editable profile; the built-in games themselves stay unchanged.
|
||||
- **Edit a custom game** — reopen any saved profile.
|
||||
|
|
|
|||
|
|
@ -41,10 +41,6 @@ def edit_custom_roster(config: dict[str, Any]) -> None:
|
|||
removed = config["roster"].pop(index)
|
||||
config["women_roster"] = [name for name in config["women_roster"]
|
||||
if name.casefold() != removed.casefold()]
|
||||
config["light_heavyweight_roster"] = [
|
||||
name for name in config.get("light_heavyweight_roster", [])
|
||||
if name.casefold() != removed.casefold()
|
||||
]
|
||||
|
||||
|
||||
def edit_custom_match_types(config: dict[str, Any]) -> None:
|
||||
|
|
@ -121,24 +117,19 @@ def edit_custom_titles(config: dict[str, Any]) -> None:
|
|||
if not name or any(item["name"].casefold() == name.casefold() for item in existing):
|
||||
print("Enter a non-empty championship name not already listed.")
|
||||
continue
|
||||
kind_options = ["singles", "tag", "women", "light_heavyweight"]
|
||||
kind_labels = ["Singles / open", "Tag team", "Women's division",
|
||||
"Light-Heavyweight division"]
|
||||
kind_options = ["singles", "tag", "women"]
|
||||
kind_labels = ["Singles / open", "Tag team", "Women's division"]
|
||||
kind = kind_options[app.ask_choice("Championship type", kind_options, labels=kind_labels)]
|
||||
existing.append({"name": name, "kind": kind})
|
||||
|
||||
|
||||
def edit_eligible_roster(config: dict[str, Any], field: str, division: str,
|
||||
require_eligible: bool = False) -> None:
|
||||
eligible = config.setdefault(field, [])
|
||||
def edit_women_roster(config: dict[str, Any]) -> None:
|
||||
while True:
|
||||
choices = ["add", "remove", "done"]
|
||||
labels = ["Add eligible wrestler", "Remove eligible wrestler", "Done"]
|
||||
action = app.ask_choice(f"{division} eligibility", choices, labels=labels)
|
||||
action = app.ask_choice("Women's division eligibility", choices, labels=labels)
|
||||
eligible = config["women_roster"]
|
||||
if action == 2:
|
||||
if require_eligible and not eligible:
|
||||
print(f"Choose at least one eligible wrestler for the {division} division.")
|
||||
continue
|
||||
return
|
||||
if action == 0:
|
||||
available = [name for name in config["roster"]
|
||||
|
|
@ -155,16 +146,6 @@ def edit_eligible_roster(config: dict[str, Any], field: str, division: str,
|
|||
eligible.pop(remove_index)
|
||||
|
||||
|
||||
def edit_women_roster(config: dict[str, Any]) -> None:
|
||||
edit_eligible_roster(config, "women_roster", "Women's division")
|
||||
|
||||
|
||||
def edit_light_heavyweight_roster(config: dict[str, Any]) -> None:
|
||||
edit_eligible_roster(
|
||||
config, "light_heavyweight_roster", "Light-Heavyweight", require_eligible=True
|
||||
)
|
||||
|
||||
|
||||
def edit_custom_shows(config: dict[str, Any]) -> None:
|
||||
while True:
|
||||
shows = config["shows"]
|
||||
|
|
@ -188,24 +169,13 @@ def edit_custom_shows(config: dict[str, Any]) -> None:
|
|||
|
||||
def edit_custom_profile(config: dict[str, Any]) -> dict[str, Any]:
|
||||
while True:
|
||||
options = ["identity", "shows", "roster", "match_types", "titles", "women"]
|
||||
options = ["identity", "shows", "roster", "match_types", "titles", "women", "save"]
|
||||
labels = ["Game/federation, platform, screenshot directory",
|
||||
f"Show names (Raw: {config['shows']['Raw']})",
|
||||
f"Edit roster ({len(config['roster'])} wrestlers)",
|
||||
f"Edit match types ({len(config['match_types'])})",
|
||||
f"Edit championships ({len(config['championships'])})",
|
||||
f"Edit Women's eligibility ({len(config['women_roster'])})"]
|
||||
has_light_heavyweight = any(
|
||||
title.get("kind") == "light_heavyweight" for title in config["championships"]
|
||||
)
|
||||
if has_light_heavyweight:
|
||||
options.append("light_heavyweight")
|
||||
labels.append(
|
||||
f"Edit Light-Heavyweight eligibility "
|
||||
f"({len(config.get('light_heavyweight_roster', []))})"
|
||||
)
|
||||
options.append("save")
|
||||
labels.append("Validate and save")
|
||||
f"Edit Women's eligibility ({len(config['women_roster'])})", "Validate and save"]
|
||||
action = app.ask_choice("BYOG editor", options, labels=labels)
|
||||
if action == 0:
|
||||
config["game_title"] = app.ask("Game title", config["game_title"]).strip()
|
||||
|
|
@ -231,12 +201,7 @@ def edit_custom_profile(config: dict[str, Any]) -> dict[str, Any]:
|
|||
app.edit_custom_titles(config)
|
||||
elif action == 5:
|
||||
app.edit_women_roster(config)
|
||||
elif has_light_heavyweight and action == 6:
|
||||
app.edit_light_heavyweight_roster(config)
|
||||
else:
|
||||
if has_light_heavyweight and not config.get("light_heavyweight_roster"):
|
||||
print("Choose eligible Light-Heavyweight wrestlers before saving this profile.")
|
||||
continue
|
||||
try:
|
||||
return app.save_custom_game(config)
|
||||
except ValueError as exc:
|
||||
|
|
@ -260,7 +225,6 @@ def builtin_profile_for_copy(game_id: str, custom_id: str) -> dict[str, Any]:
|
|||
"match_types": definitions,
|
||||
"championships": app.title_definitions_for_game(game_id),
|
||||
"women_roster": sorted(app.WOMEN_ROSTERS.get(game_id, set())),
|
||||
"light_heavyweight_roster": app.load_roster(game_id),
|
||||
"shows": {"Raw": "Monday Night Raw", "SmackDown": "Thursday Night SmackDown!",
|
||||
"PPV": "WWF PPV"},
|
||||
})
|
||||
|
|
@ -297,7 +261,6 @@ def create_custom_game() -> dict[str, Any]:
|
|||
"match_types": [],
|
||||
"championships": [],
|
||||
"women_roster": [],
|
||||
"light_heavyweight_roster": [],
|
||||
"shows": shows,
|
||||
}
|
||||
app.edit_custom_roster(config)
|
||||
|
|
@ -310,8 +273,6 @@ def create_custom_game() -> dict[str, Any]:
|
|||
app.edit_custom_titles(config)
|
||||
if any(title["kind"] == "women" for title in config["championships"]):
|
||||
app.edit_women_roster(config)
|
||||
if any(title["kind"] == "light_heavyweight" for title in config["championships"]):
|
||||
app.edit_light_heavyweight_roster(config)
|
||||
return app.edit_custom_profile(config)
|
||||
|
||||
|
||||
|
|
@ -329,9 +290,6 @@ def clone_builtin_game() -> dict[str, Any]:
|
|||
config = app.builtin_profile_for_copy(source_id, app.new_custom_game_id(federation, title))
|
||||
config["game_title"] = title or config["game_title"]
|
||||
config["federation_name"] = federation or config["federation_name"]
|
||||
if any(item["kind"] == "light_heavyweight" for item in config["championships"]):
|
||||
config["light_heavyweight_roster"] = []
|
||||
app.edit_light_heavyweight_roster(config)
|
||||
print(f"Copied {app.game_title(source_id)} into the editable BYOG directory.")
|
||||
return app.edit_custom_profile(config)
|
||||
|
||||
|
|
@ -368,4 +326,4 @@ def manage_games() -> None:
|
|||
else:
|
||||
return
|
||||
|
||||
__all__ = ['builtin_profile_for_copy', 'choose_builtin_game', 'clone_builtin_game', 'create_custom_game', 'edit_custom_match_types', 'edit_custom_profile', 'edit_custom_roster', 'edit_custom_shows', 'edit_custom_titles', 'edit_eligible_roster', 'edit_existing_custom_game', 'edit_light_heavyweight_roster', 'edit_women_roster', 'manage_games', 'show_roster']
|
||||
__all__ = ['builtin_profile_for_copy', 'choose_builtin_game', 'clone_builtin_game', 'create_custom_game', 'edit_custom_match_types', 'edit_custom_profile', 'edit_custom_roster', 'edit_custom_shows', 'edit_custom_titles', 'edit_existing_custom_game', 'edit_women_roster', 'manage_games', 'show_roster']
|
||||
|
|
|
|||
|
|
@ -61,15 +61,7 @@ def title_definitions_for_game(game_id: str,
|
|||
if game_id in app.CUSTOM_GAME_CONFIGS:
|
||||
return [dict(title) for title in app.CUSTOM_GAME_CONFIGS[game_id]["championships"]]
|
||||
return [
|
||||
{
|
||||
"name": name,
|
||||
"kind": (
|
||||
"tag" if name == "Tag Team"
|
||||
else "women" if name == "Women's"
|
||||
else "light_heavyweight" if name == "Light-Heavyweight"
|
||||
else "singles"
|
||||
),
|
||||
}
|
||||
{"name": name, "kind": "tag" if name == "Tag Team" else "women" if name == "Women's" else "singles"}
|
||||
for name in app.CHAMPIONSHIPS
|
||||
]
|
||||
|
||||
|
|
@ -251,27 +243,16 @@ def validate_custom_game(data: Any) -> dict[str, Any]:
|
|||
for item in raw_titles:
|
||||
if not isinstance(item, dict):
|
||||
raise ValueError("Each championship must be a JSON object with name and kind.")
|
||||
name = item.get("name")
|
||||
name, kind = item.get("name"), str(item.get("kind", "singles")).casefold()
|
||||
if not isinstance(name, str) or not name.strip() or name.casefold() in seen_titles:
|
||||
raise ValueError("Championship names must be non-empty and unique.")
|
||||
default_kind = "light_heavyweight" if name.casefold() == "light-heavyweight" else "singles"
|
||||
kind = str(item.get("kind", default_kind)).casefold()
|
||||
if kind not in {"singles", "tag", "women", "light_heavyweight"}:
|
||||
raise ValueError(
|
||||
f"Championship '{name}' kind must be singles, tag, women, or light_heavyweight."
|
||||
)
|
||||
if kind not in {"singles", "tag", "women"}:
|
||||
raise ValueError(f"Championship '{name}' kind must be singles, tag, or women.")
|
||||
championships.append({"name": name.strip(), "kind": kind})
|
||||
seen_titles.add(name.casefold())
|
||||
women = data.get("women_roster", [])
|
||||
if not isinstance(women, list) or any(name not in roster for name in women):
|
||||
raise ValueError("women_roster must be a subset of the roster.")
|
||||
light_heavyweight = data.get("light_heavyweight_roster", [])
|
||||
if (not isinstance(light_heavyweight, list)
|
||||
or any(name not in roster for name in light_heavyweight)):
|
||||
raise ValueError("light_heavyweight_roster must be a subset of the roster.")
|
||||
if (any(title["kind"] == "light_heavyweight" for title in championships)
|
||||
and not light_heavyweight):
|
||||
raise ValueError("light_heavyweight_roster must contain eligible wrestlers.")
|
||||
raw_shows = data.get("shows")
|
||||
if raw_shows is not None and not isinstance(raw_shows, dict):
|
||||
raise ValueError("shows must be an object with Raw, SmackDown, and PPV names.")
|
||||
|
|
@ -297,7 +278,6 @@ def validate_custom_game(data: Any) -> dict[str, Any]:
|
|||
"match_types": match_types,
|
||||
"championships": championships,
|
||||
"women_roster": list(dict.fromkeys(women)),
|
||||
"light_heavyweight_roster": list(dict.fromkeys(light_heavyweight)),
|
||||
"shows": shows,
|
||||
}
|
||||
|
||||
|
|
@ -326,7 +306,6 @@ def builtin_game_profile(game_id: str) -> dict[str, Any]:
|
|||
"match_types": app.match_type_definitions(game_id),
|
||||
"championships": app.title_definitions_for_game(game_id),
|
||||
"women_roster": sorted(app.WOMEN_ROSTERS.get(game_id, set())),
|
||||
"light_heavyweight_roster": None,
|
||||
"shows": {"Raw": "Monday Night Raw", "SmackDown": "Thursday Night SmackDown!",
|
||||
"PPV": "WWF PPV"},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,16 +141,9 @@ def record_match_result(card: dict[str, Any], index: int, auto_simulate: bool =
|
|||
if not is_player_match and not auto_simulate:
|
||||
print(f"Only {wrestler}'s matches can be recorded manually in Wrestler control.")
|
||||
return False
|
||||
if season:
|
||||
valid_division = (
|
||||
app.validate_title_defense(season, match)
|
||||
if match.get("title_defense")
|
||||
else app.validate_match_division_eligibility(season, match)
|
||||
)
|
||||
if not valid_division:
|
||||
if match.get("title_defense"):
|
||||
print("Edit this match's participants or title status before recording its result.")
|
||||
return False
|
||||
if match.get("title_defense") and season and not app.validate_title_defense(season, match):
|
||||
print("Edit this match's participants or title status before recording its result.")
|
||||
return False
|
||||
|
||||
if auto_simulate:
|
||||
app.simulate_match_result(card, index, season)
|
||||
|
|
|
|||
|
|
@ -13,10 +13,9 @@ def season_path(season_id: str) -> Path:
|
|||
|
||||
def new_season_state(name: str, game_id: str,
|
||||
champions: dict[str, list[str] | None] | None = None,
|
||||
season_id: str | None = None,
|
||||
profile: dict[str, Any] | None = None) -> dict[str, Any]:
|
||||
season_id: str | None = None) -> dict[str, Any]:
|
||||
champions = champions or {}
|
||||
profile = profile or app.game_profile(game_id)
|
||||
profile = app.game_profile(game_id)
|
||||
title_definitions = [dict(item) for item in profile["championships"]]
|
||||
title_state: dict[str, Any] = {}
|
||||
for definition in title_definitions:
|
||||
|
|
@ -70,14 +69,6 @@ def load_season(path_or_id: Path | str) -> dict[str, Any]:
|
|||
if not payload.get("season_id") or not payload.get("name"):
|
||||
raise ValueError(f"Season save is missing its identity: {path}")
|
||||
payload.setdefault("game_config", app.game_profile(payload["game_id"]))
|
||||
if payload["game_id"] in app.BUILTIN_GAME_IDS:
|
||||
for definitions in (payload.get("title_definitions"),
|
||||
payload["game_config"].get("championships")):
|
||||
if isinstance(definitions, list):
|
||||
for definition in definitions:
|
||||
if (definition.get("name") == "Light-Heavyweight"
|
||||
and definition.get("kind") == "singles"):
|
||||
definition["kind"] = "light_heavyweight"
|
||||
payload.setdefault("game_title", payload["game_config"].get("game_title", app.game_title(payload["game_id"])))
|
||||
payload.setdefault("federation_name", payload["game_config"].get(
|
||||
"federation_name", app.federation_name(payload["game_id"])
|
||||
|
|
@ -183,45 +174,13 @@ def eligible_roster_for_division(game_id: str, division: str,
|
|||
profile: dict[str, Any] | None = None) -> list[str]:
|
||||
profile = profile or app.game_profile(game_id)
|
||||
roster = list(profile.get("roster", [])) if roster is None else roster
|
||||
eligibility_field = {
|
||||
"women": "women_roster",
|
||||
"light_heavyweight": "light_heavyweight_roster",
|
||||
}.get(app.championship_kind(game_id, division, profile))
|
||||
if eligibility_field:
|
||||
eligible_names = profile.get(eligibility_field)
|
||||
# Older seasons do not have a Light-Heavyweight eligibility snapshot.
|
||||
if eligible_names is None:
|
||||
return list(roster)
|
||||
if app.championship_kind(game_id, division, profile) == "women":
|
||||
eligible_names = profile.get("women_roster", [])
|
||||
eligible = {name.casefold() for name in eligible_names}
|
||||
return [name for name in roster if name.casefold() in eligible]
|
||||
return list(roster)
|
||||
|
||||
|
||||
def validate_match_division_eligibility(season: dict[str, Any],
|
||||
match: dict[str, Any]) -> bool:
|
||||
division = match.get("ranking_division")
|
||||
if division not in app.season_title_names(season):
|
||||
return True
|
||||
if app.season_championship_kind(season, division) not in {"women", "light_heavyweight"}:
|
||||
return True
|
||||
profile = app.season_game_profile(season)
|
||||
eligible = {
|
||||
name.casefold()
|
||||
for name in app.eligible_roster_for_division(
|
||||
season["game_id"], division, profile=profile
|
||||
)
|
||||
}
|
||||
excluded = [
|
||||
name for side in match.get("sides", []) for name in side
|
||||
if name.casefold() not in eligible
|
||||
]
|
||||
if excluded:
|
||||
names = ", ".join(dict.fromkeys(excluded))
|
||||
print(f"{names} is not eligible for the {division} division.")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def choose_roster_member(names: list[str], prompt: str) -> str:
|
||||
if not names:
|
||||
raise ValueError("No eligible wrestlers are available for that championship.")
|
||||
|
|
@ -258,13 +217,6 @@ def create_season() -> dict[str, Any]:
|
|||
game_id = app.choose_game()
|
||||
profile = app.game_profile(game_id)
|
||||
name = app.ask("Season name", f"{app.game_display_name(game_id)} Season")
|
||||
has_light_heavyweight = any(
|
||||
definition.get("kind") == "light_heavyweight"
|
||||
for definition in profile["championships"]
|
||||
)
|
||||
if has_light_heavyweight and game_id in app.BUILTIN_GAME_IDS:
|
||||
profile["light_heavyweight_roster"] = []
|
||||
app.edit_light_heavyweight_roster(profile)
|
||||
champions: dict[str, list[str] | None] = {}
|
||||
used: set[str] = set()
|
||||
for definition in profile["championships"]:
|
||||
|
|
@ -273,7 +225,7 @@ def create_season() -> dict[str, Any]:
|
|||
champions[division] = holder
|
||||
if holder:
|
||||
used.update(name.casefold() for name in holder)
|
||||
season = app.new_season_state(name, game_id, champions, profile=profile)
|
||||
season = app.new_season_state(name, game_id, champions)
|
||||
app.save_season(season)
|
||||
print(f"Season saved: {app.season_path(season['season_id'])}")
|
||||
return season
|
||||
|
|
@ -350,9 +302,7 @@ def season_rivalry_id(sides: list[list[str]]) -> str | None:
|
|||
|
||||
|
||||
def record_season_match(season: dict[str, Any], card: dict[str, Any],
|
||||
match: dict[str, Any], match_index: int) -> bool:
|
||||
if not app.validate_match_division_eligibility(season, match):
|
||||
return False
|
||||
match: dict[str, Any], match_index: int) -> None:
|
||||
division = match.get("ranking_division")
|
||||
winner = match.get("winner_side")
|
||||
if division in app.season_title_names(season) and winner is not None:
|
||||
|
|
@ -401,7 +351,6 @@ def record_season_match(season: dict[str, Any], card: dict[str, Any],
|
|||
if match.get("rivalry_payoff"):
|
||||
rivalry["resolved"] = True
|
||||
rivalry["resolved_at"] = card.get("season_show", "")
|
||||
return True
|
||||
|
||||
|
||||
def validate_title_defense(season: dict[str, Any], match: dict[str, Any]) -> bool:
|
||||
|
|
@ -411,8 +360,6 @@ def validate_title_defense(season: dict[str, Any], match: dict[str, Any]) -> boo
|
|||
if division not in app.season_title_names(season):
|
||||
print("A title defense must be assigned to a championship division.")
|
||||
return False
|
||||
if not app.validate_match_division_eligibility(season, match):
|
||||
return False
|
||||
holder = season["champions"][division].get("holder")
|
||||
if holder and not any(app.side_identity(side) == app.side_identity(holder)
|
||||
for side in match.get("sides", [])):
|
||||
|
|
@ -437,12 +384,9 @@ def sync_season_card_results(card: dict[str, Any]) -> None:
|
|||
result_id = f"{season_id}:{card.get('season_show_number', 0)}:{index + 1}"
|
||||
if result_id in processed:
|
||||
continue
|
||||
if not app.validate_match_division_eligibility(season, match):
|
||||
continue
|
||||
if match.get("title_defense") and not app.validate_title_defense(season, match):
|
||||
continue
|
||||
if not app.record_season_match(season, card, match, index):
|
||||
continue
|
||||
app.record_season_match(season, card, match, index)
|
||||
processed.add(result_id)
|
||||
season["processed_results"] = sorted(processed)
|
||||
complete = all(match.get("winner_side") is not None for match in card["matches"])
|
||||
|
|
@ -455,4 +399,4 @@ def sync_season_card_results(card: dict[str, Any]) -> None:
|
|||
season["show_history"].append(card["path"])
|
||||
app.save_season(season)
|
||||
|
||||
__all__ = ['choose_initial_champion', 'choose_roster_member', 'choose_season_control_mode', 'create_season', 'eligible_roster_for_division', 'load_season', 'new_season_state', 'print_power_rankings', 'record_season_match', 'save_season', 'season_control_label', 'season_other_pool', 'season_path', 'season_ranking_entries', 'season_rivalry_id', 'season_show_brand', 'side_display', 'side_identity', 'sync_season_card_results', 'toggle_season_control_mode', 'validate_match_division_eligibility', 'validate_title_defense']
|
||||
__all__ = ['choose_initial_champion', 'choose_roster_member', 'choose_season_control_mode', 'create_season', 'eligible_roster_for_division', 'load_season', 'new_season_state', 'print_power_rankings', 'record_season_match', 'save_season', 'season_control_label', 'season_other_pool', 'season_path', 'season_ranking_entries', 'season_rivalry_id', 'season_show_brand', 'side_display', 'side_identity', 'sync_season_card_results', 'toggle_season_control_mode', 'validate_title_defense']
|
||||
|
|
|
|||
154
test_lvpwb.py
154
test_lvpwb.py
|
|
@ -916,126 +916,6 @@ class SeasonControlTests(unittest.TestCase):
|
|||
self.assertEqual(updated["next_show_number"], 2)
|
||||
|
||||
|
||||
class LightHeavyweightTests(unittest.TestCase):
|
||||
def test_builtin_season_selects_and_snapshots_eligible_wrestlers(self):
|
||||
def select_eligible(profile):
|
||||
profile["light_heavyweight_roster"] = ["X-Pac", "Jeff Hardy"]
|
||||
|
||||
def initial_champion(division, _game_id, _used, _profile):
|
||||
return ["X-Pac"] if division == "Light-Heavyweight" else None
|
||||
|
||||
with tempfile.TemporaryDirectory() as folder, \
|
||||
patch.object(app, "SEASON_DIR", Path(folder)), \
|
||||
patch.object(app, "choose_game", return_value="sd1"), \
|
||||
patch.object(app, "ask", return_value="Lightweight Season"), \
|
||||
patch.object(app, "edit_light_heavyweight_roster", side_effect=select_eligible), \
|
||||
patch.object(app, "choose_initial_champion", side_effect=initial_champion), \
|
||||
contextlib.redirect_stdout(io.StringIO()):
|
||||
season = app.create_season()
|
||||
loaded = app.load_season(season["season_id"])
|
||||
|
||||
self.assertEqual(season["game_config"]["light_heavyweight_roster"],
|
||||
["X-Pac", "Jeff Hardy"])
|
||||
self.assertEqual(
|
||||
app.eligible_roster_for_division(
|
||||
"sd1", "Light-Heavyweight", profile=loaded["game_config"]
|
||||
),
|
||||
["X-Pac", "Jeff Hardy"],
|
||||
)
|
||||
self.assertEqual(loaded["champions"]["Light-Heavyweight"]["holder"], ["X-Pac"])
|
||||
defense = {
|
||||
"ranking_division": "Light-Heavyweight", "title_defense": True,
|
||||
"sides": [["X-Pac"], ["Jeff Hardy"]], "winner_side": 1,
|
||||
}
|
||||
self.assertTrue(app.validate_title_defense(loaded, defense))
|
||||
app.record_season_match(loaded, {"season_show": "Raw"}, defense, 0)
|
||||
self.assertEqual(loaded["champions"]["Light-Heavyweight"]["holder"], ["Jeff Hardy"])
|
||||
|
||||
def test_initial_champion_random_choice_uses_only_eligible_wrestlers(self):
|
||||
profile = app.game_profile("sd1")
|
||||
profile["light_heavyweight_roster"] = ["X-Pac"]
|
||||
choices_seen = []
|
||||
|
||||
def first_choice(options):
|
||||
choices_seen.append(list(options))
|
||||
return options[0]
|
||||
|
||||
with patch.object(app, "ask_choice", return_value=1), \
|
||||
patch.object(app.random, "choice", side_effect=first_choice), \
|
||||
contextlib.redirect_stdout(io.StringIO()):
|
||||
champion = app.choose_initial_champion(
|
||||
"Light-Heavyweight", "sd1", set(), profile
|
||||
)
|
||||
self.assertEqual(champion, ["X-Pac"])
|
||||
self.assertEqual(choices_seen, [["X-Pac"]])
|
||||
|
||||
def test_ineligible_wrestlers_cannot_record_or_sync_division_results(self):
|
||||
with tempfile.TemporaryDirectory() as folder, \
|
||||
patch.object(app, "SEASON_DIR", Path(folder)):
|
||||
season = app.new_season_state(
|
||||
"Lightweight Season", "sd1",
|
||||
champions={"Light-Heavyweight": ["X-Pac"]},
|
||||
season_id="lightweight-results",
|
||||
)
|
||||
season["game_config"]["light_heavyweight_roster"] = ["X-Pac"]
|
||||
card_path = Path(folder) / "card.md"
|
||||
season["current_card"] = str(card_path)
|
||||
app.save_season(season)
|
||||
match = {
|
||||
"type": "Singles", "sides": [["X-Pac"], ["The Rock"]],
|
||||
"winner_side": 1, "ranking_division": "Light-Heavyweight",
|
||||
"title_defense": True,
|
||||
}
|
||||
card = {
|
||||
"season_id": season["season_id"], "season_show_number": 1,
|
||||
"season_show": "Raw", "path": str(card_path),
|
||||
"matches": [match],
|
||||
}
|
||||
|
||||
with contextlib.redirect_stdout(io.StringIO()):
|
||||
self.assertFalse(app.validate_title_defense(season, match))
|
||||
self.assertFalse(app.record_match_result(card, 0, auto_simulate=True))
|
||||
app.sync_season_card_results(card)
|
||||
|
||||
updated = app.load_season(season["season_id"])
|
||||
self.assertEqual(updated["champions"]["Light-Heavyweight"]["holder"], ["X-Pac"])
|
||||
self.assertEqual(updated["rankings"]["Light-Heavyweight"], {})
|
||||
self.assertEqual(updated["processed_results"], [])
|
||||
|
||||
def test_legacy_season_without_eligibility_snapshot_remains_unrestricted(self):
|
||||
season = app.new_season_state("Legacy Season", "sd1", season_id="legacy-lightweight")
|
||||
season["game_config"].pop("light_heavyweight_roster", None)
|
||||
self.assertEqual(
|
||||
app.eligible_roster_for_division(
|
||||
"sd1", "Light-Heavyweight", profile=season["game_config"]
|
||||
),
|
||||
season["game_config"]["roster"],
|
||||
)
|
||||
|
||||
def test_legacy_builtin_light_heavyweight_kind_migrates_without_restricting_roster(self):
|
||||
season = app.new_season_state(
|
||||
"Legacy Lightweight", "sd1", season_id="legacy-lightweight-kind"
|
||||
)
|
||||
for definitions in (season["title_definitions"],
|
||||
season["game_config"]["championships"]):
|
||||
next(item for item in definitions if item["name"] == "Light-Heavyweight")["kind"] = "singles"
|
||||
season["game_config"].pop("light_heavyweight_roster", None)
|
||||
with tempfile.TemporaryDirectory() as folder, \
|
||||
patch.object(app, "SEASON_DIR", Path(folder)):
|
||||
app.save_season(season)
|
||||
loaded = app.load_season(season["season_id"])
|
||||
self.assertEqual(
|
||||
app.season_championship_kind(loaded, "Light-Heavyweight"),
|
||||
"light_heavyweight",
|
||||
)
|
||||
self.assertEqual(
|
||||
app.eligible_roster_for_division(
|
||||
"sd1", "Light-Heavyweight", profile=loaded["game_config"]
|
||||
),
|
||||
loaded["game_config"]["roster"],
|
||||
)
|
||||
|
||||
|
||||
class BYOGTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self._configs = app.CUSTOM_GAME_CONFIGS
|
||||
|
|
@ -1074,7 +954,6 @@ class BYOGTests(unittest.TestCase):
|
|||
{"name": "Fantasy Women", "kind": "women"},
|
||||
],
|
||||
"women_roster": ["Cara Storm"],
|
||||
"light_heavyweight_roster": [],
|
||||
}
|
||||
data.update(overrides)
|
||||
return data
|
||||
|
|
@ -1128,7 +1007,6 @@ class BYOGTests(unittest.TestCase):
|
|||
"invalid side sizes"),
|
||||
({"match_types": []}, "at least one match type"),
|
||||
({"championships": [{"name": "Belt", "kind": "hardcore"}]}, "kind"),
|
||||
({"light_heavyweight_roster": ["Not Listed"]}, "subset of the roster"),
|
||||
({"platform": "dreamcast"}, "platform must be ps1"),
|
||||
({"screenshot_directory": 3}, "screenshot_directory must be a path string"),
|
||||
]
|
||||
|
|
@ -1175,38 +1053,6 @@ class BYOGTests(unittest.TestCase):
|
|||
app.ROOT / "custom-screens")
|
||||
self.assertTrue(app.game_has_screenshots(overridden["game_id"]))
|
||||
|
||||
def test_custom_light_heavyweight_eligibility_is_validated_and_applied(self):
|
||||
config = self.config(
|
||||
championships=[
|
||||
{"name": "Fantasy Lightweight", "kind": "light_heavyweight"},
|
||||
],
|
||||
light_heavyweight_roster=["Ava Crusher", "Cara Storm"],
|
||||
)
|
||||
self.register(config)
|
||||
profile = app.game_profile(config["game_id"])
|
||||
self.assertEqual(
|
||||
app.eligible_roster_for_division(
|
||||
config["game_id"], "Fantasy Lightweight", profile=profile
|
||||
),
|
||||
["Ava Crusher", "Cara Storm"],
|
||||
)
|
||||
self.assertEqual(
|
||||
app.championship_kind(config["game_id"], "Fantasy Lightweight", profile),
|
||||
"light_heavyweight",
|
||||
)
|
||||
with self.assertRaisesRegex(ValueError, "must contain eligible wrestlers"):
|
||||
app.validate_custom_game(self.config(championships=[
|
||||
{"name": "Fantasy Lightweight", "kind": "light_heavyweight"},
|
||||
]))
|
||||
|
||||
def test_light_heavyweight_eligibility_editor_selects_roster_members(self):
|
||||
config = {"roster": ["Ava Crusher", "Ben Brawler"],
|
||||
"light_heavyweight_roster": []}
|
||||
with patch.object(app, "ask_choice", side_effect=[0, 0, 2]), \
|
||||
contextlib.redirect_stdout(io.StringIO()):
|
||||
app.edit_light_heavyweight_roster(config)
|
||||
self.assertEqual(config["light_heavyweight_roster"], ["Ava Crusher"])
|
||||
|
||||
def test_custom_game_screenshot_override_can_be_set_in_editor(self):
|
||||
config = app.validate_custom_game(self.config())
|
||||
with patch.object(app, "ask_choice", side_effect=[0, 0, 6]), \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue