RndName 244425381d
Fix incorrect forcegroup loading
Forcegroups were not loaded correctly from preset groups during faction initialization. When a user created a new game and directly after that created another game with different factions the Forcegroups for the preset groups were still reused and therefore units which were not accessible by the faction were accidently available to the new faction.
closes #2186
2022-05-06 19:31:40 +02:00

67 lines
2.6 KiB
Python

from __future__ import annotations
import random
from typing import TYPE_CHECKING, Iterator, Optional
from game.data.groups import GroupTask
from game.armedforces.forcegroup import ForceGroup
from game.layout import LAYOUTS
from game.profiling import logged_duration
if TYPE_CHECKING:
from game.factions.faction import Faction
class ArmedForces:
"""Represents all ForceGroups which are available to the faction"""
def __init__(self, faction: Faction):
self.forces: list[ForceGroup] = []
with logged_duration(f"Loading armed forces for {faction.name}"):
self._load_forces(faction)
def add_or_update_force_group(self, new_group: ForceGroup) -> None:
"""Adds or update a forcegroup depending if a forcegroup with the exact same
tasking already exists"""
# Check if a force group with the same tasking already exists
for force_group in self.forces:
if force_group.tasks == new_group.tasks:
# Update existing group if tasks are equal
force_group.merge_group(new_group)
return
# Add a new force group
self.forces.append(new_group)
def _load_forces(self, faction: Faction) -> None:
"""Initialize the ArmedForces for the given faction.
This will create a ForceGroup for each generic Layout and PresetGroup"""
# Initialize with preset_groups from the faction
self.forces = [
preset_group.initialize_for_faction(faction)
for preset_group in faction.preset_groups
]
# Generate ForceGroup for all generic layouts by iterating over
# all layouts which are usable by the given faction.
for layout in LAYOUTS.layouts:
if layout.generic and layout.usable_by_faction(faction):
# Creates a faction compatible GorceGroup
self.add_or_update_force_group(ForceGroup.for_layout(layout, faction))
def groups_for_task(self, group_task: GroupTask) -> Iterator[ForceGroup]:
for force_group in self.forces:
if group_task in force_group.tasks:
yield force_group
def groups_for_tasks(self, tasks: list[GroupTask]) -> list[ForceGroup]:
groups = []
for task in tasks:
for group in self.groups_for_task(task):
if group not in groups:
groups.append(group)
return groups
def random_group_for_task(self, group_task: GroupTask) -> Optional[ForceGroup]:
unit_groups = list(self.groups_for_task(group_task))
return random.choice(unit_groups) if unit_groups else None