mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Restored Retribution scripts and triggers to Pretense campaigns. Pretense progress can now be translated back to Retribution. Moved the trigger clearing from pretenseluagenerator.py to pretensemissiongenerator.py
keepActive is now only enabled for airbases and carriers/LHAs, for performance reasons.
This commit is contained in:
parent
87975b9aad
commit
595c468ab2
@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass
|
||||
@ -14,10 +15,12 @@ from dcs.triggers import TriggerStart
|
||||
from dcs.vehicles import AirDefence
|
||||
|
||||
from game.ato import FlightType
|
||||
from game.dcs.aircrafttype import AircraftType
|
||||
from game.missiongenerator.luagenerator import LuaGenerator
|
||||
from game.missiongenerator.missiondata import MissionData
|
||||
from game.plugins import LuaPluginManager
|
||||
from game.theater import Airfield, OffMapSpawn
|
||||
from game.theater import Airfield, OffMapSpawn, TheaterGroundObject
|
||||
from game.theater.iadsnetwork.iadsrole import IadsRole
|
||||
from game.utils import escape_string_for_lua
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -63,12 +66,180 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
ewrj_triggers = [
|
||||
x for x in self.mission.triggerrules.triggers if isinstance(x, TriggerStart)
|
||||
]
|
||||
self.generate_pretense_plugin_data()
|
||||
self.generate_plugin_data()
|
||||
self.inject_plugins()
|
||||
for t in ewrj_triggers:
|
||||
self.mission.triggerrules.triggers.remove(t)
|
||||
self.mission.triggerrules.triggers.append(t)
|
||||
|
||||
def generate_plugin_data(self) -> None:
|
||||
lua_data = LuaData("dcsRetribution")
|
||||
|
||||
install_path = lua_data.add_item("installPath")
|
||||
install_path.set_value(os.path.abspath("."))
|
||||
|
||||
lua_data.add_item("Airbases")
|
||||
carriers_object = lua_data.add_item("Carriers")
|
||||
|
||||
for carrier in self.mission_data.carriers:
|
||||
carrier_item = carriers_object.add_item()
|
||||
carrier_item.add_key_value("dcsGroupName", carrier.group_name)
|
||||
carrier_item.add_key_value("unit_name", carrier.unit_name)
|
||||
carrier_item.add_key_value("callsign", carrier.callsign)
|
||||
carrier_item.add_key_value("radio", str(carrier.freq.mhz))
|
||||
carrier_item.add_key_value(
|
||||
"tacan", str(carrier.tacan.number) + carrier.tacan.band.name
|
||||
)
|
||||
|
||||
tankers_object = lua_data.add_item("Tankers")
|
||||
for tanker in self.mission_data.tankers:
|
||||
tanker_item = tankers_object.add_item()
|
||||
tanker_item.add_key_value("dcsGroupName", tanker.group_name)
|
||||
tanker_item.add_key_value("callsign", tanker.callsign)
|
||||
tanker_item.add_key_value("variant", tanker.variant)
|
||||
tanker_item.add_key_value("radio", str(tanker.freq.mhz))
|
||||
if tanker.tacan is not None:
|
||||
tanker_item.add_key_value(
|
||||
"tacan", str(tanker.tacan.number) + tanker.tacan.band.name
|
||||
)
|
||||
|
||||
awacs_object = lua_data.add_item("AWACs")
|
||||
for awacs in self.mission_data.awacs:
|
||||
awacs_item = awacs_object.add_item()
|
||||
awacs_item.add_key_value("dcsGroupName", awacs.group_name)
|
||||
awacs_item.add_key_value("callsign", awacs.callsign)
|
||||
awacs_item.add_key_value("radio", str(awacs.freq.mhz))
|
||||
|
||||
jtacs_object = lua_data.add_item("JTACs")
|
||||
for jtac in self.mission_data.jtacs:
|
||||
jtac_item = jtacs_object.add_item()
|
||||
jtac_item.add_key_value("dcsGroupName", jtac.group_name)
|
||||
jtac_item.add_key_value("callsign", jtac.callsign)
|
||||
jtac_item.add_key_value("zone", jtac.region)
|
||||
jtac_item.add_key_value("dcsUnit", jtac.unit_name)
|
||||
jtac_item.add_key_value("laserCode", jtac.code)
|
||||
jtac_item.add_key_value("radio", str(jtac.freq.mhz))
|
||||
jtac_item.add_key_value("modulation", jtac.freq.modulation.name)
|
||||
|
||||
logistics_object = lua_data.add_item("Logistics")
|
||||
logistics_flights = logistics_object.add_item("flights")
|
||||
crates_object = logistics_object.add_item("crates")
|
||||
spawnable_crates: dict[str, str] = {}
|
||||
transports: list[AircraftType] = []
|
||||
for logistic_info in self.mission_data.logistics:
|
||||
if logistic_info.transport not in transports:
|
||||
transports.append(logistic_info.transport)
|
||||
coalition_color = "blue" if logistic_info.blue else "red"
|
||||
logistics_item = logistics_flights.add_item()
|
||||
logistics_item.add_data_array("pilot_names", logistic_info.pilot_names)
|
||||
logistics_item.add_key_value("pickup_zone", logistic_info.pickup_zone)
|
||||
logistics_item.add_key_value("drop_off_zone", logistic_info.drop_off_zone)
|
||||
logistics_item.add_key_value("target_zone", logistic_info.target_zone)
|
||||
logistics_item.add_key_value("side", str(2 if logistic_info.blue else 1))
|
||||
logistics_item.add_key_value("logistic_unit", logistic_info.logistic_unit)
|
||||
logistics_item.add_key_value(
|
||||
"aircraft_type", logistic_info.transport.dcs_id
|
||||
)
|
||||
logistics_item.add_key_value(
|
||||
"preload", "true" if logistic_info.preload else "false"
|
||||
)
|
||||
for cargo in logistic_info.cargo:
|
||||
if cargo.unit_type not in spawnable_crates:
|
||||
spawnable_crates[cargo.unit_type] = str(200 + len(spawnable_crates))
|
||||
crate_weight = spawnable_crates[cargo.unit_type]
|
||||
for i in range(cargo.amount):
|
||||
cargo_item = crates_object.add_item()
|
||||
cargo_item.add_key_value("weight", crate_weight)
|
||||
cargo_item.add_key_value("coalition", coalition_color)
|
||||
cargo_item.add_key_value("zone", cargo.spawn_zone)
|
||||
transport_object = logistics_object.add_item("transports")
|
||||
for transport in transports:
|
||||
transport_item = transport_object.add_item()
|
||||
transport_item.add_key_value("aircraft_type", transport.dcs_id)
|
||||
transport_item.add_key_value("cabin_size", str(transport.cabin_size))
|
||||
transport_item.add_key_value(
|
||||
"troops", "true" if transport.cabin_size > 0 else "false"
|
||||
)
|
||||
transport_item.add_key_value(
|
||||
"crates", "true" if transport.can_carry_crates else "false"
|
||||
)
|
||||
spawnable_crates_object = logistics_object.add_item("spawnable_crates")
|
||||
for unit, weight in spawnable_crates.items():
|
||||
crate_item = spawnable_crates_object.add_item()
|
||||
crate_item.add_key_value("unit", unit)
|
||||
crate_item.add_key_value("weight", weight)
|
||||
|
||||
target_points = lua_data.add_item("TargetPoints")
|
||||
for flight in self.mission_data.flights:
|
||||
if flight.friendly and flight.flight_type in [
|
||||
FlightType.ANTISHIP,
|
||||
FlightType.DEAD,
|
||||
FlightType.SEAD,
|
||||
FlightType.STRIKE,
|
||||
]:
|
||||
flight_type = str(flight.flight_type)
|
||||
flight_target = flight.package.target
|
||||
if flight_target:
|
||||
flight_target_name = None
|
||||
flight_target_type = None
|
||||
if isinstance(flight_target, TheaterGroundObject):
|
||||
flight_target_name = flight_target.obj_name
|
||||
flight_target_type = (
|
||||
flight_type + f" TGT ({flight_target.category})"
|
||||
)
|
||||
elif hasattr(flight_target, "name"):
|
||||
flight_target_name = flight_target.name
|
||||
flight_target_type = flight_type + " TGT (Airbase)"
|
||||
target_item = target_points.add_item()
|
||||
if flight_target_name:
|
||||
target_item.add_key_value("name", flight_target_name)
|
||||
if flight_target_type:
|
||||
target_item.add_key_value("type", flight_target_type)
|
||||
target_item.add_key_value(
|
||||
"positionX", str(flight_target.position.x)
|
||||
)
|
||||
target_item.add_key_value(
|
||||
"positionY", str(flight_target.position.y)
|
||||
)
|
||||
|
||||
for cp in self.game.theater.controlpoints:
|
||||
coalition_object = (
|
||||
lua_data.get_or_create_item("BlueAA")
|
||||
if cp.captured
|
||||
else lua_data.get_or_create_item("RedAA")
|
||||
)
|
||||
for ground_object in cp.ground_objects:
|
||||
for g in ground_object.groups:
|
||||
threat_range = g.max_threat_range()
|
||||
|
||||
if not threat_range:
|
||||
continue
|
||||
|
||||
aa_item = coalition_object.add_item()
|
||||
aa_item.add_key_value("name", ground_object.name)
|
||||
aa_item.add_key_value("range", str(threat_range.meters))
|
||||
aa_item.add_key_value("positionX", str(ground_object.position.x))
|
||||
aa_item.add_key_value("positionY", str(ground_object.position.y))
|
||||
|
||||
# Generate IADS Lua Item
|
||||
iads_object = lua_data.add_item("IADS")
|
||||
for node in self.game.theater.iads_network.skynet_nodes(self.game):
|
||||
coalition = iads_object.get_or_create_item("BLUE" if node.player else "RED")
|
||||
iads_type = coalition.get_or_create_item(node.iads_role.value)
|
||||
iads_element = iads_type.add_item()
|
||||
iads_element.add_key_value("dcsGroupName", node.dcs_name)
|
||||
if node.iads_role in [IadsRole.SAM, IadsRole.SAM_AS_EWR]:
|
||||
# add additional SkynetProperties to SAM Sites
|
||||
for property, value in node.properties.items():
|
||||
iads_element.add_key_value(property, value)
|
||||
for role, connections in node.connections.items():
|
||||
iads_element.add_data_array(role, connections)
|
||||
|
||||
trigger = TriggerStart(comment="Set DCS Retribution data")
|
||||
trigger.add_action(DoScript(String(lua_data.create_operations_lua())))
|
||||
self.mission.triggerrules.triggers.append(trigger)
|
||||
|
||||
@staticmethod
|
||||
def generate_sam_from_preset(
|
||||
preset: str, cp_side_str: str, cp_name_trimmed: str
|
||||
@ -650,9 +821,7 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
|
||||
return lua_string_connman
|
||||
|
||||
def generate_plugin_data(self) -> None:
|
||||
self.mission.triggerrules.triggers.clear()
|
||||
|
||||
def generate_pretense_plugin_data(self) -> None:
|
||||
self.inject_plugin_script("base", "mist_4_5_107.lua", "mist_4_5_107")
|
||||
self.inject_plugin_script(
|
||||
"pretense", "pretense_compiled.lua", "pretense_compiled"
|
||||
@ -660,6 +829,23 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
|
||||
trigger = TriggerStart(comment="Pretense init")
|
||||
|
||||
lua_string_config = ""
|
||||
|
||||
lua_string_config += (
|
||||
f"Config.maxDistFromFront = "
|
||||
+ str(self.game.settings.pretense_maxdistfromfront_distance * 1000)
|
||||
+ "\n"
|
||||
)
|
||||
lua_string_config += (
|
||||
f"Config.closeOverride = "
|
||||
+ str(self.game.settings.pretense_closeoverride_distance * 1000)
|
||||
+ "\n"
|
||||
)
|
||||
if self.game.settings.pretense_do_not_generate_sead_missions:
|
||||
lua_string_config += "Config.disablePlayerSead = true\n"
|
||||
else:
|
||||
lua_string_config += "Config.disablePlayerSead = false\n"
|
||||
|
||||
init_header_file = open("./resources/plugins/pretense/init_header.lua", "r")
|
||||
init_header = init_header_file.read()
|
||||
|
||||
@ -687,10 +873,10 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
+ str(cp_side)
|
||||
+ " }\n"
|
||||
)
|
||||
lua_string_zones += f"zones.{cp_name_trimmed}.keepActive = true\n"
|
||||
max_resource = 20000
|
||||
is_helo_spawn = "false"
|
||||
is_plane_spawn = "false"
|
||||
is_keep_active = "false"
|
||||
if cp.has_helipads:
|
||||
is_helo_spawn = "true"
|
||||
max_resource = 30000
|
||||
@ -701,9 +887,12 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
is_helo_spawn = "true"
|
||||
is_plane_spawn = "true"
|
||||
max_resource = 40000
|
||||
if cp.is_lha:
|
||||
is_keep_active = "true"
|
||||
if isinstance(cp, Airfield) or cp.is_carrier:
|
||||
is_helo_spawn = "true"
|
||||
is_plane_spawn = "true"
|
||||
is_keep_active = "true"
|
||||
max_resource = 50000
|
||||
lua_string_zones += (
|
||||
f"zones.{cp_name_trimmed}.maxResource = {max_resource}\n"
|
||||
@ -714,6 +903,9 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
lua_string_zones += (
|
||||
f"zones.{cp_name_trimmed}.isPlaneSpawn = " + is_plane_spawn + "\n"
|
||||
)
|
||||
lua_string_zones += (
|
||||
f"zones.{cp_name_trimmed}.keepActive = " + is_keep_active + "\n"
|
||||
)
|
||||
if cp.is_fleet:
|
||||
lua_string_zones += self.generate_pretense_zone_sea(cp.name)
|
||||
else:
|
||||
@ -805,7 +997,8 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
init_footer = init_footer_file.read()
|
||||
|
||||
lua_string = (
|
||||
init_header
|
||||
lua_string_config
|
||||
+ init_header
|
||||
+ lua_string_zones
|
||||
+ lua_string_connman
|
||||
+ init_body_1
|
||||
@ -854,7 +1047,7 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
|
||||
def inject_plugins(self) -> None:
|
||||
for plugin in LuaPluginManager.plugins():
|
||||
if plugin.enabled and plugin.identifier not in ("base"):
|
||||
if plugin.enabled:
|
||||
plugin.inject_scripts(self)
|
||||
plugin.inject_configuration(self)
|
||||
|
||||
|
||||
@ -101,6 +101,7 @@ class PretenseMissionGenerator(MissionGenerator):
|
||||
self.generate_ground_conflicts()
|
||||
self.generate_air_units(tgo_generator)
|
||||
|
||||
self.mission.triggerrules.triggers.clear()
|
||||
PretenseTriggerGenerator(self.mission, self.game).generate()
|
||||
ForcedOptionsGenerator(self.mission, self.game).generate()
|
||||
VisualsGenerator(self.mission, self.game).generate()
|
||||
|
||||
@ -152,9 +152,72 @@ class PretenseTriggerGenerator:
|
||||
v += 1
|
||||
self.mission.triggerrules.triggers.append(mark_trigger)
|
||||
|
||||
def _generate_pretense_zone_triggers(
|
||||
def _generate_capture_triggers(
|
||||
self, player_coalition: str, enemy_coalition: str
|
||||
) -> 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:
|
||||
attacking_coalition = enemy_coalition
|
||||
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
|
||||
|
||||
trigger_zone = self.mission.triggers.add_triggerzone(
|
||||
cp.position,
|
||||
radius=TRIGGER_RADIUS_CAPTURE,
|
||||
hidden=False,
|
||||
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_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)
|
||||
|
||||
def _generate_pretense_zone_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`
|
||||
@ -166,7 +229,7 @@ class PretenseTriggerGenerator:
|
||||
trigger_radius = TRIGGER_RADIUS_CAPTURE
|
||||
if not isinstance(cp, OffMapSpawn):
|
||||
zone_color = {1: 0.0, 2: 0.0, 3: 0.0, 4: 0.15}
|
||||
trigger_zone = self.mission.triggers.add_triggerzone(
|
||||
self.mission.triggers.add_triggerzone(
|
||||
cp.position,
|
||||
radius=trigger_radius,
|
||||
hidden=False,
|
||||
@ -180,7 +243,7 @@ class PretenseTriggerGenerator:
|
||||
continue
|
||||
tgo_num += 1
|
||||
zone_color = {1: 1.0, 2: 1.0, 3: 1.0, 4: 0.15}
|
||||
trigger_zone = self.mission.triggers.add_triggerzone(
|
||||
self.mission.triggers.add_triggerzone(
|
||||
tgo.position,
|
||||
radius=TRIGGER_RADIUS_PRETENSE_TGO,
|
||||
hidden=False,
|
||||
@ -189,7 +252,7 @@ class PretenseTriggerGenerator:
|
||||
)
|
||||
for helipad in cp.helipads + cp.helipads_invisible + cp.helipads_quad:
|
||||
zone_color = {1: 1.0, 2: 1.0, 3: 1.0, 4: 0.15}
|
||||
trigger_zone = self.mission.triggers.add_triggerzone(
|
||||
self.mission.triggers.add_triggerzone(
|
||||
position=helipad,
|
||||
radius=TRIGGER_RADIUS_PRETENSE_HELI,
|
||||
hidden=False,
|
||||
@ -206,7 +269,7 @@ class PretenseTriggerGenerator:
|
||||
supply_position = origin_position.point_from_heading(
|
||||
convoy_heading, 300
|
||||
)
|
||||
trigger_zone = self.mission.triggers.add_triggerzone(
|
||||
self.mission.triggers.add_triggerzone(
|
||||
supply_position,
|
||||
radius=TRIGGER_RADIUS_PRETENSE_TGO,
|
||||
hidden=False,
|
||||
@ -219,6 +282,8 @@ class PretenseTriggerGenerator:
|
||||
]
|
||||
for airfield in airfields:
|
||||
cp_airport = self.mission.terrain.airport_by_id(airfield.airport.id)
|
||||
if cp_airport is None:
|
||||
continue
|
||||
cp_name_trimmed = "".join(
|
||||
[i for i in cp_airport.name.lower() if i.isalnum()]
|
||||
)
|
||||
@ -263,7 +328,8 @@ class PretenseTriggerGenerator:
|
||||
|
||||
self._set_skill(player_coalition, enemy_coalition)
|
||||
self._set_allegiances(player_coalition, enemy_coalition)
|
||||
self._generate_pretense_zone_triggers(player_coalition, enemy_coalition)
|
||||
self._generate_pretense_zone_triggers()
|
||||
self._generate_capture_triggers(player_coalition, enemy_coalition)
|
||||
|
||||
@classmethod
|
||||
def get_capture_zone_flag(cls) -> int:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user