fixes to frontline attack; frontline CAP WIP

This commit is contained in:
Vasyl Horbachenko
2018-07-17 02:14:46 +03:00
committed by Vasyl Horbachenko
parent 820820eb92
commit 932bec2f84
22 changed files with 297 additions and 63 deletions

View File

@@ -73,6 +73,8 @@ PRICES = {
An_30M: 13,
Yak_40: 13,
S_3B_Tanker: 13,
IL_78M: 13,
KC_135: 13,
A_50: 8,
E_3A: 8,
@@ -167,6 +169,11 @@ UNIT_BY_TASK = {
C_130,
],
Refueling: [
IL_78M,
KC_135,
],
AWACS: [E_3A, A_50, ],
PinpointStrike: [Armor.MBT_T_90, Armor.MBT_T_80U, Armor.MBT_T_55, Armor.MBT_M1A2_Abrams, Armor.MBT_M60A3_Patton, Armor.ATGM_M1134_Stryker, Armor.APC_BTR_80, ],
@@ -251,6 +258,7 @@ UNIT_BY_COUNTRY = {
L_39ZA,
IL_76MD,
IL_78M,
An_26B,
An_30M,
Yak_40,
@@ -290,6 +298,7 @@ UNIT_BY_COUNTRY = {
A_10C,
AV8BNA,
KC_135,
S_3B_Tanker,
C_130,
E_3A,
@@ -450,7 +459,11 @@ def unitdict_split(unit_dict: UnitsDict, count: int):
def unitdict_restrict_count(unit_dict: UnitsDict, total_count: int) -> UnitsDict:
return list(unitdict_split(unit_dict, total_count))[0]
groups = list(unitdict_split(unit_dict, total_count))
if len(groups) > 0:
return groups[0]
else:
return {}
def _validate_db():

View File

@@ -1,5 +1,6 @@
from .event import *
from .frontlineattack import *
from .frontlinepatrol import *
from .intercept import *
from .baseattack import *
from .navalintercept import *

View File

@@ -16,7 +16,7 @@ class BaseAttackEvent(Event):
STRENGTH_RECOVERY = 0.55
def __str__(self):
return "Attack from {} to {}".format(self.from_cp, self.to_cp)
return "Base attack from {} to {}".format(self.from_cp, self.to_cp)
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])

View File

@@ -16,7 +16,7 @@ class FrontlineAttackEvent(Event):
ATTACKER_AMOUNT_FACTOR = 0.4
ATTACKER_DEFENDER_FACTOR = 0.7
STRENGTH_INFLUENCE = 0.3
SUCCESS_MIN_TARGETS = 3
SUCCESS_TARGETS_HIT_PERCENTAGE = 0.25
defenders = None # type: db.ArmorDict
@@ -35,9 +35,9 @@ class FrontlineAttackEvent(Event):
destroyed_targets += count
if self.from_cp.captured:
return float(destroyed_targets) >= min(self.SUCCESS_MIN_TARGETS, total_targets)
return float(destroyed_targets) / total_targets >= self.SUCCESS_TARGETS_HIT_PERCENTAGE
else:
return float(destroyed_targets) < min(self.SUCCESS_MIN_TARGETS, total_targets)
return float(destroyed_targets) / total_targets < self.SUCCESS_TARGETS_HIT_PERCENTAGE
def commit(self, debriefing: Debriefing):
super(FrontlineAttackEvent, self).commit(debriefing)

View File

@@ -0,0 +1,72 @@
import math
import random
from dcs.task import *
from dcs.vehicles import AirDefence
from game import *
from game.event import *
from game.operation.frontlinepatrol import FrontlinePatrolOperation
from userdata.debriefing import Debriefing
class FrontlinePatrolEvent(Event):
ESCORT_FACTOR = 0.5
STRENGTH_INFLUENCE = 0.3
SUCCESS_TARGETS_HIT_PERCENTAGE = 0.6
cas = None # type: db.PlaneDict
escort = None # type: db.PlaneDict
@property
def threat_description(self):
return "{} aircraft + ? CAS".format(self.to_cp.base.scramble_count(self.game.settings.multiplier * self.ESCORT_FACTOR, CAP))
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
for unit, count in debriefing.destroyed_units[self.defender_name].items():
if unit in self.cas:
destroyed_targets += count
if self.from_cp.captured:
return float(destroyed_targets) / total_targets >= self.SUCCESS_TARGETS_HIT_PERCENTAGE
else:
return float(destroyed_targets) / total_targets < self.SUCCESS_TARGETS_HIT_PERCENTAGE
def commit(self, debriefing: Debriefing):
super(FrontlinePatrolEvent, self).commit(debriefing)
if self.from_cp.captured:
if self.is_successfull(debriefing):
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
else:
self.to_cp.base.affect_strength(+self.STRENGTH_INFLUENCE)
else:
if self.is_successfull(debriefing):
self.from_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
else:
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
def skip(self):
pass
def player_attacking(self, interceptors: db.PlaneDict, clients: db.PlaneDict):
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)
op = FrontlinePatrolOperation(game=self.game,
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker_clients={},
defender_clients=clients,
from_cp=self.from_cp,
to_cp=self.to_cp)
op.setup(cas=self.cas,
escort=self.escort,
interceptors=interceptors)
self.operation = op

