Cleanup oddities of CP generation.

* Don't spawn missile sites or ground locations for CVs/LHAs.
* Don't spawn ground locations around CVs/LHAs.
* Spawn AA sites even if the faction has no buildings defined.
This commit is contained in:
Dan Albert 2020-11-06 18:36:07 -08:00
parent c2ee169d16
commit 3979ee57ff

View File

@ -160,11 +160,9 @@ class GameGenerator:
class ControlPointGroundObjectGenerator: class ControlPointGroundObjectGenerator:
def __init__(self, game: Game, control_point: ControlPoint, def __init__(self, game: Game, control_point: ControlPoint) -> None:
templates: GroundObjectTemplates) -> None:
self.game = game self.game = game
self.control_point = control_point self.control_point = control_point
self.templates = templates
@property @property
def faction_name(self) -> str: def faction_name(self) -> str:
@ -179,7 +177,6 @@ class ControlPointGroundObjectGenerator:
def generate(self) -> bool: def generate(self) -> bool:
self.control_point.ground_objects = [] self.control_point.ground_objects = []
self.generate_ground_points()
if self.faction.navy_generators: if self.faction.navy_generators:
# Even airbases can generate navies if they are close enough to the # Even airbases can generate navies if they are close enough to the
# water. This is not controlled by the control point definition, but # water. This is not controlled by the control point definition, but
@ -187,85 +184,8 @@ class ControlPointGroundObjectGenerator:
# for the ship. # for the ship.
self.generate_navy() self.generate_navy()
if self.faction.missiles:
# TODO: Presumably only for airbases?
self.generate_missile_sites()
return True return True
def generate_ground_points(self) -> None:
"""Generate ground objects and AA sites for the control point."""
if self.control_point.is_global:
return
# TODO: Should probably perform this check later.
# Just because we don't have factories for the faction doesn't mean we
# shouldn't generate AA.
available_categories = self.faction.building_set
if not available_categories:
return
# Always generate at least one AA point.
self.generate_aa_site()
# And between 2 and 7 other objectives.
amount = random.randrange(2, 7)
for i in range(amount):
# 1 in 4 additional objectives are AA.
if random.randint(0, 3) == 0:
self.generate_aa_site()
else:
category = random.choice(available_categories)
self.generate_ground_point(category)
def generate_ground_point(self, category: str) -> None:
obj_name = namegen.random_objective_name()
template = random.choice(list(self.templates[category].values()))
point = find_location(category != "oil",
self.control_point.position,
self.game.theater, 10000, 40000,
self.control_point.ground_objects)
if point is None:
logging.error(
f"Could not find point for {obj_name} at {self.control_point}")
return
object_id = 0
group_id = self.game.next_group_id()
# TODO: Create only one TGO per objective, each with multiple units.
for unit in template:
object_id += 1
template_point = Point(unit["offset"].x, unit["offset"].y)
g = BuildingGroundObject(
obj_name, category, group_id, object_id, point + template_point,
unit["heading"], self.control_point, unit["type"])
self.control_point.ground_objects.append(g)
def generate_aa_site(self) -> None:
obj_name = namegen.random_objective_name()
position = find_location(True, self.control_point.position,
self.game.theater, 10000, 40000,
self.control_point.ground_objects)
if position is None:
logging.error(
f"Could not find point for {obj_name} at {self.control_point}")
return
group_id = self.game.next_group_id()
g = SamGroundObject(namegen.random_objective_name(), group_id,
position, self.control_point, for_airbase=False)
group = generate_anti_air_group(self.game, g, self.faction_name)
if group is not None:
g.groups = [group]
self.control_point.ground_objects.append(g)
def generate_navy(self) -> None: def generate_navy(self) -> None:
skip_player_navy = self.game.settings.do_not_generate_player_navy skip_player_navy = self.game.settings.do_not_generate_player_navy
if self.control_point.captured and skip_player_navy: if self.control_point.captured and skip_player_navy:
@ -297,29 +217,6 @@ class ControlPointGroundObjectGenerator:
g.groups.append(group) g.groups.append(group)
self.control_point.ground_objects.append(g) self.control_point.ground_objects.append(g)
def generate_missile_sites(self) -> None:
for i in range(self.faction.missiles_group_count):
self.generate_missile_site()
def generate_missile_site(self) -> None:
point = find_location(True, self.control_point.position,
self.game.theater, 2500, 40000, [], False)
if point is None:
logging.info(
f"Could not find point for {self.control_point} missile site")
return
group_id = self.game.next_group_id()
g = MissileSiteGroundObject(namegen.random_objective_name(), group_id,
point, self.control_point)
group = generate_missile_group(self.game, g, self.faction_name)
g.groups = []
if group is not None:
g.groups.append(group)
self.control_point.ground_objects.append(g)
return
class CarrierGroundObjectGenerator(ControlPointGroundObjectGenerator): class CarrierGroundObjectGenerator(ControlPointGroundObjectGenerator):
def generate(self) -> bool: def generate(self) -> bool:
@ -372,15 +269,121 @@ class LhaGroundObjectGenerator(ControlPointGroundObjectGenerator):
class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator): class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
def __init__(self, game: Game, control_point: ControlPoint,
templates: GroundObjectTemplates) -> None:
super().__init__(game, control_point)
self.templates = templates
def generate(self) -> bool: def generate(self) -> bool:
if not super().generate(): if not super().generate():
return False return False
for i in range(random.randint(3, 6)): self.generate_base_defenses()
self.generate_sam(i) self.generate_ground_points()
if self.faction.missiles:
self.generate_missile_sites()
return True return True
def generate_sam(self, index: int) -> None: def generate_ground_points(self) -> None:
"""Generate ground objects and AA sites for the control point."""
if self.control_point.is_global:
return
# Always generate at least one AA point.
self.generate_aa_site()
# And between 2 and 7 other objectives.
amount = random.randrange(2, 7)
for i in range(amount):
# 1 in 4 additional objectives are AA.
if random.randint(0, 3) == 0:
self.generate_aa_site()
else:
self.generate_ground_point()
def generate_ground_point(self) -> None:
try:
category = random.choice(self.faction.building_set)
except IndexError:
logging.exception("Faction has no buildings defined")
return
obj_name = namegen.random_objective_name()
template = random.choice(list(self.templates[category].values()))
point = find_location(category != "oil",
self.control_point.position,
self.game.theater, 10000, 40000,
self.control_point.ground_objects)
if point is None:
logging.error(
f"Could not find point for {obj_name} at {self.control_point}")
return
object_id = 0
group_id = self.game.next_group_id()
# TODO: Create only one TGO per objective, each with multiple units.
for unit in template:
object_id += 1
template_point = Point(unit["offset"].x, unit["offset"].y)
g = BuildingGroundObject(
obj_name, category, group_id, object_id, point + template_point,
unit["heading"], self.control_point, unit["type"])
self.control_point.ground_objects.append(g)
def generate_aa_site(self) -> None:
obj_name = namegen.random_objective_name()
position = find_location(True, self.control_point.position,
self.game.theater, 10000, 40000,
self.control_point.ground_objects)
if position is None:
logging.error(
f"Could not find point for {obj_name} at {self.control_point}")
return
group_id = self.game.next_group_id()
g = SamGroundObject(namegen.random_objective_name(), group_id,
position, self.control_point, for_airbase=False)
group = generate_anti_air_group(self.game, g, self.faction_name)
if group is not None:
g.groups = [group]
self.control_point.ground_objects.append(g)
def generate_missile_sites(self) -> None:
for i in range(self.faction.missiles_group_count):
self.generate_missile_site()
def generate_missile_site(self) -> None:
point = find_location(True, self.control_point.position,
self.game.theater, 2500, 40000, [], False)
if point is None:
logging.info(
f"Could not find point for {self.control_point} missile site")
return
group_id = self.game.next_group_id()
g = MissileSiteGroundObject(namegen.random_objective_name(), group_id,
point, self.control_point)
group = generate_missile_group(self.game, g, self.faction_name)
g.groups = []
if group is not None:
g.groups.append(group)
self.control_point.ground_objects.append(g)
return
def generate_base_defenses(self) -> None:
for i in range(random.randint(3, 6)):
self.generate_base_defense(i)
def generate_base_defense(self, index: int) -> None:
position = find_location(True, self.control_point.position, position = find_location(True, self.control_point.position,
self.game.theater, 800, 3200, [], True) self.game.theater, 800, 3200, [], True)
if position is None: if position is None:
@ -414,11 +417,9 @@ class GroundObjectGenerator:
def generate_for_control_point(self, control_point: ControlPoint) -> bool: def generate_for_control_point(self, control_point: ControlPoint) -> bool:
generator: ControlPointGroundObjectGenerator generator: ControlPointGroundObjectGenerator
if control_point.cptype == ControlPointType.AIRCRAFT_CARRIER_GROUP: if control_point.cptype == ControlPointType.AIRCRAFT_CARRIER_GROUP:
generator = CarrierGroundObjectGenerator(self.game, control_point, generator = CarrierGroundObjectGenerator(self.game, control_point)
self.templates)
elif control_point.cptype == ControlPointType.LHA_GROUP: elif control_point.cptype == ControlPointType.LHA_GROUP:
generator = LhaGroundObjectGenerator(self.game, control_point, generator = LhaGroundObjectGenerator(self.game, control_point)
self.templates)
else: else:
generator = AirbaseGroundObjectGenerator(self.game, control_point, generator = AirbaseGroundObjectGenerator(self.game, control_point,
self.templates) self.templates)