mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
naval interceptions fixed; unit placement fixes
This commit is contained in:
16
game/db.py
16
game/db.py
@@ -72,8 +72,10 @@ PRICES = {
|
||||
CV_1143_5_Admiral_Kuznetsov: 100,
|
||||
CVN_74_John_C__Stennis: 100,
|
||||
|
||||
Bulk_cargo_ship_Yakushev: 100,
|
||||
Dry_cargo_ship_Ivanov: 100,
|
||||
LHA_1_Tarawa: 30,
|
||||
Bulk_cargo_ship_Yakushev: 10,
|
||||
Dry_cargo_ship_Ivanov: 10,
|
||||
Tanker_Elnya_160: 10,
|
||||
}
|
||||
|
||||
UNIT_BY_TASK = {
|
||||
@@ -135,7 +137,7 @@ UNIT_BY_TASK = {
|
||||
],
|
||||
|
||||
Carriage: [CVN_74_John_C__Stennis, CV_1143_5_Admiral_Kuznetsov, ],
|
||||
CargoTransportation: [Dry_cargo_ship_Ivanov, Bulk_cargo_ship_Yakushev],
|
||||
CargoTransportation: [Dry_cargo_ship_Ivanov, Bulk_cargo_ship_Yakushev, Tanker_Elnya_160, LHA_1_Tarawa],
|
||||
}
|
||||
|
||||
SAM_BAN = [
|
||||
@@ -193,6 +195,7 @@ UNIT_BY_COUNTRY = {
|
||||
CV_1143_5_Admiral_Kuznetsov,
|
||||
Bulk_cargo_ship_Yakushev,
|
||||
Dry_cargo_ship_Ivanov,
|
||||
Tanker_Elnya_160,
|
||||
],
|
||||
|
||||
"USA": [
|
||||
@@ -220,15 +223,14 @@ UNIT_BY_COUNTRY = {
|
||||
AirDefence.SAM_Patriot_ICC,
|
||||
|
||||
CVN_74_John_C__Stennis,
|
||||
# TODO: verify or find out proper USA cargo ship
|
||||
Bulk_cargo_ship_Yakushev,
|
||||
Dry_cargo_ship_Ivanov,
|
||||
LHA_1_Tarawa,
|
||||
],
|
||||
}
|
||||
|
||||
PLANE_PAYLOAD_OVERRIDES = {
|
||||
FA_18C_hornet: {
|
||||
"*": "AIM-9M*6, AIM-7M*2, FUEL*3",
|
||||
Escort: "AIM-9M*6, AIM-7M*2, FUEL*3",
|
||||
CAP: "AIM-9M*6, AIM-7M*2, FUEL*3",
|
||||
},
|
||||
|
||||
# TODO: figure out a way to setup su33 loadout
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import math
|
||||
import random
|
||||
|
||||
from dcs.task import *
|
||||
|
||||
from game import db
|
||||
from game.operation.capture import CaptureOperation
|
||||
from userdata.debriefing import Debriefing
|
||||
@@ -29,8 +31,8 @@ class CaptureEvent(Event):
|
||||
return descr
|
||||
|
||||
def is_successfull(self, debriefing: Debriefing):
|
||||
alive_attackers = sum(debriefing.alive_units[self.attacker_name].values())
|
||||
alive_defenders = sum(debriefing.alive_units[self.defender_name].values())
|
||||
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 = alive_attackers > alive_defenders
|
||||
if self.from_cp.captured:
|
||||
return attackers_success
|
||||
|
||||
@@ -5,6 +5,7 @@ from dcs.task import *
|
||||
|
||||
from game import *
|
||||
from game.event import *
|
||||
from game.operation.groundintercept import GroundInterceptOperation
|
||||
from userdata.debriefing import Debriefing
|
||||
|
||||
|
||||
@@ -27,7 +28,10 @@ class GroundInterceptEvent(Event):
|
||||
if unit in self.targets:
|
||||
destroyed_targets += count
|
||||
|
||||
return (float(destroyed_targets) / float(total_targets)) >= self.SUCCESS_TARGETS_HIT_PERCENTAGE
|
||||
if self.from_cp.captured:
|
||||
return math.ceil(float(destroyed_targets) / total_targets) >= self.SUCCESS_TARGETS_HIT_PERCENTAGE
|
||||
else:
|
||||
return math.ceil(float(destroyed_targets) / total_targets) < self.SUCCESS_TARGETS_HIT_PERCENTAGE
|
||||
|
||||
def commit(self, debriefing: Debriefing):
|
||||
super(GroundInterceptEvent, self).commit(debriefing)
|
||||
@@ -38,13 +42,14 @@ class GroundInterceptEvent(Event):
|
||||
else:
|
||||
self.to_cp.base.affect_strength(+self.STRENGTH_INFLUENCE)
|
||||
else:
|
||||
assert False
|
||||
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):
|
||||
if not self.to_cp.captured:
|
||||
self.to_cp.base.affect_strength(+0.1)
|
||||
else:
|
||||
pass
|
||||
if self.to_cp.captured:
|
||||
self.to_cp.base.affect_strength(-0.1)
|
||||
|
||||
def player_attacking(self, strikegroup: db.PlaneDict, clients: db.PlaneDict):
|
||||
suitable_unittypes = db.find_unittype(PinpointStrike, self.defender_name)
|
||||
@@ -61,8 +66,31 @@ class GroundInterceptEvent(Event):
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp)
|
||||
op.setup(target=self.targets,
|
||||
strikegroup=strikegroup)
|
||||
strikegroup=strikegroup,
|
||||
interceptors={})
|
||||
|
||||
self.operation = op
|
||||
|
||||
def player_defending(self, interceptors: db.PlaneDict, clients: db.PlaneDict):
|
||||
suitable_unittypes = db.find_unittype(PinpointStrike, self.defender_name)
|
||||
random.shuffle(suitable_unittypes)
|
||||
unittypes = suitable_unittypes[:self.TARGET_VARIETY]
|
||||
typecount = max(math.floor(self.difficulty * self.TARGET_AMOUNT_FACTOR), 1)
|
||||
self.targets = {unittype: typecount for unittype in unittypes}
|
||||
|
||||
op = GroundInterceptOperation(
|
||||
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
|
||||
)
|
||||
|
||||
strikegroup = self.from_cp.base.scramble_cas()
|
||||
op.setup(target=self.targets,
|
||||
strikegroup=strikegroup,
|
||||
interceptors=interceptors)
|
||||
|
||||
self.operation = op
|
||||
|
||||
@@ -14,13 +14,14 @@ from .event import Event
|
||||
|
||||
class NavalInterceptEvent(Event):
|
||||
STRENGTH_INFLUENCE = 0.3
|
||||
SUCCESS_RATE = 0.5
|
||||
|
||||
targets = None # type: db.ShipDict
|
||||
|
||||
def _targets_count(self) -> int:
|
||||
from gen.conflictgen import IMPORTANCE_LOW, IMPORTANCE_HIGH
|
||||
factor = (self.to_cp.importance - IMPORTANCE_LOW) * 10
|
||||
return min(int(factor), 1)
|
||||
return max(int(factor), 1)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return "Naval intercept at {}".format(self.to_cp)
|
||||
@@ -33,11 +34,16 @@ class NavalInterceptEvent(Event):
|
||||
return s
|
||||
|
||||
def is_successfull(self, debriefing: Debriefing):
|
||||
targets_destroyed = [c for t, c in debriefing.destroyed_units.items() if t in self.targets.values()]
|
||||
total_targets = sum(self.targets.values())
|
||||
destroyed_targets = 0
|
||||
for unit, count in debriefing.destroyed_units[self.defender_name].items():
|
||||
if unit in self.targets:
|
||||
destroyed_targets += count
|
||||
|
||||
if self.from_cp.captured:
|
||||
return targets_destroyed > 0
|
||||
return math.ceil(float(destroyed_targets) / total_targets) > self.SUCCESS_RATE
|
||||
else:
|
||||
return targets_destroyed == 0
|
||||
return math.ceil(float(destroyed_targets) / total_targets) < self.SUCCESS_RATE
|
||||
|
||||
def commit(self, debriefing: Debriefing):
|
||||
super(NavalInterceptEvent, self).commit(debriefing)
|
||||
@@ -88,8 +94,8 @@ class NavalInterceptEvent(Event):
|
||||
self.game,
|
||||
attacker_name=self.attacker_name,
|
||||
defender_name=self.defender_name,
|
||||
attacker_clients=clients,
|
||||
defender_clients={},
|
||||
attacker_clients={},
|
||||
defender_clients=clients,
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp
|
||||
)
|
||||
|
||||
29
game/game.py
29
game/game.py
@@ -32,10 +32,12 @@ COMMISION_AMOUNTS_FACTORS = {
|
||||
ENEMY_INTERCEPT_PROBABILITY_BASE = 8
|
||||
ENEMY_INTERCEPT_GLOBAL_PROBABILITY_BASE = 5
|
||||
ENEMY_CAPTURE_PROBABILITY_BASE = 4
|
||||
ENEMY_GROUNDINTERCEPT_PROBABILITY_BASE = 8
|
||||
ENEMY_NAVALINTERCEPT_PROBABILITY_BASE = 8
|
||||
|
||||
PLAYER_INTERCEPT_PROBABILITY_BASE = 35
|
||||
PLAYER_GROUNDINTERCEPT_PROBABILITY_BASE = 35
|
||||
|
||||
PLAYER_NAVALINTERCEPT_PROBABILITY_BASE = 35
|
||||
PLAYER_INTERCEPT_GLOBAL_PROBABILITY_BASE = 25
|
||||
PLAYER_INTERCEPT_GLOBAL_PROBABILITY_LOG = 2
|
||||
|
||||
@@ -135,12 +137,21 @@ class Game:
|
||||
game=self))
|
||||
break
|
||||
|
||||
for from_cp, to_cp in self.theater.conflicts(False):
|
||||
if self._roll(ENEMY_GROUNDINTERCEPT_PROBABILITY_BASE, from_cp.base.strength):
|
||||
self.events.append(GroundInterceptEvent(attacker_name=self.enemy,
|
||||
defender_name=self.player,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp,
|
||||
game=self))
|
||||
break
|
||||
|
||||
def _generate_navalinterceptions(self):
|
||||
for from_cp, to_cp in self.theater.conflicts(True):
|
||||
if to_cp.radials == ALL_RADIALS:
|
||||
if to_cp.radials == LAND:
|
||||
continue
|
||||
|
||||
if self._roll(100, from_cp.base.strength):
|
||||
if self._roll(PLAYER_NAVALINTERCEPT_PROBABILITY_BASE, from_cp.base.strength):
|
||||
self.events.append(NavalInterceptEvent(attacker_name=self.player,
|
||||
defender_name=self.enemy,
|
||||
from_cp=from_cp,
|
||||
@@ -148,6 +159,18 @@ class Game:
|
||||
game=self))
|
||||
break
|
||||
|
||||
for from_cp, to_cp in self.theater.conflicts(False):
|
||||
if to_cp.radials == LAND:
|
||||
continue
|
||||
|
||||
if self._roll(ENEMY_NAVALINTERCEPT_PROBABILITY_BASE, from_cp.base.strength):
|
||||
self.events.append(NavalInterceptEvent(attacker_name=self.enemy,
|
||||
defender_name=self.player,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp,
|
||||
game=self))
|
||||
break
|
||||
|
||||
def _generate_globalinterceptions(self):
|
||||
global_count = len([x for x in self.theater.player_points() if x.is_global])
|
||||
for from_cp in [x for x in self.theater.player_points() if x.is_global]:
|
||||
|
||||
@@ -44,7 +44,8 @@ class CaptureOperation(Operation):
|
||||
attacker=self.mission.country(self.attacker_name),
|
||||
defender=self.mission.country(self.defender_name),
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp
|
||||
to_cp=self.to_cp,
|
||||
theater=self.game.theater
|
||||
)
|
||||
self.initialize(mission=self.mission,
|
||||
conflict=conflict)
|
||||
|
||||
@@ -13,20 +13,31 @@ from gen.conflictgen import Conflict
|
||||
from .operation import Operation
|
||||
|
||||
class GroundInterceptOperation(Operation):
|
||||
strikegroup = None # type: db.PlaneDict
|
||||
interceptors = None # type: db.PlaneDict
|
||||
target = None # type: db.ArmorDict
|
||||
|
||||
def setup(self,
|
||||
target: db.ArmorDict,
|
||||
strikegroup: db.PlaneDict):
|
||||
strikegroup: db.PlaneDict,
|
||||
interceptors: db.PlaneDict):
|
||||
self.strikegroup = strikegroup
|
||||
self.interceptors = interceptors
|
||||
self.target = target
|
||||
|
||||
def prepare(self, terrain: Terrain, is_quick: bool):
|
||||
super(GroundInterceptOperation, self).prepare(terrain, is_quick)
|
||||
if self.defender_name == self.game.player:
|
||||
self.attackers_starting_position = None
|
||||
self.defenders_starting_position = None
|
||||
|
||||
conflict = Conflict.ground_intercept_conflict(
|
||||
attacker=self.mission.country(self.attacker_name),
|
||||
defender=self.mission.country(self.defender_name),
|
||||
heading=self.to_cp.position.heading_between_point(self.from_cp.position),
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp
|
||||
to_cp=self.to_cp,
|
||||
theater=self.game.theater
|
||||
)
|
||||
|
||||
self.initialize(mission=self.mission,
|
||||
@@ -34,6 +45,9 @@ class GroundInterceptOperation(Operation):
|
||||
|
||||
def generate(self):
|
||||
self.airgen.generate_cas_strikegroup(self.strikegroup, clients=self.attacker_clients, at=self.attackers_starting_position)
|
||||
self.armorgen.generate({}, self.target)
|
||||
|
||||
if self.interceptors:
|
||||
self.airgen.generate_defense(self.interceptors, clients=self.defender_clients, at=self.defenders_starting_position)
|
||||
|
||||
self.armorgen.generate({}, self.target)
|
||||
super(GroundInterceptOperation, self).generate()
|
||||
|
||||
@@ -30,7 +30,8 @@ class InterceptOperation(Operation):
|
||||
attacker=self.mission.country(self.attacker_name),
|
||||
defender=self.mission.country(self.defender_name),
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp
|
||||
to_cp=self.to_cp,
|
||||
theater=self.game.theater
|
||||
)
|
||||
|
||||
self.initialize(mission=self.mission,
|
||||
|
||||
@@ -19,13 +19,15 @@ class NavalInterceptionOperation(Operation):
|
||||
|
||||
def prepare(self, terrain: Terrain, is_quick: bool):
|
||||
super(NavalInterceptionOperation, self).prepare(terrain, is_quick)
|
||||
if self.defender_name == self.game.player:
|
||||
self.attackers_starting_position = None
|
||||
|
||||
conflict = Conflict.naval_intercept_conflict(
|
||||
attacker=self.mission.country(self.attacker_name),
|
||||
defender=self.mission.country(self.defender_name),
|
||||
theater=self.game.theater,
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp
|
||||
to_cp=self.to_cp,
|
||||
theater=self.game.theater
|
||||
)
|
||||
|
||||
self.initialize(self.mission, conflict)
|
||||
@@ -33,17 +35,18 @@ class NavalInterceptionOperation(Operation):
|
||||
def generate(self):
|
||||
super(NavalInterceptionOperation, self).generate()
|
||||
|
||||
target_groups = self.shipgen.generate_cargo(units=self.targets)
|
||||
|
||||
self.airgen.generate_ship_strikegroup(
|
||||
attackers= self.strikegroup,
|
||||
attackers=self.strikegroup,
|
||||
clients=self.attacker_clients,
|
||||
target_groups=target_groups,
|
||||
at=self.attackers_starting_position
|
||||
)
|
||||
|
||||
self.airgen.generate_interception(
|
||||
interceptors=self.interceptors,
|
||||
clients=self.defender_clients,
|
||||
at=self.defenders_starting_position
|
||||
)
|
||||
|
||||
self.shipgen.generate_cargo(units=self.targets)
|
||||
|
||||
if self.interceptors:
|
||||
self.airgen.generate_defense(
|
||||
defenders=self.interceptors,
|
||||
clients=self.defender_clients,
|
||||
at=self.defenders_starting_position
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user