mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
number of fixes to the mission generation
This commit is contained in:
parent
2ace05c565
commit
e03342b3ff
@ -239,8 +239,6 @@ UNIT_BY_COUNTRY = {
|
|||||||
M_2000C,
|
M_2000C,
|
||||||
AV8BNA,
|
AV8BNA,
|
||||||
|
|
||||||
A_10A,
|
|
||||||
A_10C,
|
|
||||||
Su_25T,
|
Su_25T,
|
||||||
L_39ZA,
|
L_39ZA,
|
||||||
|
|
||||||
|
|||||||
@ -12,24 +12,12 @@ from .event import Event
|
|||||||
|
|
||||||
class CaptureEvent(Event):
|
class CaptureEvent(Event):
|
||||||
silent = True
|
silent = True
|
||||||
BONUS_BASE = 10
|
BONUS_BASE = 15
|
||||||
STRENGTH_RECOVERY = 0.35
|
STRENGTH_RECOVERY = 0.35
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Attack from {} to {}".format(self.from_cp, self.to_cp)
|
return "Attack from {} to {}".format(self.from_cp, self.to_cp)
|
||||||
|
|
||||||
@property
|
|
||||||
def threat_description(self):
|
|
||||||
descr = "{} aircraft + CAS, {} vehicles".format(
|
|
||||||
self.enemy_cp.base.scramble_count(self.game.settings.multiplier),
|
|
||||||
self.enemy_cp.base.assemble_count()
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.is_player_attacking:
|
|
||||||
descr += ", {} AA".format(self.enemy_cp.base.assemble_aa_count())
|
|
||||||
|
|
||||||
return descr
|
|
||||||
|
|
||||||
def is_successfull(self, debriefing: Debriefing):
|
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_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])
|
alive_defenders = sum([v for k, v in debriefing.alive_units[self.defender_name].items() if db.unit_task(k) == PinpointStrike])
|
||||||
|
|||||||
@ -18,7 +18,7 @@ class Event:
|
|||||||
difficulty = 1 # type: int
|
difficulty = 1 # type: int
|
||||||
game = None # type: Game
|
game = None # type: Game
|
||||||
environment_settings = None # type: EnvironmentSettings
|
environment_settings = None # type: EnvironmentSettings
|
||||||
BONUS_BASE = 3
|
BONUS_BASE = 5
|
||||||
|
|
||||||
def __init__(self, attacker_name: str, defender_name: str, from_cp: ControlPoint, to_cp: ControlPoint, game):
|
def __init__(self, attacker_name: str, defender_name: str, from_cp: ControlPoint, to_cp: ControlPoint, game):
|
||||||
self.attacker_name = attacker_name
|
self.attacker_name = attacker_name
|
||||||
|
|||||||
@ -18,6 +18,13 @@ class GroundInterceptEvent(Event):
|
|||||||
|
|
||||||
targets = None # type: db.ArmorDict
|
targets = None # type: db.ArmorDict
|
||||||
|
|
||||||
|
@property
|
||||||
|
def threat_description(self):
|
||||||
|
if not self.game.is_player_attack(self):
|
||||||
|
return "{} aicraft".format(self.from_cp.base.scramble_count(self.game.settings.multiplier, CAS))
|
||||||
|
else:
|
||||||
|
return super(GroundInterceptEvent, self).threat_description
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Fontline CAS from {} at {}".format(self.from_cp, self.to_cp)
|
return "Fontline CAS from {} at {}".format(self.from_cp, self.to_cp)
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,8 @@ class InfantryTransportEvent(Event):
|
|||||||
to_cp=self.to_cp
|
to_cp=self.to_cp
|
||||||
)
|
)
|
||||||
|
|
||||||
op.setup(transport=transport)
|
air_defense = db.find_unittype(AirDefence, self.defender_name)[0]
|
||||||
|
op.setup(transport=transport,
|
||||||
|
aa={air_defense: 2})
|
||||||
|
|
||||||
self.operation = op
|
self.operation = op
|
||||||
|
|||||||
@ -13,7 +13,6 @@ from .event import Event
|
|||||||
|
|
||||||
|
|
||||||
class InterceptEvent(Event):
|
class InterceptEvent(Event):
|
||||||
BONUS_BASE = 5
|
|
||||||
STRENGTH_INFLUENCE = 0.3
|
STRENGTH_INFLUENCE = 0.3
|
||||||
GLOBAL_STRENGTH_INFLUENCE = 0.3
|
GLOBAL_STRENGTH_INFLUENCE = 0.3
|
||||||
AIRDEFENSE_COUNT = 3
|
AIRDEFENSE_COUNT = 3
|
||||||
@ -25,7 +24,7 @@ class InterceptEvent(Event):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def threat_description(self):
|
def threat_description(self):
|
||||||
return "{} aircraft".format(self.enemy_cp.base.scramble_count(self.game.settings.multiplier))
|
return "{} aircraft".format(self.enemy_cp.base.scramble_count(self.game.settings.multiplier, CAP))
|
||||||
|
|
||||||
def is_successfull(self, debriefing: Debriefing):
|
def is_successfull(self, debriefing: Debriefing):
|
||||||
units_destroyed = debriefing.destroyed_units[self.defender_name].get(self.transport_unit, 0)
|
units_destroyed = debriefing.destroyed_units[self.defender_name].get(self.transport_unit, 0)
|
||||||
|
|||||||
@ -64,7 +64,7 @@ AWACS_BUDGET_COST = 4
|
|||||||
# Initial budget value
|
# Initial budget value
|
||||||
PLAYER_BUDGET_INITIAL = 120
|
PLAYER_BUDGET_INITIAL = 120
|
||||||
# Base post-turn bonus value
|
# Base post-turn bonus value
|
||||||
PLAYER_BUDGET_BASE = 30
|
PLAYER_BUDGET_BASE = 10
|
||||||
# Bonus multiplier logarithm base
|
# Bonus multiplier logarithm base
|
||||||
PLAYER_BUDGET_IMPORTANCE_LOG = 2
|
PLAYER_BUDGET_IMPORTANCE_LOG = 2
|
||||||
|
|
||||||
|
|||||||
@ -15,9 +15,11 @@ from .operation import Operation
|
|||||||
|
|
||||||
class InfantryTransportOperation(Operation):
|
class InfantryTransportOperation(Operation):
|
||||||
transport = None # type: db.HeliDict
|
transport = None # type: db.HeliDict
|
||||||
|
aa = None # type: db.AirDefenseDict
|
||||||
|
|
||||||
def setup(self, transport: db.HeliDict):
|
def setup(self, transport: db.HeliDict, aa: db.AirDefenseDict):
|
||||||
self.transport = transport
|
self.transport = transport
|
||||||
|
self.aa = aa
|
||||||
|
|
||||||
def prepare(self, terrain: Terrain, is_quick: bool):
|
def prepare(self, terrain: Terrain, is_quick: bool):
|
||||||
super(InfantryTransportOperation, self).prepare(terrain, is_quick)
|
super(InfantryTransportOperation, self).prepare(terrain, is_quick)
|
||||||
@ -40,7 +42,8 @@ class InfantryTransportOperation(Operation):
|
|||||||
at=self.attackers_starting_position
|
at=self.attackers_starting_position
|
||||||
)
|
)
|
||||||
|
|
||||||
self.armorgen.generate_passengers(count=8)
|
self.armorgen.generate_passengers(count=6)
|
||||||
|
self.aagen.generate_at_defenders_location(self.aa)
|
||||||
|
|
||||||
self.visualgen.generate_transportation_marker(self.conflict.ground_attackers_location)
|
self.visualgen.generate_transportation_marker(self.conflict.ground_attackers_location)
|
||||||
self.visualgen.generate_transportation_destination(self.conflict.position)
|
self.visualgen.generate_transportation_destination(self.conflict.position)
|
||||||
|
|||||||
10
gen/aaa.py
10
gen/aaa.py
@ -16,6 +16,16 @@ class AAConflictGenerator:
|
|||||||
self.m = mission
|
self.m = mission
|
||||||
self.conflict = conflict
|
self.conflict = conflict
|
||||||
|
|
||||||
|
def generate_at_defenders_location(self, units: db.AirDefenseDict):
|
||||||
|
for unit_type, count in units.items():
|
||||||
|
for _ in range(count):
|
||||||
|
self.m.vehicle_group(
|
||||||
|
country=self.conflict.defenders_side,
|
||||||
|
name=namegen.next_ground_group_name(),
|
||||||
|
_type=unit_type,
|
||||||
|
position=self.conflict.ground_defenders_location.random_point_within(100, 100),
|
||||||
|
group_size=1)
|
||||||
|
|
||||||
def generate(self, units: db.AirDefenseDict):
|
def generate(self, units: db.AirDefenseDict):
|
||||||
for type, count in units.items():
|
for type, count in units.items():
|
||||||
for _, radial in zip(range(count), self.conflict.radials):
|
for _, radial in zip(range(count), self.conflict.radials):
|
||||||
|
|||||||
@ -23,7 +23,8 @@ HELI_ALT = 900
|
|||||||
WARM_START_AIRSPEED = 550
|
WARM_START_AIRSPEED = 550
|
||||||
INTERCEPTION_AIRSPEED = 1000
|
INTERCEPTION_AIRSPEED = 1000
|
||||||
|
|
||||||
INTERCEPT_MAX_DISTANCE = 80000
|
DEFENCE_ENGAGEMENT_MAX_DISTANCE = 60000
|
||||||
|
INTERCEPT_MAX_DISTANCE = 200000
|
||||||
|
|
||||||
|
|
||||||
class AircraftConflictGenerator:
|
class AircraftConflictGenerator:
|
||||||
@ -87,7 +88,7 @@ class AircraftConflictGenerator:
|
|||||||
else:
|
else:
|
||||||
group.units[idx].set_client()
|
group.units[idx].set_client()
|
||||||
|
|
||||||
group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.ByPassAndEscape))
|
group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire))
|
||||||
|
|
||||||
def _generate_at_airport(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, airport: Airport = None) -> FlyingGroup:
|
def _generate_at_airport(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, airport: Airport = None) -> FlyingGroup:
|
||||||
assert count > 0
|
assert count > 0
|
||||||
@ -266,7 +267,7 @@ class AircraftConflictGenerator:
|
|||||||
|
|
||||||
group.task = CAP.name
|
group.task = CAP.name
|
||||||
wayp = group.add_waypoint(self.conflict.position, CAS_ALTITUDE, WARM_START_AIRSPEED)
|
wayp = group.add_waypoint(self.conflict.position, CAS_ALTITUDE, WARM_START_AIRSPEED)
|
||||||
wayp.tasks.append(dcs.task.EngageTargets(max_distance=INTERCEPT_MAX_DISTANCE))
|
wayp.tasks.append(dcs.task.EngageTargets(max_distance=DEFENCE_ENGAGEMENT_MAX_DISTANCE))
|
||||||
wayp.tasks.append(dcs.task.OrbitAction())
|
wayp.tasks.append(dcs.task.OrbitAction())
|
||||||
self._setup_group(group, CAP, client_count)
|
self._setup_group(group, CAP, client_count)
|
||||||
|
|
||||||
@ -307,7 +308,7 @@ class AircraftConflictGenerator:
|
|||||||
initial_wayp = group.add_waypoint(group.position.point_from_heading(heading, WORKAROUND_WAYP_DIST), INTERCEPTION_ALT, INTERCEPTION_AIRSPEED)
|
initial_wayp = group.add_waypoint(group.position.point_from_heading(heading, WORKAROUND_WAYP_DIST), INTERCEPTION_ALT, INTERCEPTION_AIRSPEED)
|
||||||
initial_wayp.tasks.append(EngageTargets(max_distance=INTERCEPT_MAX_DISTANCE))
|
initial_wayp.tasks.append(EngageTargets(max_distance=INTERCEPT_MAX_DISTANCE))
|
||||||
|
|
||||||
wayp = group.add_waypoint(self.conflict.position, 0)
|
wayp = group.add_waypoint(self.conflict.position, WARM_START_ALTITUDE, INTERCEPTION_AIRSPEED)
|
||||||
wayp.tasks.append(EngageTargets(max_distance=INTERCEPT_MAX_DISTANCE))
|
wayp.tasks.append(EngageTargets(max_distance=INTERCEPT_MAX_DISTANCE))
|
||||||
self._setup_group(group, CAP, client_count)
|
self._setup_group(group, CAP, client_count)
|
||||||
|
|
||||||
|
|||||||
@ -23,6 +23,7 @@ AIR_DISTANCE = 32000
|
|||||||
|
|
||||||
INTERCEPT_ATTACKERS_HEADING = -45, 45
|
INTERCEPT_ATTACKERS_HEADING = -45, 45
|
||||||
INTERCEPT_DEFENDERS_HEADING = -10, 10
|
INTERCEPT_DEFENDERS_HEADING = -10, 10
|
||||||
|
INTERCEPT_CONFLICT_DISTANCE = 50000
|
||||||
INTERCEPT_ATTACKERS_DISTANCE = 100000
|
INTERCEPT_ATTACKERS_DISTANCE = 100000
|
||||||
INTERCEPT_MAX_DISTANCE = 160000
|
INTERCEPT_MAX_DISTANCE = 160000
|
||||||
INTERCEPT_MIN_DISTANCE = 100000
|
INTERCEPT_MIN_DISTANCE = 100000
|
||||||
@ -41,7 +42,7 @@ def _heading_sum(h, a) -> int:
|
|||||||
if h > 360:
|
if h > 360:
|
||||||
return h - 360
|
return h - 360
|
||||||
elif h < 0:
|
elif h < 0:
|
||||||
return 360 - h
|
return 360 + h
|
||||||
else:
|
else:
|
||||||
return h
|
return h
|
||||||
|
|
||||||
@ -101,7 +102,8 @@ class Conflict:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def capture_conflict(cls, attacker: Country, defender: Country, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater):
|
def capture_conflict(cls, attacker: Country, defender: Country, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater):
|
||||||
position = to_cp.position
|
position = to_cp.position
|
||||||
attack_heading = to_cp.find_radial(to_cp.position.heading_between_point(from_cp.position))
|
attack_raw_heading = to_cp.position.heading_between_point(from_cp.position)
|
||||||
|
attack_heading = to_cp.find_radial(attack_raw_heading)
|
||||||
defense_heading = to_cp.find_radial(from_cp.position.heading_between_point(to_cp.position), ignored_radial=attack_heading)
|
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
|
distance = to_cp.size * GROUND_DISTANCE_FACTOR
|
||||||
@ -120,8 +122,8 @@ class Conflict:
|
|||||||
defenders_side=defender,
|
defenders_side=defender,
|
||||||
ground_attackers_location=attackers_location,
|
ground_attackers_location=attackers_location,
|
||||||
ground_defenders_location=defenders_location,
|
ground_defenders_location=defenders_location,
|
||||||
air_attackers_location=position.point_from_heading(attack_heading, AIR_DISTANCE),
|
air_attackers_location=position.point_from_heading(attack_raw_heading, AIR_DISTANCE),
|
||||||
air_defenders_location=position.point_from_heading(defense_heading, AIR_DISTANCE)
|
air_defenders_location=position.point_from_heading(_opposite_heading(attack_raw_heading), AIR_DISTANCE)
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -133,7 +135,7 @@ class Conflict:
|
|||||||
position = from_cp.position.point_from_heading(heading, distance)
|
position = from_cp.position.point_from_heading(heading, distance)
|
||||||
|
|
||||||
return cls(
|
return cls(
|
||||||
position=position,
|
position=position.point_from_heading(position.heading_between_point(to_cp.position), INTERCEPT_CONFLICT_DISTANCE),
|
||||||
theater=theater,
|
theater=theater,
|
||||||
from_cp=from_cp,
|
from_cp=from_cp,
|
||||||
to_cp=to_cp,
|
to_cp=to_cp,
|
||||||
@ -213,27 +215,6 @@ class Conflict:
|
|||||||
air_defenders_location=position
|
air_defenders_location=position
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def intercept_conflict(cls, attacker: Country, defender: Country, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater):
|
|
||||||
raw_distance = from_cp.position.distance_to_point(to_cp.position)
|
|
||||||
distance = max(min(raw_distance, INTERCEPT_MAX_DISTANCE), INTERCEPT_MIN_DISTANCE)
|
|
||||||
|
|
||||||
heading = _heading_sum(from_cp.position.heading_between_point(to_cp.position), random.choice([-1, 1]) * random.randint(60, 100))
|
|
||||||
position = from_cp.position.point_from_heading(heading, distance)
|
|
||||||
|
|
||||||
return cls(
|
|
||||||
position=position,
|
|
||||||
theater=theater,
|
|
||||||
from_cp=from_cp,
|
|
||||||
to_cp=to_cp,
|
|
||||||
attackers_side=attacker,
|
|
||||||
defenders_side=defender,
|
|
||||||
ground_attackers_location=None,
|
|
||||||
ground_defenders_location=None,
|
|
||||||
air_attackers_location=position.point_from_heading(random.randint(*INTERCEPT_ATTACKERS_HEADING) + heading, INTERCEPT_ATTACKERS_DISTANCE),
|
|
||||||
air_defenders_location=position
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def naval_intercept_conflict(cls, attacker: Country, defender: Country, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater):
|
def naval_intercept_conflict(cls, attacker: Country, defender: Country, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater):
|
||||||
radial = random.choice(to_cp.sea_radials)
|
radial = random.choice(to_cp.sea_radials)
|
||||||
|
|||||||
@ -28,9 +28,9 @@ RANDOM_TIME = {
|
|||||||
|
|
||||||
RANDOM_WEATHER = {
|
RANDOM_WEATHER = {
|
||||||
1: 5, # heavy rain
|
1: 5, # heavy rain
|
||||||
2: 30, # rain
|
2: 20, # rain
|
||||||
3: 40, # dynamic
|
3: 30, # dynamic
|
||||||
4: 50, # clear
|
4: 40, # clear
|
||||||
5: 100, # random
|
5: 100, # random
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@ from dcs.task import *
|
|||||||
STRENGTH_AA_ASSEMBLE_MIN = 0.2
|
STRENGTH_AA_ASSEMBLE_MIN = 0.2
|
||||||
PLANES_SCRAMBLE_MIN_BASE = 4
|
PLANES_SCRAMBLE_MIN_BASE = 4
|
||||||
PLANES_SCRAMBLE_MAX_BASE = 8
|
PLANES_SCRAMBLE_MAX_BASE = 8
|
||||||
PLANES_SCRAMBLE_FACTOR = 0.8
|
PLANES_SCRAMBLE_FACTOR = 0.6
|
||||||
|
|
||||||
|
|
||||||
class Base:
|
class Base:
|
||||||
@ -140,9 +140,14 @@ class Base:
|
|||||||
elif self.strength < 0:
|
elif self.strength < 0:
|
||||||
self.strength = 0.001
|
self.strength = 0.001
|
||||||
|
|
||||||
def scramble_count(self, multiplier: float) -> int:
|
def scramble_count(self, multiplier: float, task: Task = None) -> int:
|
||||||
count = int(math.ceil(self.total_planes * PLANES_SCRAMBLE_FACTOR * self.strength))
|
if task:
|
||||||
return min(min(max(count, PLANES_SCRAMBLE_MIN_BASE), int(PLANES_SCRAMBLE_MAX_BASE * multiplier)), self.total_planes)
|
count = sum([v for k, v in self.aircraft.items() if db.unit_task(k) == task])
|
||||||
|
else:
|
||||||
|
count = self.total_planes
|
||||||
|
|
||||||
|
count = int(math.ceil(count * PLANES_SCRAMBLE_FACTOR * self.strength))
|
||||||
|
return min(min(max(count, PLANES_SCRAMBLE_MIN_BASE), int(PLANES_SCRAMBLE_MAX_BASE * multiplier)), count)
|
||||||
|
|
||||||
def assemble_count(self):
|
def assemble_count(self):
|
||||||
return int(self.total_armor * self.strength)
|
return int(self.total_armor * self.strength)
|
||||||
@ -154,13 +159,13 @@ class Base:
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
def scramble_sweep(self, multiplier: float) -> typing.Dict[PlaneType, int]:
|
def scramble_sweep(self, multiplier: float) -> typing.Dict[PlaneType, int]:
|
||||||
return self._find_best_planes(CAP, self.scramble_count(multiplier))
|
return self._find_best_planes(CAP, self.scramble_count(multiplier, CAP))
|
||||||
|
|
||||||
def scramble_cas(self, multiplier: float) -> typing.Dict[PlaneType, int]:
|
def scramble_cas(self, multiplier: float) -> typing.Dict[PlaneType, int]:
|
||||||
return self._find_best_planes(CAS, self.scramble_count(multiplier))
|
return self._find_best_planes(CAS, self.scramble_count(multiplier, CAS))
|
||||||
|
|
||||||
def scramble_interceptors(self, multiplier: float) -> typing.Dict[PlaneType, int]:
|
def scramble_interceptors(self, multiplier: float) -> typing.Dict[PlaneType, int]:
|
||||||
return self._find_best_planes(CAP, self.scramble_count(multiplier))
|
return self._find_best_planes(CAP, self.scramble_count(multiplier, CAP))
|
||||||
|
|
||||||
def assemble_cap(self) -> typing.Dict[Armor, int]:
|
def assemble_cap(self) -> typing.Dict[Armor, int]:
|
||||||
return self._find_best_armor(PinpointStrike, self.assemble_count())
|
return self._find_best_armor(PinpointStrike, self.assemble_count())
|
||||||
|
|||||||
@ -27,9 +27,11 @@ class BaseMenu(Menu):
|
|||||||
scheduled_units = self.event.units.get(unit_type, 0)
|
scheduled_units = self.event.units.get(unit_type, 0)
|
||||||
|
|
||||||
Label(self.frame, text="{}".format(db.unit_type_name(unit_type))).grid(row=row, sticky=W)
|
Label(self.frame, text="{}".format(db.unit_type_name(unit_type))).grid(row=row, sticky=W)
|
||||||
|
|
||||||
label = Label(self.frame, text="({})".format(existing_units))
|
label = Label(self.frame, text="({})".format(existing_units))
|
||||||
self.bought_amount_labels[unit_type] = label
|
|
||||||
label.grid(column=1, row=row)
|
label.grid(column=1, row=row)
|
||||||
|
self.bought_amount_labels[unit_type] = label
|
||||||
|
|
||||||
Label(self.frame, text="{}m".format(unit_price)).grid(column=2, row=row)
|
Label(self.frame, text="{}m".format(unit_price)).grid(column=2, row=row)
|
||||||
Button(self.frame, text="+", command=self.buy(unit_type)).grid(column=3, row=row)
|
Button(self.frame, text="+", command=self.buy(unit_type)).grid(column=3, row=row)
|
||||||
Button(self.frame, text="-", command=self.sell(unit_type)).grid(column=4, row=row)
|
Button(self.frame, text="-", command=self.sell(unit_type)).grid(column=4, row=row)
|
||||||
@ -62,15 +64,22 @@ class BaseMenu(Menu):
|
|||||||
|
|
||||||
super(BaseMenu, self).dismiss()
|
super(BaseMenu, self).dismiss()
|
||||||
|
|
||||||
|
def _update_count_label(self, unit_type: UnitType):
|
||||||
|
self.bought_amount_labels[unit_type]["text"] = "({}{})".format(
|
||||||
|
self.cp.base.total_units_of_type(unit_type),
|
||||||
|
unit_type in self.event.units and ", bought {}".format(self.event.units[unit_type]) or ""
|
||||||
|
)
|
||||||
|
|
||||||
|
self.budget_label["text"] = "Budget: {}m".format(self.game.budget)
|
||||||
|
|
||||||
def buy(self, unit_type):
|
def buy(self, unit_type):
|
||||||
def action():
|
def action():
|
||||||
price = db.PRICES[unit_type]
|
price = db.PRICES[unit_type]
|
||||||
if self.game.budget >= price:
|
if self.game.budget >= price:
|
||||||
self.event.deliver({unit_type: 1})
|
self.event.deliver({unit_type: 1})
|
||||||
self.game.budget -= price
|
self.game.budget -= price
|
||||||
label = self.bought_amount_labels[unit_type] # type: Label
|
|
||||||
label["text"] = "({}, bought {})".format(self.cp.base.total_units_of_type(unit_type), self.event.units[unit_type])
|
self._update_count_label(unit_type)
|
||||||
self.budget_label["text"] = "Budget: {}m".format(self.game.budget)
|
|
||||||
|
|
||||||
return action
|
return action
|
||||||
|
|
||||||
@ -87,8 +96,6 @@ class BaseMenu(Menu):
|
|||||||
self.game.budget += price
|
self.game.budget += price
|
||||||
self.base.commit_losses({unit_type: 1})
|
self.base.commit_losses({unit_type: 1})
|
||||||
|
|
||||||
label = self.bought_amount_labels[unit_type] # type: Label
|
self._update_count_label(unit_type)
|
||||||
label["text"] = "({}, bought {})".format(self.cp.base.total_units_of_type(unit_type), self.event.units[unit_type])
|
|
||||||
self.budget_label["text"] = "Budget: {}m".format(self.game.budget)
|
|
||||||
|
|
||||||
return action
|
return action
|
||||||
@ -92,7 +92,7 @@ class Debriefing:
|
|||||||
|
|
||||||
|
|
||||||
def debriefing_directory_location() -> str:
|
def debriefing_directory_location() -> str:
|
||||||
return os.path.expanduser("~\Saved Games\DCS")
|
return os.path.expanduser("~\Saved Games\DCS\liberation_debriefings")
|
||||||
|
|
||||||
|
|
||||||
def _logfiles_snapshot() -> typing.Dict[str, float]:
|
def _logfiles_snapshot() -> typing.Dict[str, float]:
|
||||||
@ -109,14 +109,7 @@ def _poll_new_debriefing_log(snapshot: typing.Dict[str, float], callback: typing
|
|||||||
while should_run:
|
while should_run:
|
||||||
for file, timestamp in _logfiles_snapshot().items():
|
for file, timestamp in _logfiles_snapshot().items():
|
||||||
if file not in snapshot or timestamp != snapshot[file]:
|
if file not in snapshot or timestamp != snapshot[file]:
|
||||||
for _ in range(0, 3):
|
debriefing = Debriefing.parse(os.path.join(debriefing_directory_location(), file))
|
||||||
# some solid programming going on in here
|
|
||||||
try:
|
|
||||||
debriefing = Debriefing.parse(os.path.join(debriefing_directory_location(), file))
|
|
||||||
break
|
|
||||||
except:
|
|
||||||
time.sleep(3)
|
|
||||||
|
|
||||||
callback(debriefing)
|
callback(debriefing)
|
||||||
should_run = False
|
should_run = False
|
||||||
break
|
break
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user