mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
commit
08f67860be
@ -1,3 +1,12 @@
|
|||||||
|
# 2.4.1
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
* **[Units]** Fixed syntax error with the SH-60B payload file.
|
||||||
|
* **[Culling]** Missile sites generate reasonably sized non-cull zones rather than 100km ones.
|
||||||
|
* **[UI]** Budget display is also now rounded to 2 decimal places.
|
||||||
|
* **[UI]** Fixed some areas where the old, non-pretty name was displayed to users.
|
||||||
|
|
||||||
# 2.4.0
|
# 2.4.0
|
||||||
|
|
||||||
Saves from 2.3 are not compatible with 2.4.
|
Saves from 2.3 are not compatible with 2.4.
|
||||||
|
|||||||
43
game/game.py
43
game/game.py
@ -96,6 +96,9 @@ class Game:
|
|||||||
self.ground_planners: Dict[int, GroundPlanner] = {}
|
self.ground_planners: Dict[int, GroundPlanner] = {}
|
||||||
self.informations = []
|
self.informations = []
|
||||||
self.informations.append(Information("Game Start", "-" * 40, 0))
|
self.informations.append(Information("Game Start", "-" * 40, 0))
|
||||||
|
# Culling Zones are for areas around points of interest that contain things we may not wish to cull.
|
||||||
|
self.__culling_zones: List[Point] = []
|
||||||
|
# Culling Points are for individual theater ground objects that we don't wish to cull.
|
||||||
self.__culling_points: List[Point] = []
|
self.__culling_points: List[Point] = []
|
||||||
self.__destroyed_units: List[str] = []
|
self.__destroyed_units: List[str] = []
|
||||||
self.savepath = ""
|
self.savepath = ""
|
||||||
@ -378,6 +381,7 @@ class Game:
|
|||||||
Compute the current conflict center position(s), mainly used for culling calculation
|
Compute the current conflict center position(s), mainly used for culling calculation
|
||||||
:return: List of points of interests
|
:return: List of points of interests
|
||||||
"""
|
"""
|
||||||
|
zones = []
|
||||||
points = []
|
points = []
|
||||||
|
|
||||||
# By default, use the existing frontline conflict position
|
# By default, use the existing frontline conflict position
|
||||||
@ -385,23 +389,23 @@ class Game:
|
|||||||
position = Conflict.frontline_position(front_line.control_point_a,
|
position = Conflict.frontline_position(front_line.control_point_a,
|
||||||
front_line.control_point_b,
|
front_line.control_point_b,
|
||||||
self.theater)
|
self.theater)
|
||||||
points.append(position[0])
|
zones.append(position[0])
|
||||||
points.append(front_line.control_point_a.position)
|
zones.append(front_line.control_point_a.position)
|
||||||
points.append(front_line.control_point_b.position)
|
zones.append(front_line.control_point_b.position)
|
||||||
|
|
||||||
for cp in self.theater.controlpoints:
|
for cp in self.theater.controlpoints:
|
||||||
# Don't cull missile sites - their range is long enough to make them
|
# Don't cull missile sites - their range is long enough to make them
|
||||||
# easily culled despite being a threat.
|
# easily culled despite being a threat.
|
||||||
for tgo in cp.ground_objects:
|
for tgo in cp.ground_objects:
|
||||||
if isinstance(tgo, MissileSiteGroundObject):
|
if isinstance(tgo, MissileSiteGroundObject):
|
||||||
points.append(cp.position)
|
points.append(tgo.position)
|
||||||
# If do_not_cull_carrier is enabled, add carriers as culling point
|
# If do_not_cull_carrier is enabled, add carriers as culling point
|
||||||
if self.settings.perf_do_not_cull_carrier:
|
if self.settings.perf_do_not_cull_carrier:
|
||||||
if cp.is_carrier or cp.is_lha:
|
if cp.is_carrier or cp.is_lha:
|
||||||
points.append(cp.position)
|
zones.append(cp.position)
|
||||||
|
|
||||||
# If there is no conflict take the center point between the two nearest opposing bases
|
# If there is no conflict take the center point between the two nearest opposing bases
|
||||||
if len(points) == 0:
|
if len(zones) == 0:
|
||||||
cpoint = None
|
cpoint = None
|
||||||
min_distance = sys.maxsize
|
min_distance = sys.maxsize
|
||||||
for cp in self.theater.player_points():
|
for cp in self.theater.player_points():
|
||||||
@ -410,13 +414,13 @@ class Game:
|
|||||||
if d < min_distance:
|
if d < min_distance:
|
||||||
min_distance = d
|
min_distance = d
|
||||||
cpoint = Point((cp.position.x + cp2.position.x) / 2, (cp.position.y + cp2.position.y) / 2)
|
cpoint = Point((cp.position.x + cp2.position.x) / 2, (cp.position.y + cp2.position.y) / 2)
|
||||||
points.append(cp.position)
|
zones.append(cp.position)
|
||||||
points.append(cp2.position)
|
zones.append(cp2.position)
|
||||||
break
|
break
|
||||||
if cpoint is not None:
|
if cpoint is not None:
|
||||||
break
|
break
|
||||||
if cpoint is not None:
|
if cpoint is not None:
|
||||||
points.append(cpoint)
|
zones.append(cpoint)
|
||||||
|
|
||||||
packages = itertools.chain(self.blue_ato.packages,
|
packages = itertools.chain(self.blue_ato.packages,
|
||||||
self.red_ato.packages)
|
self.red_ato.packages)
|
||||||
@ -428,13 +432,14 @@ class Game:
|
|||||||
# are only interesting if there are enemies in the area, and if
|
# are only interesting if there are enemies in the area, and if
|
||||||
# there are they won't be culled because of the enemy's mission.
|
# there are they won't be culled because of the enemy's mission.
|
||||||
continue
|
continue
|
||||||
points.append(package.target.position)
|
zones.append(package.target.position)
|
||||||
|
|
||||||
# Else 0,0, since we need a default value
|
# Else 0,0, since we need a default value
|
||||||
# (in this case this means the whole map is owned by the same player, so it is not an issue)
|
# (in this case this means the whole map is owned by the same player, so it is not an issue)
|
||||||
if len(points) == 0:
|
if len(zones) == 0:
|
||||||
points.append(Point(0, 0))
|
zones.append(Point(0, 0))
|
||||||
|
|
||||||
|
self.__culling_zones = zones
|
||||||
self.__culling_points = points
|
self.__culling_points = points
|
||||||
|
|
||||||
def add_destroyed_units(self, data):
|
def add_destroyed_units(self, data):
|
||||||
@ -454,11 +459,21 @@ class Game:
|
|||||||
if self.settings.perf_culling == False:
|
if self.settings.perf_culling == False:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
for c in self.__culling_points:
|
for z in self.__culling_zones:
|
||||||
if c.distance_to_point(pos) < self.settings.perf_culling_distance * 1000:
|
if z.distance_to_point(pos) < self.settings.perf_culling_distance * 1000:
|
||||||
|
return False
|
||||||
|
for p in self.__culling_points:
|
||||||
|
if p.distance_to_point(pos) < 2500:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def get_culling_zones(self):
|
||||||
|
"""
|
||||||
|
Check culling points
|
||||||
|
:return: List of culling zones
|
||||||
|
"""
|
||||||
|
return self.__culling_zones
|
||||||
|
|
||||||
def get_culling_points(self):
|
def get_culling_points(self):
|
||||||
"""
|
"""
|
||||||
Check culling points
|
Check culling points
|
||||||
|
|||||||
@ -35,7 +35,7 @@ class QBudgetBox(QGroupBox):
|
|||||||
:param budget: Current money available
|
:param budget: Current money available
|
||||||
:param reward: Planned reward for next turn
|
:param reward: Planned reward for next turn
|
||||||
"""
|
"""
|
||||||
self.money_amount.setText(str(budget) + "M (+" + str(round(reward,2)) + "M)")
|
self.money_amount.setText(str(round(budget,2)) + "M (+" + str(round(reward,2)) + "M)")
|
||||||
|
|
||||||
def setGame(self, game):
|
def setGame(self, game):
|
||||||
if game is None:
|
if game is None:
|
||||||
|
|||||||
@ -268,13 +268,20 @@ class QLiberationMap(QGraphicsView):
|
|||||||
def display_culling(self, scene: QGraphicsScene) -> None:
|
def display_culling(self, scene: QGraphicsScene) -> None:
|
||||||
"""Draws the culling distance rings on the map"""
|
"""Draws the culling distance rings on the map"""
|
||||||
culling_points = self.game_model.game.get_culling_points()
|
culling_points = self.game_model.game.get_culling_points()
|
||||||
|
culling_zones = self.game_model.game.get_culling_zones()
|
||||||
culling_distance = self.game_model.game.settings.perf_culling_distance
|
culling_distance = self.game_model.game.settings.perf_culling_distance
|
||||||
for point in culling_points:
|
for point in culling_points:
|
||||||
culling_distance_point = Point(point.x + culling_distance*1000, point.y + culling_distance*1000)
|
culling_distance_point = Point(point.x + 2500, point.y + 2500)
|
||||||
distance_point = self._transform_point(culling_distance_point)
|
distance_point = self._transform_point(culling_distance_point)
|
||||||
transformed = self._transform_point(point)
|
transformed = self._transform_point(point)
|
||||||
radius = distance_point[0] - transformed[0]
|
radius = distance_point[0] - transformed[0]
|
||||||
scene.addEllipse(transformed[0]-radius, transformed[1]-radius, 2*radius, 2*radius, CONST.COLORS["transparent"], CONST.COLORS["light_green_transparent"])
|
scene.addEllipse(transformed[0]-radius, transformed[1]-radius, 2*radius, 2*radius, CONST.COLORS["transparent"], CONST.COLORS["light_green_transparent"])
|
||||||
|
for zone in culling_zones:
|
||||||
|
culling_distance_zone = Point(zone.x + culling_distance*1000, zone.y + culling_distance*1000)
|
||||||
|
distance_zone = self._transform_point(culling_distance_zone)
|
||||||
|
transformed = self._transform_point(zone)
|
||||||
|
radius = distance_zone[0] - transformed[0]
|
||||||
|
scene.addEllipse(transformed[0]-radius, transformed[1]-radius, 2*radius, 2*radius, CONST.COLORS["transparent"], CONST.COLORS["light_green_transparent"])
|
||||||
|
|
||||||
def draw_shapely_poly(self, scene: QGraphicsScene, poly: Polygon, pen: QPen,
|
def draw_shapely_poly(self, scene: QGraphicsScene, poly: Polygon, pen: QPen,
|
||||||
brush: QBrush) -> Optional[QPolygonF]:
|
brush: QBrush) -> Optional[QPolygonF]:
|
||||||
|
|||||||
@ -11,6 +11,8 @@ from game.theater import ControlPoint, TheaterGroundObject
|
|||||||
from qt_ui.dialogs import Dialog
|
from qt_ui.dialogs import Dialog
|
||||||
from qt_ui.uiconstants import VEHICLES_ICONS
|
from qt_ui.uiconstants import VEHICLES_ICONS
|
||||||
from qt_ui.windows.groundobject.QGroundObjectMenu import QGroundObjectMenu
|
from qt_ui.windows.groundobject.QGroundObjectMenu import QGroundObjectMenu
|
||||||
|
from game import db
|
||||||
|
from dcs import vehicles
|
||||||
|
|
||||||
|
|
||||||
class QBaseDefenseGroupInfo(QGroupBox):
|
class QBaseDefenseGroupInfo(QGroupBox):
|
||||||
@ -71,7 +73,11 @@ class QBaseDefenseGroupInfo(QGroupBox):
|
|||||||
icon.setText("<b>" + k[:8] + "</b>")
|
icon.setText("<b>" + k[:8] + "</b>")
|
||||||
icon.setProperty("style", "icon-armor")
|
icon.setProperty("style", "icon-armor")
|
||||||
self.unit_layout.addWidget(icon, i, 0)
|
self.unit_layout.addWidget(icon, i, 0)
|
||||||
self.unit_layout.addWidget(QLabel(str(v) + " x " + "<strong>" + k + "</strong>"), i, 1)
|
unit_display_name = k
|
||||||
|
unit_type = vehicles.vehicle_map.get(k)
|
||||||
|
if unit_type is not None:
|
||||||
|
unit_display_name = db.unit_get_expanded_info(self.game.enemy_country, unit_type, 'name')
|
||||||
|
self.unit_layout.addWidget(QLabel(str(v) + " x " + "<strong>" + unit_display_name + "</strong>"), i, 1)
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
|
||||||
if len(unit_dict.items()) == 0:
|
if len(unit_dict.items()) == 0:
|
||||||
|
|||||||
@ -29,6 +29,7 @@ from qt_ui.uiconstants import EVENT_ICONS
|
|||||||
from qt_ui.widgets.QBudgetBox import QBudgetBox
|
from qt_ui.widgets.QBudgetBox import QBudgetBox
|
||||||
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
|
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
|
||||||
from qt_ui.windows.groundobject.QBuildingInfo import QBuildingInfo
|
from qt_ui.windows.groundobject.QBuildingInfo import QBuildingInfo
|
||||||
|
from dcs import vehicles
|
||||||
|
|
||||||
|
|
||||||
class QGroundObjectMenu(QDialog):
|
class QGroundObjectMenu(QDialog):
|
||||||
@ -101,7 +102,11 @@ class QGroundObjectMenu(QDialog):
|
|||||||
if not hasattr(g, "units_losts"):
|
if not hasattr(g, "units_losts"):
|
||||||
g.units_losts = []
|
g.units_losts = []
|
||||||
for u in g.units:
|
for u in g.units:
|
||||||
self.intelLayout.addWidget(QLabel("<b>Unit #" + str(u.id) + " - " + str(u.type) + "</b>"), i, 0)
|
unit_display_name = u.type
|
||||||
|
unit_type = vehicles.vehicle_map.get(u.type)
|
||||||
|
if unit_type is not None:
|
||||||
|
unit_display_name = db.unit_get_expanded_info(self.game.enemy_country, unit_type, 'name')
|
||||||
|
self.intelLayout.addWidget(QLabel("<b>Unit #" + str(u.id) + " - " + str(unit_display_name) + "</b>"), i, 0)
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
|
||||||
for u in g.units_losts:
|
for u in g.units_losts:
|
||||||
|
|||||||
@ -13,6 +13,7 @@ local unitPayloads = {
|
|||||||
[1] = 30,
|
[1] = 30,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
["unitType"] = "SH-60B",
|
["unitType"] = "SH-60B",
|
||||||
}
|
}
|
||||||
return unitPayloads
|
return unitPayloads
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
dofile('Scripts/ScriptingSystem.lua')
|
dofile('Scripts/ScriptingSystem.lua')
|
||||||
|
|
||||||
--Sanitize Mission Scripting environment
|
--Sanitize Mission Scripting environment
|
||||||
--This makes unavailable some unsecure functions.
|
--This makes unavailable some unsecure functions.
|
||||||
--Mission downloaded from server to client may contain potentialy harmful lua code that may use these functions.
|
--Mission downloaded from server to client may contain potentialy harmful lua code that may use these functions.
|
||||||
--You can remove the code below and make availble these functions at your own risk.
|
--You can remove the code below and make availble these functions at your own risk.
|
||||||
|
|
||||||
|
|||||||
@ -962,7 +962,7 @@
|
|||||||
}],
|
}],
|
||||||
"AAA Bofors 40mm": [{
|
"AAA Bofors 40mm": [{
|
||||||
"default": {
|
"default": {
|
||||||
"name": "Bofors 40 mm gun",
|
"name": "Bofors 40 mm Gun",
|
||||||
"country-of-origin": "Sweden",
|
"country-of-origin": "Sweden",
|
||||||
"manufacturer": "Bofors",
|
"manufacturer": "Bofors",
|
||||||
"role": "Anti-Aircraft Gun",
|
"role": "Anti-Aircraft Gun",
|
||||||
@ -1101,7 +1101,7 @@
|
|||||||
}],
|
}],
|
||||||
"APC M2A1": [{
|
"APC M2A1": [{
|
||||||
"default": {
|
"default": {
|
||||||
"name": "M2A1 Half-track",
|
"name": "M2A1 Half-Track",
|
||||||
"country-of-origin": "USA",
|
"country-of-origin": "USA",
|
||||||
"manufacturer": "White Motor Company",
|
"manufacturer": "White Motor Company",
|
||||||
"role": "Armoured Personnel Carrier",
|
"role": "Armoured Personnel Carrier",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user