minor fixes; F-14B

This commit is contained in:
Vasyl Horbachenko 2019-03-27 08:47:29 +02:00
parent f7e2c8921c
commit c152b49b88
27 changed files with 179 additions and 28 deletions

6
.gitignore vendored
View File

@ -1,10 +1,14 @@
*.pyc
__pycache__
build/*
build/**
resources/payloads/*.lua
venv
logs.txt
.DS_Store
dist/**
a.py
resources/tools/a.miz
tests/**
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml

1
.idea/modules.xml generated
View File

@ -3,7 +3,6 @@
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/dcs_pmcliberation.iml" filepath="$PROJECT_DIR$/.idea/dcs_pmcliberation.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/dcs_pmcliberation.iml" filepath="$PROJECT_DIR$/.idea/dcs_pmcliberation.iml" />
</modules>
</component>
</project>

View File

@ -52,9 +52,7 @@ w = ui.window.Window()
try:
game = persistency.restore_game()
if not game or not is_version_compatible(game.settings.version):
new_game_menu = None # type: NewGameMenu
new_game_menu = ui.newgamemenu.NewGameMenu(w, w.start_new_game)
new_game_menu.display()
ui.newgamemenu.NewGameMenu(w, w.start_new_game).display()
else:
game.settings.version = VERSION_STRING
proceed_to_main_menu(game)

38
a.py Normal file
View File

@ -0,0 +1,38 @@
from theater.caucasus import *
from gen.conflictgen import Conflict
from matplotlib import pyplot
from matplotlib import lines
from shapely import geometry
from shapely.geometry import Polygon
from descartes.patch import PolygonPatch
def put_lines(ls, ax):
for g in ls.geoms:
ax.plot([g.xy[0][0], g.xy[0][1]], [g.xy[1][0], g.xy[1][1]])
cau = CaucasusTheater()
#left, heading, dist = Conflict.frontline_vector(cau.soganlug, cau.kutaisi, cau)
#right = left.point_from_heading(heading, dist)
left, heading = Conflict.frontline_position(cau, cau.soganlug, cau.kutaisi)
right = left.point_from_heading(heading+90, 80000)
left = left.point_from_heading(heading-90, 80000)
line = geometry.LineString([(left.x, left.y), (right.x, right.y)])
line = line.intersection(cau.land_poly)
fig = pyplot.figure(1, figsize=(20, 20), dpi=90)
ax = fig.add_subplot(121)
ax.set_ylim([0, 1500000])
ax.set_xlim([-600000, 400000])
patch = PolygonPatch(cau.land_poly, facecolor=(0, 0, 0), edgecolor=(0, 0, 0), alpha=0.5, zorder=2)
ax.add_patch(patch)
ax.plot([left.x, right.x], [left.y, right.y], 'k-', lw=2)
ax.plot([cau.soganlug.position.x, cau.soganlug.position.x+1000], [cau.soganlug.position.y, cau.soganlug.position.y+1000], lw=5)
ax.plot([cau.kutaisi.position.x, cau.kutaisi.position.x+1000], [cau.kutaisi.position.y, cau.kutaisi.position.y+1000], lw=5)
put_lines(line, ax)
pyplot.show()

View File

@ -39,11 +39,11 @@ and prioritization for the enemy (i.e. less important bases will receive units w
"""
PRICES = {
# fighter
MiG_23MLD: 18,
Su_27: 20,
MiG_23MLD: 13,
Su_27: 18,
Su_33: 22,
MiG_29A: 23,
MiG_29S: 25,
MiG_29A: 18,
MiG_29S: 20,
F_5E_3: 6,
MiG_15bis: 5,
@ -54,6 +54,7 @@ PRICES = {
M_2000C: 13,
FA_18C_hornet: 18,
F_15C: 20,
F_14B: 14,
# bomber
Su_25: 15,
@ -145,6 +146,7 @@ UNIT_BY_TASK = {
MiG_29S,
FA_18C_hornet,
F_15C,
F_14B,
M_2000C,
],
CAS: [
@ -304,6 +306,7 @@ UNIT_BY_COUNTRY = {
"USA": [
F_5E_3,
F_15C,
F_14B,
FA_18C_hornet,
AJS37,
M_2000C,
@ -367,16 +370,25 @@ Payload will be used for operation of following type, "*" category will be used
PLANE_PAYLOAD_OVERRIDES = {
FA_18C_hornet: {
CAP: "AIM-120*4,AIM-9*2,AIM-7*2,Fuel",
Escort: "AIM-120*4,AIM-9*2,AIM-7*2,Fuel",
PinpointStrike: "MK-82*8,AIM-9*2,AIM-7,FLIR Pod,Fuel",
AntishipStrike: "MK-82*8,AIM-9*2,AIM-7,FLIR Pod,Fuel",
},
F_14B: {
CAP: "AIM-54A-MK47*4, AIM-7M*2, AIM-9M*2, XT*2",
Escort: "AIM-54A-MK47*4, AIM-7M*2, AIM-9M*2, XT*2",
CAS: "AIM-54A-MK60*1, AIM-7M*1, AIM-9M*2, XT*2, Mk-82*2, LANTIRN",
GroundAttack: "AIM-54A-MK60*1, AIM-7M*1, AIM-9M*2, XT*2, Mk-82*2, LANTIRN",
},
Su_25T: {
CAS: "APU-8 Vikhr-M*2,Kh-25ML,R-73*2,SPPU-22*2,Mercury LLTV Pod,MPS-410",
},
Su_33: {
CAP: "R-73*4,R-27R*2,R-27ER*6",
Escort: "R-73*4,R-27R*2,R-27ER*6",
},
AJS37: {
@ -399,6 +411,7 @@ PLANE_PAYLOAD_OVERRIDES = {
M_2000C: {
CAP: "Combat Air Patrol",
Escort: "Combat Air Patrol",
GroundAttack: "MK-82S Heavy Strike",
},

View File

@ -111,7 +111,7 @@ class Game:
# skip naval events for non-coastal CPs
return
if event_class == BaseAttackEvent and enemy_cp.base.strength > PLAYER_BASEATTACK_THRESHOLD:
if event_class == BaseAttackEvent and enemy_cp.base.strength > PLAYER_BASEATTACK_THRESHOLD and self.settings.version != "dev":
# skip base attack events for CPs yet too strong
return
@ -163,6 +163,7 @@ class Game:
def _generate_events(self):
strikes_generated_for = set()
base_attack_generated_for = set()
for player_cp, enemy_cp in self.theater.conflicts(True):
for event_class, (player_probability, enemy_probability) in EVENT_PROBABILITIES.items():
@ -171,15 +172,20 @@ class Game:
if not Conflict.has_frontline_between(player_cp, enemy_cp):
continue
if event_class in [StrikeEvent]:
# don't generate multiple 100% strike events from each attack direction
# don't generate multiple 100% events from each attack direction
if event_class is StrikeEvent:
if enemy_cp in strikes_generated_for:
continue
if event_class is BaseAttackEvent:
if enemy_cp in base_attack_generated_for:
continue
if player_probability == 100 or player_probability > 0 and self._roll(player_probability, player_cp.base.strength):
self._generate_player_event(event_class, player_cp, enemy_cp)
if event_class in [StrikeEvent]:
if event_class is StrikeEvent:
strikes_generated_for.add(enemy_cp)
if event_class is BaseAttackEvent:
base_attack_generated_for.add(enemy_cp)
if enemy_probability == 100 or enemy_probability > 0 and self._roll(enemy_probability, enemy_cp.base.strength):
self._generate_enemy_event(event_class, player_cp, enemy_cp)

View File

@ -162,6 +162,8 @@ class Conflict:
strength_delta = (from_cp.base.strength - to_cp.base.strength) / 1.0
position = middle_point.point_from_heading(attack_heading, strength_delta * attack_distance / 2 - FRONTLINE_MIN_CP_DISTANCE)
return position, _opposite_heading(attack_heading)
ground_position = cls._find_ground_position(position, attack_distance / 2 - FRONTLINE_MIN_CP_DISTANCE, attack_heading, theater)
if ground_position:
return ground_position, _opposite_heading(attack_heading)
@ -172,6 +174,23 @@ class Conflict:
@classmethod
def frontline_vector(cls, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater) -> typing.Optional[typing.Tuple[Point, int, int]]:
initial, heading = cls.frontline_position(theater, from_cp, to_cp)
"""
probe_end_point = initial.point_from_heading(heading, FRONTLINE_LENGTH)
probe = geometry.LineString([(initial.x, initial.y), (probe_end_point.x, probe_end_point.y) ])
intersection = probe.intersection(theater.land_poly)
if isinstance(intersection, geometry.LineString):
intersection = intersection
elif isinstance(intersection, geometry.MultiLineString):
intersection = intersection.geoms[0]
else:
print(intersection)
return None
return Point(*intersection.xy[0]), _heading_sum(heading, 90), intersection.length
"""
frontline = cls.frontline_position(theater, from_cp, to_cp)
if not frontline:
return None
@ -207,9 +226,21 @@ class Conflict:
pos = new_pos
else:
return pos
return pos
"""
probe_end_point = initial.point_from_heading(heading, max_distance)
probe = geometry.LineString([(initial.x, initial.y), (probe_end_point.x, probe_end_point.y)])
intersection = probe.intersection(theater.land_poly)
if intersection is geometry.LineString:
return Point(*intersection.xy[1])
elif intersection is geometry.MultiLineString:
return Point(*intersection.geoms[0].xy[1])
return None
"""
@classmethod
def _find_ground_position(cls, initial: Point, max_distance: int, heading: int, theater: ConflictTheater) -> typing.Optional[Point]:
pos = initial
@ -218,8 +249,18 @@ class Conflict:
return pos
pos = pos.point_from_heading(heading, 500)
"""
probe_end_point = initial.point_from_heading(heading, max_distance)
probe = geometry.LineString([(initial.x, initial.y), (probe_end_point.x, probe_end_point.y) ])
logging.error("Didn't find ground position!")
intersection = probe.intersection(theater.land_poly)
if isinstance(intersection, geometry.LineString):
return Point(*intersection.xy[1])
elif isinstance(intersection, geometry.MultiLineString):
return Point(*intersection.geoms[0].xy[1])
"""
logging.error("Didn't find ground position ({})!".format(initial))
return initial
@classmethod
@ -305,7 +346,7 @@ class Conflict:
initial_location = to_cp.position.random_point_within(*GROUND_ATTACK_DISTANCE)
position = Conflict._find_ground_position(initial_location, GROUND_INTERCEPT_SPREAD, _heading_sum(heading, 180), theater)
if not position:
heading = to_cp.find_radial(to_cp.positioN.heading_between_point(from_cp.position))
heading = to_cp.find_radial(to_cp.position.heading_between_point(from_cp.position))
position = to_cp.position.point_from_heading(heading, to_cp.size * GROUND_DISTANCE_FACTOR)
return cls(

40
pyinstaller.spec Normal file
View File

@ -0,0 +1,40 @@
# -*- mode: python -*-
block_cipher = None
a = Analysis(['__init__.py'],
pathex=['C:\\Users\\shdwp\\PycharmProjects\\dcs_liberation'],
binaries=[],
datas=[
('resources', 'resources'),
('submodules/dcs/dcs/terrain/caucasus.p', 'dcs/terrain/'),
('submodules/dcs/dcs/terrain/nevada.p', 'dcs/terrain/'),
],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
icon="resources/icon.ico",
exclude_binaries=True,
name='liberation_main',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='dcs_liberation')

View File

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 81 KiB

View File

@ -1,4 +1,5 @@
import os
import shutil
from zipfile import *
@ -42,11 +43,13 @@ def _mk_archieve():
print("version already exists")
return
shutil.rmtree("./dist")
os.system("pyinstaller.exe pyinstaller.spec")
archieve = ZipFile(path, "w")
archieve.writestr("start.bat", "py.exe __init__.py \"%UserProfile%\\Saved Games\" \"{}\"".format(VERSION))
_zip_dir(archieve, ".")
os.chdir("submodules\\dcs")
_zip_dir(archieve, "dcs")
archieve.writestr("dcs_liberation.bat", "cd dist\\dcs_liberation;\nliberation_main \"%UserProfile%\\Saved Games\" \"{}\"".format(VERSION))
_zip_dir(archieve, "./dist/dcs_liberation")
_mk_archieve()

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

@ -1 +1 @@
Subproject commit fae126689132d643d317252adfb03184042a0ded
Subproject commit 4fbb7ad3e0e2eecedc4e1dd14f2eb18025fef9f5

View File

@ -53,10 +53,18 @@ class ConflictTheater:
reference_points = None # type: typing.Dict
overview_image = None # type: str
landmap = None # type: landmap.Landmap
"""
land_poly = None # type: Polygon
"""
daytime_map = None # type: typing.Dict[str, typing.Tuple[int, int]]
def __init__(self):
self.controlpoints = []
"""
self.land_poly = geometry.Polygon(self.landmap[0][0])
for x in self.landmap[1]:
self.land_poly = self.land_poly.difference(geometry.Polygon(x))
"""
def add_controlpoint(self, point: ControlPoint, connected_to: typing.Collection[ControlPoint] = []):
for connected_point in connected_to:

View File

@ -19,7 +19,6 @@ class NevadaTheater(ConflictTheater):
"night": (0, 5),
}
mina = ControlPoint.from_airport(nevada.Mina_Airport_3Q0, LAND, SIZE_SMALL, IMPORTANCE_LOW)
tonopah = ControlPoint.from_airport(nevada.Tonopah_Airport, LAND, SIZE_SMALL, IMPORTANCE_LOW)
tonopah_test_range = ControlPoint.from_airport(nevada.Tonopah_Test_Range_Airfield, LAND, SIZE_SMALL, IMPORTANCE_LOW)
lincoln_conty = ControlPoint.from_airport(nevada.Lincoln_County, LAND, SIZE_SMALL, 1.2)
@ -37,8 +36,7 @@ class NevadaTheater(ConflictTheater):
def __init__(self):
super(NevadaTheater, self).__init__()
self.add_controlpoint(self.mina, connected_to=[self.tonopah])
self.add_controlpoint(self.tonopah, connected_to=[self.mina, self.tonopah_test_range, self.lincoln_conty])
self.add_controlpoint(self.tonopah, connected_to=[self.tonopah_test_range, self.lincoln_conty])
self.add_controlpoint(self.tonopah_test_range, connected_to=[self.tonopah, self.lincoln_conty, self.groom_lake, self.pahute_mesa])
self.add_controlpoint(self.lincoln_conty, connected_to=[self.tonopah_test_range, self.mesquite])
@ -52,5 +50,5 @@ class NevadaTheater(ConflictTheater):
self.add_controlpoint(self.jean, connected_to=[self.laughlin, self.las_vegas])
self.add_controlpoint(self.laughlin, connected_to=[self.jean, self.las_vegas])
self.mina.captured = True
self.tonopah.captured = True

View File

@ -25,7 +25,7 @@ BLACK = (0, 0, 0)
BACKGROUND = pygame.Color(0, 64, 64)
ANTIALIASING = True
WIDTH = 1066
WIDTH = 800
HEIGHT = 600
MAP_PADDING = 100

View File

@ -20,7 +20,7 @@ class Window:
def __init__(self):
self.tk = Tk()
self.tk.title("DCS Liberation")
self.tk.iconbitmap("icon.ico")
self.tk.iconbitmap("resources/icon.ico")
self.tk.resizable(False, False)
self.tk.grid_columnconfigure(0, weight=1)
self.tk.grid_rowconfigure(0, weight=1)
@ -44,7 +44,7 @@ class Window:
helpmenu.add_separator()
helpmenu.add_command(label="Contribute", command=lambda: webbrowser.open_new_tab("https://github.com/shdwp/dcs_liberation"))
helpmenu.add_command(label="Forum Thread", command=lambda: webbrowser.open_new_tab("https://forums.eagle.ru/showthread.php?t=214834"))
helpmenu.add_command(label="Report an issue", command=lambda: webbrowser.open_new_tab("https://github.com/shdwp/dcs_liberation/issues"))
helpmenu.add_command(label="Report an issue", command=self.report_issue)
menubar.add_cascade(label="Help", menu=helpmenu)
self.tk.config(menu=menubar)
@ -133,6 +133,9 @@ class Window:
else:
pass
def report_issue(self):
raise logging_module.ShowLogsException()
def exit(self):
self.tk.destroy()
sys.exit(0)