From c708abafc81da094c3379d0067474273a204a81f Mon Sep 17 00:00:00 2001 From: Khopa Date: Thu, 11 Jun 2020 21:50:09 +0200 Subject: [PATCH] Started refactoring on ground objects. WW2 factions will have WW2 style buildings. Added ground objects templates for : "village", "ww2bunker", "allycamp" --- game/data/building_data.py | 16 +++++++ game/factions/germany_1944.py | 8 +++- game/factions/usa_1944.py | 4 +- gen/flights/ai_flight_planner.py | 8 ++-- gen/groundobjectsgen.py | 45 ++++++++++++------ qt_ui/widgets/map/QLiberationMap.py | 2 + qt_ui/widgets/map/QMapGroundObject.py | 2 +- resources/groundobject_templates.p | Bin 3937 -> 12118 bytes .../tools/generate_groundobject_templates.py | 2 +- resources/tools/generate_groundobjectsmap.py | 12 ++--- resources/tools/groundobject_templates.miz | Bin 14683 -> 22762 bytes resources/ui/ground_assets/allycamp.png | Bin 0 -> 206 bytes resources/ui/ground_assets/allycamp_blue.png | Bin 0 -> 206 bytes resources/ui/ground_assets/derrick.png | Bin 0 -> 194 bytes resources/ui/ground_assets/derrick_blue.png | Bin 0 -> 194 bytes resources/ui/ground_assets/village.png | Bin 0 -> 231 bytes resources/ui/ground_assets/village_blue.png | Bin 0 -> 239 bytes .../ground_assets/{warehouse.png => ware.png} | Bin .../{warehouse_blue.png => ware_blue.png} | Bin resources/ui/ground_assets/ww2bunker.png | Bin 0 -> 210 bytes resources/ui/ground_assets/ww2bunker_blue.png | Bin 0 -> 210 bytes theater/start_generator.py | 27 +++++++---- theater/theatergroundobject.py | 34 +++++++------ 23 files changed, 106 insertions(+), 54 deletions(-) create mode 100644 game/data/building_data.py create mode 100644 resources/ui/ground_assets/allycamp.png create mode 100644 resources/ui/ground_assets/allycamp_blue.png create mode 100644 resources/ui/ground_assets/derrick.png create mode 100644 resources/ui/ground_assets/derrick_blue.png create mode 100644 resources/ui/ground_assets/village.png create mode 100644 resources/ui/ground_assets/village_blue.png rename resources/ui/ground_assets/{warehouse.png => ware.png} (100%) rename resources/ui/ground_assets/{warehouse_blue.png => ware_blue.png} (100%) create mode 100644 resources/ui/ground_assets/ww2bunker.png create mode 100644 resources/ui/ground_assets/ww2bunker_blue.png diff --git a/game/data/building_data.py b/game/data/building_data.py new file mode 100644 index 00000000..9d7d5b65 --- /dev/null +++ b/game/data/building_data.py @@ -0,0 +1,16 @@ +import inspect +import dcs + +DEFAULT_AVAILABLE_BUILDINGS = ['fuel', 'ammo', 'comms', 'oil', 'ware', 'farp', 'fob', 'power', 'factory', 'derrick', 'aa'] + +WW2_GERMANY_BUILDINGS = ['fuel', 'factory', 'ww2bunker', 'ww2bunker', 'ww2bunker', 'allycamp', 'allycamp', 'aa'] +WW2_ALLIES_BUILDINGS = ['fuel', 'allycamp', 'allycamp', 'allycamp', 'allycamp', 'allycamp', 'aa'] + +FORTIFICATION_BUILDINGS = ['Siegfried Line', 'Concertina Wire', 'Czech hedgehogs 1', 'Czech hedgehogs 2', + 'Dragonteeth 1', 'Dragonteeth 2', 'Dragonteeth 3', 'Dragonteeth 4', 'Dragonteeth 5', + 'Haystack 1', 'Haystack 2', 'Haystack 3', 'Haystack 4', 'Hemmkurvenvenhindernis', + 'Log posts 1', 'Log posts 2', 'Log posts 3', 'Log ramps 1', 'Log ramps 2', 'Log ramps 3', + 'Belgian Gate', 'Container white'] + +FORTIFICATION_UNITS = [c for c in vars(dcs.vehicles.Fortification).values() if inspect.isclass(c)] +FORTIFICATION_UNITS_ID = [c.id for c in vars(dcs.vehicles.Fortification).values() if inspect.isclass(c)] \ No newline at end of file diff --git a/game/factions/germany_1944.py b/game/factions/germany_1944.py index c93f7699..9549f5fe 100644 --- a/game/factions/germany_1944.py +++ b/game/factions/germany_1944.py @@ -1,6 +1,8 @@ from dcs.planes import * from dcs.vehicles import * +from game.data.building_data import WW2_GERMANY_BUILDINGS + Germany_1944 = { "country": "Third Reich", "side": "red", @@ -32,5 +34,9 @@ Germany_1944 = { ], "shorad":[ AirDefence.AAA_8_8cm_Flak_36, - ] + ], + "objects": WW2_GERMANY_BUILDINGS, + "doctrine": { + # TODO + } } \ No newline at end of file diff --git a/game/factions/usa_1944.py b/game/factions/usa_1944.py index 192dd748..043041ce 100644 --- a/game/factions/usa_1944.py +++ b/game/factions/usa_1944.py @@ -2,6 +2,8 @@ from dcs.planes import * from dcs.ships import * from dcs.vehicles import * +from game.data.building_data import WW2_ALLIES_BUILDINGS + USA_1944 = { "country": "USA", "side": "blue", @@ -36,5 +38,5 @@ USA_1944 = { AirDefence.AAA_Bofors_40mm, ], "shorad":[ AirDefence.AAA_Bofors_40mm, - ] + ], "objects": WW2_ALLIES_BUILDINGS } \ No newline at end of file diff --git a/gen/flights/ai_flight_planner.py b/gen/flights/ai_flight_planner.py index 05557af9..739a895c 100644 --- a/gen/flights/ai_flight_planner.py +++ b/gen/flights/ai_flight_planner.py @@ -460,11 +460,11 @@ class FlightPlanner: orbit0p = loc.position.point_from_heading(hdg - 90, radius) orbit1p = loc.position.point_from_heading(hdg + 90, radius) else: - loc = for_cp.position.point_from_heading(random.randint(0, 360),random.randint(nm_to_meter(10), nm_to_meter(40))) - hdg = for_cp.position.heading_between_point(loc.position) + loc = for_cp.position.point_from_heading(random.randint(0, 360), random.randint(nm_to_meter(10), nm_to_meter(40))) + hdg = for_cp.position.heading_between_point(loc) radius = nm_to_meter(random.randint(15, 40)) - orbit0p = loc.position.point_from_heading(hdg - 90, radius) - orbit1p = loc.position.point_from_heading(hdg + 90, radius) + orbit0p = loc.point_from_heading(hdg - 90, radius) + orbit1p = loc.point_from_heading(hdg + 90, radius) # Create points ascend = self.generate_ascend_point(flight.from_cp) diff --git a/gen/groundobjectsgen.py b/gen/groundobjectsgen.py index e572fb6b..46a514e6 100644 --- a/gen/groundobjectsgen.py +++ b/gen/groundobjectsgen.py @@ -1,6 +1,7 @@ import logging from game import db +from game.data.building_data import FORTIFICATION_UNITS_ID, FORTIFICATION_UNITS from game.db import unit_type_from_name from .conflictgen import * from .naming import * @@ -50,9 +51,6 @@ class GroundObjectsGenerator: else: cp = self.conflict.from_cp - consumed_farps = set() - - for cp in self.game.theater.controlpoints: if cp.captured: @@ -113,25 +111,42 @@ class GroundObjectsGenerator: sg.points[0].tasks.append(ActivateICLSCommand(cp.icls, unit_id=sg.units[0].id)) else: + static_type = None if ground_object.dcs_identifier in warehouse_map: static_type = warehouse_map[ground_object.dcs_identifier] - else: + elif ground_object.dcs_identifier in fortification_map: static_type = fortification_map[ground_object.dcs_identifier] - - if not static_type: + elif ground_object.dcs_identifier in FORTIFICATION_UNITS_ID: + for f in FORTIFICATION_UNITS: + if f.id == ground_object.dcs_identifier: + unit_type = f + break + else: print("Didn't find {} in static _map(s)!".format(ground_object.dcs_identifier)) continue - group = self.m.static_group( - country=side, - name=ground_object.string_identifier, - _type=static_type, - position=ground_object.position, - heading=ground_object.heading, - dead=ground_object.is_dead, - ) + if static_type is None: + if not ground_object.is_dead: + group = self.m.vehicle_group( + country=side, + name=ground_object.string_identifier, + _type=unit_type, + position=ground_object.position, + heading=ground_object.heading, + ) + logging.info("generated {}object identifier {} with mission id {}".format( + "dead " if ground_object.is_dead else "", group.name, group.id)) + else: + group = self.m.static_group( + country=side, + name=ground_object.string_identifier, + _type=static_type, + position=ground_object.position, + heading=ground_object.heading, + dead=ground_object.is_dead, + ) - logging.info("generated {}object identifier {} with mission id {}".format("dead " if ground_object.is_dead else "", group.name, group.id)) + logging.info("generated {}object identifier {} with mission id {}".format("dead " if ground_object.is_dead else "", group.name, group.id)) def farp_aa(mission_obj, country, name, position: mapping.Point): diff --git a/qt_ui/widgets/map/QLiberationMap.py b/qt_ui/widgets/map/QLiberationMap.py index 59d74bbb..e2e4faf8 100644 --- a/qt_ui/widgets/map/QLiberationMap.py +++ b/qt_ui/widgets/map/QLiberationMap.py @@ -41,6 +41,7 @@ class QLiberationMap(QGraphicsView): self.setMinimumSize(800,600) self.setMaximumHeight(2160) self._zoom = 0 + self.factor = 1 self.init_scene() self.connectSignals() self.setGame(game) @@ -222,6 +223,7 @@ class QLiberationMap(QGraphicsView): else: self._zoom = -5 + def _transform_point(self, p: Point, treshold=30) -> (int, int): point_a = list(self.game.theater.reference_points.keys())[0] point_a_img = self.game.theater.reference_points[point_a] diff --git a/qt_ui/widgets/map/QMapGroundObject.py b/qt_ui/widgets/map/QMapGroundObject.py index 4e627bd5..c675d20f 100644 --- a/qt_ui/widgets/map/QMapGroundObject.py +++ b/qt_ui/widgets/map/QMapGroundObject.py @@ -17,7 +17,7 @@ class QMapGroundObject(QGraphicsRectItem): self.setAcceptHoverEvents(True) self.setZValue(2) self.buildings = buildings - #self.setFlag(QGraphicsItem.ItemIgnoresTransformations, True) + self.setFlag(QGraphicsItem.ItemIgnoresTransformations, False) if len(self.model.groups) > 0: units = {} diff --git a/resources/groundobject_templates.p b/resources/groundobject_templates.p index 5e409190f4b3c1e0f8f6952d7072ac66db45dd38..eb39274b00932d965cde939cc3bf19570df202ed 100644 GIT binary patch literal 12118 zcma*td0-Po+W_!z-yoOVkY4nFmbPgrEk`$PX@PRLKshR;ZQ91BNoRT>$6(}sK?J!K zITS<%50t71Vpn)k5s*`n`xFF01w=(b-rq{?uwL%E0t$bcKrNoNrK#@#~qX^Z_s!K~d^YcrsWvE_mUT$eb zv8ANM<|t@5+-Y-^HAMA8pF<4@Y8aALgO+>-HA<61Ba>c#(qMoOrl7`YQc}=X>j{^k zJSVFjEmLT<a=aG)bWodD?8z4_?nE~rA_UrC3fwGniF4CulEBSC&j1R=*?xetIG-l5Mk zG;^Lg@Mi#PFxGZP6AIu&AVEPu@Rp%zl-+IecpAHU5W$?FT_ltda#-%Yu^CDf=2Q2Z zpO!tMu$Dsau@o0OQ5ZqpSO@D)j}B*Wa~fNOxwyF8VJova9mYIsiL(qv@N@JaC=$-m zd;GpQyUbE02TuEV%Lr{vqnK8oY6C2e0t+@Kp=gen2#SHa0>blM4UtMN(!&gmXrGJK zAU!z}M^G;hMDCYyAYv(x#EsC})}dOiv$(hv#S@ee!s^?bpgyXdIoep}oNUFYFSq*< zl*nur1$)t2DjS}*CB0@gk_a+0stGNV%+8`{#vv$)d&vZ){Qtc2tXfoY+U%%5L8&az zG}Szc;I6S$pC&{I&` znC>Hf*bI#8YGV+ zR)X>YF>M~u{{|p(8~NJ4R5cQT6ljn_j@Sr#T0w3MY5jo&sYAg6u3+#WYn8HC3tRk;9FdR!13fa=U~e1gVOh7`NyE*pjiv{i+yGn;^^-dS@|! zLdOxOF{Qk?#F*@~l(9QXDJRPaDhIOr>}z@cE(o{R@3l66=HlTNCH_la+iCVIw1G|L z$}H$7Fu)fg}zWRx##(3tCp!1v$*KthM_dc3mDc+#Zu|q!Iov)cx!Rw8Ix&ur33g%eu7m5t%eh{%W6M@){5Px%rE3`xhiXd zeTi8O=}D3-7+Z3SN{!LzWzMW2=oMgkNN5{^I3;u6JsloM3PX>A7p?PJ#x$k>rCBg- z0%K{h#crqfymg#fPtXQNNv68r&3<2@0`Big%;Z((l7UjMdZAw9)JB3fajNazL~oyu+I%o_x~36*Qna*jlY8k!@?oZ72uwzhI_=`dS3vz4H?AsUft2~zFy z$PvE}m%yF&9fICvt@$2p&23C)U2mkd#A3t7$xd8UTIei6@AFf9K+tw}io}!W!s<;@ zB5kp--Jlt~!jc%NE7eHHaKvavA9Cg+fM!+1RYbP9lKMp0b&YVy`ru~D;?LD zPH^d4g1!Su)J|r#+u$kj{N-6Ow&fO~lLURw@^^~n?=(9_BU)`XEmI4e;U_pt&^bt7 zNJ472Xr-f=KJ=Tm%cZIGc|GR>cP6i54zxEkdIn0+W#+K<9M0~z zrDgPv>vW(i9J)%-4^ZO{$193fE704y9k{GeN(=g#K6BAa~g5*dUx?vlirIn>Eikn04v9{51Cn`VCHFs`$NUp%S_O z=PP#Z)<%Bc3-vpv{vha2NP=np(%%APxP<+Gp4c=?ZI*l&jRR(n4;a;w{*!8>l}>g# z%CM8(8kG3|;@;l`J%rGDUa4$5Ndhl!#Hp|lZD@~tdH-3#*qwdf|nwYe?DE=eC-+XWY5T)^eO8@qV#c2^(Q`9JKs!mbB) zeYbrlXTf156}@V%8C|~{2J`K_dHLBBtmZDooy=EX23qd zS=odaF7T6~;ruM8*7VV4xjARqBX&mm#N>(5y(T&=6&Cx%f^r9LA>@`Ix8kxCbY{G9 zhmvFSRW-WwQ@V3a(f|n0J$TVB_^LY zKsLO@f2q0D4=ETXHM%S((LOwJH0~5ZYoMvs~Pj+d6$OSg;|$hN^6IaHH*yfR#*@ zam#5oJlQbsY&XGn2R2+~qjm;#dI+o>+b`jGkd}>rqRKpr4netAOdrQA#>sR@!ae9d zo`p!dNpKVtrW3B4<30#-(VcYq+`f3W9TNqu~3-0H}ZoHwpHA? zLCznxYTceb+&JO(0ykcDZ{8jLJ)O3(cug7RHMg{Gf)BU1aQlGUS9Kp9zC2R`S4wF0 zNqDJ2(`@~GxQW7*z%{GxKeyjHSE;x?>wn?et96rnxXHpz0k^-78{KrOmrZYyto8z% z#bGS4&}Y730v!(M2#(4%KDjnXx$VgbM~216YtfM$Wdm~ZR5l4NwB{Aib)te&V-(I1 zawf>5RN1g1v&I4?+@2^t?V?s5?Nc5jWVQlN@L0Dz?#S5AiX64cK8?;AJjaJ|KIQR3 zo&a(-m#glb-)sFzAPx&dI@ zbA_A-vX#qKm%e>CV22`yZ>=~Ttd;Y9$^}9$1lgv_*D5=-pi?y#b8OIoF{`xl(>~=Q zA=^PNR%J0{N-$)4%GPpt9;>j~?R1?0JK$(1eWyCzZw#+dHn zV`?egB)AO9HcFHI3nm12azT|sL&K80@DtOPfmb=f<=)u}!A=JD8O}<6Coi{CR!}4_ z>=e$zv<9N3Yw5~jE4_-Q3V9mH(^WZO=%LXUp$+5~GtXQ|&<0F=$}@!gEXXcZj$Z%e zytfp&Wxo;RpjLj)r#w^0vp}A$%8^Z`yy>sV;XU@mNLY@cmd@jpf zS5Lf>_IZ_!oZhW*whVW~h-s(W?$WZ0yt6L| zb}_I^-0Z58R=dLX-5Kx}UBmOt!;9Y8rGi}s>~hXZk&J~TNM6_#oYn7aD}}rY}=m_NgGtiG7#M`;)g_wU}S^DZeJ5+ulmoH(}6CAvTa&F7ZsV>a#D z2D*efCD&41f?tQjH`8}EO1;4tg5Ly9`Fh3uodJG}e#!@^Ep(IMtx${(P@zX-=KKsN zl>*9^6%u|@_p?30Z*#FBJ@)|16uN?uTV#yE?+Ef;Am3BT*sUF2=&g{ZeWTj>xisBy zn;vPx?+fw+Ah+v~;hncEJgtqgQjd(m9}4m#AU}4KD_3luqeSU{=A#cyT5<;zRo0=a zRs0kBG0){rx=HXZC`WS{E6C=v){a+~UaIBtQ+;x`AU^}L%1thw9kZIAk3R7nu)nm~ zrHxY7CqEbD9w7I+NzpvLcJGaKe_bR-%m3<=`vmy~kYB1~R8h{VcqNzdl?|KIXLiqN z%vXA(3GWx=*FYXn$&gRab-fG~m*T%#{Gg+jJg7&;;6sA^2FSxI+40`74SY<9Uq3r^ zo0dGHPaYNIF(8j~Qi^;~bMqA$h8ZsvKcP>4E6DGFJgJiHzwa##;1$=8@_T*qlps$7 zc}69J-)mlRfRp;ob5@Tu;d6pK599@vjGbM7hfyH|<~qL4)%MGa`s5`+UIy}to3uWh zN}n-USN}GC!bnL=UezOG@DGB#2IO@&DWVKtxA0Y+iNTNh5furadzX6 zUA0l((j!gywjh57@)sS_v^(w587=v%9vOr02=XqF_jJf!*K^(ob!mp+-}FcmzAwn% zf&9Zwj+wSQNMg++w=TW1M<XQ!y`4^CX>yUwD`^r1oia*pR9|`gwAphm09J{gi z*9bb1+&Uzna*38S)MN{=9;3Pm*PtKsQN1SJB)AroW25><-41P(q2hu2OEKC zr@uJKrMdC6)hF8tvOSO;R5Geb`-f{d89!llM>WcPdhdm=4sb^(>d}K@a3}gP??IjE zCc#~x9Qz4e8?+P3o-)89-Ne7#W3XM(uve3qXZcZq)CU2 zv82CvRgF?ih+_1~SV8s#GERq#fAuVxttETuktQ53$OIsJb5f4o-{EKtrNzBO*+-x3 zE69F8Cb~&6SjI>8vAwB{QsN|CYoNcPdwhY~EZih;lU29P+`!I1E6v_-(Cwj%44SJl z#fRHpxT)Z#aaUsZ9r{$nZbALx9;NqCrZsJ%L6m#8I&+?WTjlvsRH!T3g!nXwMO>7kYo!ODg<8u!tI{8~(dN<4MZN2_ zShx;wovPci^_4No%A91*?9w2}Gg7+nK#LkI^v8*CAfoT-hHQ-Czf$_nCRFr~!EDB5 b^e?~6%3*&6>~EA#bDIt+pzoH_@`(Qd&cE0~ delta 70 zcmcZ>_fT$wGQS-Y0|P^1V&S{m!uQ?`v4tOM3qNXPuttD{9UTilWw2*(Xf_spt}Xnc Wk-_cFkip~4P@0s%3nUYZOZ5PJ!59Ys diff --git a/resources/tools/generate_groundobject_templates.py b/resources/tools/generate_groundobject_templates.py index 78f2cd3b..fce50a0f 100644 --- a/resources/tools/generate_groundobject_templates.py +++ b/resources/tools/generate_groundobject_templates.py @@ -13,7 +13,7 @@ def load_templates(): groups = {} # type: typing.Dict[str, typing.Dict[int, typing.List[Static]]] - for static_group in temp_mis.country("USA").static_group: + for static_group in temp_mis.country("USA").static_group + temp_mis.country("USAF Aggressors").static_group: for static in static_group.units: static_name = str(static.name).split()[0] tpl_name, tpl_idx = static_name[:-1], int(static_name[-1]) diff --git a/resources/tools/generate_groundobjectsmap.py b/resources/tools/generate_groundobjectsmap.py index a7962720..78c5cf74 100644 --- a/resources/tools/generate_groundobjectsmap.py +++ b/resources/tools/generate_groundobjectsmap.py @@ -1,19 +1,15 @@ import pickle -import typing -from dcs.mission import Mission -from dcs.mapping import Point -from dcs.terrain import * -from dcs.unitgroup import VehicleGroup, StaticGroup from dcs import vehicles +from dcs.mapping import Point +from dcs.mission import Mission +from dcs.terrain import * from dcs.unit import * -from dcs.statics import warehouse_map, fortification_map -from game import db from gen.groundobjectsgen import TheaterGroundObject from theater.caucasus import CaucasusTheater -from theater.persiangulf import PersianGulfTheater from theater.nevada import NevadaTheater +from theater.persiangulf import PersianGulfTheater m = Mission() m.load_file("resources/tools/cau_groundobjects.miz") diff --git a/resources/tools/groundobject_templates.miz b/resources/tools/groundobject_templates.miz index a6eb0bbdb34644b6aefb84aa0ca98db3f262f86c..10ddade8c90da2f774dbec9467260a0cb3ca8820 100644 GIT binary patch delta 18639 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 NJUJN#a#sKV0037$&{_Zh delta 10514 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 diff --git a/resources/ui/ground_assets/allycamp.png b/resources/ui/ground_assets/allycamp.png new file mode 100644 index 0000000000000000000000000000000000000000..72ea6ef1e9a4efe17735c0407030f8edab57bbad GIT binary patch literal 206 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!DLSt#}Etu(-jsC+6`8nKfbspeM(DUV3^J$`BwR_cpuO@22WQ%mvv4FO#m_6Jz4+& literal 0 HcmV?d00001 diff --git a/resources/ui/ground_assets/allycamp_blue.png b/resources/ui/ground_assets/allycamp_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..fc146c24f64d5ccb3ce448bed20c033bda583b6b GIT binary patch literal 206 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sEXgD|57Yp@DXFxk_^F~q_@xx_p#Re^N_L*e~LE*$L&8eMbG zv!n{~vc(*pclG-M9SMd?Df<<=O|LTF1v5=jvF_Z!E71I~;oHKN0wDvjg*qV{axXh7 waQgE;vErQmv4A0*p;YMO%l;!z&K_W3XtftLJE)YS544WK)78&qol`;+0538=7ytkO literal 0 HcmV?d00001 diff --git a/resources/ui/ground_assets/derrick.png b/resources/ui/ground_assets/derrick.png new file mode 100644 index 0000000000000000000000000000000000000000..b9d2180864daf68ec3603420d2bb2defc20aefd8 GIT binary patch literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sEXgD|57Yp@DXFx=C{F~q_@Ij7VtO@Va-L*b((ssenD2KM@G zoTpTz60S3taCR(^32{)B{=lFkrO?ON#u65uxSer&mcoKb@(srxcgbj3c78KsVB|DA iFg59_bJC}@1O|pSdj;`euf%Sk6%3xPelF{r5}E+-0yB94 literal 0 HcmV?d00001 diff --git a/resources/ui/ground_assets/derrick_blue.png b/resources/ui/ground_assets/derrick_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..f8de32634ae8a051b7109ea5f88da56eaf0a1914 GIT binary patch literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sEXgD|57Yp@DXFx=C{F~q_@xx_p#Re^N_L*e~LE*$L&8eMbG zv!n{~Zpdbs#o`jcr?p@bZv}%GufTBzXQtJwH{5RUHWdgs$?x#E(3NlM9G7b8h6Wbt j2VNUrDH>K98!#}eWm1r5s?H4rTEXDy>gTe~DWM4fJ{L2N literal 0 HcmV?d00001 diff --git a/resources/ui/ground_assets/village.png b/resources/ui/ground_assets/village.png new file mode 100644 index 0000000000000000000000000000000000000000..bfb83f5340dc042f3d8fccbe5519576a166ba391 GIT binary patch literal 231 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFTJAoO82v?*MS1WfN7yYg+O(j1s;*b3=DjSL74G){)!Z!po6E2 zV~E7%+_M)s4+L;H2R>%;RNrv3{zO*mrT%h9i+Httm-0*9&a&oQNPD2A`MymdkoTN0 j&lTMc<0AEX;pijGt?lf`=4G${3UY|2tDnm{r-UW|ey%=W literal 0 HcmV?d00001 diff --git a/resources/ui/ground_assets/village_blue.png b/resources/ui/ground_assets/village_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..7adfc845e8aebc3ce420d1a8639a84a293176665 GIT binary patch literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFWGs+$=&OL43`knn%6Yxs${PmUGp$M^MBm*!TiTO?T9=3_9q u%~++LtI0+5hW~{CQ-yyIjU}s-jH(&=>NzKt21H#1xyIAg&t;ucLK6TA+dxAA literal 0 HcmV?d00001 diff --git a/resources/ui/ground_assets/warehouse.png b/resources/ui/ground_assets/ware.png similarity index 100% rename from resources/ui/ground_assets/warehouse.png rename to resources/ui/ground_assets/ware.png diff --git a/resources/ui/ground_assets/warehouse_blue.png b/resources/ui/ground_assets/ware_blue.png similarity index 100% rename from resources/ui/ground_assets/warehouse_blue.png rename to resources/ui/ground_assets/ware_blue.png diff --git a/resources/ui/ground_assets/ww2bunker.png b/resources/ui/ground_assets/ww2bunker.png new file mode 100644 index 0000000000000000000000000000000000000000..32019d19b1d0cc42e3b4e474d0f261894202e5f2 GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFTJAoO82v?*MS1WfN7yYg+O(j1s;*b3=DjSL74G){)!Z!pth%r zV~E7%o6(5nNC3lZwj>TF#+HKz6grfcHVS!KvltjKFbLh_+-y8iLJnl7 Mr>mdKI;Vst03Ky4oB#j- literal 0 HcmV?d00001 diff --git a/theater/start_generator.py b/theater/start_generator.py index 28910331..824650c4 100644 --- a/theater/start_generator.py +++ b/theater/start_generator.py @@ -4,6 +4,7 @@ import random import typing import logging +from game.data.building_data import DEFAULT_AVAILABLE_BUILDINGS from gen import namegen from gen.defenses.armor_group_generator import generate_armor_group from gen.fleet.ship_group_generator import generate_carrier_group, generate_lha_group @@ -74,7 +75,7 @@ def generate_groundobjects(theater: ConflictTheater, game): if cp.cptype == ControlPointType.AIRCRAFT_CARRIER_GROUP: # Create ground object group group_id = group_id + 1 - g = TheaterGroundObject() + g = TheaterGroundObject("CARRIER") g.group_id = group_id g.object_id = 0 g.cp_id = cp.id @@ -94,7 +95,7 @@ def generate_groundobjects(theater: ConflictTheater, game): elif cp.cptype == ControlPointType.LHA_GROUP: # Create ground object group group_id = group_id + 1 - g = TheaterGroundObject() + g = TheaterGroundObject("LHA") g.group_id = group_id g.object_id = 0 g.cp_id = cp.id @@ -125,7 +126,7 @@ def generate_groundobjects(theater: ConflictTheater, game): group_id = group_id + 1 - g = TheaterGroundObject() + g = TheaterGroundObject("aa") g.group_id = group_id g.object_id = 0 g.cp_id = cp.id @@ -235,10 +236,22 @@ def generate_cp_ground_points(cp: ControlPoint, theater, game, group_id, templat if cp.is_global: return False + if cp.captured: + faction = game.player_name + else: + faction = game.enemy_name + faction_data = db.FACTIONS[faction] + + available_categories = DEFAULT_AVAILABLE_BUILDINGS + if "objects" in faction_data.keys(): + available_categories = faction_data["objects"] + + if len(available_categories) == 0: + return False + amount = random.randrange(3, 8) for i in range(0, amount): - available_categories = list(templates) obj_name = namegen.random_objective_name() if i >= amount - 1: @@ -264,7 +277,7 @@ def generate_cp_ground_points(cp: ControlPoint, theater, game, group_id, templat for object in tpl: object_id += 1 - g = TheaterGroundObject() + g = TheaterGroundObject(tpl_category) g.group_id = group_id g.object_id = object_id g.cp_id = cp.id @@ -276,10 +289,6 @@ def generate_cp_ground_points(cp: ControlPoint, theater, game, group_id, templat g.position = Point(point.x + object["offset"].x, point.y + object["offset"].y) if g.dcs_identifier == "AA": - if cp.captured: - faction = game.player_name - else: - faction = game.enemy_name g.groups = [] group = generate_anti_air_group(game, cp, g, faction) if group is not None: diff --git a/theater/theatergroundobject.py b/theater/theatergroundobject.py index 05d0aa72..51c54e2c 100644 --- a/theater/theatergroundobject.py +++ b/theater/theatergroundobject.py @@ -1,19 +1,20 @@ -import typing - from dcs.mapping import Point -from dcs.statics import * NAME_BY_CATEGORY = { "power": "Power plant", "ammo": "Ammo depot", "fuel": "Fuel depot", "aa": "AA Defense Site", - "warehouse": "Warehouse", + "ware": "Warehouse", "farp": "FARP", "fob": "FOB", "factory": "Factory", "comms": "Comms. tower", - "oil": "Oil platform" + "oil": "Oil platform", + "derrick": "Derrick", + "ww2bunker": "Bunker", + "village": "Village", + "allycamp": "Camp" } ABBREV_NAME = { @@ -21,22 +22,28 @@ ABBREV_NAME = { "ammo": "AMMO", "fuel": "FUEL", "aa": "AA", - "warehouse": "WARE", + "ware": "WARE", "farp": "FARP", "fob": "FOB", "factory": "FACTORY", "comms": "COMMST", - "oil": "OILP" + "oil": "OILP", + "derrick": "DERK", + "ww2bunker": "BUNK", + "village": "VLG", + "allycamp": "CMP", } CATEGORY_MAP = { + # Special cases "CARRIER": ["CARRIER"], "LHA": ["LHA"], "aa": ["AA"], + # Buildings "power": ["Workshop A", "Electric power box", "Garage small A", "Farm B", "Repair workshop", "Garage B"], - "warehouse": ["Warehouse", "Hangar A"], + "ware": ["Warehouse", "Hangar A"], "fuel": ["Tank", "Tank 2", "Tank 3", "Fuel tank"], "ammo": [".Ammunition depot", "Hangar B"], "farp": ["FARP Tent", "FARP Ammo Dump Coating", "FARP Fuel Depot", "FARP Command Post", "FARP CP Blindage"], @@ -45,6 +52,9 @@ CATEGORY_MAP = { "comms": ["TV tower", "Comms tower M"], "oil": ["Oil platform"], "derrick": ["Oil derrick", "Pump station", "Subsidiary structure 2"], + "ww2bunker": ["Siegfried Line", "Fire Control Bunker", "SK_C_28_naval_gun", "Concertina Wire", "Czech hedgehogs 1"], + "village": ["Small house 1B", "Small House 1A", "Small warehouse 1"], + "allycamp": [], } @@ -60,12 +70,8 @@ class TheaterGroundObject: groups = [] obj_name = "" - @property - def category(self) -> str: - for k, v in CATEGORY_MAP.items(): - if self.dcs_identifier in v: - return k - assert False, "Identifier not found in mapping: {}".format(self.dcs_identifier) + def __init__(self, category: str): + self.category = category @property def string_identifier(self):