proper waypoints for CAS escort; game and trigger balance; fixed minor bugs

This commit is contained in:
Vasyl Horbachenko 2018-07-03 02:28:19 +03:00
parent b2458ac244
commit 9845698481
8 changed files with 54 additions and 41 deletions

View File

@ -26,7 +26,7 @@ x_map = {
}
from this example `Identifier` should be used (which may or may not include category of the unit and dot + underscore characters).
For example, player accessible Hornet is called `FA_18C_hornet`, and MANPAD Igla is called `AirDefence.SAM_SA_18_Igla_MANPADS`
For example, player accessible Hornet is called `FA_18C_hornet`, and MANPAD Igla is called `AirDefence.SAM_SA_18_Igla_S_MANPADS`
"""
"""
@ -98,7 +98,7 @@ PRICES = {
AirDefence.SAM_Patriot_ICC: 15,
AirDefence.AAA_ZU_23_on_Ural_375: 5,
AirDefence.SAM_SA_18_Igla_MANPADS: 8,
AirDefence.SAM_SA_18_Igla_S_MANPADS: 8,
AirDefence.SAM_SA_19_Tunguska_2S6: 10,
AirDefence.SAM_SA_8_Osa_9A33: 15,
@ -174,8 +174,7 @@ UNIT_BY_TASK = {
AirDefence.AAA_ZU_23_on_Ural_375,
AirDefence.AAA_ZU_23_on_Ural_375,
AirDefence.SAM_SA_18_Igla_MANPADS,
AirDefence.SAM_SA_18_Igla_MANPADS,
AirDefence.SAM_SA_19_Tunguska_2S6,
AirDefence.SAM_SA_19_Tunguska_2S6,
AirDefence.SAM_SA_8_Osa_9A33,
],
@ -252,7 +251,7 @@ UNIT_BY_COUNTRY = {
Mi_8MT,
AirDefence.AAA_ZU_23_on_Ural_375,
AirDefence.SAM_SA_18_Igla_MANPADS,
AirDefence.SAM_SA_18_Igla_S_MANPADS,
AirDefence.SAM_SA_19_Tunguska_2S6,
AirDefence.SAM_SA_8_Osa_9A33,

View File

@ -46,12 +46,12 @@ Events:
* InfantryTransportEvent - helicopter infantry transport
"""
EVENT_PROBABILITIES = {
CaptureEvent: [100, 6],
InterceptEvent: [25, 9],
GroundInterceptEvent: [25, 9],
GroundAttackEvent: [0, 9],
NavalInterceptEvent: [25, 9],
AntiAAStrikeEvent: [25, 9],
CaptureEvent: [100, 8],
InterceptEvent: [25, 12],
GroundInterceptEvent: [25, 12],
GroundAttackEvent: [0, 12],
NavalInterceptEvent: [25, 12],
AntiAAStrikeEvent: [25, 12],
InfantryTransportEvent: [25, 0],
}

View File

@ -8,6 +8,7 @@ class NavalInterceptionOperation(Operation):
strikegroup = None # type: db.PlaneDict
interceptors = None # type: db.PlaneDict
targets = None # type: db.ShipDict
trigger_radius = TRIGGER_RADIUS_LARGE
def setup(self,
strikegroup: db.PlaneDict,

View File

@ -2,6 +2,7 @@ from game import db
from game.settings import Settings
from .conflictgen import *
from .naming import *
from .triggergen import TRIGGER_WAYPOINT_OFFSET
from dcs.mission import *
from dcs.unitgroup import *
@ -14,21 +15,26 @@ ESCORT_ENGAGEMENT_MAX_DIST = 100000
WORKAROUND_WAYP_DIST = 1000
WARM_START_ALTITUDE = 3000
WARM_START_AIRSPEED = 550
INTERCEPTION_ALT = 3000
INTERCEPTION_AIRSPEED = 1000
ATTACK_CIRCLE_ALT = 5000
ATTACK_CIRCLE_DURATION = 15
CAS_ALTITUDE = 1000
RTB_ALTITUDE = 1000
TRANSPORT_LANDING_ALT = 1000
HELI_ALT = 900
WARM_START_AIRSPEED = 550
INTERCEPTION_AIRSPEED = 1000
TRANSPORT_LANDING_ALT = 1000
DEFENCE_ENGAGEMENT_MAX_DISTANCE = 60000
INTERCEPT_MAX_DISTANCE = 200000
class AircraftConflictGenerator:
escort_targets = [] # type: typing.List[PlaneGroup]
escort_targets = [] # type: typing.List[typing.Tuple[PlaneGroup, int]]
def __init__(self, mission: Mission, conflict: Conflict, settings: Settings):
self.m = mission
@ -168,7 +174,7 @@ class AircraftConflictGenerator:
else:
assert False
def _generate_escort(self, side: Country, units: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition):
def _generate_escort(self, side: Country, units: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition, is_quick=False, should_orbit=False):
groups = []
for flying_type, count, client_count in self._split_to_groups(units, clients):
group = self._generate_group(
@ -184,14 +190,22 @@ class AircraftConflictGenerator:
heading = group.position.heading_between_point(self.conflict.position)
position = group.position # type: Point
wayp = group.add_waypoint(position.point_from_heading(heading, WORKAROUND_WAYP_DIST), CAS_ALTITUDE, WARM_START_AIRSPEED)
self._setup_group(group, CAP, client_count)
for group in self.escort_targets:
wayp.tasks.append(EscortTaskAction(group.id, engagement_max_dist=ESCORT_ENGAGEMENT_MAX_DIST))
for escorted_group, waypoint_index in self.escort_targets:
waypoint_index += 1
if not is_quick:
waypoint_index += TRIGGER_WAYPOINT_OFFSET
group.add_waypoint(self.conflict.from_cp.position, RTB_ALTITUDE)
group.land_at(self.conflict.from_cp.at)
wayp.tasks.append(EscortTaskAction(escorted_group.id, engagement_max_dist=ESCORT_ENGAGEMENT_MAX_DIST, lastwpt=waypoint_index))
if should_orbit:
orbit_task = ControlledTask(OrbitAction(ATTACK_CIRCLE_ALT, pattern=OrbitAction.OrbitPattern.Circle))
orbit_task.stop_after_duration(ATTACK_CIRCLE_DURATION * 60)
orbit_waypoint = group.add_waypoint(self.conflict.position, CAS_ALTITUDE)
orbit_waypoint.tasks.append(orbit_task)
orbit_waypoint.tasks.append(EngageTargets(max_distance=DEFENCE_ENGAGEMENT_MAX_DISTANCE))
groups.append(group)
return groups
@ -207,11 +221,11 @@ class AircraftConflictGenerator:
count=count,
client_count=client_count,
at=at and at or self._group_point(self.conflict.air_attackers_location))
self.escort_targets.append(group)
group.add_waypoint(self.conflict.position, CAS_ALTITUDE, WARM_START_AIRSPEED)
waypoint = group.add_waypoint(self.conflict.position, CAS_ALTITUDE, WARM_START_AIRSPEED)
group.task = CAS.name
self._setup_group(group, CAS, client_count)
self.escort_targets.append((group, group.points.index(waypoint)))
group.add_waypoint(self.conflict.from_cp.position, RTB_ALTITUDE)
group.land_at(self.conflict.from_cp.at)
@ -227,7 +241,6 @@ class AircraftConflictGenerator:
count=count,
client_count=client_count,
at=at and at or self._group_point(self.conflict.air_attackers_location))
self.escort_targets.append(group)
wayp = group.add_waypoint(self.conflict.position, CAS_ALTITUDE, WARM_START_AIRSPEED)
for target_group in target_groups:
@ -235,6 +248,7 @@ class AircraftConflictGenerator:
group.task = AntishipStrike.name
self._setup_group(group, AntishipStrike, client_count)
self.escort_targets.append((group, group.points.index(wayp)))
group.add_waypoint(self.conflict.from_cp.position, RTB_ALTITUDE)
group.land_at(self.conflict.from_cp.at)
@ -244,9 +258,10 @@ class AircraftConflictGenerator:
side=self.conflict.attackers_side,
units=attackers,
clients=clients,
at=at and at or self._group_point(self.conflict.air_attackers_location)):
at=at and at or self._group_point(self.conflict.air_attackers_location),
is_quick=at is None,
should_orbit=True):
g.add_waypoint(self.conflict.position, WARM_START_ALTITUDE)
g.add_waypoint(self.conflict.from_cp.position, RTB_ALTITUDE)
g.land_at(self.conflict.from_cp.at)
def generate_transport_escort(self, escort: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None):
@ -254,7 +269,9 @@ class AircraftConflictGenerator:
side=self.conflict.defenders_side,
units=escort,
clients=clients,
at=at and at or self._group_point(self.conflict.air_defenders_location)):
at=at and at or self._group_point(self.conflict.air_defenders_location),
is_quick=at is None,
should_orbit=False):
g.add_waypoint(self.conflict.to_cp.position, RTB_ALTITUDE)
g.land_at(self.conflict.to_cp.at)
@ -271,7 +288,7 @@ class AircraftConflictGenerator:
group.task = CAP.name
wayp = group.add_waypoint(self.conflict.position, CAS_ALTITUDE, WARM_START_AIRSPEED)
wayp.tasks.append(dcs.task.EngageTargets(max_distance=DEFENCE_ENGAGEMENT_MAX_DISTANCE))
wayp.tasks.append(dcs.task.OrbitAction())
wayp.tasks.append(dcs.task.OrbitAction(ATTACK_CIRCLE_ALT, pattern=OrbitAction.OrbitPattern.Circle))
self._setup_group(group, CAP, client_count)
group.add_waypoint(self.conflict.to_cp.position, RTB_ALTITUDE)
@ -289,10 +306,10 @@ class AircraftConflictGenerator:
client_count=client_count,
at=self._group_point(self.conflict.air_defenders_location))
group.task = Transport.name
waypoint = group.add_waypoint(destination.position.random_point_within(0, 0), TRANSPORT_LANDING_ALT)
self.escort_targets.append((group, group.points.index(waypoint)))
self.escort_targets.append(group)
group.add_waypoint(destination.position.random_point_within(0, 0), TRANSPORT_LANDING_ALT)
group.task = Transport.name
group.land_at(destination)
def generate_interception(self, interceptors: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None):

View File

@ -198,9 +198,6 @@ class Conflict:
defense_heading = to_cp.find_radial(from_cp.position.heading_between_point(to_cp.position), ignored_radial=attack_heading)
distance = to_cp.size * GROUND_DISTANCE_FACTOR
attackers_location = position.point_from_heading(attack_heading, distance)
attackers_location = Conflict._find_ground_location(attackers_location, distance * 2, _heading_sum(attack_heading, 180), theater)
defenders_location = position.point_from_heading(defense_heading, distance)
defenders_location = Conflict._find_ground_location(defenders_location, distance * 2, _heading_sum(defense_heading, 180), theater)
@ -213,7 +210,7 @@ class Conflict:
defenders_side=defender,
ground_attackers_location=None,
ground_defenders_location=defenders_location,
air_attackers_location=position.point_from_heading(attack_heading, INTERCEPT_ATTACKERS_DISTANCE),
air_attackers_location=position.point_from_heading(attack_heading, AIR_DISTANCE),
air_defenders_location=position
)

View File

@ -19,10 +19,11 @@ PUSH_TRIGGER_SIZE = 3000
REGROUP_ZONE_DISTANCE = 12000
REGROUP_ALT = 5000
TRIGGER_WAYPOINT_OFFSET = 2
TRIGGER_MIN_DISTANCE_FROM_START = 10000
TRIGGER_RADIUS_MINIMUM = 25000
TRIGGER_RADIUS_SMALL = 40000
TRIGGER_RADIUS_SMALL = 30000
TRIGGER_RADIUS_MEDIUM = 100000
TRIGGER_RADIUS_LARGE = 150000
@ -51,7 +52,7 @@ class TriggersGenerator:
activate_by_trigger.append(vehicle_group)
conflict_distance = self.conflict.from_cp.position.distance_to_point(self.conflict.position)
minimum_radius = min(conflict_distance - TRIGGER_MIN_DISTANCE_FROM_START, conflict_distance - TRIGGER_RADIUS_MINIMUM)
minimum_radius = max(conflict_distance - TRIGGER_MIN_DISTANCE_FROM_START, TRIGGER_RADIUS_MINIMUM)
if minimum_radius < 0:
minimum_radius = 0
@ -147,3 +148,4 @@ class TriggersGenerator:
# TODO: waypoint parts of this should not be post-hacked but added in airgen
self._gen_activation_trigger(activation_trigger_radius, player_coalition, enemy_coalition)
self._gen_push_trigger(player_coalition)

View File

@ -150,7 +150,7 @@ class Base:
return min(min(max(count, PLANES_SCRAMBLE_MIN_BASE), int(PLANES_SCRAMBLE_MAX_BASE * multiplier)), count)
def assemble_count(self):
return int(self.total_armor * self.strength)
return int(self.total_armor * min(self.strength + 0.5, 1))
def assemble_aa_count(self) -> int:
if self.strength > STRENGTH_AA_ASSEMBLE_MIN:

View File

@ -41,7 +41,6 @@ class PersianGulfTheater(ConflictTheater):
bandar_abbas = ControlPoint.from_airport(persiangulf.Bandar_Abbas_Intl, LAND, SIZE_BIG, IMPORTANCE_HIGH)
lar = ControlPoint.from_airport(persiangulf.Lar_Airbase, LAND, SIZE_REGULAR, IMPORTANCE_HIGH)
east_carrier = ControlPoint.carrier("West carrier", Point(-91023.430176, -159467.078125))
west_carrier = ControlPoint.carrier("East carrier", Point(-100531.972946, 60939.275818))
def __init__(self):
@ -67,10 +66,8 @@ class PersianGulfTheater(ConflictTheater):
self.add_controlpoint(self.bandar_abbas, connected_to=[self.havadarya])
self.add_controlpoint(self.lar, connected_to=[self.bandar_lengeh, self.qeshm, self.havadarya])
self.add_controlpoint(self.east_carrier)
self.add_controlpoint(self.west_carrier)
self.east_carrier.captured = True
self.west_carrier.captured = True
self.al_dhafra.captured = True