From b403379b06d9fe1c8a5b7e98ff04a6f35168313e Mon Sep 17 00:00:00 2001 From: MaelkMaelk <65122264+MaelkMaelk@users.noreply.github.com> Date: Sat, 5 Oct 2024 18:41:36 +0200 Subject: [PATCH 1/7] Save + callsigns + routes feet : callsigns database, heure sur les routes et meilleur systeme de save xml --- Python/XML/aircraft.xml | 101 ++++++--- Python/XML/carteSecteur.xml | 139 ++++++++++-- Python/XML/simu.xml | 412 +++++++++++++++++++++++++++++++++++- Python/client.py | 13 +- Python/horloge.py | 12 ++ Python/interface.py | 7 +- Python/paquets_avion.py | 8 +- Python/player.py | 18 +- Python/server.py | 45 ++-- Python/server_browser.py | 6 +- 10 files changed, 678 insertions(+), 83 deletions(-) diff --git a/Python/XML/aircraft.xml b/Python/XML/aircraft.xml index e434a4f..b8dfd30 100644 --- a/Python/XML/aircraft.xml +++ b/Python/XML/aircraft.xml @@ -1,49 +1,26 @@ - + + - 330 + 280 410 2000 3000 - 220 + 200 450 1500 2000 - - 200 - 430 - 1000 - 1500 - - 330 + 280 410 2000 2500 - - 200 - 450 - 1000 - 1500 - - - 330 - 450 - 500 - 1000 - - - 160 - 370 - 1000 - 1500 - 240 450 @@ -57,7 +34,7 @@ 3000 - 400 + 310 550 2000 2500 @@ -69,16 +46,76 @@ 2500 - 330 + 280 550 1500 2000 - 330 + 280 550 2500 3000 - \ No newline at end of file + + + + AIGLE AZUR + AMERICAN + AIR Canada + AIR FRANCE + AEROFLOT + AIR FRANCE + AIRBUS INDUSTRIE + AIR MALTA + AEROMEXICO + ARGENTINA + AUSTRIAN + UKRAINE INTERNATIONAL + ALITALIA + SPEEDBIRD + BEE-LINE + AIR BERLIN + CONDOR + CONTINENTAL + C.S.A. + AIR ALGERIE + LUFTHANSA + SHAMROCK + EUROWINGS + EASY + ALPINE + FINNAIR + FRENCH POST + HOP AIR + IBERIA + SPANAIR + KLM + KENIYA + LIBAIR + LOT + MALEV + CEDAR JET + EGYPTAIR + OLYMPIC + ROYAL AIR MAROC + ROYAL AIR MAROC + JORDANIAN + TAROM + RYANAIR + SPRINGBOCK + SCANDINAVIAN + SAUDIA + SWISS + SYRIANAIR + AIR Portugal + TUNAIR + THOMAS COOK + TURKAIR + TRANSAVIA + FRANCE SOLEIL + EMIRATES + VIRGIN + + \ No newline at end of file diff --git a/Python/XML/carteSecteur.xml b/Python/XML/carteSecteur.xml index c2944ed..ba3c058 100644 --- a/Python/XML/carteSecteur.xml +++ b/Python/XML/carteSecteur.xml @@ -86,7 +86,7 @@ 709 - 995 + 1008 1146 @@ -109,6 +109,18 @@ 970 328 + + 838 + 412 + + + 739 + 225 + + + 806 + 354 + 947 620 @@ -141,10 +153,6 @@ 2028 997 - - 2000 - 980 - 1645 1097 @@ -174,12 +182,12 @@ 1644 - 1107 - 1237 + 1108 + 1236 - 991 - 1265 + 993 + 1266 1108 @@ -190,12 +198,40 @@ 1303 - 844 - 1249 + 840 + 1253 - 720 - 1339 + 699 + 1341 + + + 572 + 1421 + + + 2094 + 1968 + + + 2229 + 944 + + + 1995 + 533 + + + 1901 + 463 + + + 1273 + 446 + + + 1947 + 1538 @@ -301,6 +337,9 @@ TRANSIT SO NE + + FRI + MELKA @@ -338,6 +377,9 @@ TRANSIT E-SE N + + ATN + BURGO @@ -368,6 +410,9 @@ TRANSIT SE N + + ATN + BURGO @@ -391,6 +436,9 @@ JAMBI + + VAREK + I2 @@ -398,6 +446,9 @@ TRANSIT E SO + + BIELA + JUVEN @@ -428,12 +479,12 @@ OS - + DEPART SO LIML - LIML + BIELA 20 @@ -528,6 +579,9 @@ SEVET + + RAPID + 250 G2 @@ -556,6 +610,9 @@ SEVET + + RAPID + 250 G2 @@ -621,6 +678,12 @@ BERNI + + ETAMO + + + DIRMO + N2 N3 @@ -629,6 +692,9 @@ TRANSIT SE NO + + MIROS + JAMBI @@ -652,6 +718,12 @@ BERNI + + ETAMO + + + DIRMO + N2 N3 @@ -660,6 +732,9 @@ TRANSIT SE NO + + MIROS + JAMBI @@ -749,6 +824,40 @@ JAMBI + + VAREK + + I2 + + + + DEPART + LFVB + SE + + BST + 20 + + + LSE + + + AVRIL + + + WS + 240 + + + RETNO + + + SANTO + True + + + SAMOS + I2 diff --git a/Python/XML/simu.xml b/Python/XML/simu.xml index fb9033f..66365d6 100644 --- a/Python/XML/simu.xml +++ b/Python/XML/simu.xml @@ -1,16 +1,414 @@ - 1002 + + + 1100 + + - - FCACA - DH8D - ABISA-BERNI + + + + + + AZA2310 + + + A320 + + + GAI-JUVEN + + + 34000 + + + False + + + 1135.3324760807482 + + + 1228.8072431366452 + + + 340 + + + + + + + + + RYR1463 + + + B738 + + + ATN-SAMOS + + + 31000 + + + False + + + 1391.831528809085 + + + 679.2623145312475 + + + 310 + + + + + + + + + BAW2356 + + + A320 + + + ATN-VAREK + + + 33000 + + + False + + + 1273 + + + 446 + + + 330 + + + + + + + + + TAP1423 + + + B738 + + + FRI-GAI + + + 33000 + + + False + + + 1817.5277008612927 + + + 522.2153916966897 + + + 330 + + + + + + + + + IBE1223 + + + B738 + + + Depart LIML + + + 2000 + + + False + + + 2229 + + + 944 + + + 370 + + + + + + + + + HOP1203 + + + AT72 + + + ABISA-NEV + + + 32000 + + + False + + + 1283.213204244729 + + + 1062.0078521348714 + + + 320 + + + + + + + + + SWR1203 + + + A320 + + + GAI-RAPID + + + 34000 + + + True + + + 699 + + + 1341 + + + 340 + + + + + + + + + TAP2356 + + + B738 + + + FRI-GAI + + + 33000 + + + False + + + 1347.300142085819 + + + 862.4423715769826 + + + 330 + + + + + + + + + SWR3104 + + + A320 + + + GAI-RAPID + + + 32000 + + + True + + + 706.5181602549122 + + + 1339.095399402089 + + + 320 + + + + + + + + + BAW1203 + + + A320 + + + MIROS-DIRMO + + + 36000 + + + False + + + 1947 + + + 1538 + + + 360 + + + + + + + BAW123C + B738 + MIROS-DIRMO 30000 False - 1400 - 1300 + 1947 + 1538 300 + + EJU1245 + A320 + Depart RETNO SAMOS + 2000 + False + 1390.5612858047484 + 761.8281404330812 + 330 + + + DLH1230 + B738 + ABISA-RAPID + 30000 + False + 1375 + 1644 + 300 + + + AFR1203 + A320 + ATN-VAREK + 30000 + False + 1273 + 446 + 300 + + + EWG1542 + A320 + FRI-GAI + 29000 + False + 1901 + 463 + 290 + + + EZY1299 + B738 + Depart MEN + 2000 + False + 1384 + 759 + 310 + + + AZA142M + B738 + GAI-JUVEN + 38000 + False + 699 + 1341 + 300 + + + TVF1236 + B738 + ATN-SAMOS + 31000 + False + 1273 + 446 + 310 + + + DAH1278 + A320 + ABISA-RAPID + 32000 + True + 1375 + 1644 + 320 + + + SWR1244 + B738 + ABISA-RAPID + 34000 + True + 1375 + 1644 + 340 + + + diff --git a/Python/client.py b/Python/client.py index 2c61f36..c44fa2f 100644 --- a/Python/client.py +++ b/Python/client.py @@ -16,14 +16,21 @@ # recherche de tous les serveurs sur le réseau address = server_browser.serverBrowser() -print(address) +if address: + print(address) +else: + time.sleep(20) + exit() # fenêtre Pygame, mettre en 1920, 1080 pour plein écran pygame.init() width = 1000 height = 1000 - win = pygame.display.set_mode((width, height)) + +# win = pygame.display.set_mode() +# width, height = pygame.display.get_surface().get_size() + path = Path(os.getcwd()) manager = pygame_gui.UIManager((width, height), path / 'ressources' / 'theme.json') @@ -511,7 +518,7 @@ def main(server_ip: str): avion.drawEstimatedRoute(carte['points'], conflitGen.temps, color, win, zoom, scroll) for avion in dictAvionsAff.values(): - avion.draw(win, zoom, scroll, vecteurs, vecteurSetting, carte['points']) + avion.draw(win, zoom, scroll, vecteurs, vecteurSetting, carte['points'], game.heure) # on affiche les boutons manager.update(time_delta) diff --git a/Python/horloge.py b/Python/horloge.py index 0041236..52643f4 100644 --- a/Python/horloge.py +++ b/Python/horloge.py @@ -9,3 +9,15 @@ def affichageHeure(heure: float) -> str: minutes = '0' + minutes return heures + ':' + minutes + + +def heureXML(heure: float) -> str: + + heures = str(round(heure // 3600 % 24)) + if len(heures) == 1: + heures = '0' + heures + minutes = str(round(heure % 3600 // 60)) + if len(minutes) == 1: + minutes = '0' + minutes + + return heures + minutes diff --git a/Python/interface.py b/Python/interface.py index 7a8a304..0570a2b 100644 --- a/Python/interface.py +++ b/Python/interface.py @@ -199,7 +199,10 @@ def checkFields(self, event): self.returnValues.update({'PFL': int(event.text)}) except: # si l'utilisateur rentre n'importe quoi, on remet à la valeur du FL - self.returnValues.update({'PFL': self.returnValues['FL']}) + if 'FL' in self.returnValues: + self.returnValues.update({'PFL': self.returnValues['FL']}) + else: + self.returnValues.update({'PFL': 310}) # on vérifie l'indicatif elif event.ui_element == self.indicatifinput: @@ -782,7 +785,7 @@ def __init__(self, avion, pos: list[float, float], valeur: str): self.listeDroite = None objectID = None - if valeur == 'DCT': # TODO boutons directs en blanc + if valeur == 'DCT': self.liste = [point['name'] for point in self.avion.papa.route['points']] self.listeAff = self.liste[self.liste.index(avion.papa.nextPoint['name']):] objectID = pygame_gui.core.ObjectID('@menuLabel', 'menuBlanc') diff --git a/Python/paquets_avion.py b/Python/paquets_avion.py index 65c4259..5c536ca 100644 --- a/Python/paquets_avion.py +++ b/Python/paquets_avion.py @@ -71,7 +71,12 @@ def __init__(self, gameMap, Id, indicatif, aircraft, perfos, route, arrival, FL= else: self.medevac = '' - self.callsignFreq = 'Austrian' # TODO ajouter les callsigns + if indicatif[:2] in gameMap['callsigns']: + self.callsignFreq = gameMap['callsigns'][indicatif[:2]] + elif indicatif[:3] in gameMap['callsigns']: + self.callsignFreq = gameMap['callsigns'][indicatif[:3]] + else: + self.callsignFreq = 'caca' if route['type'] == 'DEPART': self.provenance = route['provenance'] @@ -164,6 +169,7 @@ def __init__(self, gameMap, Id, indicatif, aircraft, perfos, route, arrival, FL= def findNextPoint(self, carte): self.nextPoint = findClosestSegment(self.route['points'], (self.x, self.y), carte['points'])[1] + self.DCT = self.nextPoint['name'] def changeXFL(self, carte) -> None: """ diff --git a/Python/player.py b/Python/player.py index 5cf8416..f62d445 100644 --- a/Python/player.py +++ b/Python/player.py @@ -6,10 +6,12 @@ import pygame import pygame_gui +import horloge # Imports fichiers from Python.valeurs_config import * import Python.geometry as geometry import Python.interface as interface +import Python.horloge as horloge def positionAffichage(x: int, y: int, zoom: float, scrollX: float, scrollY: float): @@ -154,7 +156,7 @@ def drawSep(self, window, zoom): img = font.render(lettre, True, (170, 170, 255)) window.blit(img, coords) - def draw(self, win, zoom, scroll, vecteurs, vecteurSetting, points): + def draw(self, win, zoom, scroll, vecteurs, vecteurSetting, points, temps): # updates @@ -165,7 +167,7 @@ def draw(self, win, zoom, scroll, vecteurs, vecteurSetting, points): self.bouton.set_position((self.affX, self.affY)) if self.drawRouteBool: - self.drawRoute(points, win, zoom, scroll) + self.drawRoute(points, win, zoom, scroll, temps) if self.pointDessinDirect: self.drawDirect(points, self.pointDessinDirect, win, zoom, scroll) @@ -323,13 +325,14 @@ def drawEstimatedRoute(self, points, temps, color, win, zoom, scroll): distance -= legDistance # on enlève la distance de la branche parcourue à la distance à parcourir pointUn = pointDeux # on passe au prochain point - def drawRoute(self, points, win, zoom, scroll): + def drawRoute(self, points: dict, win, zoom: float, scroll: tuple[float, float] | list[float, float], temps: float): """ Dessine la route future de l'avion avec les estimées en temps :param points: la liste des points récupérer les coords :param win: l'écran pygame :param zoom: le niveau de zoom :param scroll: le scroll format [x, y] + :param temps: l'heure de la partie :return: """ @@ -339,16 +342,23 @@ def drawRoute(self, points, win, zoom, scroll): point1 = points[route[route.index(nextPoint) - 1]['name']][:2] point2 = points[nextPoint['name']][:2] pointUn = geometry.calculateShortestPoint(point1, point2, [self.papa.x, self.papa.y]) - # TODO heure de passage pour chaque point route = route[route.index(nextPoint):] # on ne considère que la route devant l'avion + font = pygame.font.SysFont('arial', 15) + for point in route: + pointDeux = [points[point['name']][0], points[point['name']][1]] + temps += geometry.calculateDistance(pointUn[0], pointUn[1], pointDeux[0], pointDeux[1]) / self.papa.speedPx * radarRefresh pygame.draw.line(win, (46, 80, 174), (pointUn[0] * zoom + scroll[0], pointUn[1] * zoom + scroll[1]), (pointDeux[0] * zoom + scroll[0], pointDeux[1] * zoom + scroll[1]), 3) + img = font.render(horloge.affichageHeure(temps), True, (170, 170, 255)) + coords = (pointDeux[0] * zoom - 5 + scroll[0], pointDeux[1] * zoom - 20 + scroll[1]) + win.blit(img, coords) + pointUn = pointDeux # on passe au prochain point def checkClicked(self, event) -> bool: diff --git a/Python/server.py b/Python/server.py index 91cb6f8..7d5a3dd 100644 --- a/Python/server.py +++ b/Python/server.py @@ -14,6 +14,7 @@ from pathlib import Path # Import fichiers +import Python.horloge as horloge from Python.network import MCAST_GRP, MCAST_PORT, port from Python.paquets_avion import * @@ -214,29 +215,39 @@ tree = ET.parse(dossierXML / aircraftFile) root = tree.getroot() -for aircraft in root: +for aircraft in root.find('aircrafts'): aircraftType.update( {aircraft.attrib['name']: {'IAS': int(aircraft.find('speed').text), 'plafond': int(aircraft.find('ceiling').text), 'ROC': int(aircraft.find('ROC').text), 'ROD': int(aircraft.find('ROD').text)}}) +callsignList = {} +for callsign in root.find('callsigns'): + callsignList.update({callsign.attrib['indicatif']: callsign.text}) + +gameMap.update({'callsigns': callsignList}) planeId = 0 + +simuTree = None try: # on essaye de charger une simu, si elle existe - tree = ET.parse(dossierXML / simu) + simuTree = ET.parse(dossierXML / simu).getroot() - heure = tree.find('heure').text + heure = simuTree.find('heure').text heure = int(heure[0:2]) * 3600 + int(heure[2:]) * 60 + game = Game(heure) + avionSpawnListe = [] - for avion in tree.find('avions'): + avionsXML = simuTree.find('avions') + for avion in avionsXML: avionDict = {} for XMLpoint in avion: try: - XMLpointValue = int(XMLpoint.text) + XMLpointValue = float(XMLpoint.text) except: XMLpointValue = XMLpoint.text avionDict.update({XMLpoint.tag: XMLpointValue}) @@ -271,16 +282,11 @@ heure = input('Heure de début de simu, format: hhmm') heure = int(heure[0:2]) * 3600 + int(heure[2:]) * 60 avionSpawnListe = [] - -game = Game(heure) - -# XML écriture - -SimuTree = ET.Element('simu') -heureXML = ET.SubElement(SimuTree, 'heure') -heureXML.text = '1002' -avionsXML = ET.SubElement(SimuTree, 'avions') - + simuTree = ET.Element('simu') + game = Game(heure) + heureXML = ET.SubElement(simuTree, 'heure') + heureXML.text = horloge.heureXML(game.heure) + avionsXML = ET.SubElement(simuTree, 'avions') def generateAvionXML(parent, heureEcriture, indicatifEcriture, aircraftEcriture, routeEcriture, altitudeEcriture, xEcriture=None, yEcriture=None, headingEcriture=None, PFLEcriture=None): @@ -403,14 +409,17 @@ def threaded_ping_responder(): PFLEcriture=req[2].PFL) elif req[1] == 'DelayedAdd': + req[2][1].Id = planeId + planeId += 1 + avionSpawnListe.append((game.heure + req[2][0], req[2][1])) if mode_ecriture: - heures = str(round(game.heure + req[2][0] // 3600)) + heures = str(round((game.heure + req[2][0]) // 3600)) if len(heures) == 1: heures = '0' + heures - minutes = str(round(game.heure + req[2][0] % 3600 // 60)) + minutes = str(round((game.heure + req[2][0]) % 3600 // 60)) if len(minutes) == 1: minutes = '0' + minutes @@ -490,7 +499,7 @@ def threaded_ping_responder(): if accelerationTemporelle > 0.5: accelerationTemporelle -= 0.5 elif req[1] == 'Save' and mode_ecriture: - xmlstr = minidom.parseString(ET.tostring(SimuTree)).toprettyxml(indent=" ") + xmlstr = minidom.parseString(ET.tostring(simuTree)).toprettyxml(indent=" ") with open("XML/simu.xml", "w") as f: f.write(xmlstr) diff --git a/Python/server_browser.py b/Python/server_browser.py index 6dd4201..3439d59 100644 --- a/Python/server_browser.py +++ b/Python/server_browser.py @@ -26,7 +26,11 @@ def serverBrowser(): serverList.update({data: address}) sock.close() if len(serverList) <= 1: - return list(serverList.values())[0][0] + try: + return list(serverList.values())[0][0] + except IndexError: + print('Aucun serveur trouvé') + return None print('Liste des serveurs actifs:') for i in range(len(list(serverList.keys()))): print(i, ' - ', list(serverList.keys())[i], '\n') From 3bf59567023d1132215bb19312a87c40ccbec58b Mon Sep 17 00:00:00 2001 From: MaelkMaelk <65122264+MaelkMaelk@users.noreply.github.com> Date: Sun, 6 Oct 2024 00:50:25 +0200 Subject: [PATCH 2/7] Menus pilotes feet : suppression de l'ancien menu pilote pour les menus controleurs plus ergonomiques --- Python/client.py | 30 +----- Python/interface.py | 232 +++++--------------------------------------- Python/player.py | 30 +++--- Python/server.py | 19 +++- 4 files changed, 56 insertions(+), 255 deletions(-) diff --git a/Python/client.py b/Python/client.py index c44fa2f..2345839 100644 --- a/Python/client.py +++ b/Python/client.py @@ -50,7 +50,6 @@ def main(server_ip: str): # menus conflitBool = False conflitGen = None - menuAvion = None menuATC = None menuValeurs = None flightDataWindow = None @@ -213,21 +212,6 @@ def main(server_ip: str): curseur_cercles = True pygame.mouse.set_cursor(pygame.cursors.broken_x) - # on regarde si notre menu pour le pilote est actif - if menuAvion is not None: - - # si on valide les modifs, alors la fonction checkEvent retourne les modifs - modifications = menuAvion.checkEvent(event) - if modifications: - - # on applique alors les modifs - avionId = modifications[0] - modifications = modifications[1] - - # pour chaque modif, on prépare une requête au serveur - for changement, valeur in modifications.items(): - localRequests.append((avionId, changement, valeur)) - if menuATC is not None: # si on valide les modifs, alors la fonction checkEvent retourne les modifs @@ -278,15 +262,12 @@ def main(server_ip: str): if type(action) in [list, tuple]: # si c'est un tuple alors cela correspond à une requête localRequests.append(action) - elif action == 'menuPIL' and menuAvion is None: # si c'est menu alors, on vérifie qu'on peut menu - menuAvion = interface.menuAvion(avion) - elif action == 'menuATC' and menuATC is None: menuATC = interface.menuATC(avion, pygame.mouse.get_pos()) elif menuValeurs is None and action is not None: # si on a renvoyé autre chose alors c'est une valeur pour ouvrir un menu - menuValeurs = interface.menuValeurs(avion, pygame.mouse.get_pos(), action) + menuValeurs = interface.menuValeurs(avion, pygame.mouse.get_pos(), action, pilote) # Menu de selection nouvel avion # si notre menu est ouvert @@ -325,7 +306,7 @@ def main(server_ip: str): elif event.type == pygame_gui.UI_TEXT_ENTRY_CHANGED: nouvelAvionWin.checkFields(event) - if menuAvion or nouvelAvionWin: + if nouvelAvionWin: pass # zoom géré ici @@ -376,9 +357,6 @@ def main(server_ip: str): manager.process_events(event) - if menuAvion is not None: - menuAvion.checkSliders() - if conflitGen is not None: conflitGen.checkScrollBar(carte) @@ -443,10 +421,6 @@ def main(server_ip: str): pressing = False # on se débarrasse des menus inutils - if menuAvion is not None: - if not menuAvion.checkAlive(): - menuAvion = None - if menuATC is not None: if not menuATC.checkAlive(): menuATC = None diff --git a/Python/interface.py b/Python/interface.py index 0570a2b..8f4f160 100644 --- a/Python/interface.py +++ b/Python/interface.py @@ -215,200 +215,6 @@ def checkAlive(self): return self.window.alive() -class menuAvion: - - def __init__(self, avion): - self.avion = avion - self.window = self.window = pygame_gui.elements.UIWindow(pygame.Rect((400, 400), (600, 350))) - - # génération boutons heading - self.headingLabel = pygame_gui.elements.UILabel( - relative_rect=pygame.Rect((0, 17), (100, 17)), - container=self.window, - text=('Cap - ' + str(round(avion.papa.heading)))) - - self.headingContainer = pygame_gui.elements.UIScrollingContainer( - pygame.Rect((0, 34), (100, 200)), - container=self.window) - - tempo = scrollListGen(range(round(avion.papa.heading / 5) * 5 - 25, round(avion.papa.heading / 5) * 5 + 30, 5), - pygame.Rect((0, 0), (75, 17)), self.headingContainer) - - self.headingBoutonListe = tempo[1] - self.headingSlider = tempo[0] - self.headingSlider.set_scroll_from_start_percentage((round(avion.papa.heading / 5) * 5 - 15) / 300 * 0.8) - - # génération boutons Alti - self.altiLabel = pygame_gui.elements.UILabel( - relative_rect=pygame.Rect((0, 17), (100, 17)), - container=self.window, - text=('FL - ' + str(round(avion.papa.altitude / 100))), - anchors={'left': 'left', 'left_target': self.headingLabel}) - - self.altiContainer = pygame_gui.elements.UIScrollingContainer( - pygame.Rect((0, 34), (100, 200)), - container=self.window, - anchors={'left': 'left', 'left_target': self.headingContainer}) - - tempo = scrollListGen( - range(round(avion.papa.altitude / 1000) * 10 - 50, round(avion.papa.altitude / 1000) * 10 + 60, 10), - pygame.Rect((0, 0), (75, 17)), self.altiContainer) - - self.altiBoutonListe = tempo[1] - self.altiSlider = tempo[0] - - self.altiSlider.set_scroll_from_start_percentage((round(avion.papa.altitude / 1000) * 10 - 30) / 410 * 0.8) - - # génération boutons speed - self.speedLabel = pygame_gui.elements.UILabel( - relative_rect=pygame.Rect((0, 17), (100, 17)), - container=self.window, text=('IAS - ' + str(avion.papa.speedIAS)), - anchors={'left': 'left', 'left_target': self.altiLabel}) - - self.speedContainer = pygame_gui.elements.UIScrollingContainer( - pygame.Rect((0, 34), (100, 200)), - container=self.window, - anchors={'left': 'left', 'left_target': self.altiContainer}) - - tempo = scrollListGen( - range(round(avion.papa.speedIAS / 10) * 10 - 50, round(avion.papa.speedIAS / 10) * 10 + 60, 10), - pygame.Rect((0, 0), (75, 17)), self.speedContainer) - - self.speedBoutonListe = tempo[1] - self.speedSlider = tempo[0] - self.speedSlider.set_scroll_from_start_percentage((round(avion.papa.speedIAS / 10) * 10 - 100) / 330 * 0.8) - - # génération boutons points - - self.pointContainer = pygame_gui.elements.UIScrollingContainer( - pygame.Rect((0, 0), (100, 200)), - container=self.window, - anchors={'left': 'left', 'left_target': self.speedContainer}) - - tempo = scrollListGen([point['name'] for point in avion.papa.route['points']], - pygame.Rect((0, 0), (75, 17)), - self.pointContainer, - sliderBool=False) - - self.pointBoutonListe = tempo[1] - - # génération boutons next routes - - self.routeContainer = pygame_gui.elements.UIScrollingContainer( - pygame.Rect((0, 0), (100, 200)), - container=self.window, - anchors={'left': 'left', 'left_target': self.pointContainer}) - - # bouton validation - - self.validerBouton = pygame_gui.elements.UIButton( - pygame.Rect((200, 90), (75, 17)), - text='valider', - container=self.window, - anchors={'top': 'top', 'top_target': self.pointContainer}) - - # dict pour les valeurs que le menu renverra - self.returnValues = {} - - def checkAlive(self): - return self.window.alive() - - def checkSliders(self): - - """ - Change la valeur des boutons en fonction de la position du slider, pour tout le menu - """ - - selectedValue = None - if self.headingSlider.has_moved_recently: - if 'Heading' in self.returnValues: - selectedValue = self.returnValues['Heading'] - - value = round( - (360 - 5 * (len(self.headingBoutonListe) - 1)) * (self.headingSlider.start_percentage / 0.8) / 5) * 5 - for bouton in self.headingBoutonListe: - bouton.text = str(value) - bouton.rebuild() - if selectedValue == value: - bouton.disable() - else: - bouton.enable() - value += 5 - - elif self.altiSlider.has_moved_recently: - if 'Altitude' in self.returnValues: - selectedValue = self.returnValues['Altitude'] - - # la valeur de niveau oscille entre 0 et 410 - value = round( - (410 - 10 * (len(self.headingBoutonListe) - 1)) * (self.altiSlider.start_percentage / 0.8) / 10) * 10 - for bouton in self.altiBoutonListe: - bouton.text = str(value) - bouton.rebuild() - if selectedValue == value: - bouton.disable() - else: - bouton.enable() - value += 10 - - elif self.speedSlider.has_moved_recently: - if 'IAS' in self.returnValues: - selectedValue = self.returnValues['IAS'] - - value = round((330 - 10 * (len(self.headingBoutonListe) - 1)) * ( - self.speedSlider.start_percentage / 0.8) / 10) * 10 + 70 - for bouton in self.speedBoutonListe: - bouton.text = str(value) - bouton.rebuild() - if selectedValue == value: - bouton.disable() - else: - bouton.enable() - value += 10 - - def checkEvent(self, event): - - """ - Vérifie si un des boutons du menu a été pressé et modifie les données en conséquence - :arg event: l'évenement qu'il faut vérifier - :returns: le dictionaire de valeurs si on valide, None sinon - """ - - # heading - if event.ui_element in self.headingBoutonListe: - - self.returnValues.update({'Heading': int(event.ui_element.text)}) - selectButtonInList(self.headingBoutonListe, event.ui_element) - # on enlève le direct pour ne pas faire de confusion - if 'Direct' in self.returnValues: - self.returnValues.pop('Direct') - - # ALTI - elif event.ui_element in self.altiBoutonListe: - - self.returnValues.update({'Altitude': int(event.ui_element.text) * 100}) - selectButtonInList(self.altiBoutonListe, event.ui_element) - - # speed - elif event.ui_element in self.speedBoutonListe: - - selectButtonInList(self.speedBoutonListe, event.ui_element) - self.returnValues.update({'IAS': int(event.ui_element.text)}) - - # direct - elif event.ui_element in self.pointBoutonListe: - - selectButtonInList(self.pointBoutonListe, event.ui_element) - self.returnValues.update({'Direct': event.ui_element.text}) - if 'Heading' in self.returnValues: - self.returnValues.pop('Heading') - - elif event.ui_element is self.validerBouton: - - self.window.kill() - return self.avion.Id, self.returnValues - - class etiquette: def __init__(self, avion): @@ -756,13 +562,14 @@ def checkAlive(self): class menuValeurs: - def __init__(self, avion, pos: list[float, float], valeur: str): + def __init__(self, avion, pos: list[float, float] | tuple[float, float], valeur: str, pilote: bool): """ Menu utilisé par le controleur pour changer les valeurs des différents champs :param avion: :param pos: :param valeur: + :param pilote: si on est en pilote ou non """ self.avion = avion @@ -809,16 +616,16 @@ def __init__(self, avion, pos: list[float, float], valeur: str): self.liste.reverse() self.listeAff = self.liste[-7:] - elif valeur in ['XFL', 'PFL', 'CFL']: + elif valeur in ['XFL', 'PFL', 'CFL', 'FL']: self.liste = [*range(0, 600, 10)] self.liste.reverse() indexDuFL = self.liste.index(avion.papa.PFL) self.liste[indexDuFL] = "R" + str(avion.papa.PFL) self.listeAff = self.liste[indexDuFL - 4: indexDuFL + 5] - elif valeur == 'HDG': + elif valeur in ['HDG', 'C_HDG']: - cap = round(avion.papa.heading // 5) * 5 + 5 + cap = round(avion.papa.selectedHeading // 5) * 5 + 5 self.liste = [*range(5, 365, 5)] indexDuCap = self.liste.index(cap) @@ -910,7 +717,7 @@ def __init__(self, avion, pos: list[float, float], valeur: str): self.topContainer.set_dimensions((width, self.headingDCT.get_abs_rect()[3] * 2)) - if self.valeur == 'HDG': + if self.valeur in ['C_HDG', 'HDG']: listeDroite = [] listeGauche = [] @@ -1015,6 +822,16 @@ def __init__(self, avion, pos: list[float, float], valeur: str): (width, height)) + if pilote: + if self.valeur == 'DCT': + self.valeur = 'Direct' + elif self.valeur == 'C_Rate': + self.valeur = 'Rate' + elif self.valeur == 'C_IAS': + self.valeur = 'IAS' + elif self.valeur == 'C_HDG': + self.valeur = 'HDG' + def checkEvent(self, event): """ Vérifies si un event est relié à ce menu et prend les actions en conséquence @@ -1068,27 +885,30 @@ def checkEvent(self, event): elif event.ui_element == self.resume: self.kill() - if self.valeur in ['DCT', 'HDG']: # si c'est un cap, alors on veut continuer au cap - return self.avion.Id, 'HDG', ' ' + if self.valeur in ['DCT', 'C_HDG']: # si c'est un cap, alors on veut continuer au cap + return self.avion.Id, 'C_HDG', self.avion.papa.selectedHeading + + elif self.valeur in ['Direct', 'HDG']: + return self.avion.Id, 'HDG', self.avion.papa.selectedHeading else: # si c'est une rate ou IAS : on enlève return self.avion.Id, self.valeur, None elif event.ui_element == self.headingDCT: self.kill() - if self.valeur == 'HDG': + if self.valeur in ['C_HDG', 'HDG']: return 'DCT' else: - return 'HDG' + return 'C_HDG' - elif self.valeur == 'HDG': + elif self.valeur in ['C_HDG', 'HDG']: if event.ui_element in self.listeGauche: self.kill() if self.avion.papa.clearedHeading: heading = round(self.avion.papa.clearedHeading - int(event.ui_element.text[1:])) else: heading = round(self.avion.papa.selectedHeading - int(event.ui_element.text[1:])) - return self.avion.Id, 'HDG', heading + return self.avion.Id, self.valeur, heading elif event.ui_element in self.listeDroite: self.kill() @@ -1096,7 +916,7 @@ def checkEvent(self, event): heading = round(self.avion.papa.clearedHeading + int(event.ui_element.text[1:])) else: heading = round(self.avion.papa.selectedHeading + int(event.ui_element.text[1:])) - return self.avion.Id, 'HDG', heading + return self.avion.Id, self.valeur, heading def checkScrolled(self, event): """ diff --git a/Python/player.py b/Python/player.py index f62d445..20047ac 100644 --- a/Python/player.py +++ b/Python/player.py @@ -6,7 +6,6 @@ import pygame import pygame_gui -import horloge # Imports fichiers from Python.valeurs_config import * import Python.geometry as geometry @@ -430,15 +429,11 @@ def checkEvent(self, event, pilote, conflitBool): if event.mouse_button == 3 and pilote: return self.Id, 'EtatFreq', None - if event.mouse_button == 1 and pilote: - return 'menuPIL' - - elif event.mouse_button == 1: + elif event.mouse_button == 1 and pilote: return 'menuATC' elif event.mouse_button == 3 and self.papa.integreOrganique and ( - self.etiquette.indicatif.get_object_ids()[1] in ['@etiquetteBold', '@etiquetteBoldBlue'] - or pilote): # clic droit + self.etiquette.indicatif.get_object_ids()[1] in ['@etiquetteBold', '@etiquetteBoldBlue']): self.unBold() @@ -449,28 +444,31 @@ def checkEvent(self, event, pilote, conflitBool): elif event.ui_element == self.etiquette.XPT and event.mouse_button == 3 and not pilote: self.drawRouteBool = not self.drawRouteBool - elif event.ui_element == self.etiquette.XPT and event.mouse_button == 1 and not pilote: + elif event.ui_element == self.etiquette.XPT and event.mouse_button == 1: return 'XPT' - elif event.ui_element == self.etiquette.DCT and event.mouse_button == 1 and not pilote: + elif event.ui_element == self.etiquette.DCT and event.mouse_button == 1: return 'DCT' - elif event.ui_element == self.etiquette.DCT and event.mouse_button == 2 and not pilote: - return 'HDG' + elif event.ui_element == self.etiquette.DCT and event.mouse_button == 2: + return 'C_HDG' - elif event.ui_element == self.etiquette.XFL and event.mouse_button == 1 and not pilote: + elif event.ui_element == self.etiquette.XFL and event.mouse_button == 1: return 'XFL' - elif event.ui_element == self.etiquette.PFL and event.mouse_button == 1 and not pilote: + elif event.ui_element == self.etiquette.PFL and event.mouse_button == 1: return 'PFL' - elif event.ui_element == self.etiquette.CFL and event.mouse_button == 1 and not pilote: + elif event.ui_element == self.etiquette.CFL and event.mouse_button == 1: return 'CFL' - elif event.ui_element == self.etiquette.clearedSpeed and event.mouse_button == 1 and not pilote: + elif event.ui_element == self.etiquette.AFL and event.mouse_button == 1 and pilote: + return 'FL' + + elif event.ui_element == self.etiquette.clearedSpeed and event.mouse_button == 1: return 'C_IAS' - elif event.ui_element == self.etiquette.rate and event.mouse_button == 1 and not pilote: + elif event.ui_element == self.etiquette.rate and event.mouse_button == 1: return 'C_Rate' def checkEtiquetteOnHover(self): diff --git a/Python/server.py b/Python/server.py index 7d5a3dd..26aef03 100644 --- a/Python/server.py +++ b/Python/server.py @@ -435,8 +435,8 @@ def threaded_ping_responder(): elif req[1] == 'Remove': dictAvion.pop(req[0]) - elif req[1] == 'Altitude': - dictAvion[req[0]].selectedAlti = req[2] + elif req[1] == 'FL': + dictAvion[req[0]].selectedAlti = req[2] * 100 elif req[1] == 'PFL': dictAvion[req[0]].PFL = req[2] dictAvion[req[0]].changeXFL(gameMap) @@ -452,18 +452,27 @@ def threaded_ping_responder(): dictAvion[req[0]].clearedRate = req[2] else: dictAvion[req[0]].clearedRate = None + elif req[1] == 'Rate': + signe = (dictAvion[req[0]].evolution * req[2]) / abs(dictAvion[req[0]].evolution * req[2]) + dictAvion[req[0]].evolution = signe * req[2] elif req[1] == 'XFL': dictAvion[req[0]].XFL = req[2] dictAvion[req[0]].changeSortieSecteur(gameMap) elif req[1] == 'XPT': dictAvion[req[0]].XPT = req[2] - elif req[1] == 'HDG': + elif req[1] == 'C_HDG': dictAvion[req[0]].clearedHeading = req[2] - elif req[1] == 'Heading': + elif req[1] == 'HDG': + if type(req[2]) in [float, int]: + newHeading = req[2] + elif req[2][0] == '-': + newHeading = dictAvion[req[0]].selectedHeading - int(req[2][1:]) + elif req[2][0] == '+': + newHeading = dictAvion[req[0]].selectedHeading + int(req[2][1:]) dictAvion[req[0]].headingMode = True dictAvion[req[0]].selectedHeading = req[2] elif req[1] == 'IAS': - dictAvion[req[0]].selectedIAS = req[2] + dictAvion[req[0]].selectedIAS = req[2] * 10 elif req[1] == 'DCT': dictAvion[req[0]].clearedHeading = None dictAvion[req[0]].DCT = req[2] From 5902c12b26609e51cc46a91783a9e401cfd9d3a9 Mon Sep 17 00:00:00 2001 From: MaelkMaelk <65122264+MaelkMaelk@users.noreply.github.com> Date: Sun, 6 Oct 2024 23:47:09 +0200 Subject: [PATCH 3/7] feet and fic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feet : XML joli mtn (vraiment) feet : heure avion plus précise fix : generateXML refait fix : arrivées XML mieux fix : menus Cap s'ouvrent à partir de DCT --- Python/XML/simu.xml | 444 +++------------------------------------ Python/client.py | 4 +- Python/horloge.py | 13 +- Python/player.py | 2 +- Python/server.py | 230 ++++++++------------ Python/server_browser.py | 1 + Python/server_def.py | 50 +++++ 7 files changed, 189 insertions(+), 555 deletions(-) diff --git a/Python/XML/simu.xml b/Python/XML/simu.xml index 66365d6..d38a1e6 100644 --- a/Python/XML/simu.xml +++ b/Python/XML/simu.xml @@ -1,414 +1,36 @@ - - - 1100 - - - - - - - - - AZA2310 - - - A320 - - - GAI-JUVEN - - - 34000 - - - False - - - 1135.3324760807482 - - - 1228.8072431366452 - - - 340 - - - - - - - - - RYR1463 - - - B738 - - - ATN-SAMOS - - - 31000 - - - False - - - 1391.831528809085 - - - 679.2623145312475 - - - 310 - - - - - - - - - BAW2356 - - - A320 - - - ATN-VAREK - - - 33000 - - - False - - - 1273 - - - 446 - - - 330 - - - - - - - - - TAP1423 - - - B738 - - - FRI-GAI - - - 33000 - - - False - - - 1817.5277008612927 - - - 522.2153916966897 - - - 330 - - - - - - - - - IBE1223 - - - B738 - - - Depart LIML - - - 2000 - - - False - - - 2229 - - - 944 - - - 370 - - - - - - - - - HOP1203 - - - AT72 - - - ABISA-NEV - - - 32000 - - - False - - - 1283.213204244729 - - - 1062.0078521348714 - - - 320 - - - - - - - - - SWR1203 - - - A320 - - - GAI-RAPID - - - 34000 - - - True - - - 699 - - - 1341 - - - 340 - - - - - - - - - TAP2356 - - - B738 - - - FRI-GAI - - - 33000 - - - False - - - 1347.300142085819 - - - 862.4423715769826 - - - 330 - - - - - - - - - SWR3104 - - - A320 - - - GAI-RAPID - - - 32000 - - - True - - - 706.5181602549122 - - - 1339.095399402089 - - - 320 - - - - - - - - - BAW1203 - - - A320 - - - MIROS-DIRMO - - - 36000 - - - False - - - 1947 - - - 1538 - - - 360 - - - - - - - BAW123C - B738 - MIROS-DIRMO - 30000 - False - 1947 - 1538 - 300 - - - EJU1245 - A320 - Depart RETNO SAMOS - 2000 - False - 1390.5612858047484 - 761.8281404330812 - 330 - - - DLH1230 - B738 - ABISA-RAPID - 30000 - False - 1375 - 1644 - 300 - - - AFR1203 - A320 - ATN-VAREK - 30000 - False - 1273 - 446 - 300 - - - EWG1542 - A320 - FRI-GAI - 29000 - False - 1901 - 463 - 290 - - - EZY1299 - B738 - Depart MEN - 2000 - False - 1384 - 759 - 310 - - - AZA142M - B738 - GAI-JUVEN - 38000 - False - 699 - 1341 - 300 - - - TVF1236 - B738 - ATN-SAMOS - 31000 - False - 1273 - 446 - 310 - - - DAH1278 - A320 - ABISA-RAPID - 32000 - True - 1375 - 1644 - 320 - - - SWR1244 - B738 - ABISA-RAPID - 34000 - True - 1375 - 1644 - 340 - - - - + 100200 + + + FCACA + E195 + FRI-GAI + 30000 + False + 1901 + 463 + 300 + + + FCACA + B738 + MIROS-DIRMO + 30000 + False + 1848.27707757998 + 1472.4922664315754 + 300 + + + FCACA + E195 + ABISA-RAPID + 30000 + False + 1375 + 1644 + 300 + + diff --git a/Python/client.py b/Python/client.py index 2345839..4dd2e0b 100644 --- a/Python/client.py +++ b/Python/client.py @@ -240,8 +240,8 @@ def main(server_ip: str): if action: if type(action) in [list, tuple]: # si c'est un tuple alors cela correspond à une requête localRequests.append(action) - elif action in ['HDG', 'DCT']: - menuValeurs = interface.menuValeurs(menuValeurs.avion, pygame.mouse.get_pos(), action) + elif action in ['C_HDG', 'DCT']: + menuValeurs = interface.menuValeurs(menuValeurs.avion, pygame.mouse.get_pos(), action, pilote) if curseur_aliSep: for sep in sepDict: diff --git a/Python/horloge.py b/Python/horloge.py index 52643f4..6892dac 100644 --- a/Python/horloge.py +++ b/Python/horloge.py @@ -13,11 +13,22 @@ def affichageHeure(heure: float) -> str: def heureXML(heure: float) -> str: + """ + Renvoies un str avec l'heure en format hhmmss + :param heure: + :return: + """ + heures = str(round(heure // 3600 % 24)) if len(heures) == 1: heures = '0' + heures + minutes = str(round(heure % 3600 // 60)) if len(minutes) == 1: minutes = '0' + minutes - return heures + minutes + secondes = str(round(heure % 3600 % 60)) + if len(secondes) == 1: + secondes = '0' + secondes + + return heures + minutes + secondes diff --git a/Python/player.py b/Python/player.py index 20047ac..90ab4be 100644 --- a/Python/player.py +++ b/Python/player.py @@ -429,7 +429,7 @@ def checkEvent(self, event, pilote, conflitBool): if event.mouse_button == 3 and pilote: return self.Id, 'EtatFreq', None - elif event.mouse_button == 1 and pilote: + elif event.mouse_button == 1 and not pilote: return 'menuATC' elif event.mouse_button == 3 and self.papa.integreOrganique and ( diff --git a/Python/server.py b/Python/server.py index 26aef03..3cb96d4 100644 --- a/Python/server.py +++ b/Python/server.py @@ -17,6 +17,7 @@ import Python.horloge as horloge from Python.network import MCAST_GRP, MCAST_PORT, port from Python.paquets_avion import * +import Python.server_def as server_def dossierXML = Path("").absolute() / 'XML' @@ -235,7 +236,7 @@ simuTree = ET.parse(dossierXML / simu).getroot() heure = simuTree.find('heure').text - heure = int(heure[0:2]) * 3600 + int(heure[2:]) * 60 + heure = int(heure[0:2]) * 3600 + int(heure[2:4]) * 60 + int(heure[4:]) game = Game(heure) @@ -253,7 +254,7 @@ avionDict.update({XMLpoint.tag: XMLpointValue}) heureSpawn = avion.attrib['heure'] - heureSpawn = int(heureSpawn[0:2]) * 3600 + int(heureSpawn[2:]) * 60 + heureSpawn = int(heureSpawn[0:2]) * 3600 + int(heureSpawn[2:4]) * 60 + int(heureSpawn[4:]) for route in gameMap['routes']: if route == avionDict['route']: @@ -288,36 +289,6 @@ heureXML.text = horloge.heureXML(game.heure) avionsXML = ET.SubElement(simuTree, 'avions') -def generateAvionXML(parent, heureEcriture, indicatifEcriture, aircraftEcriture, routeEcriture, altitudeEcriture, xEcriture=None, yEcriture=None, headingEcriture=None, PFLEcriture=None): - - avionXML = ET.SubElement(parent, 'avion') - avionXML.set('heure', str(heureEcriture)) - - node = ET.SubElement(avionXML, 'indicatif') - node.text = str(indicatifEcriture) - node = ET.SubElement(avionXML, 'aircraft') - node.text = str(aircraftEcriture) - node = ET.SubElement(avionXML, 'route') - node.text = str(routeEcriture) - node = ET.SubElement(avionXML, 'altitude') - node.text = str(altitudeEcriture) - node = ET.SubElement(avionXML, 'arrival') - node.text = str(arrival) - - if xEcriture is not None: - node = ET.SubElement(avionXML, 'x') - node.text = str(xEcriture) - node = ET.SubElement(avionXML, 'y') - node.text = str(yEcriture) - - if headingEcriture is not None: - node = ET.SubElement(avionXML, 'heading') - node.text = str(headingEcriture) - - if PFLEcriture is not None: - node = ET.SubElement(avionXML, 'PFL') - node.text = str(PFLEcriture) - def threaded_client(conn, caca): global dictAvion @@ -385,130 +356,109 @@ def threaded_ping_responder(): requests.append(inReq) for reqSublist in requests: for req in reqSublist: # format requêtes : [Id avion, type requête, data] - if req[1] == 'Add': - req[2].Id = planeId - dictAvion.update({planeId: req[2]}) + reqType = req[1] + reqId = req[0] + reqContent = None + + if len(req) == 3: + reqContent = req[2] + + if reqType == 'Add': + + reqContent.Id = planeId + dictAvion.update({planeId: reqContent}) planeId += 1 + if mode_ecriture: + heure = horloge.heureXML(game.heure) + server_def.generateAvionXML(avionsXML, reqContent, heure) - heures = str(round(game.heure // 3600)) - if len(heures) == 1: - heures = '0' + heures - minutes = str(round(game.heure % 3600 // 60)) - if len(minutes) == 1: - minutes = '0' + minutes - - generateAvionXML(avionsXML, - heures + minutes, - req[2].indicatif, - req[2].aircraft, - req[2].route['name'], - req[2].altitude, - xEcriture=req[2].x, - yEcriture=req[2].y, - PFLEcriture=req[2].PFL) - elif req[1] == 'DelayedAdd': - - req[2][1].Id = planeId - planeId += 1 + elif reqType == 'DelayedAdd': - avionSpawnListe.append((game.heure + req[2][0], req[2][1])) + reqContent[1].Id = planeId + avionSpawnListe.append((game.heure + reqContent[0], reqContent[1])) + planeId += 1 if mode_ecriture: - - heures = str(round((game.heure + req[2][0]) // 3600)) - if len(heures) == 1: - heures = '0' + heures - minutes = str(round((game.heure + req[2][0]) % 3600 // 60)) - if len(minutes) == 1: - minutes = '0' + minutes - - generateAvionXML(avionsXML, - heures + minutes, - req[2][1].indicatif, - req[2][1].aircraft, - req[2][1].route['name'], - req[2][1].altitude, - xEcriture=req[2][1].x, - yEcriture=req[2][1].y, - PFLEcriture=req[2][1].PFL) - - elif req[1] == 'Remove': - dictAvion.pop(req[0]) - elif req[1] == 'FL': - dictAvion[req[0]].selectedAlti = req[2] * 100 - elif req[1] == 'PFL': - dictAvion[req[0]].PFL = req[2] - dictAvion[req[0]].changeXFL(gameMap) - elif req[1] == 'CFL': - dictAvion[req[0]].CFL = req[2] - elif req[1] == 'C_IAS': + heure = horloge.heureXML(game.heure) + server_def.generateAvionXML(avionsXML, reqContent, heure) + + elif reqType == 'Remove': + dictAvion.pop(reqId) + elif reqType == 'FL': + dictAvion[reqId].selectedAlti = reqContent * 100 + elif reqType == 'PFL': + dictAvion[reqId].PFL = reqContent + dictAvion[reqId].changeXFL(gameMap) + elif reqType == 'CFL': + dictAvion[reqId].CFL = reqContent + elif reqType == 'C_IAS': if len(req) == 3: - dictAvion[req[0]].clearedIAS = req[2] + dictAvion[reqId].clearedIAS = reqContent else: - dictAvion[req[0]].clearedIAS = None - elif req[1] == 'C_Rate': + dictAvion[reqId].clearedIAS = None + elif reqType == 'C_Rate': if len(req) == 3: - dictAvion[req[0]].clearedRate = req[2] + dictAvion[reqId].clearedRate = reqContent else: - dictAvion[req[0]].clearedRate = None - elif req[1] == 'Rate': - signe = (dictAvion[req[0]].evolution * req[2]) / abs(dictAvion[req[0]].evolution * req[2]) - dictAvion[req[0]].evolution = signe * req[2] - elif req[1] == 'XFL': - dictAvion[req[0]].XFL = req[2] - dictAvion[req[0]].changeSortieSecteur(gameMap) - elif req[1] == 'XPT': - dictAvion[req[0]].XPT = req[2] - elif req[1] == 'C_HDG': - dictAvion[req[0]].clearedHeading = req[2] - elif req[1] == 'HDG': - if type(req[2]) in [float, int]: - newHeading = req[2] - elif req[2][0] == '-': - newHeading = dictAvion[req[0]].selectedHeading - int(req[2][1:]) - elif req[2][0] == '+': - newHeading = dictAvion[req[0]].selectedHeading + int(req[2][1:]) - dictAvion[req[0]].headingMode = True - dictAvion[req[0]].selectedHeading = req[2] - elif req[1] == 'IAS': - dictAvion[req[0]].selectedIAS = req[2] * 10 - elif req[1] == 'DCT': - dictAvion[req[0]].clearedHeading = None - dictAvion[req[0]].DCT = req[2] - elif req[1] == 'Warning': - dictAvion[req[0]].warning = not dictAvion[req[0]].warning - elif req[1] == 'Integre': - dictAvion[req[0]].integreOrganique = True - elif req[1] == 'Direct': - dictAvion[req[0]].headingMode = False - for point in dictAvion[req[0]].route['points']: - if point['name'] == req[2]: - dictAvion[req[0]].nextPoint = point + dictAvion[reqId].clearedRate = None + elif reqType == 'Rate': + signe = (dictAvion[reqId].evolution * reqContent) / abs(dictAvion[reqId].evolution * reqContent) + dictAvion[reqId].evolution = signe * reqContent + elif reqType == 'XFL': + dictAvion[reqId].XFL = reqContent + dictAvion[reqId].changeSortieSecteur(gameMap) + elif reqType == 'XPT': + dictAvion[reqId].XPT = reqContent + elif reqType == 'C_HDG': + dictAvion[reqId].clearedHeading = reqContent + elif reqType == 'HDG': + if type(reqContent) in [float, int]: + newHeading = reqContent + elif reqContent[0] == '-': + newHeading = dictAvion[reqId].selectedHeading - int(reqContent[1:]) + elif reqContent[0] == '+': + newHeading = dictAvion[reqId].selectedHeading + int(reqContent[1:]) + dictAvion[reqId].headingMode = True + dictAvion[reqId].selectedHeading = reqContent + elif reqType == 'IAS': + dictAvion[reqId].selectedIAS = reqContent * 10 + elif reqType == 'DCT': + dictAvion[reqId].clearedHeading = None + dictAvion[reqId].DCT = reqContent + elif reqType == 'Warning': + dictAvion[reqId].warning = not dictAvion[reqId].warning + elif reqType == 'Integre': + dictAvion[reqId].integreOrganique = True + elif reqType == 'Direct': + dictAvion[reqId].headingMode = False + for point in dictAvion[reqId].route['points']: + if point['name'] == reqContent: + dictAvion[reqId].nextPoint = point break - elif req[1] == 'Route': - dictAvion[req[0]].nextRoute = req[2] - dictAvion[req[0]].changeRoute(gameMap) - elif req[1] == 'HighlightBouton': - if req[2] in dictAvion[req[0]].boutonsHighlight: # si le bouton est déjà highlight alors: - dictAvion[req[0]].boutonsHighlight.remove(req[2]) + elif reqType == 'Route': + dictAvion[reqId].nextRoute = reqContent + dictAvion[reqId].changeRoute(gameMap) + elif reqType == 'HighlightBouton': + if reqContent in dictAvion[reqId].boutonsHighlight: # si le bouton est déjà highlight alors: + dictAvion[reqId].boutonsHighlight.remove(reqContent) else: - dictAvion[req[0]].boutonsHighlight.append(req[2]) - elif req[1] == 'Montrer': - dictAvion[req[0]].montrer = not dictAvion[req[0]].montrer - elif req[1] == 'EtatFreq': - dictAvion[req[0]].updateEtatFreq(req[2]) - elif req[1] == 'FL?': - dictAvion[req[0]].FLInterro = not dictAvion[req[0]].FLInterro - elif req[1] == 'Pause': + dictAvion[reqId].boutonsHighlight.append(reqContent) + elif reqType == 'Montrer': + dictAvion[reqId].montrer = not dictAvion[reqId].montrer + elif reqType == 'EtatFreq': + dictAvion[reqId].updateEtatFreq(reqContent) + elif reqType == 'FL?': + dictAvion[reqId].FLInterro = not dictAvion[reqId].FLInterro + elif reqType == 'Pause': game.paused = not game.paused - elif req[1] == 'Faster': + elif reqType == 'Faster': accelerationTemporelle += 0.5 - elif req[1] == 'Slower': + elif reqType == 'Slower': if accelerationTemporelle > 0.5: accelerationTemporelle -= 0.5 - elif req[1] == 'Save' and mode_ecriture: - xmlstr = minidom.parseString(ET.tostring(simuTree)).toprettyxml(indent=" ") + elif reqType == 'Save' and mode_ecriture: + xmlstr = server_def.prettyPrint(minidom.parseString(ET.tostring(simuTree))) with open("XML/simu.xml", "w") as f: f.write(xmlstr) diff --git a/Python/server_browser.py b/Python/server_browser.py index 3439d59..ea06345 100644 --- a/Python/server_browser.py +++ b/Python/server_browser.py @@ -5,6 +5,7 @@ # Imports fichiers from Python.network import MCAST_GRP, MCAST_PORT + def serverBrowser(): """Lan scan et server browser en une fonction renvoie une adresse IP en str""" diff --git a/Python/server_def.py b/Python/server_def.py index 88c01fb..204949b 100644 --- a/Python/server_def.py +++ b/Python/server_def.py @@ -2,6 +2,9 @@ # Native imports import math +# Module imports +import xml.etree.ElementTree as ET + # Imports fichiers import Python.geometry as geometry from Python.valeurs_config import * @@ -39,3 +42,50 @@ def STCA(avion1, avion2, carte) -> bool: return False +def generateAvionXML(parentNode, avion, heureXML): + + """ + Transforme un avion packet en un element XML + :param parentNode: La node XML dans laquelle on va inscrire notre nouvel avion + :param avion: L'avion Packet qu'il faut transformer en XML + :param heureXML: + :return: + """ + + avionXML = ET.SubElement(parentNode, 'avion') + avionXML.set('heure', str(heureXML)) + + node = ET.SubElement(avionXML, 'indicatif') + node.text = str(avion.indicatif) + node = ET.SubElement(avionXML, 'aircraft') + node.text = str(avion.aircraft) + node = ET.SubElement(avionXML, 'route') + node.text = str(avion.route['name']) + node = ET.SubElement(avionXML, 'altitude') + node.text = str(avion.altitude) + node = ET.SubElement(avionXML, 'arrival') + node.text = str(avion.arrival) + + node = ET.SubElement(avionXML, 'x') + node.text = str(avion.x) + node = ET.SubElement(avionXML, 'y') + node.text = str(avion.y) + + node = ET.SubElement(avionXML, 'PFL') + node.text = str(avion.PFL) + + +def prettyPrint(docXML): + """ + Rend le XML joli à regarder + :param docXML: le doc XML à transformer + :return: + """ + + XMLstring = '' + + for line in docXML.toprettyxml().split('\n'): + if not line.strip() == '': + XMLstring += line + '\n' + + return XMLstring From 330e500868f01859b6dff8624ebecc2e1f209459 Mon Sep 17 00:00:00 2001 From: MaelkMaelk <65122264+MaelkMaelk@users.noreply.github.com> Date: Mon, 7 Oct 2024 11:31:46 +0200 Subject: [PATCH 4/7] mach number --- Python/paquets_avion.py | 34 ++++++++++++++- Python/server.py | 90 ++++++++++++++++++---------------------- Python/valeurs_config.py | 2 + 3 files changed, 74 insertions(+), 52 deletions(-) diff --git a/Python/paquets_avion.py b/Python/paquets_avion.py index 5c536ca..7fbf8e2 100644 --- a/Python/paquets_avion.py +++ b/Python/paquets_avion.py @@ -1,4 +1,4 @@ - +import math # Native imports import random @@ -7,6 +7,33 @@ from Python.valeurs_config import * +def densite_de_l_air(altitude: float) -> float: + """ + Cacule la densité de l'air à cette altitude + :param altitude: en ft + :return: + """ + + altitude = 0.3048 * altitude + densite = 352.995 * (1 - 0.0000225577 * altitude) ** 5.25516 / (288.15 - 0.0065 * altitude) + + return densite + + +def trueAirSpeed(IAS: float, densite: float) -> float: + + return IAS * math.sqrt(densite_air_surface / densite) + + +def machNumber(TAS, altitude): + + temperature = 15 - altitude / 500 + 273.15 + if temperature <= 217.15: + temperature = 217.15 + + return TAS / math.sqrt(TAS_to_mach_yR * temperature) + + class Game: def __init__(self, heure): self.ready = False @@ -53,6 +80,10 @@ def __init__(self, gameMap, Id, indicatif, aircraft, perfos, route, arrival, FL= self.altitude = altiDefault self.speedIAS = perfos['IAS'] + densite = densite_de_l_air(self.altitude) + self.TAS = trueAirSpeed(self.speedIAS, densite) + self.mach = machNumber(self.TAS, self.altitude) + print(self.mach) self.speedGS = self.speedIAS + self.altitude / 200 # la GS dépends de l'alti self.speedPx = self.speedGS / gameMap['mapScale'] * heureEnRefresh @@ -160,7 +191,6 @@ def __init__(self, gameMap, Id, indicatif, aircraft, perfos, route, arrival, FL= self.selectedAlti = self.CFL * 100 self.selectedHeading = self.heading self.selectedIAS = self.speedIAS - self.mach = self.speedIAS self.clearedIAS = None self.clearedMach = None self.clearedHeading = None diff --git a/Python/server.py b/Python/server.py index 3cb96d4..8d3f31b 100644 --- a/Python/server.py +++ b/Python/server.py @@ -231,63 +231,53 @@ planeId = 0 simuTree = None -try: # on essaye de charger une simu, si elle existe - simuTree = ET.parse(dossierXML / simu).getroot() - heure = simuTree.find('heure').text - heure = int(heure[0:2]) * 3600 + int(heure[2:4]) * 60 + int(heure[4:]) +simuTree = ET.parse(dossierXML / simu).getroot() - game = Game(heure) +heure = simuTree.find('heure').text +heure = int(heure[0:2]) * 3600 + int(heure[2:4]) * 60 + int(heure[4:]) - avionSpawnListe = [] - avionsXML = simuTree.find('avions') - for avion in avionsXML: +game = Game(heure) - avionDict = {} +avionSpawnListe = [] +avionsXML = simuTree.find('avions') +for avion in avionsXML: - for XMLpoint in avion: - try: - XMLpointValue = float(XMLpoint.text) - except: - XMLpointValue = XMLpoint.text - avionDict.update({XMLpoint.tag: XMLpointValue}) - - heureSpawn = avion.attrib['heure'] - heureSpawn = int(heureSpawn[0:2]) * 3600 + int(heureSpawn[2:4]) * 60 + int(heureSpawn[4:]) + avionDict = {} - for route in gameMap['routes']: - if route == avionDict['route']: - spawnRoute = gameMap['routes'][route] - break - if 'altitude' in avionDict: - spawnFL = round(avionDict['altitude'] / 100) - else: - spawnFL = None - avionPack = AvionPacket( - gameMap, - planeId, - avionDict['indicatif'], - avionDict['aircraft'], - aircraftType[avionDict['aircraft']], - spawnRoute, - avionDict['arrival'] == 'True', - FL=spawnFL, - x=avionDict['x'], - y=avionDict['y']) - planeId += 1 - - avionSpawnListe.append((heureSpawn, avionPack)) -except: # sinon, on demande juste l'heure de début - - heure = input('Heure de début de simu, format: hhmm') - heure = int(heure[0:2]) * 3600 + int(heure[2:]) * 60 - avionSpawnListe = [] - simuTree = ET.Element('simu') - game = Game(heure) - heureXML = ET.SubElement(simuTree, 'heure') - heureXML.text = horloge.heureXML(game.heure) - avionsXML = ET.SubElement(simuTree, 'avions') + for XMLpoint in avion: + try: + XMLpointValue = float(XMLpoint.text) + except: + XMLpointValue = XMLpoint.text + avionDict.update({XMLpoint.tag: XMLpointValue}) + + heureSpawn = avion.attrib['heure'] + heureSpawn = int(heureSpawn[0:2]) * 3600 + int(heureSpawn[2:4]) * 60 + int(heureSpawn[4:]) + + for route in gameMap['routes']: + if route == avionDict['route']: + spawnRoute = gameMap['routes'][route] + break + if 'altitude' in avionDict: + spawnFL = round(avionDict['altitude'] / 100) + else: + spawnFL = None + avionPack = AvionPacket( + gameMap, + planeId, + avionDict['indicatif'], + avionDict['aircraft'], + aircraftType[avionDict['aircraft']], + spawnRoute, + avionDict['arrival'] == 'True', + FL=spawnFL, + x=avionDict['x'], + y=avionDict['y']) + planeId += 1 + + avionSpawnListe.append((heureSpawn, avionPack)) def threaded_client(conn, caca): diff --git a/Python/valeurs_config.py b/Python/valeurs_config.py index b6a6cf1..b481360 100644 --- a/Python/valeurs_config.py +++ b/Python/valeurs_config.py @@ -11,3 +11,5 @@ dragDelay = 150 # on utilise cette valeur seuil pour déterminer si on doit cliquer sur un bouton ou drag l'etiquette offsettEtiquetteDefault = 30 # de combien les etiquettes sont décalées en px à quand on les dessine la 1ere fois temps_disparition_menus = 300 # en combien de milli sec les menus disparaissent après ne plus être survolé +TAS_to_mach_yR = 287.052874 * 1.4 +densite_air_surface = 1.225 From a3ffb3e18e55fd1c0edc0a883e0578c95b154bbe Mon Sep 17 00:00:00 2001 From: MaelkMaelk <65122264+MaelkMaelk@users.noreply.github.com> Date: Mon, 7 Oct 2024 22:11:13 +0200 Subject: [PATCH 5/7] =?UTF-8?q?d=C3=A9but=20mach=20et=20perfos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit menus mach nickel, transition mach IAS à travailler --- Python/XML/aircraft.xml | 285 +++++++++++++++++++++++++++++------- Python/XML/carteSecteur.xml | 8 +- Python/XML/simu.xml | 26 +--- Python/client.py | 2 +- Python/interface.py | 31 +++- Python/paquets_avion.py | 184 ++++++++++++++++------- Python/server.py | 14 +- Python/valeurs_config.py | 7 +- Python/vitesses.py | 94 ++++++++++++ 9 files changed, 509 insertions(+), 142 deletions(-) create mode 100644 Python/vitesses.py diff --git a/Python/XML/aircraft.xml b/Python/XML/aircraft.xml index b8dfd30..100b686 100644 --- a/Python/XML/aircraft.xml +++ b/Python/XML/aircraft.xml @@ -3,62 +3,235 @@ - - 280 - 410 - 2000 - 3000 - - - 200 - 450 - 1500 - 2000 - - - 280 - 410 - 2000 - 2500 - - - 240 - 450 - 1300 - 1700 - - - 250 - 450 - 2000 - 3000 - - - 310 - 550 - 2000 - 2500 - - - 210 - 550 - 2000 - 2500 - - - 280 - 550 - 1500 - 2000 - - - 280 - 550 - 2500 - 3000 - - - + + 0.74 + 0.70 + 0.74 + + 270 + 270 + + 280 + + 1000 + 1500 + + 2500 + 2500 + + 3500 + + + + 0.79 + 0.78 + 0.78 + + 290 + 290 + + 280 + + 1500 + 800 + + 2000 + 2000 + + 3500 + + + + 0.79 + 0.76 + 0.76 + + 290 + 290 + + 290 + + 1000 + 800 + + 2000 + 2000 + + 3500 + + + + 0.79 + 0.78 + 0.78 + + 290 + 290 + + 290 + + 1000 + 800 + + 1500 + 2200 + + 3500 + + + + 0.79 + 0.78 + 0.78 + + 290 + 290 + + 290 + + 1000 + 800 + + 1400 + 2000 + + 3500 + + + + 0.79 + 0.78 + 0.78 + + 290 + 290 + + 290 + + 1000 + 1000 + + 1800 + 2000 + + 2500 + + + + 0.78 + 0.78 + 0.78 + + 290 + 290 + + 290 + + 1000 + 1000 + + 1500 + 2300 + + 2500 + + + + 0.78 + 0.78 + 0.78 + + 290 + 290 + + 290 + + 1000 + 1000 + + 1500 + 2100 + + 2500 + + + + 0.78 + 0.78 + 0.78 + + 290 + 290 + + 290 + + 1000 + 1500 + + 1200 + 1800 + + 2500 + + + + 0.81 + 0.80 + 0.81 + + 290 + 290 + + 290 + + 1200 + 1500 + + 1200 + 1500 + + 2500 + + + + 0.84 + 0.82 + 0.84 + + 300 + 300 + + 300 + + 1500 + 1000 + + 2000 + 2500 + + 2500 + + + + 0.46 + 0.46 + 0.46 + + 200 + 200 + + 240 + + 1000 + 1500 + + 1500 + 1000 + + 1500 + + + AIGLE AZUR diff --git a/Python/XML/carteSecteur.xml b/Python/XML/carteSecteur.xml index ba3c058..931d434 100644 --- a/Python/XML/carteSecteur.xml +++ b/Python/XML/carteSecteur.xml @@ -771,7 +771,7 @@ S BST - 20 + 50 LSE @@ -802,7 +802,7 @@ SE BST - 20 + 50 LSE @@ -836,7 +836,7 @@ SE BST - 20 + 50 LSE @@ -867,7 +867,7 @@ SO BST - 20 + 50 LSE diff --git a/Python/XML/simu.xml b/Python/XML/simu.xml index d38a1e6..ead6d33 100644 --- a/Python/XML/simu.xml +++ b/Python/XML/simu.xml @@ -2,35 +2,15 @@ 100200 - + FCACA - E195 + B738 FRI-GAI - 30000 + 26000 False 1901 463 300 - - FCACA - B738 - MIROS-DIRMO - 30000 - False - 1848.27707757998 - 1472.4922664315754 - 300 - - - FCACA - E195 - ABISA-RAPID - 30000 - False - 1375 - 1644 - 300 - diff --git a/Python/client.py b/Python/client.py index 4dd2e0b..fab957f 100644 --- a/Python/client.py +++ b/Python/client.py @@ -240,7 +240,7 @@ def main(server_ip: str): if action: if type(action) in [list, tuple]: # si c'est un tuple alors cela correspond à une requête localRequests.append(action) - elif action in ['C_HDG', 'DCT']: + elif type(action) is str: menuValeurs = interface.menuValeurs(menuValeurs.avion, pygame.mouse.get_pos(), action, pilote) if curseur_aliSep: diff --git a/Python/interface.py b/Python/interface.py index 8f4f160..6f3c312 100644 --- a/Python/interface.py +++ b/Python/interface.py @@ -611,6 +611,17 @@ def __init__(self, avion, pos: list[float, float] | tuple[float, float], valeur: indexDeVitesse = self.liste.index(round(avion.papa.speedIAS / 10)) self.listeAff = self.liste[indexDeVitesse - 4: indexDeVitesse + 5] + elif valeur == 'C_Mach': + self.liste = [*range(30, 99)] + self.liste.reverse() + + for i in range(len(self.liste)): + self.liste[i] = self.liste[i] / 100 + + indexDeVitesse = self.liste.index(round(avion.papa.mach, 2)) + + self.listeAff = self.liste[indexDeVitesse - 4: indexDeVitesse + 5] + elif valeur == 'C_Rate': self.liste = [*range(500, 6000, 500)] self.liste.reverse() @@ -649,7 +660,7 @@ def __init__(self, avion, pos: list[float, float] | tuple[float, float], valeur: self.plusBouton = None self.moinsBouton = None - if valeur == 'C_IAS': + if valeur in ['C_IAS', 'C_Mach']: self.noeud = pygame_gui.elements.UIButton( pygame.Rect((0, 0), (width / 2, -1)), container=self.topContainer, @@ -822,6 +833,11 @@ def __init__(self, avion, pos: list[float, float] | tuple[float, float], valeur: (width, height)) + if self.valeur == 'C_IAS': + self.noeud.select() + elif self.valeur == 'C_Mach': + self.mach.select() + if pilote: if self.valeur == 'DCT': self.valeur = 'Direct' @@ -829,6 +845,8 @@ def __init__(self, avion, pos: list[float, float] | tuple[float, float], valeur: self.valeur = 'Rate' elif self.valeur == 'C_IAS': self.valeur = 'IAS' + elif self.valeur == 'C_Mach': + self.valeur = 'Mach' elif self.valeur == 'C_HDG': self.valeur = 'HDG' @@ -883,6 +901,16 @@ def checkEvent(self, event): self.moinsBouton.select() self.plusBouton.unselect() + elif event.ui_element == self.noeud: + if self.mach.is_selected: + self.kill() + return 'C_IAS' + + elif event.ui_element == self.mach: + if self.noeud.is_selected: + self.kill() + return 'C_Mach' + elif event.ui_element == self.resume: self.kill() if self.valeur in ['DCT', 'C_HDG']: # si c'est un cap, alors on veut continuer au cap @@ -918,6 +946,7 @@ def checkEvent(self, event): heading = round(self.avion.papa.selectedHeading + int(event.ui_element.text[1:])) return self.avion.Id, self.valeur, heading + def checkScrolled(self, event): """ Vérifie si le menu est en train d'être scrollé diff --git a/Python/paquets_avion.py b/Python/paquets_avion.py index 7fbf8e2..119384f 100644 --- a/Python/paquets_avion.py +++ b/Python/paquets_avion.py @@ -5,33 +5,7 @@ # Imports fichiers from Python.geometry import * from Python.valeurs_config import * - - -def densite_de_l_air(altitude: float) -> float: - """ - Cacule la densité de l'air à cette altitude - :param altitude: en ft - :return: - """ - - altitude = 0.3048 * altitude - densite = 352.995 * (1 - 0.0000225577 * altitude) ** 5.25516 / (288.15 - 0.0065 * altitude) - - return densite - - -def trueAirSpeed(IAS: float, densite: float) -> float: - - return IAS * math.sqrt(densite_air_surface / densite) - - -def machNumber(TAS, altitude): - - temperature = 15 - altitude / 500 + 273.15 - if temperature <= 217.15: - temperature = 217.15 - - return TAS / math.sqrt(TAS_to_mach_yR * temperature) +import Python.vitesses as vitesses class Game: @@ -79,13 +53,8 @@ def __init__(self, gameMap, Id, indicatif, aircraft, perfos, route, arrival, FL= else: self.altitude = altiDefault - self.speedIAS = perfos['IAS'] - densite = densite_de_l_air(self.altitude) - self.TAS = trueAirSpeed(self.speedIAS, densite) - self.mach = machNumber(self.TAS, self.altitude) - print(self.mach) - self.speedGS = self.speedIAS + self.altitude / 200 # la GS dépends de l'alti - self.speedPx = self.speedGS / gameMap['mapScale'] * heureEnRefresh + self.evolution = 0 # taux de variation/radar refresh + self.altitudeEvoTxt = '-' # RADAR display self.warning = False @@ -119,11 +88,6 @@ def __init__(self, gameMap, Id, indicatif, aircraft, perfos, route, arrival, FL= else: self.destination = random.choice(gameMap['aeroports'][route['destination']]) - # perfo - self.turnRate = turnRateDefault - self.maxROC = perfos['ROC'] - self.maxROD = perfos['ROD'] - # format route {nomRoute, routeType, listeRoutePoints, sortie} points : {caractéristiques eg : nom alti IAS} self.route = route @@ -132,8 +96,6 @@ def __init__(self, gameMap, Id, indicatif, aircraft, perfos, route, arrival, FL= self.nextPoint = None self.findNextPoint(gameMap) - self.evolution = 0 # taux de variation/radar refresh - self.altitudeEvoTxt = '-' if PFL is not None: self.PFL = PFL elif gameMap['floor'] < self.altitude/100 < gameMap['ceiling']: @@ -187,15 +149,36 @@ def __init__(self, gameMap, Id, indicatif, aircraft, perfos, route, arrival, FL= gameMap['points'][self.nextPoint['name']][1]) self.headingRad = (self.heading - 90) / 180 * math.pi - # selected + # perfo + self.turnRate = turnRateDefault + self.perfos = perfos + self.forcedSpeed = False + self.forcedEvo = False + self.machMode = False + self.changeSpeed() + + # selected + vitesses + if self.machMode: + self.speedIAS = self.perfos['descentIAS'] + self.selectedIAS = self.perfos['descentIAS'] + self.mach = self.selectedMach + else: + self.speedIAS = self.selectedIAS + self.mach = vitesses.IAS_to_Mach(self.speedIAS, self.altitude) + + self.speedTAS = vitesses.mach_to_TAS(self.mach, self.altitude) + self.speedGS = self.speedTAS + self.selectedAlti = self.CFL * 100 self.selectedHeading = self.heading - self.selectedIAS = self.speedIAS + self.selectedMach = self.mach self.clearedIAS = None self.clearedMach = None self.clearedHeading = None self.clearedRate = None + self.speedPx = self.speedGS / gameMap['mapScale'] * heureEnRefresh + def findNextPoint(self, carte): self.nextPoint = findClosestSegment(self.route['points'], (self.x, self.y), carte['points'])[1] @@ -247,7 +230,6 @@ def updateAlti(self): if self.altitude != self.selectedAlti: # on regarde s'il faut évoluer if self.altitude - self.selectedAlti > 0: - self.evolution = - self.maxROD # on arrive dans moins d'un refresh ? if abs(self.altitude - self.selectedAlti) <= abs(self.evolution / 60 * radarRefresh): @@ -257,8 +239,6 @@ def updateAlti(self): self.altitudeEvoTxt = '↓' else: - self.evolution = self.maxROC - # on arrive dans moins d'un refresh ? if abs(self.altitude - self.selectedAlti) <= abs(self.evolution / 60 * radarRefresh): self.altitude = self.selectedAlti # alors, on met le niveau cible @@ -270,6 +250,42 @@ def updateAlti(self): self.altitudeEvoTxt = '-' self.evolution = 0 + def changeEvolution(self) -> None: + """ + Sélectionne la vitesse en fonction de la phase de vol + :return: + """ + + if self.forcedEvo: + return None + + if self.altitude >= altitude_conversion: + # ici, on prend les perfos en croisière + + if self.selectedAlti < self.altitude: + self.evolution = - self.perfos['cruiseROD'] + + else: + self.evolution = self.perfos['cruiseROC'] + + elif self.altitude >= altitude_cruise: + # ici, on regarde si on est en montée/descente ou alors, si on approche du niveau de croisière + + if self.selectedAlti < self.altitude: + self.evolution = - self.perfos['cruiseROD'] + + else: + self.evolution = self.perfos['climbROC'] + + else: + # ici, on est dans les basses couches donc on prend les perfos en basse alti + + if self.selectedAlti < self.altitude: + self.evolution = - self.perfos['descentROD'] + + else: + self.evolution = self.perfos['initialClimbROC'] + def move(self, gameMap): # frequence update @@ -313,19 +329,87 @@ def move(self, gameMap): self.comete = self.comete[1:9] self.comete.append((self.x, self.y)) + self.changeEvolution() self.updateAlti() # on change le niveau de l'avion si on est en evolution - if self.speedIAS != self.selectedIAS: # s'il faut accélérer ou ralentir - # on change la vitesse par un pas d'accél/deccel défaut - self.speedIAS += (self.selectedIAS - self.speedIAS)/abs(self.selectedIAS - self.speedIAS) * acceldefault + self.changeSpeed() + self.computeSpeed() - self.speedGS = self.speedIAS + self.altitude / 200 self.speedPx = self.speedGS / gameMap['mapScale'] * heureEnRefresh # on convertit les kt en px/refresh # mouvement self.x += self.speedPx * math.cos(self.headingRad) self.y += self.speedPx * math.sin(self.headingRad) + def computeSpeed(self): + + """ + Fait évoluer la vitesse si on a besoin + :return: + """ + if not self.machMode: + if self.speedIAS != self.selectedIAS: # s'il faut accélérer ou ralentir + # on change la vitesse par un pas d'accél/deccel défaut + if abs(self.selectedIAS - self.speedIAS) <= acceldefault: + self.speedIAS = self.selectedIAS + else: + self.speedIAS += (self.selectedIAS - self.speedIAS)/abs(self.selectedIAS - self.speedIAS) * acceldefault + + self.mach = vitesses.IAS_to_Mach(self.speedIAS, self.altitude) + else: + if self.mach != self.selectedMach: + # on change la vitesse par un pas d'accél/deccel défaut + if abs(self.selectedMach - self.mach) <= acceldefaultMach: + self.mach = self.selectedMach + else: + self.mach += (self.selectedMach - self.mach) / abs(self.selectedMach - self.mach) * acceldefaultMach + + self.speedTAS = vitesses.mach_to_TAS(self.mach, self.altitude) + self.speedGS = self.speedTAS + + def changeSpeed(self) -> None: + """ + Sélectionne la vitesse en fonction de la phase de vol + :return: + """ + + self.machMode = False + + if self.forcedSpeed: + return None + + if self.altitude >= altitude_conversion: # au-dessus de l'alti de conversion tout se fera en mach + + self.machMode = True + + if self.evolution == 0: + self.selectedMach = self.perfos['cruiseMach'] + + elif self.evolution < 0: + self.selectedMach = self.perfos['descentMach'] + + else: + self.selectedMach = self.perfos['climbMach'] + + elif self.altitude >= altitude_cruise: # en-dessous de l'alti de conversion tout se fera en IAS + # ici, on regarde si on est en montée/descente initiale ou alors, si on approche du niveau de croisière + + if self.evolution <= 0: # on prend les perfs de descente pour la croisière (pas trouvé de perfo IAS cruise) + self.selectedIAS = self.perfos['descentIAS'] + + else: + self.selectedIAS = self.perfos['climbIAS'] + + else: + # ici, on est dans les basses couches donc on prend les perfos en basse alti + + if self.evolution <= 0: + self.selectedIAS = self.perfos['descentIAS'] + # les perfos sont les mêmes pendant la majorité de la descente d'où le manque de 240 + + else: + self.selectedIAS = self.perfos['initialClimbIAS'] + def calculeEstimate(self, points: dict, pointVoulu: str) -> float: """ Calcule le temps à un point sur notre route. Pour avoir l'estimée, il faudra rajouter l'heure courante diff --git a/Python/server.py b/Python/server.py index 8d3f31b..72141b2 100644 --- a/Python/server.py +++ b/Python/server.py @@ -217,11 +217,17 @@ root = tree.getroot() for aircraft in root.find('aircrafts'): + + aircraftPerf = {} + for XMLpoint in aircraft: + try: + XMLpointValue = float(XMLpoint.text) + except: + XMLpointValue = XMLpoint.text + aircraftPerf.update({XMLpoint.tag: XMLpointValue}) + aircraftType.update( - {aircraft.attrib['name']: {'IAS': int(aircraft.find('speed').text), - 'plafond': int(aircraft.find('ceiling').text), - 'ROC': int(aircraft.find('ROC').text), - 'ROD': int(aircraft.find('ROD').text)}}) + {aircraft.attrib['name']: aircraftPerf}) callsignList = {} for callsign in root.find('callsigns'): diff --git a/Python/valeurs_config.py b/Python/valeurs_config.py index b481360..9014775 100644 --- a/Python/valeurs_config.py +++ b/Python/valeurs_config.py @@ -3,7 +3,8 @@ nmToFeet = 6076 secteurDefault = 'RU' # secteur par défault, si le programme n'arrive pas à trouver un secteur de sortie altiDefault = 30000 # alti en pied par défault, si on ne rentre pas d'alti pour spawn un avion -acceldefault = 3 # accélération/decelération de kt par refresh +acceldefault = 3 # accélération/decelération en kt par refresh +acceldefaultMach = 0.003 # accélération/decelération en point de mach par refresh turnRateDefault = 10 # turnrate/refresh par défault liste_etat_freq = ['previousFreq', 'previousShoot', 'inFreq', 'nextCoord', 'nextShoot', 'nextFreq'] valeurCoord = 8 # combien de minute avant la sortie la coord passe @@ -11,5 +12,5 @@ dragDelay = 150 # on utilise cette valeur seuil pour déterminer si on doit cliquer sur un bouton ou drag l'etiquette offsettEtiquetteDefault = 30 # de combien les etiquettes sont décalées en px à quand on les dessine la 1ere fois temps_disparition_menus = 300 # en combien de milli sec les menus disparaissent après ne plus être survolé -TAS_to_mach_yR = 287.052874 * 1.4 -densite_air_surface = 1.225 +altitude_conversion = 27900 +altitude_cruise = 25000 diff --git a/Python/vitesses.py b/Python/vitesses.py new file mode 100644 index 0000000..7e56c33 --- /dev/null +++ b/Python/vitesses.py @@ -0,0 +1,94 @@ + +# Native imports +from math import sqrt + +ms_per_kt = 0.51444 +feet_per_metre = 3.28 + +# Some useful constants + +g = 9.81 # Acceleration due to gravity +R = 287 # Specific gas constant for air +L = 0.0065 # Lapse rate in K/m +T0 = 288.15 # ISA sea level temp in K +p0 = 101325 # ISA sea level pressure in Pa +k = 1.4 # k is a shorthand for Gamma, the ratio of specific heats for air +lss0 = sqrt(k*R*T0) # ISA sea level speed sound + + +def compressible_pitot(M): + """ + Renvoies un delta de pression en fonction d'un mach + :param M: + :return: + """ + + return (M*M*(k-1)/2 + 1) ** (k/(k-1)) - 1 + + +def pitot_to_Mach(d): + """ + Retourne un machNumber en fonction d'un delta de pression + :param d: + :return: + """ + return sqrt(((d+1)**((k-1)/k) - 1)*2/(k-1)) + + +def temperature(h): + """ + Température en fonction de l'alti (bloquée à -56C) + :param h: + :return: + """ + T = T0 - h*L + if T <= 217.15: + T = 217.15 + return T + + +def lss(h): + """ + Vitesse du son en fonction de l'alti + :param h: + :return: + """ + return sqrt(k*R*temperature(h)) + + +def pressure(h): + """ + Pression en fonction de l'alti + :param h: + :return: + """ + return p0 * (temperature(h) / T0) ** (g / L / R) + + +def IAS_to_Mach(IAS, alti): + + """ + Converti une IAS en Mach + :param IAS: + :param alti: + :return: + """ + + alti = alti / feet_per_metre + IAS = IAS * ms_per_kt + ps = pressure(alti) + pd = compressible_pitot(IAS/lss0) * p0 + + return pitot_to_Mach(pd / ps) + + +def mach_to_TAS(M, alti): + """ + Converti un point de mach en TAS + :param M: + :param alti: + :return: + """ + alti = alti / feet_per_metre + return lss(alti) * M / ms_per_kt + From 23250836fa283e48d3cae5cc7970e70fcdd98144 Mon Sep 17 00:00:00 2001 From: MaelkMaelk <65122264+MaelkMaelk@users.noreply.github.com> Date: Tue, 8 Oct 2024 00:50:26 +0200 Subject: [PATCH 6/7] bordel --- Python/interface.py | 2 +- Python/paquets_avion.py | 11 ++++++--- Python/player.py | 3 +++ Python/server.py | 54 ++++++++++++++++++++++++++++++++++++++--- Python/vitesses.py | 9 +++++++ 5 files changed, 71 insertions(+), 8 deletions(-) diff --git a/Python/interface.py b/Python/interface.py index 6f3c312..781bf25 100644 --- a/Python/interface.py +++ b/Python/interface.py @@ -371,7 +371,7 @@ def update(self, avion): if avion.papa.clearedIAS and self.extended: self.clearedSpeed.set_text("k" + avion.papa.clearedIAS) elif avion.papa.clearedMach and self.extended: - self.clearedSpeed.set_text("k" + avion.papa.clearedMach) + self.clearedSpeed.set_text("m" + avion.papa.clearedMach) else: self.clearedSpeed.set_text("S") diff --git a/Python/paquets_avion.py b/Python/paquets_avion.py index 119384f..e245c92 100644 --- a/Python/paquets_avion.py +++ b/Python/paquets_avion.py @@ -159,14 +159,15 @@ def __init__(self, gameMap, Id, indicatif, aircraft, perfos, route, arrival, FL= # selected + vitesses if self.machMode: - self.speedIAS = self.perfos['descentIAS'] self.selectedIAS = self.perfos['descentIAS'] self.mach = self.selectedMach + self.speedTAS = vitesses.mach_to_TAS(self.mach, self.altitude) + self.speedIAS = vitesses.TAS_to_IAS(self.speedTAS, self.altitude) else: self.speedIAS = self.selectedIAS self.mach = vitesses.IAS_to_Mach(self.speedIAS, self.altitude) + self.speedTAS = vitesses.mach_to_TAS(self.mach, self.altitude) - self.speedTAS = vitesses.mach_to_TAS(self.mach, self.altitude) self.speedGS = self.speedTAS self.selectedAlti = self.CFL * 100 @@ -347,6 +348,7 @@ def computeSpeed(self): Fait évoluer la vitesse si on a besoin :return: """ + if not self.machMode: if self.speedIAS != self.selectedIAS: # s'il faut accélérer ou ralentir # on change la vitesse par un pas d'accél/deccel défaut @@ -364,6 +366,8 @@ def computeSpeed(self): else: self.mach += (self.selectedMach - self.mach) / abs(self.selectedMach - self.mach) * acceldefaultMach + self.speedIAS = vitesses.TAS_to_IAS(self.speedTAS, self.altitude) + self.speedTAS = vitesses.mach_to_TAS(self.mach, self.altitude) self.speedGS = self.speedTAS @@ -373,11 +377,10 @@ def changeSpeed(self) -> None: :return: """ - self.machMode = False - if self.forcedSpeed: return None + self.machMode = False if self.altitude >= altitude_conversion: # au-dessus de l'alti de conversion tout se fera en mach self.machMode = True diff --git a/Python/player.py b/Python/player.py index 90ab4be..f480e0b 100644 --- a/Python/player.py +++ b/Python/player.py @@ -465,6 +465,9 @@ def checkEvent(self, event, pilote, conflitBool): elif event.ui_element == self.etiquette.AFL and event.mouse_button == 1 and pilote: return 'FL' + elif event.ui_element == self.etiquette.clearedSpeed and event.mouse_button == 1 and self.papa.machMode: + return 'C_Mach' + elif event.ui_element == self.etiquette.clearedSpeed and event.mouse_button == 1: return 'C_IAS' diff --git a/Python/server.py b/Python/server.py index 72141b2..eecc9fd 100644 --- a/Python/server.py +++ b/Python/server.py @@ -381,33 +381,54 @@ def threaded_ping_responder(): elif reqType == 'Remove': dictAvion.pop(reqId) + elif reqType == 'FL': dictAvion[reqId].selectedAlti = reqContent * 100 + elif reqType == 'PFL': dictAvion[reqId].PFL = reqContent dictAvion[reqId].changeXFL(gameMap) + elif reqType == 'CFL': dictAvion[reqId].CFL = reqContent + elif reqType == 'C_IAS': if len(req) == 3: dictAvion[reqId].clearedIAS = reqContent else: dictAvion[reqId].clearedIAS = None + + elif reqType == 'C_Mach': + print(req) + if reqContent: + dictAvion[reqId].clearedMach = reqContent + else: + dictAvion[reqId].clearedMach = None + elif reqType == 'C_Rate': if len(req) == 3: dictAvion[reqId].clearedRate = reqContent else: dictAvion[reqId].clearedRate = None + elif reqType == 'Rate': - signe = (dictAvion[reqId].evolution * reqContent) / abs(dictAvion[reqId].evolution * reqContent) - dictAvion[reqId].evolution = signe * reqContent + if reqContent: + dictAvion[reqId].forcedEvo = True + signe = (dictAvion[reqId].evolution * reqContent) / abs(dictAvion[reqId].evolution * reqContent) + dictAvion[reqId].evolution = signe * reqContent + else: + dictAvion[reqId].forcedEvo = True + elif reqType == 'XFL': dictAvion[reqId].XFL = reqContent dictAvion[reqId].changeSortieSecteur(gameMap) + elif reqType == 'XPT': dictAvion[reqId].XPT = reqContent + elif reqType == 'C_HDG': dictAvion[reqId].clearedHeading = reqContent + elif reqType == 'HDG': if type(reqContent) in [float, int]: newHeading = reqContent @@ -417,42 +438,69 @@ def threaded_ping_responder(): newHeading = dictAvion[reqId].selectedHeading + int(reqContent[1:]) dictAvion[reqId].headingMode = True dictAvion[reqId].selectedHeading = reqContent + elif reqType == 'IAS': - dictAvion[reqId].selectedIAS = reqContent * 10 + if reqContent: + dictAvion[reqId].forcedSpeed = True + dictAvion[reqId].machMode = False + dictAvion[reqId].selectedIAS = reqContent * 10 + else: + dictAvion[reqId].forcedSpeed = False + + elif reqType == 'Mach': + if reqContent: + dictAvion[reqId].forcedSpeed = True + dictAvion[reqId].machMode = True + dictAvion[reqId].selectedMach = float(reqContent) + else: + dictAvion[reqId].forcedSpeed = False + elif reqType == 'DCT': dictAvion[reqId].clearedHeading = None dictAvion[reqId].DCT = reqContent + elif reqType == 'Warning': dictAvion[reqId].warning = not dictAvion[reqId].warning + elif reqType == 'Integre': dictAvion[reqId].integreOrganique = True + elif reqType == 'Direct': dictAvion[reqId].headingMode = False for point in dictAvion[reqId].route['points']: if point['name'] == reqContent: dictAvion[reqId].nextPoint = point break + elif reqType == 'Route': dictAvion[reqId].nextRoute = reqContent dictAvion[reqId].changeRoute(gameMap) + elif reqType == 'HighlightBouton': if reqContent in dictAvion[reqId].boutonsHighlight: # si le bouton est déjà highlight alors: dictAvion[reqId].boutonsHighlight.remove(reqContent) else: dictAvion[reqId].boutonsHighlight.append(reqContent) + elif reqType == 'Montrer': dictAvion[reqId].montrer = not dictAvion[reqId].montrer + elif reqType == 'EtatFreq': dictAvion[reqId].updateEtatFreq(reqContent) + elif reqType == 'FL?': dictAvion[reqId].FLInterro = not dictAvion[reqId].FLInterro + elif reqType == 'Pause': game.paused = not game.paused + elif reqType == 'Faster': accelerationTemporelle += 0.5 + elif reqType == 'Slower': if accelerationTemporelle > 0.5: accelerationTemporelle -= 0.5 + elif reqType == 'Save' and mode_ecriture: xmlstr = server_def.prettyPrint(minidom.parseString(ET.tostring(simuTree))) with open("XML/simu.xml", "w") as f: diff --git a/Python/vitesses.py b/Python/vitesses.py index 7e56c33..504194b 100644 --- a/Python/vitesses.py +++ b/Python/vitesses.py @@ -92,3 +92,12 @@ def mach_to_TAS(M, alti): alti = alti / feet_per_metre return lss(alti) * M / ms_per_kt + +def TAS_to_IAS(TAS, alti): + """ + Convertit une TAS en IAS, de façon très grossière + :return: + """ + + return TAS - alti / 185 + From 7527f748259b1f554c302d90aa3eb4d6ac4223a6 Mon Sep 17 00:00:00 2001 From: MaelkMaelk <65122264+MaelkMaelk@users.noreply.github.com> Date: Tue, 8 Oct 2024 13:42:29 +0200 Subject: [PATCH 7/7] replay fix : menus mach et IAS fonctionnent mtn feet: replays --- Python/XML/simu.xml | 16 ------- Python/capture.py | 10 ++++ Python/client.py | 14 ++++++ Python/paquets_avion.py | 2 + Python/player.py | 4 +- Python/server.py | 100 ++++++++++++++++++++++----------------- Python/valeurs_config.py | 3 ++ 7 files changed, 89 insertions(+), 60 deletions(-) delete mode 100644 Python/XML/simu.xml create mode 100644 Python/capture.py diff --git a/Python/XML/simu.xml b/Python/XML/simu.xml deleted file mode 100644 index ead6d33..0000000 --- a/Python/XML/simu.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - 100200 - - - FCACA - B738 - FRI-GAI - 26000 - False - 1901 - 463 - 300 - - - diff --git a/Python/capture.py b/Python/capture.py new file mode 100644 index 0000000..307c3d5 --- /dev/null +++ b/Python/capture.py @@ -0,0 +1,10 @@ + + +# Module Import + +import pygame + + +def saveScreenshot(win, path): + screencopy = win.copy() + pygame.image.save(screencopy, path) diff --git a/Python/client.py b/Python/client.py index fab957f..c2f3859 100644 --- a/Python/client.py +++ b/Python/client.py @@ -13,6 +13,7 @@ import Python.interface as interface from Python.paquets_avion import * import Python.outils_radar as outils_radar +import Python.capture as capture # recherche de tous les serveurs sur le réseau address = server_browser.serverBrowser() @@ -39,6 +40,11 @@ clock = pygame.time.Clock() font = pygame.font.SysFont('arial', 18) +if replayMode: + dossierScreen = Path('replay') / (str(time.localtime()[1]) + '_' + str(time.localtime()[2]) + '_' + + str(time.localtime()[3]) + 'h' + str(time.localtime()[4])) + dossierScreen.mkdir() + def main(server_ip: str): global temps @@ -55,6 +61,9 @@ def main(server_ip: str): flightDataWindow = None menuRadar = interface.menuRadar() + # screenshots replays + dernierScreen = pygame.time.get_ticks() + # on se connecte au serveur n = Network(server_ip) packet = n.getP() @@ -516,6 +525,11 @@ def main(server_ip: str): img = font.render(str(distance), True, (255, 105, 180)) win.blit(img, (pygame.mouse.get_pos()[0] + 20, pygame.mouse.get_pos()[1])) + # prise des screenshots + if pygame.time.get_ticks() >= dernierScreen + delaiScreen and replayMode and not pilote: + capture.saveScreenshot(win, dossierScreen / (horloge.heureXML(game.heure) + '.png')) + dernierScreen = pygame.time.get_ticks() + # envoi des packets # on fait avec un try and except au cas où un paquet se perde diff --git a/Python/paquets_avion.py b/Python/paquets_avion.py index e245c92..73974f6 100644 --- a/Python/paquets_avion.py +++ b/Python/paquets_avion.py @@ -177,6 +177,8 @@ def __init__(self, gameMap, Id, indicatif, aircraft, perfos, route, arrival, FL= self.clearedMach = None self.clearedHeading = None self.clearedRate = None + self.clearedMachMode = False + self.clearedIASMode = False self.speedPx = self.speedGS / gameMap['mapScale'] * heureEnRefresh diff --git a/Python/player.py b/Python/player.py index f480e0b..8fc7220 100644 --- a/Python/player.py +++ b/Python/player.py @@ -465,7 +465,9 @@ def checkEvent(self, event, pilote, conflitBool): elif event.ui_element == self.etiquette.AFL and event.mouse_button == 1 and pilote: return 'FL' - elif event.ui_element == self.etiquette.clearedSpeed and event.mouse_button == 1 and self.papa.machMode: + elif (event.ui_element == self.etiquette.clearedSpeed and event.mouse_button == 1 and + (self.papa.machMode or self.papa.clearedMach) and not self.papa.clearedIAS): + return 'C_Mach' elif event.ui_element == self.etiquette.clearedSpeed and event.mouse_button == 1: diff --git a/Python/server.py b/Python/server.py index eecc9fd..6ff2ad5 100644 --- a/Python/server.py +++ b/Python/server.py @@ -238,52 +238,62 @@ simuTree = None +try: + simuTree = ET.parse(dossierXML / simu).getroot() -simuTree = ET.parse(dossierXML / simu).getroot() - -heure = simuTree.find('heure').text -heure = int(heure[0:2]) * 3600 + int(heure[2:4]) * 60 + int(heure[4:]) + heure = simuTree.find('heure').text + heure = int(heure[0:2]) * 3600 + int(heure[2:4]) * 60 + int(heure[4:]) -game = Game(heure) + game = Game(heure) -avionSpawnListe = [] -avionsXML = simuTree.find('avions') -for avion in avionsXML: + avionSpawnListe = [] + avionsXML = simuTree.find('avions') + for avion in avionsXML: - avionDict = {} + avionDict = {} - for XMLpoint in avion: - try: - XMLpointValue = float(XMLpoint.text) - except: - XMLpointValue = XMLpoint.text - avionDict.update({XMLpoint.tag: XMLpointValue}) + for XMLpoint in avion: + try: + XMLpointValue = float(XMLpoint.text) + except: + XMLpointValue = XMLpoint.text + avionDict.update({XMLpoint.tag: XMLpointValue}) - heureSpawn = avion.attrib['heure'] - heureSpawn = int(heureSpawn[0:2]) * 3600 + int(heureSpawn[2:4]) * 60 + int(heureSpawn[4:]) + heureSpawn = avion.attrib['heure'] + heureSpawn = int(heureSpawn[0:2]) * 3600 + int(heureSpawn[2:4]) * 60 + int(heureSpawn[4:]) - for route in gameMap['routes']: - if route == avionDict['route']: - spawnRoute = gameMap['routes'][route] - break - if 'altitude' in avionDict: - spawnFL = round(avionDict['altitude'] / 100) - else: - spawnFL = None - avionPack = AvionPacket( - gameMap, - planeId, - avionDict['indicatif'], - avionDict['aircraft'], - aircraftType[avionDict['aircraft']], - spawnRoute, - avionDict['arrival'] == 'True', - FL=spawnFL, - x=avionDict['x'], - y=avionDict['y']) - planeId += 1 - - avionSpawnListe.append((heureSpawn, avionPack)) + for route in gameMap['routes']: + if route == avionDict['route']: + spawnRoute = gameMap['routes'][route] + break + if 'altitude' in avionDict: + spawnFL = round(avionDict['altitude'] / 100) + else: + spawnFL = None + avionPack = AvionPacket( + gameMap, + planeId, + avionDict['indicatif'], + avionDict['aircraft'], + aircraftType[avionDict['aircraft']], + spawnRoute, + avionDict['arrival'] == 'True', + FL=spawnFL, + x=avionDict['x'], + y=avionDict['y']) + planeId += 1 + + avionSpawnListe.append((heureSpawn, avionPack)) +except: + + heure = input('Heure de début de simu, format: hhmm') + heure = int(heure[0:2]) * 3600 + int(heure[2:]) * 60 + avionSpawnListe = [] + simuTree = ET.Element('simu') + game = Game(heure) + heureXML = ET.SubElement(simuTree, 'heure') + heureXML.text = horloge.heureXML(game.heure) + avionsXML = ET.SubElement(simuTree, 'avions') def threaded_client(conn, caca): @@ -358,6 +368,7 @@ def threaded_ping_responder(): if len(req) == 3: reqContent = req[2] + print(req) if reqType == 'Add': @@ -393,20 +404,23 @@ def threaded_ping_responder(): dictAvion[reqId].CFL = reqContent elif reqType == 'C_IAS': - if len(req) == 3: + if reqContent: dictAvion[reqId].clearedIAS = reqContent + dictAvion[reqId].clearedMach = None else: + dictAvion[reqId].clearedMach = None dictAvion[reqId].clearedIAS = None elif reqType == 'C_Mach': - print(req) if reqContent: dictAvion[reqId].clearedMach = reqContent + dictAvion[reqId].clearedIAS = None else: dictAvion[reqId].clearedMach = None + dictAvion[reqId].clearedIAS = None elif reqType == 'C_Rate': - if len(req) == 3: + if reqContent: dictAvion[reqId].clearedRate = reqContent else: dictAvion[reqId].clearedRate = None @@ -417,7 +431,7 @@ def threaded_ping_responder(): signe = (dictAvion[reqId].evolution * reqContent) / abs(dictAvion[reqId].evolution * reqContent) dictAvion[reqId].evolution = signe * reqContent else: - dictAvion[reqId].forcedEvo = True + dictAvion[reqId].forcedEvo = False elif reqType == 'XFL': dictAvion[reqId].XFL = reqContent diff --git a/Python/valeurs_config.py b/Python/valeurs_config.py index 9014775..fc219fb 100644 --- a/Python/valeurs_config.py +++ b/Python/valeurs_config.py @@ -14,3 +14,6 @@ temps_disparition_menus = 300 # en combien de milli sec les menus disparaissent après ne plus être survolé altitude_conversion = 27900 altitude_cruise = 25000 + +delaiScreen = 6900 +replayMode = False