Civ 6: Add era requirements for boosts and update boost prereqs (#5296)
* Resolve #5136 * Resolves #5210
This commit is contained in:
@@ -20,6 +20,7 @@ class CivVIBoostData:
|
|||||||
Prereq: List[str]
|
Prereq: List[str]
|
||||||
PrereqRequiredCount: int
|
PrereqRequiredCount: int
|
||||||
Classification: str
|
Classification: str
|
||||||
|
EraRequired: bool = False
|
||||||
|
|
||||||
|
|
||||||
class GoodyHutRewardData(TypedDict):
|
class GoodyHutRewardData(TypedDict):
|
||||||
|
|||||||
@@ -150,7 +150,10 @@ def generate_era_location_table() -> Dict[str, Dict[str, CivVILocationData]]:
|
|||||||
location = CivVILocationData(
|
location = CivVILocationData(
|
||||||
boost.Type, 0, 0, id_base, boost.EraType, CivVICheckType.BOOST
|
boost.Type, 0, 0, id_base, boost.EraType, CivVICheckType.BOOST
|
||||||
)
|
)
|
||||||
era_locations["ERA_ANCIENT"][boost.Type] = location
|
# If EraRequired is True, place the boost in its actual era
|
||||||
|
# Otherwise, place it in ERA_ANCIENT for early access
|
||||||
|
target_era = boost.EraType if boost.EraRequired else "ERA_ANCIENT"
|
||||||
|
era_locations[target_era][boost.Type] = location
|
||||||
id_base += 1
|
id_base += 1
|
||||||
|
|
||||||
return era_locations
|
return era_locations
|
||||||
|
|||||||
@@ -210,8 +210,8 @@ boosts: List[CivVIBoostData] = [
|
|||||||
CivVIBoostData(
|
CivVIBoostData(
|
||||||
"BOOST_TECH_SQUARE_RIGGING",
|
"BOOST_TECH_SQUARE_RIGGING",
|
||||||
"ERA_RENAISSANCE",
|
"ERA_RENAISSANCE",
|
||||||
["TECH_GUNPOWDER"],
|
["TECH_GUNPOWDER", "TECH_MILITARY_ENGINEERING", "TECH_MINING"],
|
||||||
1,
|
3,
|
||||||
"DEFAULT",
|
"DEFAULT",
|
||||||
),
|
),
|
||||||
CivVIBoostData(
|
CivVIBoostData(
|
||||||
@@ -252,15 +252,15 @@ boosts: List[CivVIBoostData] = [
|
|||||||
CivVIBoostData(
|
CivVIBoostData(
|
||||||
"BOOST_TECH_BALLISTICS",
|
"BOOST_TECH_BALLISTICS",
|
||||||
"ERA_INDUSTRIAL",
|
"ERA_INDUSTRIAL",
|
||||||
["TECH_SIEGE_TACTICS", "TECH_MILITARY_ENGINEERING"],
|
["TECH_SIEGE_TACTICS", "TECH_MILITARY_ENGINEERING", "TECH_BRONZE_WORKING"],
|
||||||
2,
|
3,
|
||||||
"DEFAULT",
|
"DEFAULT",
|
||||||
),
|
),
|
||||||
CivVIBoostData(
|
CivVIBoostData(
|
||||||
"BOOST_TECH_MILITARY_SCIENCE",
|
"BOOST_TECH_MILITARY_SCIENCE",
|
||||||
"ERA_INDUSTRIAL",
|
"ERA_INDUSTRIAL",
|
||||||
["TECH_STIRRUPS"],
|
["TECH_BRONZE_WORKING", "TECH_STIRRUPS", "TECH_MINING"],
|
||||||
1,
|
3,
|
||||||
"DEFAULT",
|
"DEFAULT",
|
||||||
),
|
),
|
||||||
CivVIBoostData(
|
CivVIBoostData(
|
||||||
@@ -301,8 +301,8 @@ boosts: List[CivVIBoostData] = [
|
|||||||
CivVIBoostData(
|
CivVIBoostData(
|
||||||
"BOOST_TECH_REPLACEABLE_PARTS",
|
"BOOST_TECH_REPLACEABLE_PARTS",
|
||||||
"ERA_MODERN",
|
"ERA_MODERN",
|
||||||
["TECH_MILITARY_SCIENCE"],
|
["TECH_MILITARY_SCIENCE", "TECH_MINING"],
|
||||||
1,
|
2,
|
||||||
"DEFAULT",
|
"DEFAULT",
|
||||||
),
|
),
|
||||||
CivVIBoostData(
|
CivVIBoostData(
|
||||||
@@ -343,8 +343,8 @@ boosts: List[CivVIBoostData] = [
|
|||||||
CivVIBoostData(
|
CivVIBoostData(
|
||||||
"BOOST_TECH_ADVANCED_FLIGHT",
|
"BOOST_TECH_ADVANCED_FLIGHT",
|
||||||
"ERA_ATOMIC",
|
"ERA_ATOMIC",
|
||||||
["TECH_FLIGHT"],
|
["TECH_FLIGHT", "TECH_REFINING", "TECH_MINING"],
|
||||||
1,
|
3,
|
||||||
"DEFAULT",
|
"DEFAULT",
|
||||||
),
|
),
|
||||||
CivVIBoostData(
|
CivVIBoostData(
|
||||||
@@ -436,8 +436,8 @@ boosts: List[CivVIBoostData] = [
|
|||||||
CivVIBoostData(
|
CivVIBoostData(
|
||||||
"BOOST_TECH_COMPOSITES",
|
"BOOST_TECH_COMPOSITES",
|
||||||
"ERA_INFORMATION",
|
"ERA_INFORMATION",
|
||||||
["TECH_COMBUSTION"],
|
["TECH_COMBUSTION", "TECH_REFINING", "TECH_MINING"],
|
||||||
1,
|
3,
|
||||||
"DEFAULT",
|
"DEFAULT",
|
||||||
),
|
),
|
||||||
CivVIBoostData(
|
CivVIBoostData(
|
||||||
@@ -470,7 +470,7 @@ boosts: List[CivVIBoostData] = [
|
|||||||
"TECH_ELECTRICITY",
|
"TECH_ELECTRICITY",
|
||||||
"TECH_NUCLEAR_FISSION",
|
"TECH_NUCLEAR_FISSION",
|
||||||
],
|
],
|
||||||
1,
|
4,
|
||||||
"DEFAULT",
|
"DEFAULT",
|
||||||
),
|
),
|
||||||
CivVIBoostData(
|
CivVIBoostData(
|
||||||
@@ -651,10 +651,11 @@ boosts: List[CivVIBoostData] = [
|
|||||||
),
|
),
|
||||||
CivVIBoostData(
|
CivVIBoostData(
|
||||||
"BOOST_CIVIC_FEUDALISM",
|
"BOOST_CIVIC_FEUDALISM",
|
||||||
"ERA_MEDIEVAL",
|
"ERA_CLASSICAL",
|
||||||
[],
|
[],
|
||||||
0,
|
0,
|
||||||
"DEFAULT",
|
"DEFAULT",
|
||||||
|
True,
|
||||||
),
|
),
|
||||||
CivVIBoostData(
|
CivVIBoostData(
|
||||||
"BOOST_CIVIC_CIVIL_SERVICE",
|
"BOOST_CIVIC_CIVIL_SERVICE",
|
||||||
@@ -662,6 +663,7 @@ boosts: List[CivVIBoostData] = [
|
|||||||
[],
|
[],
|
||||||
0,
|
0,
|
||||||
"DEFAULT",
|
"DEFAULT",
|
||||||
|
True,
|
||||||
),
|
),
|
||||||
CivVIBoostData(
|
CivVIBoostData(
|
||||||
"BOOST_CIVIC_MERCENARIES",
|
"BOOST_CIVIC_MERCENARIES",
|
||||||
@@ -790,6 +792,7 @@ boosts: List[CivVIBoostData] = [
|
|||||||
[],
|
[],
|
||||||
0,
|
0,
|
||||||
"DEFAULT",
|
"DEFAULT",
|
||||||
|
True
|
||||||
),
|
),
|
||||||
CivVIBoostData(
|
CivVIBoostData(
|
||||||
"BOOST_CIVIC_CONSERVATION",
|
"BOOST_CIVIC_CONSERVATION",
|
||||||
@@ -885,6 +888,7 @@ boosts: List[CivVIBoostData] = [
|
|||||||
["TECH_ROCKETRY"],
|
["TECH_ROCKETRY"],
|
||||||
1,
|
1,
|
||||||
"DEFAULT",
|
"DEFAULT",
|
||||||
|
True
|
||||||
),
|
),
|
||||||
CivVIBoostData(
|
CivVIBoostData(
|
||||||
"BOOST_CIVIC_GLOBALIZATION",
|
"BOOST_CIVIC_GLOBALIZATION",
|
||||||
|
|||||||
@@ -105,3 +105,78 @@ class TestBoostsanityExcluded(CivVITestBase):
|
|||||||
if "BOOST" in location.name:
|
if "BOOST" in location.name:
|
||||||
found_locations += 1
|
found_locations += 1
|
||||||
self.assertEqual(found_locations, 0)
|
self.assertEqual(found_locations, 0)
|
||||||
|
|
||||||
|
|
||||||
|
class TestBoostsanityEraRequired(CivVITestBase):
|
||||||
|
options = {
|
||||||
|
"boostsanity": "true",
|
||||||
|
"progression_style": "none",
|
||||||
|
"shuffle_goody_hut_rewards": "false",
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_era_required_boosts_not_accessible_early(self) -> None:
|
||||||
|
# BOOST_CIVIC_FEUDALISM has EraRequired=True and ERA_CLASSICAL
|
||||||
|
# It should NOT be accessible in Ancient era
|
||||||
|
self.assertFalse(self.can_reach_location("BOOST_CIVIC_FEUDALISM"))
|
||||||
|
|
||||||
|
# BOOST_CIVIC_URBANIZATION has EraRequired=True and ERA_INDUSTRIAL
|
||||||
|
# It should NOT be accessible in Ancient era
|
||||||
|
self.assertFalse(self.can_reach_location("BOOST_CIVIC_URBANIZATION"))
|
||||||
|
|
||||||
|
# BOOST_CIVIC_SPACE_RACE has EraRequired=True and ERA_ATOMIC
|
||||||
|
# It should NOT be accessible in Ancient era
|
||||||
|
self.assertFalse(self.can_reach_location("BOOST_CIVIC_SPACE_RACE"))
|
||||||
|
|
||||||
|
# Regular boosts without EraRequired should be accessible
|
||||||
|
self.assertTrue(self.can_reach_location("BOOST_TECH_SAILING"))
|
||||||
|
self.assertTrue(self.can_reach_location("BOOST_CIVIC_MILITARY_TRADITION"))
|
||||||
|
|
||||||
|
def test_era_required_boosts_accessible_in_correct_era(self) -> None:
|
||||||
|
# Collect items to reach Classical era
|
||||||
|
self.collect_by_name(["Mining", "Bronze Working", "Astrology", "Writing",
|
||||||
|
"Irrigation", "Sailing", "Animal Husbandry",
|
||||||
|
"State Workforce", "Foreign Trade"])
|
||||||
|
|
||||||
|
# BOOST_CIVIC_FEUDALISM should now be accessible in Classical era
|
||||||
|
self.assertTrue(self.can_reach_location("BOOST_CIVIC_FEUDALISM"))
|
||||||
|
|
||||||
|
# BOOST_CIVIC_URBANIZATION still not accessible (requires Industrial)
|
||||||
|
self.assertFalse(self.can_reach_location("BOOST_CIVIC_URBANIZATION"))
|
||||||
|
|
||||||
|
# Collect more items to reach Industrial era
|
||||||
|
self.collect_all_but(["TECH_ROCKETRY"])
|
||||||
|
|
||||||
|
# Now BOOST_CIVIC_URBANIZATION should be accessible
|
||||||
|
self.assertTrue(self.can_reach_location("BOOST_CIVIC_URBANIZATION"))
|
||||||
|
|
||||||
|
|
||||||
|
class TestBoostsanityEraRequiredWithProgression(CivVITestBase):
|
||||||
|
options = {
|
||||||
|
"boostsanity": "true",
|
||||||
|
"progression_style": "eras_and_districts",
|
||||||
|
"shuffle_goody_hut_rewards": "false",
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_era_required_with_progressive_eras(self) -> None:
|
||||||
|
# Collect all items except Progressive Era
|
||||||
|
self.collect_all_but(["Progressive Era"])
|
||||||
|
|
||||||
|
# Even with all other items, era-required boosts should not be accessible
|
||||||
|
self.assertFalse(self.can_reach_location("BOOST_CIVIC_FEUDALISM"))
|
||||||
|
self.assertFalse(self.can_reach_location("BOOST_CIVIC_URBANIZATION"))
|
||||||
|
|
||||||
|
# Collect enough Progressive Era items to reach Classical (needs 2)
|
||||||
|
self.collect(self.get_item_by_name("Progressive Era"))
|
||||||
|
self.collect(self.get_item_by_name("Progressive Era"))
|
||||||
|
|
||||||
|
# BOOST_CIVIC_FEUDALISM should now be accessible
|
||||||
|
self.assertTrue(self.can_reach_location("BOOST_CIVIC_FEUDALISM"))
|
||||||
|
|
||||||
|
# But BOOST_CIVIC_URBANIZATION still requires Industrial era (needs 5 total)
|
||||||
|
self.assertFalse(self.can_reach_location("BOOST_CIVIC_URBANIZATION"))
|
||||||
|
|
||||||
|
# Collect 3 more Progressive Era items to reach Industrial
|
||||||
|
self.collect_by_name(["Progressive Era", "Progressive Era", "Progressive Era"])
|
||||||
|
|
||||||
|
# Now BOOST_CIVIC_URBANIZATION should be accessible
|
||||||
|
self.assertTrue(self.can_reach_location("BOOST_CIVIC_URBANIZATION"))
|
||||||
|
|||||||
Reference in New Issue
Block a user