mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
persistent time and weather between regular and quick missions; defense AA for frontline CAS
This commit is contained in:
parent
f8c1956614
commit
2ace05c565
@ -18,9 +18,6 @@ class CaptureEvent(Event):
|
|||||||
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)
|
||||||
|
|
||||||
def bonus(self):
|
|
||||||
return
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def threat_description(self):
|
def threat_description(self):
|
||||||
descr = "{} aircraft + CAS, {} vehicles".format(
|
descr = "{} aircraft + CAS, {} vehicles".format(
|
||||||
|
|||||||
@ -5,6 +5,7 @@ from theater import *
|
|||||||
from gen.environmentgen import EnvironmentSettings
|
from gen.environmentgen import EnvironmentSettings
|
||||||
|
|
||||||
from userdata.debriefing import Debriefing
|
from userdata.debriefing import Debriefing
|
||||||
|
from userdata import persistency
|
||||||
|
|
||||||
DIFFICULTY_LOG_BASE = 1.1
|
DIFFICULTY_LOG_BASE = 1.1
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ class Event:
|
|||||||
|
|
||||||
self.operation.prepare(self.game.theater.terrain, is_quick=False)
|
self.operation.prepare(self.game.theater.terrain, is_quick=False)
|
||||||
self.operation.generate()
|
self.operation.generate()
|
||||||
self.operation.mission.save("build/nextturn.miz")
|
self.operation.mission.save(persistency.mission_path_for("liberation_nextturn.miz"))
|
||||||
self.environment_settings = self.operation.environment_settings
|
self.environment_settings = self.operation.environment_settings
|
||||||
|
|
||||||
def generate_quick(self):
|
def generate_quick(self):
|
||||||
@ -61,7 +62,7 @@ class Event:
|
|||||||
|
|
||||||
self.operation.prepare(self.game.theater.terrain, is_quick=True)
|
self.operation.prepare(self.game.theater.terrain, is_quick=True)
|
||||||
self.operation.generate()
|
self.operation.generate()
|
||||||
self.operation.mission.save('build/nextturn_quick.miz')
|
self.operation.mission.save(persistency.mission_path_for("liberation_nextturn_quick.miz"))
|
||||||
|
|
||||||
def commit(self, debriefing: Debriefing):
|
def commit(self, debriefing: Debriefing):
|
||||||
for country, losses in debriefing.destroyed_units.items():
|
for country, losses in debriefing.destroyed_units.items():
|
||||||
|
|||||||
@ -157,7 +157,7 @@ class Game:
|
|||||||
awarded_points = COMMISION_AMOUNTS_FACTORS[for_task] * math.pow(cp.importance, COMMISION_AMOUNTS_SCALE) * self.settings.multiplier
|
awarded_points = COMMISION_AMOUNTS_FACTORS[for_task] * math.pow(cp.importance, COMMISION_AMOUNTS_SCALE) * self.settings.multiplier
|
||||||
points_to_spend = cp.base.append_commision_points(for_task, awarded_points)
|
points_to_spend = cp.base.append_commision_points(for_task, awarded_points)
|
||||||
if points_to_spend > 0:
|
if points_to_spend > 0:
|
||||||
unittypes = self._commision_unit_types(cp, for_task)
|
unittypes = self.commision_unit_types(cp, for_task)
|
||||||
d = {random.choice(unittypes): points_to_spend}
|
d = {random.choice(unittypes): points_to_spend}
|
||||||
print("Commision {}: {}".format(cp, d))
|
print("Commision {}: {}".format(cp, d))
|
||||||
cp.base.commision_units(d)
|
cp.base.commision_units(d)
|
||||||
|
|||||||
@ -45,6 +45,7 @@ class InfantryTransportOperation(Operation):
|
|||||||
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)
|
||||||
|
|
||||||
|
# TODO: horrible, horrible hack
|
||||||
# this will disable vehicle activation triggers,
|
# this will disable vehicle activation triggers,
|
||||||
# which aren't needed on this type of missions
|
# which aren't needed on this type of missions
|
||||||
self.is_quick = True
|
self.is_quick = True
|
||||||
|
|||||||
@ -10,7 +10,7 @@ from dcs.task import *
|
|||||||
from dcs.terrain.terrain import NoParkingSlotError
|
from dcs.terrain.terrain import NoParkingSlotError
|
||||||
|
|
||||||
SPREAD_DISTANCE_FACTOR = 1, 2
|
SPREAD_DISTANCE_FACTOR = 1, 2
|
||||||
ESCORT_MAX_DIST = 30000
|
ESCORT_MAX_DIST = 80000
|
||||||
WORKAROUND_WAYP_DIST = 1000
|
WORKAROUND_WAYP_DIST = 1000
|
||||||
|
|
||||||
WARM_START_ALTITUDE = 4600
|
WARM_START_ALTITUDE = 4600
|
||||||
@ -20,7 +20,7 @@ RTB_ALTITUDE = 4600
|
|||||||
TRANSPORT_LANDING_ALT = 4600
|
TRANSPORT_LANDING_ALT = 4600
|
||||||
HELI_ALT = 900
|
HELI_ALT = 900
|
||||||
|
|
||||||
WARM_START_AIRSPEED = 540
|
WARM_START_AIRSPEED = 550
|
||||||
INTERCEPTION_AIRSPEED = 1000
|
INTERCEPTION_AIRSPEED = 1000
|
||||||
|
|
||||||
INTERCEPT_MAX_DISTANCE = 80000
|
INTERCEPT_MAX_DISTANCE = 80000
|
||||||
@ -117,7 +117,7 @@ class AircraftConflictGenerator:
|
|||||||
airport=None,
|
airport=None,
|
||||||
position=pos,
|
position=pos,
|
||||||
altitude=alt,
|
altitude=alt,
|
||||||
speed=WARM_START_AIRSPEED + random.randint(500, 3000),
|
speed=WARM_START_AIRSPEED,
|
||||||
maintask=None,
|
maintask=None,
|
||||||
start_type=StartType.Warm,
|
start_type=StartType.Warm,
|
||||||
group_size=count)
|
group_size=count)
|
||||||
|
|||||||
@ -87,9 +87,12 @@ class Conflict:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def _find_ground_location(cls, initial: Point, max_distance: int, heading: int, theater: ConflictTheater) -> Point:
|
def _find_ground_location(cls, initial: Point, max_distance: int, heading: int, theater: ConflictTheater) -> Point:
|
||||||
for _ in range(0, int(max_distance), 800):
|
for _ in range(0, int(max_distance), 800):
|
||||||
|
for _ in range(3):
|
||||||
if theater.is_on_land(initial):
|
if theater.is_on_land(initial):
|
||||||
return initial
|
return initial
|
||||||
|
|
||||||
|
initial = initial.random_point_within(1000, 1000)
|
||||||
|
|
||||||
initial = initial.point_from_heading(heading, 800)
|
initial = initial.point_from_heading(heading, 800)
|
||||||
|
|
||||||
print("Didn't find ground position!")
|
print("Didn't find ground position!")
|
||||||
|
|||||||
@ -28,8 +28,8 @@ RANDOM_TIME = {
|
|||||||
|
|
||||||
RANDOM_WEATHER = {
|
RANDOM_WEATHER = {
|
||||||
1: 5, # heavy rain
|
1: 5, # heavy rain
|
||||||
2: 20, # rain
|
2: 30, # rain
|
||||||
3: 30, # dynamic
|
3: 40, # dynamic
|
||||||
4: 50, # clear
|
4: 50, # clear
|
||||||
5: 100, # random
|
5: 100, # random
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,6 +52,7 @@ class TriggersGenerator:
|
|||||||
activation_trigger_zone = self.mission.triggers.add_triggerzone(self.conflict.position, zone_size, name="Activation zone")
|
activation_trigger_zone = self.mission.triggers.add_triggerzone(self.conflict.position, zone_size, name="Activation zone")
|
||||||
activation_trigger = TriggerOnce(Event.NoEvent, "Activation trigger")
|
activation_trigger = TriggerOnce(Event.NoEvent, "Activation trigger")
|
||||||
activation_trigger.add_condition(PartOfCoalitionInZone(player_coalition, activation_trigger_zone.id))
|
activation_trigger.add_condition(PartOfCoalitionInZone(player_coalition, activation_trigger_zone.id))
|
||||||
|
activation_trigger.add_condition(FlagIsTrue())
|
||||||
for group in activate_by_trigger:
|
for group in activate_by_trigger:
|
||||||
activation_trigger.add_action(ActivateGroup(group.id))
|
activation_trigger.add_action(ActivateGroup(group.id))
|
||||||
|
|
||||||
@ -94,6 +95,7 @@ class TriggersGenerator:
|
|||||||
push_trigger.add_action(AITaskPush(group.id, 1))
|
push_trigger.add_action(AITaskPush(group.id, 1))
|
||||||
message_string = self.mission.string("Task force is in the air, proceed with the objective.")
|
message_string = self.mission.string("Task force is in the air, proceed with the objective.")
|
||||||
push_trigger.add_action(MessageToAll(message_string, clearview=True))
|
push_trigger.add_action(MessageToAll(message_string, clearview=True))
|
||||||
|
push_trigger.add_action(SetFlagValue())
|
||||||
|
|
||||||
self.mission.triggerrules.triggers.append(push_trigger)
|
self.mission.triggerrules.triggers.append(push_trigger)
|
||||||
|
|
||||||
|
|||||||
@ -132,7 +132,8 @@ class EventMenu(Menu):
|
|||||||
def client_one(self, unit_type: UnitType) -> typing.Callable:
|
def client_one(self, unit_type: UnitType) -> typing.Callable:
|
||||||
def action():
|
def action():
|
||||||
entry = self.aircraft_client_entries[unit_type] # type: Entry
|
entry = self.aircraft_client_entries[unit_type] # type: Entry
|
||||||
amount = int(entry.get())
|
value = entry.get()
|
||||||
|
amount = int(value and value or "0")
|
||||||
entry.delete(0, END)
|
entry.delete(0, END)
|
||||||
entry.insert(0, str(amount+1))
|
entry.insert(0, str(amount+1))
|
||||||
return action
|
return action
|
||||||
|
|||||||
@ -35,7 +35,8 @@ class EventResultsMenu(Menu):
|
|||||||
Button(self.frame, text="full losses, fail", command=self.simulate_result(1, 0)).grid(row=3, column=1)
|
Button(self.frame, text="full losses, fail", command=self.simulate_result(1, 0)).grid(row=3, column=1)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Label(self.frame, text="Play the mission and save debriefing to {}".format(debriefing_directory_location())).grid(row=0, column=0)
|
Label(self.frame, text="Play the mission and save debriefing to").grid(row=0, column=0)
|
||||||
|
Label(self.frame, text=debriefing_directory_location()).grid(row=1, column=0)
|
||||||
else:
|
else:
|
||||||
row = 0
|
row = 0
|
||||||
if self.event.is_successfull(self.debriefing):
|
if self.event.is_successfull(self.debriefing):
|
||||||
|
|||||||
@ -90,8 +90,9 @@ class Debriefing:
|
|||||||
enemy.name: self.alive_units.get(enemy.id, {}),
|
enemy.name: self.alive_units.get(enemy.id, {}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def debriefing_directory_location() -> str:
|
def debriefing_directory_location() -> str:
|
||||||
return "build/debriefing"
|
return os.path.expanduser("~\Saved Games\DCS")
|
||||||
|
|
||||||
|
|
||||||
def _logfiles_snapshot() -> typing.Dict[str, float]:
|
def _logfiles_snapshot() -> typing.Dict[str, float]:
|
||||||
@ -108,11 +109,19 @@ 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]:
|
||||||
callback(Debriefing.parse(os.path.join(debriefing_directory_location(), file)))
|
for _ in range(0, 3):
|
||||||
|
# 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)
|
||||||
should_run = False
|
should_run = False
|
||||||
break
|
break
|
||||||
|
|
||||||
time.sleep(1)
|
time.sleep(3)
|
||||||
|
|
||||||
|
|
||||||
def wait_for_debriefing(callback: typing.Callable):
|
def wait_for_debriefing(callback: typing.Callable):
|
||||||
|
|||||||
@ -3,22 +3,24 @@ import pickle
|
|||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
from game.game import Game
|
|
||||||
|
|
||||||
|
|
||||||
def _save_file() -> str:
|
def _save_file() -> str:
|
||||||
return "build/save"
|
return os.path.expanduser("~\Saved Games\DCS\liberation_save")
|
||||||
|
|
||||||
|
|
||||||
def _temporary_save_file() -> str:
|
def _temporary_save_file() -> str:
|
||||||
return "build/save_tmp"
|
return os.path.expanduser("~\Saved Games\DCS\liberation_save_tmp")
|
||||||
|
|
||||||
|
|
||||||
def _save_file_exists() -> bool:
|
def _save_file_exists() -> bool:
|
||||||
return os.path.exists(_save_file())
|
return os.path.exists(_save_file())
|
||||||
|
|
||||||
|
|
||||||
def restore_game() -> typing.Optional[Game]:
|
def mission_path_for(name: str) -> str:
|
||||||
|
return os.path.expanduser("~\Saved Games\DCS\Missions\{}".format(name))
|
||||||
|
|
||||||
|
|
||||||
|
def restore_game():
|
||||||
if not _save_file_exists():
|
if not _save_file_exists():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -30,7 +32,7 @@ def restore_game() -> typing.Optional[Game]:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def save_game(game: Game) -> bool:
|
def save_game(game) -> bool:
|
||||||
try:
|
try:
|
||||||
with open(_temporary_save_file(), "wb") as f:
|
with open(_temporary_save_file(), "wb") as f:
|
||||||
pickle.dump(game, f)
|
pickle.dump(game, f)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user