View File

@@ -5,6 +5,7 @@ import math
from dcs.task import *
from dcs.vehicles import *
from gen.conflictgen import Conflict
from userdata.debriefing import Debriefing
from theater import *
@@ -23,7 +24,7 @@ COMMISION_LIMITS_FACTORS = {
COMMISION_AMOUNTS_SCALE = 1.5
COMMISION_AMOUNTS_FACTORS = {
PinpointStrike: 2,
PinpointStrike: 6,
CAS: 1,
CAP: 2,
AirDefence: 0.3,
@@ -31,6 +32,7 @@ COMMISION_AMOUNTS_FACTORS = {
PLAYER_INTERCEPT_GLOBAL_PROBABILITY_BASE = 25
PLAYER_INTERCEPT_GLOBAL_PROBABILITY_LOG = 2
PLAYER_BASEATTACK_THRESHOLD = 0.2
"""
Various events probabilities. First key is player probabilty, second is enemy probability.
@@ -47,8 +49,9 @@ Events:
"""
EVENT_PROBABILITIES = {
BaseAttackEvent: [100, 10],
InterceptEvent: [25, 10],
FrontlineAttackEvent: [100, 0],
FrontlinePatrolEvent: [1000, 0],
InterceptEvent: [25, 10],
InsurgentAttackEvent: [0, 10],
NavalInterceptEvent: [25, 10],
AntiAAStrikeEvent: [25, 10],
@@ -65,7 +68,7 @@ ENEMY_BASE_STRENGTH_RECOVERY = 0.05
AWACS_BUDGET_COST = 4
# Initial budget value
PLAYER_BUDGET_INITIAL = 120
PLAYER_BUDGET_INITIAL = 170
# Base post-turn bonus value
PLAYER_BUDGET_BASE = 10
# Bonus multiplier logarithm base
@@ -112,11 +115,18 @@ class Game:
continue
for event_class, (player_probability, enemy_probability) in EVENT_PROBABILITIES.items():
if event_class == FrontlineAttackEvent or event_class == InfantryTransportEvent or event_class == FrontlinePatrolEvent:
if not Conflict.has_frontline_between(player_cp, enemy_cp):
continue
if self._roll(player_probability, player_cp.base.strength):
if event_class == NavalInterceptEvent and enemy_cp.radials == LAND:
pass
else:
self.events.append(event_class(self.player, self.enemy, player_cp, enemy_cp, self))
if event_class == BaseAttackEvent and enemy_cp.base.strength > PLAYER_BASEATTACK_THRESHOLD:
pass
else:
self.events.append(event_class(self.player, self.enemy, player_cp, enemy_cp, self))
elif self._roll(enemy_probability, enemy_cp.base.strength):
if event_class in enemy_generated_types:
continue

View File

@@ -6,7 +6,7 @@ from gen.aircraft import *
from gen.aaa import *
from gen.shipgen import *
from gen.triggergen import *
from gen.awacsgen import *
from gen.airsupportgen import *
from gen.visualgen import *
from gen.conflictgen import Conflict

View File

@@ -6,7 +6,7 @@ from gen.aircraft import *
from gen.aaa import *
from gen.shipgen import *
from gen.triggergen import *
from gen.awacsgen import *
from gen.airsupportgen import *
from gen.visualgen import *
from .operation import Operation
@@ -60,7 +60,7 @@ class BaseAttackOperation(Operation):
self.airgen.generate_defense(self.intercept, clients=self.defender_clients, at=self.defenders_starting_position)
self.airgen.generate_cas_strikegroup(self.cas, clients=self.attacker_clients, at=self.attackers_starting_position)
self.airgen.generate_strikegroup_escort(self.escort, clients=self.attacker_clients, at=self.attackers_starting_position)
self.airgen.generate_attackers_escort(self.escort, clients=self.attacker_clients, at=self.attackers_starting_position)
self.visualgen.generate_target_smokes(self.to_cp)
super(BaseAttackOperation, self).generate()

View File

@@ -8,7 +8,7 @@ from gen.aircraft import *
from gen.aaa import *
from gen.shipgen import *
from gen.triggergen import *
from gen.awacsgen import *
from gen.airsupportgen import *
from gen.visualgen import *
from gen.conflictgen import Conflict

View File

@@ -0,0 +1,53 @@
from itertools import zip_longest
from dcs.terrain import Terrain
from game import db
from gen.armor import *
from gen.aircraft import *
from gen.aaa import *
from gen.shipgen import *
from gen.triggergen import *
from gen.airsupportgen import *
from gen.visualgen import *
from gen.conflictgen import Conflict
from .operation import Operation
MAX_DISTANCE_BETWEEN_GROUPS = 12000
class FrontlinePatrolOperation(Operation):
cas = None # type: db.PlaneDict
escort = None # type: db.PlaneDict
interceptors = None # type: db.PlaneDict
def setup(self, cas: db.PlaneDict, escort: db.PlaneDict, interceptors: db.PlaneDict):
self.cas = cas
self.escort = escort
self.interceptors = interceptors
def prepare(self, terrain: Terrain, is_quick: bool):
super(FrontlinePatrolOperation, self).prepare(terrain, is_quick)
self.defenders_starting_position = None
conflict = Conflict.frontline_cap_conflict(
attacker=self.mission.country(self.attacker_name),
defender=self.mission.country(self.defender_name),
from_cp=self.from_cp,
to_cp=self.to_cp,
theater=self.game.theater
)
self.initialize(mission=self.mission,
conflict=conflict)
def generate(self):
self.airgen.generate_defenders_cas(self.cas, {}, self.defenders_starting_position)
self.airgen.generate_defenders_escort(self.escort, {}, self.defenders_starting_position)
self.airgen.generate_patrol(self.interceptors, self.defender_clients, self.attackers_starting_position)
# todo: generate armor
super(FrontlinePatrolOperation, self).generate()

View File

@@ -6,7 +6,7 @@ from gen.aircraft import *
from gen.aaa import *
from gen.shipgen import *
from gen.triggergen import *
from gen.awacsgen import *
from gen.airsupportgen import *
from gen.visualgen import *
from gen.conflictgen import Conflict

View File

@@ -6,7 +6,7 @@ from gen.aircraft import *
from gen.aaa import *
from gen.shipgen import *
from gen.triggergen import *
from gen.awacsgen import *
from gen.airsupportgen import *
from gen.visualgen import *
from gen.conflictgen import Conflict

View File

@@ -52,7 +52,7 @@ class InterceptOperation(Operation):
self.attackers_starting_position = ship
self.airgen.generate_transport(self.transport, self.to_cp.at)
self.airgen.generate_transport_escort(self.escort, clients=self.defender_clients)
self.airgen.generate_defenders_escort(self.escort, clients=self.defender_clients)
self.airgen.generate_interception(self.interceptors, clients=self.attacker_clients, at=self.attackers_starting_position)
super(InterceptOperation, self).generate()

View File

@@ -18,7 +18,7 @@ class Operation:
extra_aagen = None # type: ExtraAAConflictGenerator
shipgen = None # type: ShipGenerator
triggersgen = None # type: TriggersGenerator
awacsgen = None # type: AWACSConflictGenerator
awacsgen = None # type: AirSupportConflictGenerator
visualgen = None # type: VisualGenerator
envgen = None # type: EnvironmentGenerator
@@ -52,7 +52,7 @@ class Operation:
self.airgen = AircraftConflictGenerator(mission, conflict, self.game.settings)
self.aagen = AAConflictGenerator(mission, conflict)
self.shipgen = ShipGenerator(mission, conflict)
self.awacsgen = AWACSConflictGenerator(mission, conflict, self.game)
self.awacsgen = AirSupportConflictGenerator(mission, conflict, self.game)
self.triggersgen = TriggersGenerator(mission, conflict, self.game)
self.visualgen = VisualGenerator(mission, conflict, self.game)
self.envgen = EnviromentGenerator(mission, conflict, self.game)
@@ -78,9 +78,7 @@ class Operation:
def generate(self):
self.visualgen.generate()
if self.is_awacs_enabled:
self.awacsgen.generate()
self.awacsgen.generate(self.is_awacs_enabled)
self.extra_aagen.generate()
self.triggersgen.generate(self.is_quick, self.trigger_radius)