refactor trigger zone generation

This commit is contained in:
Eclipse/Druss99 2025-10-04 21:58:32 -04:00 committed by Raffson
parent c0748e2a3e
commit 855d269420
4 changed files with 82 additions and 240 deletions

View File

@ -98,9 +98,6 @@ class Coalition:
state = self.__dict__.copy()
# Avoid persisting any volatile types that can be deterministically
# recomputed on load for the sake of save compatibility.
if state["player"] != Player.NEUTRAL:
del state["_threat_zone"]
del state["_navmesh"]
del state["faker"]
return state

View File

@ -32,6 +32,7 @@ from game.theater.controlpoint import Fob, TRIGGER_RADIUS_CAPTURE
if TYPE_CHECKING:
from game.game import Game
from game.theater.controlpoint import ControlPoint
PUSH_TRIGGER_SIZE = 3000
PUSH_TRIGGER_ACTIVATION_AGL = 25
@ -179,26 +180,57 @@ class TriggerGenerator:
# clear_trigger.add_action(MessageToAll(text=String("Enable clear trigger"),))
self.mission.triggerrules.triggers.append(enable_clear_trigger)
def _generate_capture_triggers(
self, player_coalition: str, enemy_coalition: str
) -> None:
def _create_capture_trigger(
self,
trigger_zone_id: int,
flag: int,
capturing_coalition: str,
losing_coalition: str,
capturing_coalition_int: int,
cp: ControlPoint,
flag_condition_true: bool = False,
) -> TriggerCondition:
"""Helper method to create a single capture trigger with the given parameters."""
trigger = TriggerCondition(Event.NoEvent, "Capture Trigger")
trigger.add_condition(
AllOfCoalitionOutsideZone(
losing_coalition, trigger_zone_id, unit_type="GROUND"
)
)
trigger.add_condition(
PartOfCoalitionInZone(
capturing_coalition, trigger_zone_id, unit_type="GROUND"
)
)
if flag_condition_true:
trigger.add_condition(FlagIsTrue(flag=flag))
trigger.add_action(ClearFlag(flag=flag))
else:
trigger.add_condition(FlagIsFalse(flag=flag))
trigger.add_action(SetFlag(flag=flag))
script_string = String(
f'base_capture_events[#base_capture_events + 1] = "{cp.id}||{capturing_coalition_int}||{cp.full_name}"'
)
trigger.add_action(DoScript(script_string))
return trigger
def _generate_capture_triggers(self) -> None:
"""Creates a pair of triggers for each control point of `cls.capture_zone_types`.
One for the initial capture of a control point, and one if it is recaptured.
Directly appends to the global `base_capture_events` var declared by `dcs_libaration.lua`
"""
for cp in self.game.theater.controlpoints:
if isinstance(cp, self.capture_zone_types) and not cp.is_carrier:
if cp.captured.is_blue:
attacking_coalition = enemy_coalition
attacking_coalition = str.lower(cp.captured.opponent.name)
defending_coalition = str.lower(cp.captured.opponent.opponent.name)
if attacking_coalition == "red":
attack_coalition_int = 1 # 1 is the Event int for Red
defending_coalition = player_coalition
defend_coalition_int = 2 # 2 is the Event int for Blue
else:
attacking_coalition = player_coalition
attack_coalition_int = 2
defending_coalition = enemy_coalition
defend_coalition_int = 1
if isinstance(cp, self.capture_zone_types) and not cp.is_carrier:
trigger_zone = self.mission.triggers.add_triggerzone(
cp.position,
radius=TRIGGER_RADIUS_CAPTURE,
@ -206,87 +238,47 @@ class TriggerGenerator:
name="CAPTURE",
)
flag = self.get_capture_zone_flag()
capture_trigger = TriggerCondition(Event.NoEvent, "Capture Trigger")
capture_trigger.add_condition(
AllOfCoalitionOutsideZone(
defending_coalition, trigger_zone.id, unit_type="GROUND"
capture = self._create_capture_trigger(
trigger_zone.id,
flag,
attacking_coalition,
defending_coalition,
attack_coalition_int,
cp,
)
recapture = self._create_capture_trigger(
trigger_zone.id,
flag,
defending_coalition,
attacking_coalition,
defend_coalition_int,
cp,
flag_condition_true=True,
)
capture_trigger.add_condition(
PartOfCoalitionInZone(
attacking_coalition, trigger_zone.id, unit_type="GROUND"
)
)
capture_trigger.add_condition(FlagIsFalse(flag=flag))
script_string = String(
f'base_capture_events[#base_capture_events + 1] = "{cp.id}||{attack_coalition_int}||{cp.full_name}"'
)
capture_trigger.add_action(DoScript(script_string))
capture_trigger.add_action(SetFlag(flag=flag))
self.mission.triggerrules.triggers.append(capture_trigger)
recapture_trigger = TriggerCondition(Event.NoEvent, "Capture Trigger")
recapture_trigger.add_condition(
AllOfCoalitionOutsideZone(
attacking_coalition, trigger_zone.id, unit_type="GROUND"
)
)
recapture_trigger.add_condition(
PartOfCoalitionInZone(
defending_coalition, trigger_zone.id, unit_type="GROUND"
)
)
recapture_trigger.add_condition(FlagIsTrue(flag=flag))
script_string = String(
f'base_capture_events[#base_capture_events + 1] = "{cp.id}||{defend_coalition_int}||{cp.full_name}"'
)
recapture_trigger.add_action(DoScript(script_string))
recapture_trigger.add_action(ClearFlag(flag=flag))
self.mission.triggerrules.triggers.append(recapture_trigger)
self.mission.triggerrules.triggers.extend([capture, recapture])
if cp.captured.is_neutral:
red_capture_trigger = TriggerCondition(
Event.NoEvent, "Capture Trigger"
# In this case attacking_coalition is blue and defending_coalition is red because
# neutral control points always have blue set as the opponent
red_capture = self._create_capture_trigger(
trigger_zone.id,
flag,
defending_coalition,
attacking_coalition,
defend_coalition_int,
cp,
)
red_capture_trigger.add_condition(
AllOfCoalitionOutsideZone(
attacking_coalition, trigger_zone.id, unit_type="GROUND"
red_recapture = self._create_capture_trigger(
trigger_zone.id,
flag,
defending_coalition,
attacking_coalition,
defend_coalition_int,
cp,
flag_condition_true=True,
)
)
red_capture_trigger.add_condition(
PartOfCoalitionInZone(
defending_coalition, trigger_zone.id, unit_type="GROUND"
)
)
red_capture_trigger.add_condition(FlagIsFalse(flag=flag))
script_string = String(
f'base_capture_events[#base_capture_events + 1] = "{cp.id}||{defend_coalition_int}||{cp.full_name}"'
)
red_capture_trigger.add_action(DoScript(script_string))
red_capture_trigger.add_action(SetFlag(flag=flag))
self.mission.triggerrules.triggers.append(red_capture_trigger)
inverted_recapture_trigger = TriggerCondition(
Event.NoEvent, "Capture Trigger"
)
inverted_recapture_trigger.add_condition(
AllOfCoalitionOutsideZone(
defending_coalition, trigger_zone.id, unit_type="GROUND"
)
)
inverted_recapture_trigger.add_condition(
PartOfCoalitionInZone(
attacking_coalition, trigger_zone.id, unit_type="GROUND"
)
)
inverted_recapture_trigger.add_condition(FlagIsTrue(flag=flag))
script_string = String(
f'base_capture_events[#base_capture_events + 1] = "{cp.id}||{attack_coalition_int}||{cp.full_name}"'
)
inverted_recapture_trigger.add_action(DoScript(script_string))
inverted_recapture_trigger.add_action(ClearFlag(flag=flag))
self.mission.triggerrules.triggers.append(
inverted_recapture_trigger
self.mission.triggerrules.triggers.extend(
[red_capture, red_recapture]
)
def generate(self) -> None:
@ -296,7 +288,7 @@ class TriggerGenerator:
self._set_skill(player_coalition, enemy_coalition)
self._set_allegiances(player_coalition, enemy_coalition)
self._gen_markers()
self._generate_capture_triggers(player_coalition, enemy_coalition)
self._generate_capture_triggers()
if self.game.settings.ground_start_scenery_remove_triggers:
try:
self._generate_clear_statics_trigger(self.game.scenery_clear_zones)

View File

@ -1,147 +0,0 @@
---
name: Persian Gulf - Scenic Route - Neutral
theater: Persian Gulf
authors: Fuzzle
description: <p>A lightweight naval campaign involving a US Navy carrier group pushing across the coast of Iran. <strong>This is a purely naval campaign, meaning you will need to use the Air Assault mission type with transports to take the first FOB. Ensure you soften it up enough first!</strong></p><p><strong>Backstory:</strong> Iran has declared war on all US forces in the Gulf resulting in all local allies withdrawing their support for American troops. A lone carrier group must pacify the southern coast of Iran and hold out until backup can arrive lest the US and her interests be ejected from the region permanently.</p>
version: "10.7"
advanced_iads: true
recommended_player_faction: US Navy 2005
recommended_enemy_faction: Iran 2015
miz: scenic_route_neutral.miz
performance: 1
recommended_start_date: 2005-04-26
recommended_player_money: 1000
recommended_enemy_money: 1300
recommended_player_income_multiplier: 1.2
recommended_enemy_income_multiplier: 0.7
squadrons:
#BLUFOR CVN
Naval-1:
- primary: BARCAP
secondary: air-to-air
aircraft:
- VF-143
size: 14
- primary: SEAD
secondary: air-to-ground
aircraft:
- VFA-113
- primary: AEW&C
aircraft:
- VAW-125
size: 2
- primary: Refueling
aircraft:
- VS-35 (Tanker)
size: 4
- primary: Anti-ship
secondary: air-to-ground
aircraft:
- VS-35
size: 8
- primary: Transport
aircraft:
- HSM-40
size: 2
# BLUFOR LHA
Naval-2:
- primary: BAI
secondary: air-to-ground
aircraft:
- VMA-223
size: 10
- primary: Transport
secondary: air-to-ground
aircraft:
- HMLA-169 (UH-1H)
size: 4
- primary: CAS
secondary: air-to-ground
aircraft:
- HMLA-169 (AH-1W)
size: 6
# OPFOR CVN
Naval-3:
- primary: BARCAP
secondary: any
- primary: Strike
secondary: any
- primary: BAI
secondary: any
- primary: Refueling
# Kish Intl
24:
- primary: AEW&C
aircraft:
- A-50
size: 1
- primary: BARCAP
secondary: any
aircraft:
- F-14A Tomcat (Block 135-GR Late)
- primary: Strike
secondary: air-to-ground
aircraft:
- Su-24MK Fencer-D
- primary: BARCAP
secondary: any
aircraft:
- F-4E Phantom II
# Havadarya
9:
- primary: BARCAP
secondary: any
aircraft:
- F-4E Phantom II
size: 10
- primary: CAS
secondary: air-to-ground
aircraft:
- Su-25 Frogfoot
size: 12
# Bandar Abbas Intl
2:
- primary: TARCAP
secondary: any
aircraft:
- F-5E Tiger II
- primary: BARCAP
secondary: air-to-ground
aircraft:
- MiG-29A Fulcrum-A
- primary: Strike
secondary: air-to-ground
aircraft:
- Su-24MK
- primary: BARCAP
secondary: air-to-ground
aircraft:
- F-4E Phantom II
# OPFOR First FOB
FOB Seerik:
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-24V Hind-E
size: 6
# OPFOR Second FOB
FOB Kohnehshahr:
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-24V Hind-F
size: 6
# OPFOR Third FOB
FOB Khvosh:
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-28N Havoc
size: 6
# OPFOR Last FOB
FOB Charak:
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-28N Havoc
size: 6