updates to CAP op

This commit is contained in:
Vasyl Horbachenko 2018-07-18 00:45:55 +03:00
parent 3b454470f9
commit 683114f916
7 changed files with 58 additions and 25 deletions

1
.gitignore vendored
View File

@ -2,6 +2,7 @@
__pycache__
build/*
resources/payloads/*.lua
venv
logs.txt
.DS_Store
# User-specific stuff

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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()

View File

@ -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