mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
updates to CAP op
This commit is contained in:
parent
3b454470f9
commit
683114f916
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,6 +2,7 @@
|
||||
__pycache__
|
||||
build/*
|
||||
resources/payloads/*.lua
|
||||
venv
|
||||
logs.txt
|
||||
.DS_Store
|
||||
# User-specific stuff
|
||||
|
||||
@ -16,7 +16,7 @@ class FrontlineAttackEvent(Event):
|
||||
ATTACKER_AMOUNT_FACTOR = 0.4
|
||||
ATTACKER_DEFENDER_FACTOR = 0.7
|
||||
STRENGTH_INFLUENCE = 0.2
|
||||
SUCCESS_TARGETS_HIT_PERCENTAGE = 0.25
|
||||
SUCCESS_FACTOR = 1.5
|
||||
|
||||
defenders = None # type: db.ArmorDict
|
||||
|
||||
@ -28,16 +28,13 @@ class FrontlineAttackEvent(Event):
|
||||
return "Frontline attack from {} at {}".format(self.from_cp, self.to_cp)
|
||||
|
||||
def is_successfull(self, debriefing: Debriefing):
|
||||
total_targets = sum(self.defenders.values())
|
||||
destroyed_targets = 0
|
||||
for unit, count in debriefing.destroyed_units[self.defender_name].items():
|
||||
if unit in self.defenders:
|
||||
destroyed_targets += count
|
||||
|
||||
alive_attackers = sum([v for k, v in debriefing.alive_units[self.attacker_name].items() if db.unit_task(k) == PinpointStrike])
|
||||
alive_defenders = sum([v for k, v in debriefing.alive_units[self.defender_name].items() if db.unit_task(k) == PinpointStrike])
|
||||
attackers_success = (float(alive_attackers) / alive_defenders) > self.SUCCESS_FACTOR
|
||||
if self.from_cp.captured:
|
||||
return float(destroyed_targets) / total_targets >= self.SUCCESS_TARGETS_HIT_PERCENTAGE
|
||||
return attackers_success
|
||||
else:
|
||||
return float(destroyed_targets) / total_targets < self.SUCCESS_TARGETS_HIT_PERCENTAGE
|
||||
return not attackers_success
|
||||
|
||||
def commit(self, debriefing: Debriefing):
|
||||
super(FrontlineAttackEvent, self).commit(debriefing)
|
||||
|
||||
@ -13,7 +13,7 @@ from userdata.debriefing import Debriefing
|
||||
class FrontlinePatrolEvent(Event):
|
||||
ESCORT_FACTOR = 0.5
|
||||
STRENGTH_INFLUENCE = 0.2
|
||||
SUCCESS_TARGETS_HIT_PERCENTAGE = 0.33
|
||||
SUCCESS_FACTOR = 0.8
|
||||
|
||||
cas = None # type: db.PlaneDict
|
||||
escort = None # type: db.PlaneDict
|
||||
@ -25,6 +25,7 @@ class FrontlinePatrolEvent(Event):
|
||||
def __str__(self):
|
||||
return "Frontline CAP from {} at {}".format(self.from_cp, self.to_cp)
|
||||
|
||||
"""
|
||||
def is_successfull(self, debriefing: Debriefing):
|
||||
total_targets = sum(self.cas.values())
|
||||
destroyed_targets = 0
|
||||
@ -36,6 +37,16 @@ class FrontlinePatrolEvent(Event):
|
||||
return float(destroyed_targets) / total_targets >= self.SUCCESS_TARGETS_HIT_PERCENTAGE
|
||||
else:
|
||||
return float(destroyed_targets) / total_targets < self.SUCCESS_TARGETS_HIT_PERCENTAGE
|
||||
"""
|
||||
|
||||
def is_successfull(self, debriefing: Debriefing):
|
||||
alive_attackers = sum([v for k, v in debriefing.alive_units[self.attacker_name].items() if db.unit_task(k) == PinpointStrike])
|
||||
alive_defenders = sum([v for k, v in debriefing.alive_units[self.defender_name].items() if db.unit_task(k) == PinpointStrike])
|
||||
attackers_success = (float(alive_attackers) / alive_defenders) >= self.SUCCESS_FACTOR
|
||||
if self.from_cp.captured:
|
||||
return attackers_success
|
||||
else:
|
||||
return not attackers_success
|
||||
|
||||
def commit(self, debriefing: Debriefing):
|
||||
super(FrontlinePatrolEvent, self).commit(debriefing)
|
||||
@ -54,7 +65,7 @@ class FrontlinePatrolEvent(Event):
|
||||
def skip(self):
|
||||
pass
|
||||
|
||||
def player_attacking(self, interceptors: db.PlaneDict, clients: db.PlaneDict):
|
||||
def player_attacking(self, interceptors: db.PlaneDict, clients: db.PlaneDict, armor: db.ArmorDict):
|
||||
self.cas = self.to_cp.base.scramble_cas(self.game.settings.multiplier)
|
||||
self.escort = self.to_cp.base.scramble_sweep(self.game.settings.multiplier * self.ESCORT_FACTOR)
|
||||
|
||||
@ -65,10 +76,12 @@ class FrontlinePatrolEvent(Event):
|
||||
defender_clients={},
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp)
|
||||
|
||||
defenders = self.to_cp.base.assemble_attack()
|
||||
op.setup(cas=self.cas,
|
||||
escort=self.escort,
|
||||
interceptors=interceptors,
|
||||
armor_attackers=self.from_cp.base.assemble_attack(),
|
||||
armor_defenders=self.to_cp.base.assemble_attack())
|
||||
armor_attackers=db.unitdict_restrict_count(armor, sum(defenders.values())),
|
||||
armor_defenders=defenders)
|
||||
|
||||
self.operation = op
|
||||
|
||||
@ -262,11 +262,12 @@ class AircraftConflictGenerator:
|
||||
client_count=client_count,
|
||||
at=at and at or self._group_point(self.conflict.air_defenders_location))
|
||||
|
||||
pos = self.conflict.air_defenders_location.point_from_heading(self.conflict.heading-90, CAP_CAS_DISTANCE)
|
||||
waypoint = group.add_waypoint(pos, CAS_ALTITUDE, WARM_START_AIRSPEED)
|
||||
location = self._group_point(self.conflict.air_defenders_location)
|
||||
insertion_point = self.conflict.find_insertion_point(location)
|
||||
waypoint = group.add_waypoint(insertion_point, CAS_ALTITUDE, WARM_START_AIRSPEED)
|
||||
|
||||
if self.conflict.is_vector:
|
||||
destination_tail = self.conflict.tail.distance_to_point(pos) > self.conflict.position.distance_to_point(pos)
|
||||
destination_tail = self.conflict.tail.distance_to_point(insertion_point) > self.conflict.position.distance_to_point(insertion_point)
|
||||
group.add_waypoint(destination_tail and self.conflict.tail or self.conflict.position, CAS_ALTITUDE, WARM_START_AIRSPEED)
|
||||
|
||||
group.task = CAS.name
|
||||
|
||||
@ -20,7 +20,7 @@ AIR_DISTANCE = 40000
|
||||
|
||||
CAPTURE_AIR_ATTACKERS_DISTANCE = 25000
|
||||
CAPTURE_AIR_DEFENDERS_DISTANCE = 60000
|
||||
CAP_CAS_DISTANCE = 10000
|
||||
CAP_CAS_DISTANCE = 10000, 120000
|
||||
|
||||
GROUND_INTERCEPT_SPREAD = 5000
|
||||
GROUND_DISTANCE_FACTOR = 1
|
||||
@ -123,6 +123,21 @@ class Conflict:
|
||||
def to_size(self):
|
||||
return self.to_cp.size * GROUND_DISTANCE_FACTOR
|
||||
|
||||
def find_insertion_point(self, other_point: Point) -> Point:
|
||||
dx = self.position.x - self.tail.x
|
||||
dy = self.position.y - self.tail.y
|
||||
dr2 = float(dx ** 2 + dy ** 2)
|
||||
|
||||
lerp = ((other_point.x - self.tail.x) * dx + (other_point.y - self.tail.y) * dy) / dr2
|
||||
if lerp < 0:
|
||||
lerp = 0
|
||||
elif lerp > 1:
|
||||
lerp = 1
|
||||
|
||||
x = lerp * dx + self.tail.x
|
||||
y = lerp * dy + self.tail.y
|
||||
return Point(x, y)
|
||||
|
||||
@classmethod
|
||||
def has_frontline_between(cls, from_cp: ControlPoint, to_cp: ControlPoint) -> bool:
|
||||
return from_cp.has_frontline and to_cp.has_frontline
|
||||
@ -138,6 +153,7 @@ class Conflict:
|
||||
center_position, heading = cls.frontline_position(from_cp, to_cp)
|
||||
|
||||
left_position = center_position
|
||||
|
||||
for offset in range(0, int(FRONTLINE_LENGTH / 2), 1000):
|
||||
pos = center_position.point_from_heading(_heading_sum(heading, -90), offset)
|
||||
if not theater.is_on_land(pos):
|
||||
@ -266,7 +282,7 @@ class Conflict:
|
||||
position, heading, distance = cls.frontline_vector(from_cp, to_cp, theater)
|
||||
attack_position = position.point_from_heading(heading, randint(0, int(distance)))
|
||||
attackers_position = attack_position.point_from_heading(heading - 90, AIR_DISTANCE)
|
||||
defenders_position = attack_position.point_from_heading(heading + 90, CAP_CAS_DISTANCE)
|
||||
defenders_position = attack_position.point_from_heading(heading + 90, random.randint(*CAP_CAS_DISTANCE))
|
||||
|
||||
return cls(
|
||||
position=position,
|
||||
|
||||
@ -18,7 +18,7 @@ from gen import *
|
||||
WEATHER_CLOUD_BASE = 2000, 3000
|
||||
WEATHER_CLOUD_DENSITY = 1, 8
|
||||
WEATHER_CLOUD_THICKNESS = 100, 400
|
||||
WEATHER_CLOUD_BASE_MIN = 2400
|
||||
WEATHER_CLOUD_BASE_MIN = 1600
|
||||
|
||||
RANDOM_TIME = {
|
||||
"night": 5,
|
||||
@ -28,10 +28,10 @@ RANDOM_TIME = {
|
||||
}
|
||||
|
||||
RANDOM_WEATHER = {
|
||||
1: 5, # heavy rain
|
||||
2: 15, # rain
|
||||
3: 25, # dynamic
|
||||
4: 35, # clear
|
||||
1: 10, # heavy rain
|
||||
2: 20, # rain
|
||||
3: 30, # dynamic
|
||||
4: 40, # clear
|
||||
5: 100, # random
|
||||
}
|
||||
|
||||
@ -90,8 +90,13 @@ class EnviromentGenerator:
|
||||
self.mission.weather.wind_at_8000 = Wind(wind_direction, wind_speed * 3)
|
||||
|
||||
if self.mission.weather.clouds_density > 0:
|
||||
# sometimes clouds are randomized way too low and need to be fixed
|
||||
self.mission.weather.clouds_base = max(self.mission.weather.clouds_base, WEATHER_CLOUD_BASE_MIN)
|
||||
|
||||
if self.mission.weather.wind_at_ground == 0:
|
||||
# frontline smokes look silly w/o any wind
|
||||
self.mission.weather.wind_at_ground = random.randint(1, 2)
|
||||
|
||||
def generate(self) -> EnvironmentSettings:
|
||||
self._gen_random_time()
|
||||
self._gen_random_weather()
|
||||
|
||||
@ -8,7 +8,7 @@ from game.event import *
|
||||
|
||||
UNITTYPES_FOR_EVENTS = {
|
||||
FrontlineAttackEvent: [CAS, PinpointStrike],
|
||||
FrontlinePatrolEvent: [CAP],
|
||||
FrontlinePatrolEvent: [CAP, PinpointStrike],
|
||||
InterceptEvent: [CAP],
|
||||
InsurgentAttackEvent: [CAS],
|
||||
NavalInterceptEvent: [CAS],
|
||||
@ -218,7 +218,7 @@ class EventMenu(Menu):
|
||||
e.player_attacking(armor=scrambled_armor, strikegroup=scrambled_aircraft, clients=scrambled_clients)
|
||||
elif type(self.event) is FrontlinePatrolEvent:
|
||||
e = self.event # type: FrontlinePatrolEvent
|
||||
e.player_attacking(interceptors=scrambled_aircraft, clients=scrambled_clients)
|
||||
e.player_attacking(interceptors=scrambled_aircraft, clients=scrambled_clients, armor=scrambled_armor)
|
||||
elif type(self.event) is NavalInterceptEvent:
|
||||
e = self.event # type: NavalInterceptEvent
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user