|
@@ -0,0 +1,2451 @@
|
|
|
|
|
+#from __future__ import unicode_literals
|
|
|
|
|
+# -*- coding: utf-8 -*-
|
|
|
|
|
+from __future__ import division
|
|
|
|
|
+import os
|
|
|
|
|
+from sys import exit, argv, getsizeof, settrace
|
|
|
|
|
+from time import time, sleep, strftime, localtime
|
|
|
|
|
+from threading import Thread
|
|
|
|
|
+
|
|
|
|
|
+from PyQt4.QtCore import *
|
|
|
|
|
+from PyQt4.QtGui import *
|
|
|
|
|
+from PyQt4 import QtOpenGL
|
|
|
|
|
+
|
|
|
|
|
+from ui.ecran_editionTerrain import Ui_editionTerrain
|
|
|
|
|
+from ui.ecran_editionCreature import Ui_editionCreature
|
|
|
|
|
+from ui.ecran_editionDecor import Ui_editionDecor
|
|
|
|
|
+
|
|
|
|
|
+from ui.ecran_gestionCombat import Ui_gestionCombat
|
|
|
|
|
+from ui.ecran_editionAttaques import Ui_editionAttaques
|
|
|
|
|
+from ui.ecran_affichageTexte import Ui_affichageTexte
|
|
|
|
|
+
|
|
|
|
|
+from Case import Case
|
|
|
|
|
+from Pion import Pion
|
|
|
|
|
+from PionDecor import PionDecor
|
|
|
|
|
+
|
|
|
|
|
+from Cache import Cache
|
|
|
|
|
+from EntreeSortie import EntreeSortie
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+import regles as regles
|
|
|
|
|
+from outilsSvg import *
|
|
|
|
|
+from lancer import jet, estJetValide
|
|
|
|
|
+
|
|
|
|
|
+from operator import itemgetter, attrgetter
|
|
|
|
|
+from math import *
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+class Plateau(QGraphicsScene):
|
|
|
|
|
+ """plateau de jeu contenant les cases, decors et pions"""
|
|
|
|
|
+ def __init__(self, fenetre, parent=None):
|
|
|
|
|
+ super(Plateau, self).__init__()
|
|
|
|
|
+ #parametres et variables
|
|
|
|
|
+ self.id = ""
|
|
|
|
|
+ self.nom = ""
|
|
|
|
|
+ self.chapitre = 0
|
|
|
|
|
+ self.fenetre = fenetre
|
|
|
|
|
+ self.nbCasesX = 0
|
|
|
|
|
+ self.nbCasesY = 0
|
|
|
|
|
+ self.hCase = 0
|
|
|
|
|
+ self.cases = {} #dict des cases du plateau (coordonnées: case)
|
|
|
|
|
+ self.pions = {} #liste de pions positionnes sur le plateau
|
|
|
|
|
+ self.decors = {} #liste des decors places sur le plateau
|
|
|
|
|
+ self.ordreJeu = {} #numero du pion: ordre de jeu
|
|
|
|
|
+ self.numPionEnCours = 0
|
|
|
|
|
+ self.tour = 1
|
|
|
|
|
+ self.cacheEnCours = 1
|
|
|
|
|
+ self.caches = {}
|
|
|
|
|
+ self.polygonesCaches = {}
|
|
|
|
|
+ for i in range(1,5):
|
|
|
|
|
+ self.caches[i] = {"actif":False,"listeCases":[]}
|
|
|
|
|
+ self.polygonesCaches[i] = None
|
|
|
|
|
+
|
|
|
|
|
+ self.listeCasesZonePlacement = []
|
|
|
|
|
+ self.polygoneZonePlacement = None
|
|
|
|
|
+ self.entreesSorties = []
|
|
|
|
|
+ self.modePrincipal = "creation"
|
|
|
|
|
+ self.modeActif = ""
|
|
|
|
|
+ self.modeCombat = ""
|
|
|
|
|
+ self.nbZoomActuel = 0
|
|
|
|
|
+ self.epaisseurpinceau = 0
|
|
|
|
|
+ self.enCours = False
|
|
|
|
|
+ self.public = False
|
|
|
|
|
+ self.dateCreation = ""
|
|
|
|
|
+ self.dateSvg = ""
|
|
|
|
|
+ self.notes = ""
|
|
|
|
|
+
|
|
|
|
|
+ #note: la hauteur Z (qui gere l'empilement des objets graphiques est distribuee de cette maniere:
|
|
|
|
|
+ #cases : 0 a 9
|
|
|
|
|
+ #pions : 10 et +
|
|
|
|
|
+
|
|
|
|
|
+ def __getstate__(self):
|
|
|
|
|
+ self.dateSvg = time()
|
|
|
|
|
+ state = {key:value for key, value in self.__dict__.items() if not key in ["fenetre", "modeActif", "listMode", "cacheEnCours", \
|
|
|
|
|
+ "modeParam", "nbZoomActuel", "epaisseurPinceau", \
|
|
|
|
|
+ "editionTerrain", "editionCreature", "editionDecor", \
|
|
|
|
|
+ "polygoneZonePlacement", "gestionCombat", "polygonesCaches", \
|
|
|
|
|
+ "editionAttaques"]}
|
|
|
|
|
+ return (state)
|
|
|
|
|
+
|
|
|
|
|
+ def __setstate__(self, state):
|
|
|
|
|
+ self.__dict__ = state
|
|
|
|
|
+
|
|
|
|
|
+ def creer(self, idPlateau, nom, chapitre, formeCases, nbCasesX, nbCasesY, couleur = QColor(0, 255, 0, 80)):
|
|
|
|
|
+ """cree le plateau"""
|
|
|
|
|
+ self.id = idPlateau
|
|
|
|
|
+ self.nom = nom
|
|
|
|
|
+ self.chapitre = chapitre
|
|
|
|
|
+ self.dateCreation = time()
|
|
|
|
|
+ self.hCase = 120 #hauteur d'une case
|
|
|
|
|
+ self.nbCasesX = nbCasesX #nb cases en x
|
|
|
|
|
+ self.nbCasesY = nbCasesY #nb cases en y
|
|
|
|
|
+ self.formeCases = formeCases
|
|
|
|
|
+ self.gestionCombat = None
|
|
|
|
|
+ self.initialisationGraphique()
|
|
|
|
|
+ self.connexions()
|
|
|
|
|
+
|
|
|
|
|
+ #cree les cases hexagonales
|
|
|
|
|
+ for x in range(nbCasesX):
|
|
|
|
|
+ for y in range(nbCasesY):
|
|
|
|
|
+ if formeCases == "H":
|
|
|
|
|
+ if 1 == (x % 2):
|
|
|
|
|
+ y += 0.5
|
|
|
|
|
+ c = Case(self)
|
|
|
|
|
+ c.creer(x, y, couleur)
|
|
|
|
|
+ self.cases[(x,y)] = c
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ def recreer(self, fenetre):
|
|
|
|
|
+ self.fenetre = fenetre
|
|
|
|
|
+ self.gestionCombat = None
|
|
|
|
|
+ super(Plateau, self).__init__()
|
|
|
|
|
+ self.connexions()
|
|
|
|
|
+
|
|
|
|
|
+ self.initialisationGraphique()
|
|
|
|
|
+
|
|
|
|
|
+ #recreation des cases
|
|
|
|
|
+ for coord in self.cases:
|
|
|
|
|
+ self.cases[coord].recreer(self)
|
|
|
|
|
+
|
|
|
|
|
+ #recreation des pions
|
|
|
|
|
+ for numPion in self.pions:
|
|
|
|
|
+ self.pions[numPion].recreer(self)
|
|
|
|
|
+ self.majOrdreJeu()
|
|
|
|
|
+
|
|
|
|
|
+ #recreation des decors
|
|
|
|
|
+ for num in self.decors:
|
|
|
|
|
+ self.decors[num].recreer(self)
|
|
|
|
|
+
|
|
|
|
|
+ #recreation des marqueurs entree/sortie
|
|
|
|
|
+ for entreeSortie in self.entreesSorties:
|
|
|
|
|
+ entreeSortie.recreer(self)
|
|
|
|
|
+
|
|
|
|
|
+ #recreation de la zone de placement:
|
|
|
|
|
+ if len(self.listeCasesZonePlacement) > 0:
|
|
|
|
|
+ self.polygoneZonePlacement = None
|
|
|
|
|
+ self.majZonePlacement(self.listeCasesZonePlacement)
|
|
|
|
|
+
|
|
|
|
|
+ #recreation des caches
|
|
|
|
|
+ self.polygonesCaches = {}
|
|
|
|
|
+ for i in range(1,5):
|
|
|
|
|
+ self.polygonesCaches[i] = None
|
|
|
|
|
+
|
|
|
|
|
+ def fermer(self):
|
|
|
|
|
+ """ferme le plateau 'proprement'"""
|
|
|
|
|
+ for item in self.items():
|
|
|
|
|
+ item.prepareGeometryChange()
|
|
|
|
|
+ self.removeItem(item)
|
|
|
|
|
+ if self.gestionCombat != None:
|
|
|
|
|
+ del self.gestionCombat
|
|
|
|
|
+ self.fenetre.reinitialiserPanneauxPlateau()
|
|
|
|
|
+
|
|
|
|
|
+ def connexions(self):
|
|
|
|
|
+ """connecte le plateau aux differents widgets de la fenetre principale"""
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.modeCreationPlateau, SIGNAL("clicked()"), self.plateauModeCreation, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.modeCombatPlateau, SIGNAL("clicked()"), self.plateauModeCombat, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.afficherGestionCombat, SIGNAL("clicked()"), self.afficheEcranGestionCombat, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.terrainCouleur, SIGNAL("clicked()"), self.modePeintureCase, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.terrainCopie, SIGNAL("clicked()"), self.modeCopieTerrain, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.pionCouleur, SIGNAL("clicked()"), self.majCouleurPion, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.terrainEdit, SIGNAL("clicked()"), self.terrainEdit, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.terrainNouveau, SIGNAL("clicked()"), self.terrainNouveau, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.creatureEdit, SIGNAL("clicked()"), self.creatureEdit, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.creatureNouveau, SIGNAL("clicked()"), self.creatureNouveau, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.pionSimpleCreer, SIGNAL("clicked()"), self.modeCreationPion, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.pionSupprimer, SIGNAL("clicked()"), self.majModePionSupprimer, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.decorEdit, SIGNAL("clicked()"), self.decorEdit, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.decorNouveau, SIGNAL("clicked()"), self.decorNouveau, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.decorSupprimer, SIGNAL("clicked()"), self.majModePionSupprimer, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.definirEntree, SIGNAL("clicked()"), self.majModeDefinirEntree, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.definirSortie, SIGNAL("clicked()"), self.majModeDefinirSortie, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.definirZonePlacement, SIGNAL("clicked()"), self.majModeZonePlacement, Qt.UniqueConnection)
|
|
|
|
|
+
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.formeSimple, SIGNAL("clicked()"), self.majModeForme, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.formeLigne, SIGNAL("clicked()"), self.majModeForme, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.formeLigneOrientee, SIGNAL("clicked()"), self.majModeForme, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.formeEllipseVide, SIGNAL("clicked()"), self.majModeForme, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.formeEllipsePlein, SIGNAL("clicked()"), self.majModeForme, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.formeRectVide, SIGNAL("clicked()"), self.majModeForme, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.formeRectPlein, SIGNAL("clicked()"), self.majModeForme, Qt.UniqueConnection)
|
|
|
|
|
+
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.effFeu, SIGNAL("clicked()"), self.modeCaseEffet, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.effEau, SIGNAL("clicked()"), self.modeCaseEffet, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.effGlace, SIGNAL("clicked()"), self.modeCaseEffet, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.effPoison, SIGNAL("clicked()"), self.modeCaseEffet, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.effEffacer, SIGNAL("clicked()"), self.modeCaseEffet, Qt.UniqueConnection)
|
|
|
|
|
+
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.cacheActif, SIGNAL("clicked()"), self.majEtatCacheEnCours, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.cacheVoir, SIGNAL("clicked()"), self.voirCacheEnCours, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.cachePlacer, SIGNAL("clicked()"), self.placerCacheEnCours, Qt.UniqueConnection)
|
|
|
|
|
+
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.combatDeplacement, SIGNAL("clicked()"), self.majModeCombatDeplacement, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.ui.combatDeplacement.setCheckable(True)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.combatAttaqueCaC, SIGNAL("clicked()"), self.majModeCombatAttaqueCaC, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.ui.combatAttaqueCaC.setCheckable(True)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.combatAttaqueDist, SIGNAL("clicked()"), self.majModeCombatAttaqueDist, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.ui.combatAttaqueDist.setCheckable(True)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.combatAttaqueZone, SIGNAL("clicked()"), self.fenetre.barreCombatZone, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.combatAttaqueZone, SIGNAL("clicked()"), self.majModeCombatZone, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.ui.combatAttaqueZone.setCheckable(True)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.combatVol, SIGNAL("clicked()"), self.fenetre.barreCombatVol, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.combatVol_altitude, SIGNAL("valueChanged(int)"), self.majZPion, Qt.UniqueConnection)
|
|
|
|
|
+ #self.fenetre.connect(self.fenetre.ui.combatVol_altitude, SIGNAL("editingFinished()"), self.majVisibiliteBarreCombat)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.combatZone_ligne, SIGNAL("clicked()"), self.majModeCombatZoneForme, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.ui.combatZone_ligne.setCheckable(True)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.combatZone_disque, SIGNAL("clicked()"), self.majModeCombatZoneForme, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.ui.combatZone_disque.setCheckable(True)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.combatZone_cone, SIGNAL("clicked()"), self.majModeCombatZoneForme, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.ui.combatZone_cone.setCheckable(True)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.combatRetour, SIGNAL("clicked()"), self.fenetre.barreCombatMenu, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.combatPasserTour, SIGNAL("clicked()"), self.pionSuivant, Qt.UniqueConnection)
|
|
|
|
|
+ #self.connect(self.ui.combatInventaire, SIGNAL("clicked()"), self.majModePionSupprimer)
|
|
|
|
|
+
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.modeAffichagePlateau, SIGNAL("currentIndexChanged(int)"), self.majModeAffichage, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.listTerrains, SIGNAL("cellClicked(int,int)"), self.modeMajTerrainCase, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.listCreatures, SIGNAL("cellClicked(int,int)"), self.modeCreationCreaturePion, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.listDecors, SIGNAL("cellClicked(int,int)"), self.modeCreationDecor, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.epaisseurPinceau, SIGNAL("valueChanged(int)"), self.majEpaisseurPinceau, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.altitudeCase, SIGNAL("valueChanged(double)"), self.modeMajAltitudeCase, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.infoOrdreJeu, SIGNAL("cellClicked(int,int)"), self.clicListOrdreJeu, Qt.UniqueConnection)
|
|
|
|
|
+
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.listeAttributs, SIGNAL("cellChanged(int,int)"), self.listeAttributCelluleModifiee, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.editerAttaques, SIGNAL("clicked()"), self.afficheEcranEditionAttaques, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.notesPion, SIGNAL("textChanged()"), self.majNotesPion, Qt.UniqueConnection)
|
|
|
|
|
+
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.notesMjPlateau, SIGNAL("textChanged()"), self.majNotesPlateau, Qt.UniqueConnection)
|
|
|
|
|
+ self.fenetre.connect(self.fenetre.ui.agrandirNotesMjPlateau, SIGNAL("clicked()"), self.agrandirNotesMjPlateau, Qt.UniqueConnection)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ def initialisationGraphique(self):
|
|
|
|
|
+ """cree la scene graphique et les parametres necessaires a son fonctionnement, et met a jour l'interface"""
|
|
|
|
|
+ #on cree la scene graphique
|
|
|
|
|
+ kx = 1
|
|
|
|
|
+ if self.formeCases == "H":
|
|
|
|
|
+ kx = 0.866
|
|
|
|
|
+ marge = 240
|
|
|
|
|
+ self.setSceneRect(0 - marge, 0 - marge, (kx*self.hCase*(self.nbCasesX+2)) + marge, (self.hCase*(self.nbCasesY+2)) + marge)
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setScene(self)
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.scale(0.25, 0.25)
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.centerOn(QPointF(0,0))
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(1)
|
|
|
|
|
+ self.setItemIndexMethod(QGraphicsScene.BspTreeIndex)
|
|
|
|
|
+
|
|
|
|
|
+ #self.setItemIndexMethod(QGraphicsScene.NoIndex)
|
|
|
|
|
+ self.nbZoomActuel = 0
|
|
|
|
|
+ self.epaisseurPinceau = 1
|
|
|
|
|
+ self.polygoneZonePlacement = None
|
|
|
|
|
+ self.polygonesCaches = {}
|
|
|
|
|
+ for i in range(1,5):
|
|
|
|
|
+ self.polygonesCaches[i] = None
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ #gestion du mode d'interaction avec le plateau
|
|
|
|
|
+ self.modeActif = "standard"
|
|
|
|
|
+ self.listMode = ["standard", "caseMajTerrain", "caseCopie", "caseMajEffet", "caseMajAltitude", "pionCreation", \
|
|
|
|
|
+ "pionSelectionne", "pionDecorCreation", "pionDecorSelectionne", "pionSupprimer", "cachePlacer", \
|
|
|
|
|
+ "combatDeplacement", "combatAttaqueCaC", "combatAttaqueDist", \
|
|
|
|
|
+ "placementEntreeSortie", "majZonePlacement"]
|
|
|
|
|
+
|
|
|
|
|
+ self.modeParam = {"terrain": None, "numPionSelectionne": 0, "pionNouveau": None, "creature": None, "decor": None, "effet":"", "couleurPion": QColor("grey"), \
|
|
|
|
|
+ "coordProjectionPosition": (0,0), "formeProjectionPosition": None, "nbRotations": 0, \
|
|
|
|
|
+ "typeFormeDessin": "simple", "formeDessin": None, "origineFormeDessin": None, "point2FormeDessin": None, "listeCasesFormeDessin": [], \
|
|
|
|
|
+ "projectionFormeDessin": [], "formeCoordEnCours": (0,0), \
|
|
|
|
|
+ "zoneAttaqueCaC": [], "cibleAttaqueCaC": None, "cibleAttaqueDist": None, "pionCibleAttaqueDist": None, "ligneAttaqueDist": None, \
|
|
|
|
|
+ "typeAttaqueZone": "", "formeAttaqueZone": None, "origineAttaqueZone": None, "point2AttaqueZone": None, "listeCasesAttaqueZone": [], "ligneMireAttaqueZone": None, \
|
|
|
|
|
+ "entreeSortie": None}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ #mise a jour de l'interface de creation
|
|
|
|
|
+ self.fenetre.majVisibilitePanneauxPlateau("creation")
|
|
|
|
|
+ self.fenetre.ui.nomPlateau.setText(QString.fromUtf8(self.nom))
|
|
|
|
|
+ self.fenetre.ui.nomPlateau.setText(QString.fromUtf8(self.nom))
|
|
|
|
|
+ self.majBoutonsCouleursPerso()
|
|
|
|
|
+ self.majBoutonsCaches()
|
|
|
|
|
+ self.majListTerrains()
|
|
|
|
|
+ self.majListCreatures()
|
|
|
|
|
+ self.majListDecors()
|
|
|
|
|
+ self.initListeOrdreJeu()
|
|
|
|
|
+ self.initListeAttaques()
|
|
|
|
|
+ self.fenetre.ui.notesMjPlateau.setText(QString.fromUtf8(self.notes))
|
|
|
|
|
+
|
|
|
|
|
+ if self.modeParam["couleurPion"].isValid():
|
|
|
|
|
+ self.fenetre.ui.pionCouleur.setStyleSheet("QPushButton {backGround:%s}" %(self.modeParam["couleurPion"].name()))
|
|
|
|
|
+
|
|
|
|
|
+ #mise a jour de l'interface d'informations
|
|
|
|
|
+ self.majInfosPion(None)
|
|
|
|
|
+ self.majInfosDecor(None)
|
|
|
|
|
+
|
|
|
|
|
+ def estCree(self):
|
|
|
|
|
+ """renvoie vrai si des cases ont ete creees"""
|
|
|
|
|
+ if len(self.cases) > 0:
|
|
|
|
|
+ retour = True
|
|
|
|
|
+ else:
|
|
|
|
|
+ retour = False
|
|
|
|
|
+ return retour
|
|
|
|
|
+
|
|
|
|
|
+ def majBoutonsCouleursPerso(self):
|
|
|
|
|
+ """met a jour l'affichage des couleurs customisees dans la boite de dialogue de selection de couleur"""
|
|
|
|
|
+ for i in range(0,16):
|
|
|
|
|
+ rgb = QColorDialog(self.fenetre.ui.vuePlateau).customColor(i)
|
|
|
|
|
+ couleur = QColor(rgb)
|
|
|
|
|
+ bouton = self.fenetre.ui.outilsEditionPlateau.findChild(QToolButton, "terrainCouleurPerso{}".format(i+1))
|
|
|
|
|
+ if couleur.isValid():
|
|
|
|
|
+ bouton.setStyleSheet("QToolButton {backGround:%s}"%(couleur.name()))
|
|
|
|
|
+ self.fenetre.connect(bouton, SIGNAL("clicked()"), self.modePeintureCase_perso)
|
|
|
|
|
+
|
|
|
|
|
+ def chercherCouleur(self):
|
|
|
|
|
+ """ouvre la boite de dialogue de selection de couleur"""
|
|
|
|
|
+ couleur = QColorDialog(self.fenetre.ui.vuePlateau).getColor(QColor("white"), self.fenetre.ui.vuePlateau)
|
|
|
|
|
+ self.majBoutonsCouleursPerso()
|
|
|
|
|
+ return couleur
|
|
|
|
|
+
|
|
|
|
|
+ def majBoutonsCaches(self):
|
|
|
|
|
+ """met a jour l'affichage et connecte les boutons de caches"""
|
|
|
|
|
+ for i in range(1,5):
|
|
|
|
|
+ bouton = self.fenetre.ui.outilsEditionPlateau.findChild(QToolButton, "plateauCache{}".format(i))
|
|
|
|
|
+ self.fenetre.connect(bouton, SIGNAL("clicked()"), self.majAffichageMenuCache)
|
|
|
|
|
+
|
|
|
|
|
+ def majListesPions(self, numPion = None):
|
|
|
|
|
+ """met a jour les listes contenant des donnees liees aux pions"""
|
|
|
|
|
+## self.majListeOrdreJeu()
|
|
|
|
|
+##
|
|
|
|
|
+## if numPion == None or numPion == self.pionSelectionne().numero:
|
|
|
|
|
+## self.majListeAttributs()
|
|
|
|
|
+## QApplication.processEvents()
|
|
|
|
|
+ pass
|
|
|
|
|
+
|
|
|
|
|
+ def majNotesPlateau(self):
|
|
|
|
|
+ """les notes du plateau ont ete maj a l'ecran"""
|
|
|
|
|
+ self.notes = str(self.fenetre.ui.notesMjPlateau.toPlainText().toUtf8())
|
|
|
|
|
+
|
|
|
|
|
+ def agrandirNotesMjPlateau(self):
|
|
|
|
|
+ """affiche les notes du plateau dans une QDialog, puis recupere les donnees qui y sont saisies"""
|
|
|
|
|
+ affichageTexte = EcranAffichageTexte(self.notes)
|
|
|
|
|
+ affichageTexte.setAttribute(Qt.WA_DeleteOnClose)
|
|
|
|
|
+ r = affichageTexte.exec_()
|
|
|
|
|
+ self.fenetre.ui.notesMjPlateau.setText(QString.fromUtf8(affichageTexte.recupererTexte()))
|
|
|
|
|
+
|
|
|
|
|
+ ##### affichage de la liste des terrains enregistres, et fonctions d'acces aux donnees""""
|
|
|
|
|
+ def afficheEcranEditionTerrains(self, terrain = None):
|
|
|
|
|
+ """affiche l'ecran d'edition/creation de terrains"""
|
|
|
|
|
+ self.editionTerrain = EcranEditionTerrain(terrain)
|
|
|
|
|
+ self.connect(self.fenetre, SIGNAL("majListTerrains()"), self.majListTerrains)
|
|
|
|
|
+ self.connect(self.editionTerrain, SIGNAL("majListTerrains()"), self.majListTerrains)
|
|
|
|
|
+ self.editionTerrain.setAttribute(Qt.WA_DeleteOnClose)
|
|
|
|
|
+ r = self.editionTerrain.exec_()
|
|
|
|
|
+
|
|
|
|
|
+ def majListTerrains(self):
|
|
|
|
|
+ """mise a jour de la liste des terrains depuis la sauvegarde"""
|
|
|
|
|
+ dico = afficheSvg("biblio\\terrain")
|
|
|
|
|
+ while self.fenetre.ui.listTerrains.rowCount() > 0:
|
|
|
|
|
+ self.fenetre.ui.listTerrains.removeRow(0)
|
|
|
|
|
+ index = 0
|
|
|
|
|
+ #self.fenetre.ui.listTerrains.setColumnWidth(0,0)
|
|
|
|
|
+ self.fenetre.ui.listTerrains.hideColumn(0)
|
|
|
|
|
+ self.fenetre.ui.listTerrains.sizeHintForColumn(1)
|
|
|
|
|
+ for elt in dico:
|
|
|
|
|
+ terrain = dico[elt]
|
|
|
|
|
+ self.fenetre.ui.listTerrains.insertRow(int(index))
|
|
|
|
|
+ self.fenetre.ui.listTerrains.setItem(int(index),0,QTableWidgetItem(QString.fromUtf8(elt)))
|
|
|
|
|
+ icon = QIcon("img\\"+terrain.imgTexture)
|
|
|
|
|
+ item = QTableWidgetItem(icon,QString.fromUtf8(terrain.nom))
|
|
|
|
|
+ self.fenetre.ui.listTerrains.setItem(int(index),1,item)
|
|
|
|
|
+ index += 1
|
|
|
|
|
+ self.fenetre.ui.listTerrains.setIconSize(QSize(30,20))
|
|
|
|
|
+ self.fenetre.ui.listTerrains.sizeHintForColumn(1)
|
|
|
|
|
+ self.fenetre.ui.listTerrains.sortItems(0)
|
|
|
|
|
+ self.majMode("standard")
|
|
|
|
|
+
|
|
|
|
|
+ def terrainEdit(self):
|
|
|
|
|
+ """ouvre la fenetre 'terrains' en mode edition"""
|
|
|
|
|
+ index = self.fenetre.ui.listTerrains.item(self.fenetre.ui.listTerrains.currentRow(), 0)
|
|
|
|
|
+ if index > 0:
|
|
|
|
|
+ terrain = charger("biblio\\terrain", str(index.text().toUtf8()))
|
|
|
|
|
+ self.afficheEcranEditionTerrains(terrain)
|
|
|
|
|
+
|
|
|
|
|
+ def terrainNouveau(self):
|
|
|
|
|
+ """ouvre la fenetre 'terrains' en mode edition"""
|
|
|
|
|
+ self.afficheEcranEditionTerrains()
|
|
|
|
|
+ ###############
|
|
|
|
|
+
|
|
|
|
|
+ ##### affichage de la liste des creatures enregistrees, et fonctions d'acces aux donnees""""
|
|
|
|
|
+ def afficheEcranEditionCreatures(self, creature = None):
|
|
|
|
|
+ """affiche l'ecran d'edition/creation de creatures"""
|
|
|
|
|
+ self.editionCreature = EcranEditionCreature(creature, self.formeCases)
|
|
|
|
|
+ self.editionCreature.setAttribute(Qt.WA_DeleteOnClose)
|
|
|
|
|
+ self.connect(self.fenetre, SIGNAL("majListCreatures()"), self.majListCreatures)
|
|
|
|
|
+ self.connect(self.editionCreature, SIGNAL("majListCreatures()"), self.majListCreatures)
|
|
|
|
|
+ r = self.editionCreature.exec_()
|
|
|
|
|
+
|
|
|
|
|
+ def majListCreatures(self):
|
|
|
|
|
+ """mise a jour de la liste des creatures depuis la sauvegarde"""
|
|
|
|
|
+ dico = afficheSvg("biblio\\creature")
|
|
|
|
|
+ while self.fenetre.ui.listCreatures.rowCount() > 0:
|
|
|
|
|
+ self.fenetre.ui.listCreatures.removeRow(0)
|
|
|
|
|
+ index = 0
|
|
|
|
|
+ #self.fenetre.ui.listTerrains.setColumnWidth(0,0)
|
|
|
|
|
+ self.fenetre.ui.listCreatures.hideColumn(0)
|
|
|
|
|
+ self.fenetre.ui.listCreatures.sizeHintForColumn(1)
|
|
|
|
|
+ for elt in dico:
|
|
|
|
|
+ creature = dico[elt]
|
|
|
|
|
+ self.fenetre.ui.listCreatures.insertRow(int(index))
|
|
|
|
|
+ self.fenetre.ui.listCreatures.setItem(int(index),0,QTableWidgetItem(QString.fromUtf8(elt)))
|
|
|
|
|
+ icon = QIcon("img\\"+creature.logo)
|
|
|
|
|
+ item = QTableWidgetItem(icon,QString.fromUtf8(creature.nom))
|
|
|
|
|
+ self.fenetre.ui.listCreatures.setItem(int(index),1,item)
|
|
|
|
|
+ index += 1
|
|
|
|
|
+ self.fenetre.ui.listCreatures.setIconSize(QSize(30,20))
|
|
|
|
|
+ self.fenetre.ui.listCreatures.sizeHintForColumn(1)
|
|
|
|
|
+## self.fenetre.ui.listCreatures.sortItems(0)
|
|
|
|
|
+ trierTable(self.fenetre.ui.listCreatures, 0, 0)
|
|
|
|
|
+ self.majMode("standard")
|
|
|
|
|
+
|
|
|
|
|
+ def creatureEdit(self):
|
|
|
|
|
+ """ouvre la fenetre 'creatures' en mode edition"""
|
|
|
|
|
+ index = self.fenetre.ui.listCreatures.item(self.fenetre.ui.listCreatures.currentRow(), 0)
|
|
|
|
|
+ if index > 0:
|
|
|
|
|
+ creature = charger("biblio\\creature", str(index.text().toUtf8()))
|
|
|
|
|
+ self.afficheEcranEditionCreatures(creature)
|
|
|
|
|
+
|
|
|
|
|
+ def creatureNouveau(self):
|
|
|
|
|
+ """ouvre la fenetre 'creatures' en mode edition"""
|
|
|
|
|
+ self.afficheEcranEditionCreatures()
|
|
|
|
|
+
|
|
|
|
|
+ ###############
|
|
|
|
|
+
|
|
|
|
|
+ ##### affichage de la liste des decors enregistrees, et fonctions d'acces aux donnees""""
|
|
|
|
|
+ def afficheEcranEditionDecors(self, decor = None):
|
|
|
|
|
+ """affiche l'ecran d'edition/creation de decors"""
|
|
|
|
|
+ self.editionDecor = EcranEditionDecors(decor, self.formeCases)
|
|
|
|
|
+ self.editionDecor.setAttribute(Qt.WA_DeleteOnClose)
|
|
|
|
|
+ self.connect(self.fenetre, SIGNAL("majListDecors()"), self.majListDecors)
|
|
|
|
|
+ self.connect(self.editionDecor, SIGNAL("majListDecors()"), self.majListDecors)
|
|
|
|
|
+ r = self.editionDecor.exec_()
|
|
|
|
|
+
|
|
|
|
|
+ def majListDecors(self):
|
|
|
|
|
+ """mise a jour de la liste des decors depuis la sauvegarde"""
|
|
|
|
|
+ dico = afficheSvg("biblio\\decor")
|
|
|
|
|
+ while self.fenetre.ui.listDecors.rowCount() > 0:
|
|
|
|
|
+ self.fenetre.ui.listDecors.removeRow(0)
|
|
|
|
|
+ index = 0
|
|
|
|
|
+ #self.fenetre.ui.listTerrains.setColumnWidth(0,0)
|
|
|
|
|
+ self.fenetre.ui.listDecors.hideColumn(0)
|
|
|
|
|
+ self.fenetre.ui.listDecors.sizeHintForColumn(1)
|
|
|
|
|
+ for elt in dico:
|
|
|
|
|
+ decor = dico[elt]
|
|
|
|
|
+ self.fenetre.ui.listDecors.insertRow(int(index))
|
|
|
|
|
+ self.fenetre.ui.listDecors.setItem(int(index),0,QTableWidgetItem(QString.fromUtf8(elt)))
|
|
|
|
|
+ icon = QIcon("img\\"+decor.logo)
|
|
|
|
|
+ item = QTableWidgetItem(icon,QString.fromUtf8(decor.nom))
|
|
|
|
|
+ self.fenetre.ui.listDecors.setItem(int(index),1,item)
|
|
|
|
|
+ index += 1
|
|
|
|
|
+ self.fenetre.ui.listDecors.setIconSize(QSize(30,20))
|
|
|
|
|
+ self.fenetre.ui.listDecors.sizeHintForColumn(1)
|
|
|
|
|
+## self.fenetre.ui.listDecors.sortItems(0)
|
|
|
|
|
+ trierTable(self.fenetre.ui.listDecors, 0, 0)
|
|
|
|
|
+ self.majMode("standard")
|
|
|
|
|
+
|
|
|
|
|
+ def decorEdit(self):
|
|
|
|
|
+ """ouvre la fenetre 'decors' en mode edition"""
|
|
|
|
|
+ index = self.fenetre.ui.listDecors.item(self.fenetre.ui.listDecors.currentRow(), 0)
|
|
|
|
|
+ if index > 0:
|
|
|
|
|
+ decor = charger("biblio\\decor", str(index.text().toUtf8()))
|
|
|
|
|
+ self.afficheEcranEditionDecors(decor)
|
|
|
|
|
+
|
|
|
|
|
+ def decorNouveau(self):
|
|
|
|
|
+ """ouvre la fenetre 'decors' en mode edition"""
|
|
|
|
|
+ self.afficheEcranEditionDecors()
|
|
|
|
|
+
|
|
|
|
|
+ ###############
|
|
|
|
|
+
|
|
|
|
|
+ ########### affichage des curseurs personnalises ########
|
|
|
|
|
+ def curseurSelection(self):
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+ curseurPix = QPixmap("img\\curseurEpee.png")#.scaledToHeight(55, Qt.FastTransformation)
|
|
|
|
|
+ curseurPix.setMask(curseurPix.createHeuristicMask())
|
|
|
|
|
+ curseurPointe = QCursor(curseurPix, 0, 0)
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setCursor(curseurPointe)
|
|
|
|
|
+
|
|
|
|
|
+ def curseurPinceau(self):
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+ curseurPix = QPixmap("img\\curseurPinceau.png")
|
|
|
|
|
+ curseurPinceau = QCursor(curseurPix, 0, curseurPix.height())
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setCursor(curseurPinceau)
|
|
|
|
|
+
|
|
|
|
|
+ def curseurGomme(self):
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+ curseurPix = QPixmap("img\\gomme.png")#.scaledToHeight(55, Qt.FastTransformation)
|
|
|
|
|
+ curseurGomme = QCursor(curseurPix, 0, 0)
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setCursor(curseurGomme)
|
|
|
|
|
+
|
|
|
|
|
+ def curseurSeringue(self):
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+ curseurPix = QPixmap("img\\curseurSeringue.png")
|
|
|
|
|
+ curseurSeringue = QCursor(curseurPix, 0, 0)
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setCursor(curseurSeringue)
|
|
|
|
|
+
|
|
|
|
|
+ def curseurEpee(self, valide = True):
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+ if valide:
|
|
|
|
|
+ curseurPix = QPixmap("img\\curseurEpee.png")
|
|
|
|
|
+ curseurSeringue = QCursor(curseurPix, 0, 0)
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setCursor(curseurSeringue)
|
|
|
|
|
+
|
|
|
|
|
+ def curseurArc(self):
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+ curseurPix = QPixmap("img\\arc.png")
|
|
|
|
|
+ curseurSeringue = QCursor(curseurPix, curseurPix.width(), 0)
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setCursor(curseurSeringue)
|
|
|
|
|
+
|
|
|
|
|
+ def curseurBaguette(self):
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+ curseurPix = QPixmap("img\\baguette.png")
|
|
|
|
|
+ curseurBaguette = QCursor(curseurPix, curseurPix.width(), 0)
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setCursor(curseurBaguette)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ ############
|
|
|
|
|
+
|
|
|
|
|
+ ##### activation des differents modes d'interaction avec le plateau et mises a jour des principaux parametres #######
|
|
|
|
|
+ def plateauModeCreation(self):
|
|
|
|
|
+ self.fenetre.majVisibilitePanneauxPlateau("creation")
|
|
|
|
|
+ self.modePrincipal = "creation"
|
|
|
|
|
+
|
|
|
|
|
+ def plateauModeCombat(self):
|
|
|
|
|
+ self.fenetre.majVisibilitePanneauxPlateau("combat")
|
|
|
|
|
+ self.modePrincipal = "combat"
|
|
|
|
|
+
|
|
|
|
|
+ def majModeAffichage(self, index):
|
|
|
|
|
+ """met a jour le mode d'affichage"""
|
|
|
|
|
+ nouveauMode = ""
|
|
|
|
|
+ if index == 0:
|
|
|
|
|
+ #passe a l'affichage standard
|
|
|
|
|
+ pass
|
|
|
|
|
+ elif index == 1:
|
|
|
|
|
+ #passe en mode affichage de l'altitude
|
|
|
|
|
+ nouveauMode = "altitude"
|
|
|
|
|
+ elif index == 2:
|
|
|
|
|
+ #affichage des terrains slt
|
|
|
|
|
+ nouveauMode = "terrain"
|
|
|
|
|
+ elif index == 3:
|
|
|
|
|
+ #affichage tactique
|
|
|
|
|
+ nouveauMode = "tactique"
|
|
|
|
|
+
|
|
|
|
|
+ for coord in self.cases:
|
|
|
|
|
+ self.cases[coord].majAffichageSpecial(nouveauMode)
|
|
|
|
|
+
|
|
|
|
|
+ def modePeintureCase(self):
|
|
|
|
|
+ """enclenche le mode peinture de case a partir de la couleur selectionnee"""
|
|
|
|
|
+ self.majMode("standard")
|
|
|
|
|
+ couleur = self.chercherCouleur()
|
|
|
|
|
+ if couleur.isValid():
|
|
|
|
|
+ self.majMode("caseMajTerrain", couleur)
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.majMode("standard")
|
|
|
|
|
+
|
|
|
|
|
+ def modePeintureCase_perso(self):
|
|
|
|
|
+ origine = self.sender().objectName()
|
|
|
|
|
+ index = int(origine.replace("terrainCouleurPerso",""))-1
|
|
|
|
|
+ couleur = QColor(QColorDialog(self.fenetre.ui.vuePlateau).customColor(index))
|
|
|
|
|
+ if couleur.isValid():
|
|
|
|
|
+ self.majMode("caseMajTerrain", couleur)
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.majMode("standard")
|
|
|
|
|
+
|
|
|
|
|
+ def modeCopieTerrain(self):
|
|
|
|
|
+ """enclenche le mode copie de case"""
|
|
|
|
|
+ self.majMode("caseCopie")
|
|
|
|
|
+
|
|
|
|
|
+ def modeCaseEffet(self):
|
|
|
|
|
+ """enclenche le mode de mise a jour de l'ffet actif des cases"""
|
|
|
|
|
+ self.majMode("standard")
|
|
|
|
|
+ origine = self.sender().objectName()
|
|
|
|
|
+ if origine == "effFeu":
|
|
|
|
|
+ effet = "brule"
|
|
|
|
|
+ elif origine == "effEau":
|
|
|
|
|
+ effet = "eau"
|
|
|
|
|
+ elif origine == "effGlace":
|
|
|
|
|
+ effet = "glace"
|
|
|
|
|
+ elif origine == "effPoison":
|
|
|
|
|
+ effet = "poison"
|
|
|
|
|
+ elif origine == "effEffacer":
|
|
|
|
|
+ effet = "aucun"
|
|
|
|
|
+
|
|
|
|
|
+ self.majMode("caseMajEffet", effet)
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setFocus()
|
|
|
|
|
+
|
|
|
|
|
+ def modeCreationPion(self):
|
|
|
|
|
+ """enclenche le mode de creation de pions simples"""
|
|
|
|
|
+ self.majMode("pionCreation")
|
|
|
|
|
+
|
|
|
|
|
+ def majModePionSupprimer(self):
|
|
|
|
|
+ """enclenche le mode suppression de pions sur clic gauche (creatures ou decors)"""
|
|
|
|
|
+ self.majMode("pionSupprimer")
|
|
|
|
|
+
|
|
|
|
|
+ def modeCreationDecor(self, ligne, col):
|
|
|
|
|
+ """enclenche le mode de creation de decors depuis la liste des decors"""
|
|
|
|
|
+ index = self.fenetre.ui.listDecors.item(ligne, 0)
|
|
|
|
|
+ decor = charger("biblio\\decor", str(index.text().toUtf8()))
|
|
|
|
|
+ self.majMode("pionDecorCreation", decor)
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setFocus()
|
|
|
|
|
+
|
|
|
|
|
+ def modeCreationCreaturePion(self, ligne, col):
|
|
|
|
|
+ """enclenche le mode de creation de pions depuis la liste des creatures"""
|
|
|
|
|
+ index = self.fenetre.ui.listCreatures.item(ligne, 0)
|
|
|
|
|
+ creature = charger("biblio\\creature", str(index.text().toUtf8()))
|
|
|
|
|
+ self.majMode("pionCreation", creature)
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setFocus()
|
|
|
|
|
+
|
|
|
|
|
+ def modeMajTerrainCase(self, ligne, col):
|
|
|
|
|
+ """enclenche le mode permettant la mise a jour du terrain des cases"""
|
|
|
|
|
+ index = self.fenetre.ui.listTerrains.item(ligne, 0)
|
|
|
|
|
+ terrain = charger("biblio\\terrain", str(index.text().toUtf8()))
|
|
|
|
|
+ self.majMode("caseMajTerrain", terrain)
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setFocus()
|
|
|
|
|
+
|
|
|
|
|
+ def majCouleurPion(self):
|
|
|
|
|
+ """selectionne une nouvelle couleur"""
|
|
|
|
|
+ self.majMode("standard")
|
|
|
|
|
+ couleur = self.chercherCouleur()
|
|
|
|
|
+ if couleur.isValid():
|
|
|
|
|
+ self.modeParam["couleurPion"] = couleur
|
|
|
|
|
+ self.fenetre.ui.pionCouleur.setStyleSheet("QPushButton {backGround:%s}" %(self.modeParam["couleurPion"].name()))
|
|
|
|
|
+
|
|
|
|
|
+ def majEpaisseurPinceau(self, epaisseur):
|
|
|
|
|
+ """met a jour l'epaisseur du pinceau (en cases)"""
|
|
|
|
|
+ self.fenetre.ui.valeurEpaisseurPinceau.setText(QString.fromUtf8(str(epaisseur)))
|
|
|
|
|
+ self.epaisseurPinceau = int(epaisseur)
|
|
|
|
|
+
|
|
|
|
|
+ def modeMajAltitudeCase(self):
|
|
|
|
|
+ self.majMode("caseMajAltitude")
|
|
|
|
|
+
|
|
|
|
|
+ def majModeForme(self):
|
|
|
|
|
+ """met a jour la forme utilisee pour la peinture"""
|
|
|
|
|
+ bouton = self.sender().objectName()
|
|
|
|
|
+ if bouton == "formeSimple":
|
|
|
|
|
+ self.modeParam["typeFormeDessin"] = "simple"
|
|
|
|
|
+ elif bouton == "formeLigne":
|
|
|
|
|
+ self.modeParam["typeFormeDessin"] = "ligne"
|
|
|
|
|
+ elif bouton == "formeLigneOrientee":
|
|
|
|
|
+ self.modeParam["typeFormeDessin"] = "frontiere"
|
|
|
|
|
+ elif bouton == "formeEllipseVide":
|
|
|
|
|
+ self.modeParam["typeFormeDessin"] = "ellipseV"
|
|
|
|
|
+ elif bouton == "formeEllipsePlein":
|
|
|
|
|
+ self.modeParam["typeFormeDessin"] = "ellipseP"
|
|
|
|
|
+ elif bouton == "formeRectVide":
|
|
|
|
|
+ self.modeParam["typeFormeDessin"] = "rectV"
|
|
|
|
|
+ elif bouton == "formeRectPlein":
|
|
|
|
|
+ self.modeParam["typeFormeDessin"] = "rectP"
|
|
|
|
|
+
|
|
|
|
|
+ if self.modeActif[0:7] != "caseMaj":
|
|
|
|
|
+ self.majMode("caseMajTerrain", self.modeParam["terrain"])
|
|
|
|
|
+
|
|
|
|
|
+ def majAffichageMenuCache(self):
|
|
|
|
|
+ """un bouton 'cache' a ete clique, on met a jour les infos"""
|
|
|
|
|
+ origine = self.sender().objectName()
|
|
|
|
|
+ index = int(origine.replace("plateauCache",""))
|
|
|
|
|
+ self.cacheEnCours = index
|
|
|
|
|
+ for i in range(1,5):
|
|
|
|
|
+ bouton = self.fenetre.ui.outilsEditionPlateau.findChild(QToolButton, "plateauCache{}".format(i))
|
|
|
|
|
+ bouton.setCheckable(True)
|
|
|
|
|
+ bouton.setChecked((i == index))
|
|
|
|
|
+ self.fenetre.ui.cacheActif.setChecked(self.caches[index]["actif"])
|
|
|
|
|
+ self.voirCacheEnCours()
|
|
|
|
|
+
|
|
|
|
|
+ def majModeCombatDeplacement(self):
|
|
|
|
|
+ """active le mode de combat 'deplacement' (mode standard)"""
|
|
|
|
|
+ self.majModeCombat("combatDeplacement")
|
|
|
|
|
+
|
|
|
|
|
+ def majModeCombatAttaqueCaC(self):
|
|
|
|
|
+ """active le mode de combat 'corps-a-corps'"""
|
|
|
|
|
+ self.majModeCombat("combatAttaqueCaC")
|
|
|
|
|
+
|
|
|
|
|
+ def majModeCombatAttaqueDist(self):
|
|
|
|
|
+ """active le mode de combat 'attaque a distance'"""
|
|
|
|
|
+ self.majModeCombat("combatAttaqueDist")
|
|
|
|
|
+
|
|
|
|
|
+ def majModeCombatZone(self):
|
|
|
|
|
+ if not len(self.modeParam["typeAttaqueZone"]) > 0: self.modeParam["typeAttaqueZone"] = "ligne"
|
|
|
|
|
+ self.majModeCombat("combatAttaqueZone")
|
|
|
|
|
+
|
|
|
|
|
+ def majModeCombatZoneForme(self):
|
|
|
|
|
+ if self.modeCombat == "combatAttaqueZone":
|
|
|
|
|
+ origine = self.sender().objectName()
|
|
|
|
|
+ self.modeParam["typeAttaqueZone"] = str(origine).split("_")[1]
|
|
|
|
|
+ self.majModeCombat("combatAttaqueZone")
|
|
|
|
|
+
|
|
|
|
|
+ def majModeDefinirEntree(self):
|
|
|
|
|
+ self.modeParam["entreeSortie"] = EntreeSortie(self, "E")
|
|
|
|
|
+ self.modeParam["entreeSortie"].creerForme()
|
|
|
|
|
+ self.majMode("placementEntreeSortie")
|
|
|
|
|
+
|
|
|
|
|
+ def majModeDefinirSortie(self):
|
|
|
|
|
+ self.modeParam["entreeSortie"] = EntreeSortie(self, "S")
|
|
|
|
|
+ self.modeParam["entreeSortie"].creerForme()
|
|
|
|
|
+ self.majMode("placementEntreeSortie")
|
|
|
|
|
+
|
|
|
|
|
+ def majModeZonePlacement(self):
|
|
|
|
|
+ self.majMode("majZonePlacement")
|
|
|
|
|
+
|
|
|
|
|
+ def majMode(self, mode = "standard", param = None):
|
|
|
|
|
+ """modifie ou reinitialise le type d'interaction avec le plateau"""
|
|
|
|
|
+ reinit = True #doit-on reinitialiser a la fin de l'operation
|
|
|
|
|
+ ##on desactive le mode precedent
|
|
|
|
|
+ if self.pionSelectionne() != None:
|
|
|
|
|
+ self.pionSelectionne().afficheOmbreSelection(False)
|
|
|
|
|
+ if self.modeActif == "pionSelectionne":
|
|
|
|
|
+ self.majModeCombat("")
|
|
|
|
|
+ self.modeParam["numPionSelectionne"] = 0
|
|
|
|
|
+ elif self.pionDecorSelectionne() != None:
|
|
|
|
|
+ self.pionDecorSelectionne().afficheOmbreSelection(False)
|
|
|
|
|
+ self.modeParam["numPionSelectionne"] = 0
|
|
|
|
|
+
|
|
|
|
|
+ if self.modeActif == "pionSelectionne" or self.modeActif == "pionCreation" or self.modeActif == "pionDecorSelectionne" or self.modeActif == "pionDecorCreation":
|
|
|
|
|
+ self.majProjectionPosition(False)
|
|
|
|
|
+ self.modeParam["formeProjectionPosition"] = None
|
|
|
|
|
+ self.modeParam["coordProjectionPosition"] = None
|
|
|
|
|
+ self.modeParam["nbRotations"] = 0
|
|
|
|
|
+
|
|
|
|
|
+ if self.modeActif[0:7] == "caseMaj" or self.modeActif == "cachePlacer" or self.modeActif == "majZonePlacement":
|
|
|
|
|
+ if self.modeParam["formeDessin"] != None:
|
|
|
|
|
+ self.modeParam["formeDessin"].prepareGeometryChange()
|
|
|
|
|
+ self.removeItem(self.modeParam["formeDessin"])
|
|
|
|
|
+ self.modeParam["formeDessin"] = None
|
|
|
|
|
+ self.modeParam["origineFormeDessin"] = None
|
|
|
|
|
+ self.modeParam["point2FormeDessin"] = None
|
|
|
|
|
+
|
|
|
|
|
+ self.afficherListeCases(self.modeParam["listeCasesFormeDessin"], False)
|
|
|
|
|
+ self.modeParam["listeCasesFormeDessin"] = []
|
|
|
|
|
+
|
|
|
|
|
+ if self.modeActif == "placementEntreeSortie":
|
|
|
|
|
+ if self.modeParam["entreeSortie"] != None:
|
|
|
|
|
+ self.modeParam["entreeSortie"].prepareGeometryChange()
|
|
|
|
|
+ self.removeItem(self.modeParam["entreeSortie"])
|
|
|
|
|
+ self.modeParam["entreeSortie"] = None
|
|
|
|
|
+
|
|
|
|
|
+ ### definition du nouveau mode
|
|
|
|
|
+ if mode in self.listMode and mode != "standard":
|
|
|
|
|
+ self.modeActif = mode
|
|
|
|
|
+ reinit = False
|
|
|
|
|
+ if mode == "caseMajTerrain":
|
|
|
|
|
+ #curseur pinceau, on ajoute des terrains au cases
|
|
|
|
|
+ if param != None:
|
|
|
|
|
+ self.curseurPinceau()
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+ self.modeParam["terrain"] = param
|
|
|
|
|
+
|
|
|
|
|
+ elif mode == "caseCopie":
|
|
|
|
|
+ #curseur seringue, on 'preleve' le terrain sur la case cliquee, avant de passer en mode majTerrain
|
|
|
|
|
+ self.curseurSeringue()
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+
|
|
|
|
|
+ elif mode == "caseMajEffet":
|
|
|
|
|
+ #on met a jour l'effet actif sur les cases
|
|
|
|
|
+ if param != None:
|
|
|
|
|
+ self.curseurPinceau()
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+ self.modeParam["effet"] = param
|
|
|
|
|
+
|
|
|
|
|
+ elif mode == "caseMajAltitude":
|
|
|
|
|
+ self.curseurPinceau()
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+
|
|
|
|
|
+ elif mode == "cachePlacer":
|
|
|
|
|
+ self.curseurPinceau()
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+ self.modeParam["typeFormeDessin"] = "rectP"
|
|
|
|
|
+
|
|
|
|
|
+ elif mode == "majZonePlacement":
|
|
|
|
|
+ self.curseurPinceau()
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+ self.modeParam["typeFormeDessin"] = "rectP"
|
|
|
|
|
+
|
|
|
|
|
+ elif mode == "placementEntreeSortie":
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+
|
|
|
|
|
+ elif mode == "pionDecorCreation":
|
|
|
|
|
+ #curseur 'plus', on cree de nouveaux decors
|
|
|
|
|
+ self.modeParam["decor"] = None
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+ self.modeParam["formeProjectionPosition"] = Forme(self.formeCases)
|
|
|
|
|
+ self.modeParam["nbRotations"] = 0
|
|
|
|
|
+ if param != None:
|
|
|
|
|
+ if param.__class__.__name__ == "Decor":
|
|
|
|
|
+ self.modeParam["decor"] = param
|
|
|
|
|
+ self.modeParam["formeProjectionPosition"].definirForme(self.modeParam["decor"].formeDef[self.formeCases])
|
|
|
|
|
+
|
|
|
|
|
+ elif mode == "pionDecorSelectionne":
|
|
|
|
|
+ #un pion decor est selectionne
|
|
|
|
|
+ if param != None:
|
|
|
|
|
+ self.modeParam["numPionSelectionne"] = param
|
|
|
|
|
+ self.pionDecorSelectionne().afficheOmbreSelection(True)
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setCursor(QCursor(Qt.ArrowCursor))
|
|
|
|
|
+ self.modeParam["formeProjectionPosition"] = Forme(self.formeCases)
|
|
|
|
|
+ self.modeParam["formeProjectionPosition"].definirForme(self.pionDecorSelectionne().forme.formeDef)
|
|
|
|
|
+ self.modeParam["nbRotations"] = self.pionDecorSelectionne().nbRotations
|
|
|
|
|
+
|
|
|
|
|
+ elif mode == "pionCreation":
|
|
|
|
|
+ #curseur 'plus', on cree de nouveaux pions
|
|
|
|
|
+ self.modeParam["creature"] = None
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+ self.modeParam["formeProjectionPosition"] = Forme(self.formeCases)
|
|
|
|
|
+ self.modeParam["nbRotations"] = 0
|
|
|
|
|
+ if param != None:
|
|
|
|
|
+ if param.__class__.__name__ == "Creature":
|
|
|
|
|
+ self.modeParam["creature"] = param
|
|
|
|
|
+ self.modeParam["formeProjectionPosition"].definirForme(self.modeParam["creature"].formeDef[self.formeCases])
|
|
|
|
|
+
|
|
|
|
|
+ elif mode == "pionSupprimer":
|
|
|
|
|
+ #mode suppression de pions/pions decors
|
|
|
|
|
+ self.curseurGomme()
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+
|
|
|
|
|
+ elif mode == "pionSelectionne":
|
|
|
|
|
+ #un pion est selectionne, on affiche les deplacements possibles
|
|
|
|
|
+ if param != None:
|
|
|
|
|
+ self.modeParam["numPionSelectionne"] = param
|
|
|
|
|
+ self.pionSelectionne().afficheOmbreSelection(True)
|
|
|
|
|
+ self.numPionEnCours = param
|
|
|
|
|
+ for i in range(0, self.fenetre.ui.infoOrdreJeu.rowCount()):
|
|
|
|
|
+ if str(self.fenetre.ui.infoOrdreJeu.item(i, 0).text().toUtf8()) == str(param):
|
|
|
|
|
+ self.fenetre.ui.infoOrdreJeu.setCurrentCell(i,0)
|
|
|
|
|
+
|
|
|
|
|
+ self.majAffichagePionSelectionne()
|
|
|
|
|
+ self.majListeAttributs()
|
|
|
|
|
+ self.afficherNotesPion()
|
|
|
|
|
+ self.majListeAttaques()
|
|
|
|
|
+ self.majModeCombat("aucun")
|
|
|
|
|
+
|
|
|
|
|
+ elif not mode in self.listMode:
|
|
|
|
|
+ print("mode non reconnu")
|
|
|
|
|
+
|
|
|
|
|
+ ##on reinitialise si necessaire
|
|
|
|
|
+ if reinit:
|
|
|
|
|
+ #mode standard : pas d'interaction avec les cases, on deplace le plateau en le saisissant ou les pions en cliquant dessus
|
|
|
|
|
+ self.modeActif = "standard"
|
|
|
|
|
+ self.majAffichagePionSelectionne()
|
|
|
|
|
+ self.majInfosPion()
|
|
|
|
|
+ self.majInfosDecor()
|
|
|
|
|
+ self.majListeAttributs()
|
|
|
|
|
+ self.majListeAttaques()
|
|
|
|
|
+ self.afficherNotesPion()
|
|
|
|
|
+ self.fenetre.majVisibiliteBarreCombat("menu")
|
|
|
|
|
+ QApplication.processEvents()
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setCursor(QCursor(Qt.ArrowCursor))
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(1)
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setFocus()
|
|
|
|
|
+
|
|
|
|
|
+ def majModeCombat(self, mode = ""):
|
|
|
|
|
+ """met a jour le mode de combat actif pour le pion selectionne"""
|
|
|
|
|
+ ## on desactive le mode precedent si besoin
|
|
|
|
|
+ #la projection de position
|
|
|
|
|
+
|
|
|
|
|
+ if self.modeCombat == "combatDeplacement":
|
|
|
|
|
+ #le champ de deplacement
|
|
|
|
|
+ if self.modePrincipal == "combat":
|
|
|
|
|
+ self.afficherChampDeplacement(False)
|
|
|
|
|
+ self.majProjectionPosition(False)
|
|
|
|
|
+ self.modeParam["formeProjectionPosition"] = None
|
|
|
|
|
+ self.modeParam["coordProjectionPosition"] = None
|
|
|
|
|
+ self.modeParam["nbRotations"] = 0
|
|
|
|
|
+
|
|
|
|
|
+ elif self.modeCombat == "combatAttaqueCaC":
|
|
|
|
|
+ #la zone d'attaque au cac
|
|
|
|
|
+ self.materialiserPions(True)
|
|
|
|
|
+ self.majZoneAttaqueCaC(False)
|
|
|
|
|
+ self.modeParam["zoneAttaqueCaC"] = []
|
|
|
|
|
+ if self.modeParam["cibleAttaqueCaC"] != None:
|
|
|
|
|
+ self.modeParam["cibleAttaqueCaC"].estCibleAttaque(False)
|
|
|
|
|
+ self.modeParam["cibleAttaqueCaC"] = None
|
|
|
|
|
+
|
|
|
|
|
+ elif self.modeCombat == "combatAttaqueDist":
|
|
|
|
|
+ self.materialiserPions(True)
|
|
|
|
|
+ self.majLigneMireAttaqueDist()
|
|
|
|
|
+
|
|
|
|
|
+ elif self.modeCombat == "combatAttaqueZone":
|
|
|
|
|
+ #l'attaque de zone
|
|
|
|
|
+ self.materialiserPions(True)
|
|
|
|
|
+ QApplication.processEvents()
|
|
|
|
|
+ self.reinitAttaqueZone()
|
|
|
|
|
+ if mode != "combatAttaqueZone": self.fenetre.majVisibiliteBarreCombat("menu")
|
|
|
|
|
+ self.modeParam["listeCasesAttaqueZone"] = []
|
|
|
|
|
+
|
|
|
|
|
+ ## maj de l'aspect des boutons selon le mode demande
|
|
|
|
|
+ for item in self.fenetre.ui.barreBasCombat.children():
|
|
|
|
|
+ if item.__class__.__name__ == "QToolButton":
|
|
|
|
|
+ if item.isCheckable():
|
|
|
|
|
+ item.setChecked((item.objectName() == mode and self.pionSelectionne() != None))
|
|
|
|
|
+ if mode == "combatAttaqueZone":
|
|
|
|
|
+ item.setChecked((item.objectName() == "combatZone_{}".format(self.modeParam["typeAttaqueZone"])\
|
|
|
|
|
+ and self.pionSelectionne() != None))
|
|
|
|
|
+
|
|
|
|
|
+ ## definition du nouveau mode de combat
|
|
|
|
|
+ if self.pionSelectionne() != None:
|
|
|
|
|
+ self.modeCombat = mode
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setDragMode(0)
|
|
|
|
|
+ self.fenetre.ui.combatVol_altitude.setValue(self.pionSelectionne().z)
|
|
|
|
|
+ if mode == "aucun":
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setCursor(QCursor(Qt.ArrowCursor))
|
|
|
|
|
+
|
|
|
|
|
+ if mode == "combatDeplacement":
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.setCursor(QCursor(Qt.ArrowCursor))
|
|
|
|
|
+ self.modeParam["formeProjectionPosition"] = Forme(self.formeCases)
|
|
|
|
|
+ self.modeParam["formeProjectionPosition"].definirForme(self.pionSelectionne().forme.formeDef)
|
|
|
|
|
+ self.modeParam["nbRotations"] = self.pionSelectionne().nbRotations
|
|
|
|
|
+
|
|
|
|
|
+ if self.modePrincipal == "combat":
|
|
|
|
|
+ #si mode combat, affichage de la zone de deplacement
|
|
|
|
|
+ self.afficherChampDeplacement(True)
|
|
|
|
|
+
|
|
|
|
|
+ elif mode == "combatAttaqueCaC":
|
|
|
|
|
+ self.curseurEpee()
|
|
|
|
|
+ self.materialiserPions(False)
|
|
|
|
|
+ self.modeParam["zoneAttaqueCaC"] = self.zone(self.pionSelectionne().position, self.pionSelectionne().creature.allonge, True, True)
|
|
|
|
|
+ self.majZoneAttaqueCaC(True)
|
|
|
|
|
+
|
|
|
|
|
+ elif mode == "combatAttaqueDist":
|
|
|
|
|
+ self.curseurArc()
|
|
|
|
|
+ self.materialiserPions(False)
|
|
|
|
|
+
|
|
|
|
|
+ elif mode == "combatAttaqueZone":
|
|
|
|
|
+ self.curseurBaguette()
|
|
|
|
|
+ self.materialiserPions(False)
|
|
|
|
|
+ self.majFormeAttaqueZone()
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.fenetre.ui.combatVol_altitude.setValue(0)
|
|
|
|
|
+
|
|
|
|
|
+ ###############
|
|
|
|
|
+
|
|
|
|
|
+ ########## Gestion du combat ##############
|
|
|
|
|
+ def majAffichageTour(self):
|
|
|
|
|
+ """met a jour l'affichage du tour en cours"""
|
|
|
|
|
+ self.fenetre.ui.combatTour.setText(QString.fromUtf8("Tour: {}".format(self.tour)))
|
|
|
|
|
+
|
|
|
|
|
+ def majAffichagePionSelectionne(self):
|
|
|
|
|
+ """affiche le nom et le logo du pion actuellement selectionne"""
|
|
|
|
|
+ if self.pionSelectionne() != None:
|
|
|
|
|
+ self.fenetre.ui.combatPionSelectionne.setText(QString.fromUtf8(self.pionSelectionne().txtId()))
|
|
|
|
|
+ if len(self.pionSelectionne().creature.img["nom"]) > 0:
|
|
|
|
|
+ pix = QPixmap(QString.fromUtf8("img\\"+self.pionSelectionne().creature.img["nom"]))
|
|
|
|
|
+ pix = pix.scaled(44, 44, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
|
|
|
|
+ self.fenetre.ui.combatPionSelectionne_img.setPixmap(pix)
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.fenetre.ui.combatPionSelectionne_img.setPixmap(QPixmap())
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.fenetre.ui.combatPionSelectionne_img.setPixmap(QPixmap())
|
|
|
|
|
+ self.fenetre.ui.combatPionSelectionne.setText(QString.fromUtf8("Pas de pion selectionné"))
|
|
|
|
|
+
|
|
|
|
|
+ def initListeOrdreJeu(self):
|
|
|
|
|
+ """cree les colonnes et met en forme la table ordre jeu"""
|
|
|
|
|
+## self.fenetre.ui.infoOrdreJeu.setColumnWidth(0, 20)
|
|
|
|
|
+ self.fenetre.ui.infoOrdreJeu.setColumnWidth(2, 30)
|
|
|
|
|
+ self.fenetre.ui.infoOrdreJeu.hideColumn(0)
|
|
|
|
|
+## self.fenetre.ui.infoOrdreJeu.hideColumn(2)
|
|
|
|
|
+ self.fenetre.ui.infoOrdreJeu.setIconSize(QSize(30,20))
|
|
|
|
|
+
|
|
|
|
|
+ def majListeOrdreJeu(self):
|
|
|
|
|
+ """met a jour la liste des pions infoOrdreJeu"""
|
|
|
|
|
+ while self.fenetre.ui.infoOrdreJeu.rowCount() > 0:
|
|
|
|
|
+ self.fenetre.ui.infoOrdreJeu.removeRow(0)
|
|
|
|
|
+ index = 0
|
|
|
|
|
+ for num in self.ordreJeu:
|
|
|
|
|
+ self.fenetre.ui.infoOrdreJeu.insertRow(int(index))
|
|
|
|
|
+ self.fenetre.ui.infoOrdreJeu.setItem(int(index), 0, QTableWidgetItem(QString.fromUtf8(str(num))))
|
|
|
|
|
+ icon = QIcon("img\\"+self.pions[num].creature.logo)
|
|
|
|
|
+ item = QTableWidgetItem(icon,QString.fromUtf8(self.pions[num].txtId()))
|
|
|
|
|
+ self.fenetre.ui.infoOrdreJeu.setItem(int(index), 1, item)
|
|
|
|
|
+ self.fenetre.ui.infoOrdreJeu.setItem(int(index), 2, QTableWidgetItem(QString.fromUtf8(str(self.ordreJeu[num]))))
|
|
|
|
|
+ index += 1
|
|
|
|
|
+
|
|
|
|
|
+ self.fenetre.ui.infoOrdreJeu.sizeHintForColumn(1)
|
|
|
|
|
+ trierTable(self.fenetre.ui.infoOrdreJeu, 2, 0)
|
|
|
|
|
+
|
|
|
|
|
+ def clicListOrdreJeu(self, ligne, col):
|
|
|
|
|
+ """on a clique dans la liste d'ordre de jeu, le pion correspondant est selectionne et centre sur la carte"""
|
|
|
|
|
+ numPion = int(self.fenetre.ui.infoOrdreJeu.item(ligne, 0).text().toUtf8())
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.centerOn(self.cases[self.pions[numPion].position].centreGraphique)
|
|
|
|
|
+ self.pionSaisir(numPion)
|
|
|
|
|
+
|
|
|
|
|
+ def pionSuivant(self):
|
|
|
|
|
+ """selection du pion suivant dans la liste d'ordre de jeu"""
|
|
|
|
|
+ if self.numPionEnCours in self.pions:
|
|
|
|
|
+ suivant = self.ordreJeu[self.numPionEnCours] + 1
|
|
|
|
|
+ else:
|
|
|
|
|
+ suivant = 1
|
|
|
|
|
+ if suivant > len(self.ordreJeu):
|
|
|
|
|
+ self.tour += 1
|
|
|
|
|
+ self.majAffichageTour()
|
|
|
|
|
+ suivant = 1
|
|
|
|
|
+ for num in self.ordreJeu:
|
|
|
|
|
+ if self.ordreJeu[num] == suivant:
|
|
|
|
|
+ numPion = num
|
|
|
|
|
+ break
|
|
|
|
|
+
|
|
|
|
|
+ for ligne in range(0, self.fenetre.ui.infoOrdreJeu.rowCount()):
|
|
|
|
|
+ item = self.fenetre.ui.infoOrdreJeu.item(ligne, 0)
|
|
|
|
|
+ item.setSelected(int(self.fenetre.ui.infoOrdreJeu.item(ligne, 0).text().toUtf8()) == numPion)
|
|
|
|
|
+ if int(item.text().toUtf8()) == numPion:
|
|
|
|
|
+ self.fenetre.ui.infoOrdreJeu.scrollToItem(item)
|
|
|
|
|
+
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.centerOn(self.cases[self.pions[numPion].position].centreGraphique)
|
|
|
|
|
+ self.pionSaisir(numPion)
|
|
|
|
|
+
|
|
|
|
|
+ def afficheEcranGestionCombat(self):
|
|
|
|
|
+ #*egc
|
|
|
|
|
+ """affiche l'ecran de gestion du combat"""
|
|
|
|
|
+ self.gestionCombat = EcranGestionCombat(self)
|
|
|
|
|
+ self.gestionCombat.show()
|
|
|
|
|
+ self.connect(self.fenetre, SIGNAL("majListesPions"), self.majListesPions)
|
|
|
|
|
+ self.connect(self.gestionCombat, SIGNAL("majListesPions"), self.majListesPions)
|
|
|
|
|
+ QApplication.processEvents()
|
|
|
|
|
+## r = self.gestionCombat.exec_()
|
|
|
|
|
+
|
|
|
|
|
+ def majOrdreJeu(self):
|
|
|
|
|
+ """met a jour l'ordre de jeu des pions en fonction de l'attribut prevu par les regles s'il existe,
|
|
|
|
|
+ ou en fonction de l'ordre de jeu parametre sinon"""
|
|
|
|
|
+ attribut = regles.attributOrdreJeu()
|
|
|
|
|
+ if attribut != None:
|
|
|
|
|
+ dico = {}
|
|
|
|
|
+ for numPion in self.pions:
|
|
|
|
|
+ dico[numPion] = int(self.pions[numPion].lstCarac[attribut])
|
|
|
|
|
+ ordre = sorted(dico, key = dico.get, reverse=(regles.sensTriOrdreJeu() == 1))
|
|
|
|
|
+ self.ordreJeu = {}
|
|
|
|
|
+ for numPion in self.pions:
|
|
|
|
|
+ self.ordreJeu[numPion] = ordre.index(numPion) + 1
|
|
|
|
|
+ self.majListeOrdreJeu()
|
|
|
|
|
+
|
|
|
|
|
+ def pionDeplacerDansOrdreJeu(self, numPion, nouvellePosition):
|
|
|
|
|
+ """deplace un pion dans le dictionnaire gerant l'ordre de jeu de maniere a assurer sa coherence
|
|
|
|
|
+ nouvellePosition = 0 supprime le pion de la liste"""
|
|
|
|
|
+ if numPion in self.ordreJeu:
|
|
|
|
|
+ if nouvellePosition == 0:
|
|
|
|
|
+ del self.ordreJeu[numPion]
|
|
|
|
|
+ if len(self.ordreJeu) > 0:
|
|
|
|
|
+ i = 0
|
|
|
|
|
+ tmp = sorted(self.ordreJeu, key=self.ordreJeu.get)
|
|
|
|
|
+ if numPion in tmp:
|
|
|
|
|
+ tmp.remove(numPion)
|
|
|
|
|
+ for num in tmp:
|
|
|
|
|
+ i += 1
|
|
|
|
|
+ if i == nouvellePosition:
|
|
|
|
|
+ self.ordreJeu[numPion] = i
|
|
|
|
|
+ i += 1
|
|
|
|
|
+ self.ordreJeu[num] = i
|
|
|
|
|
+ if i < nouvellePosition:
|
|
|
|
|
+ self.ordreJeu[numPion] = i + 1
|
|
|
|
|
+ elif nouvellePosition > 0:
|
|
|
|
|
+ self.ordreJeu[numPion] = 1
|
|
|
|
|
+ self.majOrdreJeu()
|
|
|
|
|
+
|
|
|
|
|
+ def majListeAttributs(self):
|
|
|
|
|
+ """met a jour la liste des attributs dans le panneau de combat"""
|
|
|
|
|
+ self.fenetre.ui.listeAttributs.setColumnWidth(0, (0.4*self.fenetre.ui.listeAttributs.width()))
|
|
|
|
|
+ self.fenetre.ui.listeAttributs.setColumnWidth(1, (0.4*self.fenetre.ui.listeAttributs.width()))
|
|
|
|
|
+ self.disconnect(self.fenetre.ui.listeAttributs, SIGNAL("cellChanged(int,int)"), self.listeAttributCelluleModifiee)
|
|
|
|
|
+
|
|
|
|
|
+ #on vide la liste
|
|
|
|
|
+ while self.fenetre.ui.listeAttributs.rowCount() > 0:
|
|
|
|
|
+ self.fenetre.ui.listeAttributs.removeRow(0)
|
|
|
|
|
+ self.fenetre.ui.listeAttributs.setVisible((self.pionSelectionne() != None))
|
|
|
|
|
+ if self.pionSelectionne() != None:
|
|
|
|
|
+ #creation des lignes de base
|
|
|
|
|
+ lignesBase = ["Nom","Etat","Alt."] #attention: modifier aussi dans listeAttributCelluleModifiee
|
|
|
|
|
+ for i in range(0, 10): #10 premieres colonnes reservees pour les infos de base
|
|
|
|
|
+ self.fenetre.ui.listeAttributs.insertRow(i)
|
|
|
|
|
+ item = QTableWidgetItem()
|
|
|
|
|
+ if i < len(lignesBase):
|
|
|
|
|
+ item.setText(QString.fromUtf8(lignesBase[i]))
|
|
|
|
|
+ item.setFlags(Qt.NoItemFlags)
|
|
|
|
|
+ self.fenetre.ui.listeAttributs.setItem(i, 0, item)
|
|
|
|
|
+ self.fenetre.ui.listeAttributs.setRowHidden(i, (i >= len(lignesBase)))
|
|
|
|
|
+
|
|
|
|
|
+ #maj des donnees de base
|
|
|
|
|
+ self.fenetre.ui.listeAttributs.setItem(lignesBase.index("Nom"), 1, QTableWidgetItem(QString.fromUtf8(str(self.pionSelectionne().nom))))
|
|
|
|
|
+ self.fenetre.ui.listeAttributs.setItem(lignesBase.index("Etat"), 1, QTableWidgetItem(QString.fromUtf8(str(self.pionSelectionne().etat))))
|
|
|
|
|
+ self.fenetre.ui.listeAttributs.setItem(lignesBase.index("Alt."), 1, QTableWidgetItem(QString.fromUtf8(str(self.pionSelectionne().z))))
|
|
|
|
|
+
|
|
|
|
|
+ #attributs issus des regles utilisees
|
|
|
|
|
+ ordre = regles.ordreAttributs()
|
|
|
|
|
+ for elt in ordre:
|
|
|
|
|
+ ligne = 10 + ordre.index(elt)
|
|
|
|
|
+ self.fenetre.ui.listeAttributs.insertRow(ligne)
|
|
|
|
|
+ item = QTableWidgetItem(QString.fromUtf8(elt))
|
|
|
|
|
+ item.setFlags(Qt.NoItemFlags)
|
|
|
|
|
+ self.fenetre.ui.listeAttributs.setItem(ligne, 0, item)
|
|
|
|
|
+ self.fenetre.ui.listeAttributs.setItem(ligne, 1, QTableWidgetItem(QString.fromUtf8(str(self.pionSelectionne().lstCarac[elt]))))
|
|
|
|
|
+
|
|
|
|
|
+ self.connect(self.fenetre.ui.listeAttributs, SIGNAL("cellChanged(int,int)"), self.listeAttributCelluleModifiee)
|
|
|
|
|
+
|
|
|
|
|
+ def listeAttributCelluleModifiee(self, ligne, colonne):
|
|
|
|
|
+ """une cellule de la liste des attributs a ete modifiee"""
|
|
|
|
|
+ if colonne != 1:
|
|
|
|
|
+ print("valeur non modifiable")
|
|
|
|
|
+ else:
|
|
|
|
|
+ #on verifie la validite de la donnee entree
|
|
|
|
|
+ lignesBase = ["Nom","Etat","Alt."] #attention: modifier aussi dans majListeAttribut
|
|
|
|
|
+ if ligne < len(lignesBase):
|
|
|
|
|
+ pass
|
|
|
|
|
+ elif ligne >= 10:
|
|
|
|
|
+ attribut = regles.ordreAttributs()[(ligne - 10)]
|
|
|
|
|
+ nouvelleVal = str(self.fenetre.ui.listeAttributs.item(ligne, 1).text().toUtf8())
|
|
|
|
|
+ valVerifiee = regles.listeControle()[attribut].controler(nouvelleVal)
|
|
|
|
|
+ if valVerifiee != None:
|
|
|
|
|
+ self.pionSelectionne().lstCarac[attribut] = valVerifiee
|
|
|
|
|
+ if attribut == regles.attributOrdreJeu():
|
|
|
|
|
+ print("maj ordre (a implementer)")
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.fenetre.ui.listeAttributs.setItem(ligne, 1, QTableWidgetItem(QString.fromUtf8(str(self.pionSelectionne().lstCarac[attribut]))))
|
|
|
|
|
+
|
|
|
|
|
+ def initListeAttaques(self):
|
|
|
|
|
+ """met en forme et connecte la liste des attaques du pion"""
|
|
|
|
|
+ self.fenetre.ui.listeAttaques.setColumnWidth(0, 0)
|
|
|
|
|
+ self.fenetre.ui.listeAttaques.setColumnWidth(1, (0.3*self.fenetre.ui.listeAttaques.width()))
|
|
|
|
|
+ self.fenetre.ui.listeAttaques.setColumnWidth(2, (0.7*self.fenetre.ui.listeAttaques.width()))
|
|
|
|
|
+ self.connect(self.fenetre.ui.listeAttaques, SIGNAL("itemSelectionChanged()"), self.majInfosAttaqueEC)
|
|
|
|
|
+ self.connect(self.fenetre.ui.listeAttaques, SIGNAL("cellClicked(int, int)"), self.listeAttaquesCelluleCliquee)
|
|
|
|
|
+ self.connect(self.fenetre.ui.notesAttaqueEC, SIGNAL("textChanged()"), self.majNotesAttaqueEC)
|
|
|
|
|
+ self.fenetre.ui.listeAttributsAttaqueEC.setColumnWidth(0, (0.49*self.fenetre.ui.listeAttributsAttaqueEC.width()))
|
|
|
|
|
+ self.fenetre.ui.listeAttributsAttaqueEC.setColumnWidth(1, (0.5*self.fenetre.ui.listeAttributsAttaqueEC.width()))
|
|
|
|
|
+
|
|
|
|
|
+ def majListeAttaques(self):
|
|
|
|
|
+ #*eea
|
|
|
|
|
+ """met a jour la liste des attaques du pion dans le panneau de combat"""
|
|
|
|
|
+ #on vide la liste
|
|
|
|
|
+ while self.fenetre.ui.listeAttaques.rowCount() > 0:
|
|
|
|
|
+ self.fenetre.ui.listeAttaques.removeRow(0)
|
|
|
|
|
+
|
|
|
|
|
+ self.fenetre.ui.listeAttaques.setVisible((self.pionSelectionne() != None))
|
|
|
|
|
+ self.fenetre.ui.titreAttaques.setVisible((self.pionSelectionne() != None))
|
|
|
|
|
+ self.fenetre.ui.editerAttaques.setVisible((self.pionSelectionne() != None))
|
|
|
|
|
+ self.fenetre.ui.panneauAttaqueEC.setVisible((self.pionSelectionne() != None))
|
|
|
|
|
+
|
|
|
|
|
+ i = 0
|
|
|
|
|
+ if self.pionSelectionne() != None:
|
|
|
|
|
+ for attaque in self.pionSelectionne().attaques:
|
|
|
|
|
+ self.fenetre.ui.listeAttaques.insertRow(i)
|
|
|
|
|
+ self.fenetre.ui.listeAttaques.setItem(i, 0, QTableWidgetItem(QString.fromUtf8(str(self.pionSelectionne().attaques.index(attaque)))))
|
|
|
|
|
+ icone = None
|
|
|
|
|
+ if attaque.typ == "cac":
|
|
|
|
|
+ icone = QIcon("img\\curseurEpee.png")
|
|
|
|
|
+ if attaque.typ == "dist":
|
|
|
|
|
+ icone = QIcon("img\\arc.png")
|
|
|
|
|
+ if attaque.typ == "zone":
|
|
|
|
|
+ icone = QIcon("img\\baguette.png")
|
|
|
|
|
+ if icone != None:
|
|
|
|
|
+ self.fenetre.ui.listeAttaques.setItem(i, 1, QTableWidgetItem(icone, QString.fromUtf8("")))
|
|
|
|
|
+ self.fenetre.ui.listeAttaques.setItem(i, 2, QTableWidgetItem(QString.fromUtf8(attaque.nom)))
|
|
|
|
|
+ self.majInfosAttaqueEC()
|
|
|
|
|
+
|
|
|
|
|
+ def listeAttaquesCelluleCliquee(self, ligne, colonne):
|
|
|
|
|
+ """on a clique sur une cellule de la liste des attaques"""
|
|
|
|
|
+ numAttaque = int(str(self.fenetre.ui.listeAttaques.item(ligne, 0).text().toUtf8()))
|
|
|
|
|
+ if numAttaque >= 0:
|
|
|
|
|
+ self.utiliserAttaque(numAttaque)
|
|
|
|
|
+
|
|
|
|
|
+ def utiliserAttaque(self, numAttaque):
|
|
|
|
|
+ """le pion selectionne utilise son attaque n"""
|
|
|
|
|
+ if self.pionSelectionne() != None:
|
|
|
|
|
+ if numAttaque < len(self.pionSelectionne().attaques):
|
|
|
|
|
+ attaque = self.pionSelectionne().attaques[numAttaque]
|
|
|
|
|
+ if attaque.typ == "cac":
|
|
|
|
|
+ self.majModeCombat("combatAttaqueCaC")
|
|
|
|
|
+ if attaque.typ == "dist":
|
|
|
|
|
+ self.majModeCombat("combatAttaqueDist")
|
|
|
|
|
+ if attaque.typ == "zone":
|
|
|
|
|
+ self.modeParam["typeAttaqueZone"] = attaque.formeZone
|
|
|
|
|
+ self.fenetre.ui.combatZone_disqueRayon.setValue(attaque.rayon)
|
|
|
|
|
+ self.majModeCombat("combatAttaqueZone")
|
|
|
|
|
+
|
|
|
|
|
+ def majInfosAttaqueEC(self):
|
|
|
|
|
+ #*aec
|
|
|
|
|
+ """met a jour les infos de l'attaque en cours (selectionnee)"""
|
|
|
|
|
+ selection = self.fenetre.ui.listeAttaques.selectedItems()
|
|
|
|
|
+ self.fenetre.ui.panneauAttaqueEC.setVisible(self.pionSelectionne() != None and len(selection) > 0)
|
|
|
|
|
+ if self.pionSelectionne() != None and len(selection) > 0:
|
|
|
|
|
+ ligne = selection[0].row()
|
|
|
|
|
+ numAttaque = int(str(self.fenetre.ui.listeAttaques.item(ligne, 0).text().toUtf8()))
|
|
|
|
|
+ self.disconnect(self.fenetre.ui.listeAttributsAttaqueEC, SIGNAL("cellChanged(int,int)"), self.attaqueECCelluleModifiee)
|
|
|
|
|
+ #on vide la liste
|
|
|
|
|
+ while self.fenetre.ui.listeAttributsAttaqueEC.rowCount() > 0:
|
|
|
|
|
+ self.fenetre.ui.listeAttributsAttaqueEC.removeRow(0)
|
|
|
|
|
+
|
|
|
|
|
+ self.fenetre.ui.listeAttributsAttaqueEC.insertRow(0)
|
|
|
|
|
+ self.fenetre.ui.listeAttributsAttaqueEC.setItem(0, 0, QTableWidgetItem(QString.fromUtf8("numAtt")))
|
|
|
|
|
+ self.fenetre.ui.listeAttributsAttaqueEC.setItem(0, 1, QTableWidgetItem(QString.fromUtf8(str(numAttaque))))
|
|
|
|
|
+ self.fenetre.ui.listeAttributsAttaqueEC.setRowHidden(0, True)
|
|
|
|
|
+
|
|
|
|
|
+ #attributs issus des regles utilisees
|
|
|
|
|
+ ordre = regles.ordreAttributsAttaques()
|
|
|
|
|
+ for elt in ordre:
|
|
|
|
|
+ ligne = 1 + ordre.index(elt)
|
|
|
|
|
+ self.fenetre.ui.listeAttributsAttaqueEC.insertRow(ligne)
|
|
|
|
|
+ item = QTableWidgetItem(QString.fromUtf8(elt))
|
|
|
|
|
+ item.setFlags(Qt.NoItemFlags)
|
|
|
|
|
+ self.fenetre.ui.listeAttributsAttaqueEC.setItem(ligne, 0, item)
|
|
|
|
|
+ self.fenetre.ui.listeAttributsAttaqueEC.setItem(ligne, 1, QTableWidgetItem(QString.fromUtf8(str(self.pionSelectionne().attaques[numAttaque].attributs[elt]))))
|
|
|
|
|
+
|
|
|
|
|
+ self.connect(self.fenetre.ui.listeAttributsAttaqueEC, SIGNAL("cellChanged(int,int)"), self.attaqueECCelluleModifiee)
|
|
|
|
|
+ #maj des notes
|
|
|
|
|
+ self.disconnect(self.fenetre.ui.notesAttaqueEC, SIGNAL("textChanged()"), self.majNotesAttaqueEC)
|
|
|
|
|
+ self.fenetre.ui.notesAttaqueEC.setText(QString.fromUtf8(self.pionSelectionne().attaques[numAttaque].notes))
|
|
|
|
|
+ self.connect(self.fenetre.ui.notesAttaqueEC, SIGNAL("textChanged()"), self.majNotesAttaqueEC)
|
|
|
|
|
+
|
|
|
|
|
+ def attaqueECCelluleModifiee(self, ligne, colonne):
|
|
|
|
|
+ """une cellule de la liste d'attributs de l'attaque en cours a ete modifiee"""
|
|
|
|
|
+ pass
|
|
|
|
|
+
|
|
|
|
|
+ def majNotesAttaqueEC(self):
|
|
|
|
|
+ """met a jour les notes de l'attaque en cours (selectionnee)"""
|
|
|
|
|
+ selection = self.fenetre.ui.listeAttaques.selectedItems()
|
|
|
|
|
+ self.fenetre.ui.panneauAttaqueEC.setVisible(self.pionSelectionne() != None and len(selection) > 0)
|
|
|
|
|
+ if self.pionSelectionne() != None and len(selection) > 0:
|
|
|
|
|
+ ligne = selection[0].row()
|
|
|
|
|
+ numAttaque = int(str(self.fenetre.ui.listeAttaques.item(ligne, 0).text().toUtf8()))
|
|
|
|
|
+ self.pionSelectionne().attaques[numAttaque].notes = str(self.fenetre.ui.notesAttaqueEC.toPlainText().toUtf8())
|
|
|
|
|
+
|
|
|
|
|
+ def afficheEcranEditionAttaques(self):
|
|
|
|
|
+ """affiche l'ecran d'edition/creation d'attaques"""
|
|
|
|
|
+ if self.pionSelectionne() != None:
|
|
|
|
|
+ self.editionAttaques = QDialog()
|
|
|
|
|
+ frame = EcranEditionAttaques(self.pionSelectionne())
|
|
|
|
|
+ frame.setParent(self.editionAttaques)
|
|
|
|
|
+ self.editionAttaques.setAttribute(Qt.WA_DeleteOnClose)
|
|
|
|
|
+ r = self.editionAttaques.exec_()
|
|
|
|
|
+ del self.editionAttaques
|
|
|
|
|
+ self.majListeAttaques()
|
|
|
|
|
+
|
|
|
|
|
+ def majNotesPion(self):
|
|
|
|
|
+ """les notes du pion ont ete mises a jour"""
|
|
|
|
|
+ if self.pionSelectionne() != None:
|
|
|
|
|
+ self.pionSelectionne().notes = str(self.fenetre.ui.notesPion.toPlainText().toUtf8())
|
|
|
|
|
+ else:
|
|
|
|
|
+ pass
|
|
|
|
|
+
|
|
|
|
|
+ def afficherNotesPion(self):
|
|
|
|
|
+ """affiche les notes du pion selectionne dans le QTextEdit dedie"""
|
|
|
|
|
+ self.fenetre.ui.notesPion.setVisible((self.pionSelectionne() != None))
|
|
|
|
|
+ if self.pionSelectionne() != None:
|
|
|
|
|
+ self.fenetre.ui.notesPion.setText(QString.fromUtf8(self.pionSelectionne().notes))
|
|
|
|
|
+
|
|
|
|
|
+ ###############
|
|
|
|
|
+
|
|
|
|
|
+ ############### fonctions de calcul ################
|
|
|
|
|
+ def zone(self, origine, distance, z=0, conditionFranchissable = False, conditionVisible = False):
|
|
|
|
|
+ """renvoie un dictionnaire representant la liste des coordonnees des cases comprises dans la zone
|
|
|
|
|
+ la zone en question est la liste des cases situees a une distance d des coordonnees d'origine
|
|
|
|
|
+ z = 0 -> hauteur z de l'origine par rapport a l'altitude de la case
|
|
|
|
|
+ conditionFranchissable = Vrai -> les cases infranchissables ne sont pas prises en compte
|
|
|
|
|
+ conditionVisible = Vrai -> les cases bloquant la visibilite ne sont pas prises en compte
|
|
|
|
|
+ [cf methode A* (A-star)]"""
|
|
|
|
|
+
|
|
|
|
|
+ aVerifier = []
|
|
|
|
|
+ aVerifier2 = []
|
|
|
|
|
+ resultat = {}
|
|
|
|
|
+ k = 0
|
|
|
|
|
+ #on part de la premiere case, puis on itere a partir de chaque nouveau depart
|
|
|
|
|
+ if origine in self.cases:
|
|
|
|
|
+ aVerifier.append(origine)
|
|
|
|
|
+ while k <= distance:
|
|
|
|
|
+ for depart in aVerifier:
|
|
|
|
|
+ for coord in self.cases[depart].voisins:
|
|
|
|
|
+ if not coord in aVerifier and not coord in aVerifier2 and not coord in resultat:
|
|
|
|
|
+ if conditionFranchissable and not conditionVisible:
|
|
|
|
|
+ if self.cases[coord].estFranchissable(z):
|
|
|
|
|
+ aVerifier2.append(coord)
|
|
|
|
|
+ elif not conditionFranchissable and conditionVisible:
|
|
|
|
|
+ if self.cases[coord].terrain.visibilite:
|
|
|
|
|
+ aVerifier2.append(coord)
|
|
|
|
|
+ elif conditionFranchissable and conditionVisible:
|
|
|
|
|
+ if self.cases[coord].estFranchissable(z) and self.cases[coord].terrain.visibilite:
|
|
|
|
|
+ aVerifier2.append(coord)
|
|
|
|
|
+ else:
|
|
|
|
|
+ aVerifier2.append(coord)
|
|
|
|
|
+ for elt in aVerifier:
|
|
|
|
|
+ resultat[elt] = k
|
|
|
|
|
+ aVerifier = aVerifier2
|
|
|
|
|
+ aVerifier2 = []
|
|
|
|
|
+ k += 1
|
|
|
|
|
+
|
|
|
|
|
+ return resultat
|
|
|
|
|
+
|
|
|
|
|
+ def coordonneesValides(self, coord):
|
|
|
|
|
+ """les coordonnees entrees en parametre sont elles celles d'une case du plateau"""
|
|
|
|
|
+ return (coord[0] >= 0 and coord[1] >= 0 and coord[0] < self.nbCasesX and coord[1] < self.nbCasesY)
|
|
|
|
|
+
|
|
|
|
|
+ def polygoneAgglo(self, listeCases):
|
|
|
|
|
+ """renvoie un polygone contruit par agglomeration des polygones des cases de la liste
|
|
|
|
|
+ les cases doivent etre adjacentes (cases hexagonales ou carrees)"""
|
|
|
|
|
+ pointsPolygone = []
|
|
|
|
|
+ segments = []
|
|
|
|
|
+ case = Case(self)
|
|
|
|
|
+
|
|
|
|
|
+ #on verifie que toutes les cases sont adjacentes les unes aux autres
|
|
|
|
|
+ valide = True
|
|
|
|
|
+ if len(listeCases) > 1:
|
|
|
|
|
+ for coord in listeCases:
|
|
|
|
|
+ if not len(set(listeCases).intersection(self.lstCoordAdjacentes(coord[0], coord[1]))) > 0: valide = False
|
|
|
|
|
+ if not len(listeCases) > 0:
|
|
|
|
|
+ valide = False
|
|
|
|
|
+
|
|
|
|
|
+ if valide:
|
|
|
|
|
+ #on parcourt les faces des polygones des cases, et on ne garde que ceux qui n'ont pas de case 'en face'
|
|
|
|
|
+ for coord in listeCases:
|
|
|
|
|
+ polygone = case.polygone(coord[0], coord[1])
|
|
|
|
|
+ voisins = self.lstCoordAdjacentes(coord[0], coord[1])
|
|
|
|
|
+ for i in range(0, len(voisins)):
|
|
|
|
|
+ if not voisins[i] in listeCases:
|
|
|
|
|
+ j = i+1
|
|
|
|
|
+ if j > len(voisins) - 1:
|
|
|
|
|
+ j = 0
|
|
|
|
|
+ segments.append(QLineF(polygone[i], polygone[j]))
|
|
|
|
|
+
|
|
|
|
|
+ #on 'accroche' les segments les uns aux autres, dans l'ordre
|
|
|
|
|
+ segments2 = [segments[0]]
|
|
|
|
|
+ for segment2 in segments2:
|
|
|
|
|
+ for segment in segments:
|
|
|
|
|
+ if not QLineF(segment.p1(), segment.p2()) in segments2 and not QLineF(segment.p2(), segment.p1()) in segments2:
|
|
|
|
|
+ if sqrt((segment.p1().x()-segment2.p2().x())**2+(segment.p1().y()-segment2.p2().y())**2) < 1:
|
|
|
|
|
+ segments2.append(QLineF(segment.p1(), segment.p2()))
|
|
|
|
|
+ elif sqrt((segment.p2().x()-segment2.p2().x())**2+(segment.p2().y()-segment2.p2().y())**2) < 1:
|
|
|
|
|
+ segments2.append(QLineF(segment.p2(), segment.p1()))
|
|
|
|
|
+
|
|
|
|
|
+ pointsPolygone = []
|
|
|
|
|
+ premierPoint = segments2[0].p1()
|
|
|
|
|
+ pointsPolygone.append(premierPoint)
|
|
|
|
|
+ for segment in segments2:
|
|
|
|
|
+ pointSuivant = segment.p2()
|
|
|
|
|
+ if pointSuivant != premierPoint:
|
|
|
|
|
+ pointsPolygone.append(pointSuivant)
|
|
|
|
|
+
|
|
|
|
|
+ #creation du polygone
|
|
|
|
|
+ polygone = QPolygonF()
|
|
|
|
|
+ for point in pointsPolygone:
|
|
|
|
|
+ polygone.append(point)
|
|
|
|
|
+ else:
|
|
|
|
|
+ polygone = None
|
|
|
|
|
+
|
|
|
|
|
+ return polygone
|
|
|
|
|
+
|
|
|
|
|
+ def lstCoordAdjacentes(self, x, y):
|
|
|
|
|
+ """renvoie la liste des coordonnees adjacentes, sans condition d'existence sur le plateau
|
|
|
|
|
+ attention: l'ordre est important"""
|
|
|
|
|
+ if self.formeCases == "H":
|
|
|
|
|
+ voisins = [(x, y-1), (x+1, y-0.5), (x+1, y+0.5), (x, y+1), (x-1, y+0.5), (x-1, y-0.5)]
|
|
|
|
|
+ else:
|
|
|
|
|
+ voisins = [(x, y-1), (x+1, y), (x, y+1), (x-1, y)]
|
|
|
|
|
+ return voisins
|
|
|
|
|
+
|
|
|
|
|
+ def coordCentreListeCases(self, listeCases):
|
|
|
|
|
+ """renvoie les coordonnees centrales d'une liste de cases"""
|
|
|
|
|
+ retour = None
|
|
|
|
|
+ if len(listeCases) > 0:
|
|
|
|
|
+ listeTriee = sorted(listeCases)
|
|
|
|
|
+ posMilieu = int(len(listeCases)/2)
|
|
|
|
|
+ retour = listeTriee[posMilieu]
|
|
|
|
|
+ return retour
|
|
|
|
|
+
|
|
|
|
|
+ def coordonneesAuPoint(self, point):
|
|
|
|
|
+ """renvoie les coordonnees de la case situee au QPointF entre en parametre"""
|
|
|
|
|
+ coord = None
|
|
|
|
|
+ if point != None:
|
|
|
|
|
+ lstObjets = self.fenetre.ui.vuePlateau.scene().items(point)
|
|
|
|
|
+ for objet in lstObjets:
|
|
|
|
|
+ if objet:
|
|
|
|
|
+ if objet.__class__.__name__ == "Case":
|
|
|
|
|
+ coord = (objet.x, objet.y)
|
|
|
|
|
+ break
|
|
|
|
|
+ return coord
|
|
|
|
|
+
|
|
|
|
|
+ def creerOrigineFormeDessin(self, coord):
|
|
|
|
|
+ """place le point d'origine de la forme de selection"""
|
|
|
|
|
+ self.modeParam["listeCasesFormeDessin"] = []
|
|
|
|
|
+ self.modeParam["origineFormeDessin"] = self.cases[coord].centreGraphique
|
|
|
|
|
+ self.modeParam["point2FormeDessin"] = self.cases[coord].centreGraphique
|
|
|
|
|
+ self.modeParam["listeCasesFormeDessin"] = [coord]
|
|
|
|
|
+ self.afficherListeCases(self.modeParam["listeCasesFormeDessin"], True)
|
|
|
|
|
+
|
|
|
|
|
+ def majFormeDessin(self):
|
|
|
|
|
+ """cree/maj la forme utilisee pour selectionner les cases et met a jour la liste des cases selectionnes"""
|
|
|
|
|
+ self.afficherListeCases(self.modeParam["listeCasesFormeDessin"], False)
|
|
|
|
|
+
|
|
|
|
|
+ pinceau = QPen()
|
|
|
|
|
+ pinceau.setColor(QColor("black"))
|
|
|
|
|
+ point2 = self.modeParam["point2FormeDessin"]
|
|
|
|
|
+
|
|
|
|
|
+ if self.modeParam["typeFormeDessin"] == "simple":
|
|
|
|
|
+ #pas de forme: on ajoute les cases survolees a la liste des cases
|
|
|
|
|
+ coordPoint2 = self.coordonneesAuPoint(point2)
|
|
|
|
|
+ zone = self.zone(coordPoint2, self.epaisseurPinceau-1)
|
|
|
|
|
+ for coord in zone:
|
|
|
|
|
+ if not coord in self.modeParam["listeCasesFormeDessin"]:
|
|
|
|
|
+ self.modeParam["listeCasesFormeDessin"].append(coord)
|
|
|
|
|
+
|
|
|
|
|
+ elif self.modeParam["typeFormeDessin"] == "frontiere":
|
|
|
|
|
+ #droite qui selectionne toutes les cases situees au dessus d'elle
|
|
|
|
|
+ if self.modeParam["formeDessin"] == None:
|
|
|
|
|
+ self.modeParam["formeDessin"] = QGraphicsLineItem()
|
|
|
|
|
+ self.modeParam["formeDessin"].setPen(pinceau)
|
|
|
|
|
+ self.addItem(self.modeParam["formeDessin"])
|
|
|
|
|
+ ligne = QLineF(self.modeParam["origineFormeDessin"], point2)
|
|
|
|
|
+ orientation = int((1+int(ligne.angle()/22.5))/2)
|
|
|
|
|
+ ligne.setAngle(orientation*45)
|
|
|
|
|
+ self.modeParam["formeDessin"].setLine(ligne)
|
|
|
|
|
+ self.modeParam["listeCasesFormeDessin"] = self.selectionFrontiere()
|
|
|
|
|
+
|
|
|
|
|
+ else:
|
|
|
|
|
+ if self.modeParam["typeFormeDessin"] == "ligne":
|
|
|
|
|
+ #segment simple
|
|
|
|
|
+ if self.modeParam["formeDessin"] == None:
|
|
|
|
|
+ self.modeParam["formeDessin"] = QGraphicsLineItem()
|
|
|
|
|
+ self.modeParam["formeDessin"].setPen(pinceau)
|
|
|
|
|
+ self.modeParam["formeDessin"].prepareGeometryChange()
|
|
|
|
|
+ self.addItem(self.modeParam["formeDessin"])
|
|
|
|
|
+ ligne = QLineF(self.modeParam["origineFormeDessin"], point2)
|
|
|
|
|
+ self.modeParam["formeDessin"].setLine(ligne)
|
|
|
|
|
+
|
|
|
|
|
+ elif self.modeParam["typeFormeDessin"] == "rectV" or self.modeParam["typeFormeDessin"] == "rectP":
|
|
|
|
|
+ #rectangle
|
|
|
|
|
+ if self.modeParam["formeDessin"] == None:
|
|
|
|
|
+ self.modeParam["formeDessin"] = QGraphicsRectItem()
|
|
|
|
|
+ self.modeParam["formeDessin"].prepareGeometryChange()
|
|
|
|
|
+ self.modeParam["formeDessin"].setPen(pinceau)
|
|
|
|
|
+ self.addItem(self.modeParam["formeDessin"])
|
|
|
|
|
+ rect = self.rectFormeDessin(self.modeParam["origineFormeDessin"], point2)
|
|
|
|
|
+ self.modeParam["formeDessin"].setRect(rect)
|
|
|
|
|
+
|
|
|
|
|
+ elif self.modeParam["typeFormeDessin"] == "ellipseV" or self.modeParam["typeFormeDessin"] == "ellipseP":
|
|
|
|
|
+ #ellipse
|
|
|
|
|
+ if self.modeParam["formeDessin"] == None:
|
|
|
|
|
+ self.modeParam["formeDessin"] = QGraphicsEllipseItem()
|
|
|
|
|
+ self.modeParam["formeDessin"].prepareGeometryChange()
|
|
|
|
|
+ self.modeParam["formeDessin"].setPen(pinceau)
|
|
|
|
|
+ self.addItem(self.modeParam["formeDessin"])
|
|
|
|
|
+ rect = self.rectFormeDessin(self.modeParam["origineFormeDessin"], point2)
|
|
|
|
|
+ self.modeParam["formeDessin"].setRect(rect)
|
|
|
|
|
+
|
|
|
|
|
+ #on liste les cases intersectant la forme
|
|
|
|
|
+ plein = (self.modeParam["typeFormeDessin"][len(self.modeParam["typeFormeDessin"])-1:] == "P")
|
|
|
|
|
+ self.modeParam["listeCasesFormeDessin"] = self.casesSousForme(self.modeParam["formeDessin"], plein, self.epaisseurPinceau - 1)
|
|
|
|
|
+ self.afficherListeCases(self.modeParam["listeCasesFormeDessin"], True)
|
|
|
|
|
+
|
|
|
|
|
+ def casesSousForme(self, forme, plein = True, epaisseur = 0):
|
|
|
|
|
+ """renvoie la liste des cases en collision avec un QGraphicsItem en parametre
|
|
|
|
|
+ plein = False: pas le contenu de la forme
|
|
|
|
|
+ epaisseur = renvoie aussi les cases voisines jusqu'a la distance demandee"""
|
|
|
|
|
+ tmp = []
|
|
|
|
|
+ listeCases = []
|
|
|
|
|
+ point1 = None
|
|
|
|
|
+ point2 = None
|
|
|
|
|
+ #point 1 et 2
|
|
|
|
|
+ if forme.__class__.__name__ == "QGraphicsLineItem":
|
|
|
|
|
+ point1 = forme.line().p1()
|
|
|
|
|
+ point2 = forme.line().p2()
|
|
|
|
|
+ elif forme.__class__.__name__ == "QGraphicsRectItem" or forme.__class__.__name__ == "QGraphicsEllipseItem":
|
|
|
|
|
+ point1 = forme.rect().topLeft()
|
|
|
|
|
+ point2 = forme.rect().bottomRight()
|
|
|
|
|
+ else:
|
|
|
|
|
+ point1 = forme.boundingRect().topLeft()
|
|
|
|
|
+ point2 = forme.boundingRect().bottomRight()
|
|
|
|
|
+
|
|
|
|
|
+ #preselection des cases (meilleures perf)
|
|
|
|
|
+ if point1 != None and point2 != None and point1 != point2:
|
|
|
|
|
+ preSelection = self.preSelectionCollision(point1, point2)
|
|
|
|
|
+ else:
|
|
|
|
|
+ preSelection = []
|
|
|
|
|
+ for coord in self.cases:
|
|
|
|
|
+ preSelection.append(coord)
|
|
|
|
|
+
|
|
|
|
|
+ #on liste les cases en collision avec la forme
|
|
|
|
|
+ for coord in preSelection:
|
|
|
|
|
+ if self.cases[coord].collidesWithItem(forme, Qt.IntersectsItemShape):
|
|
|
|
|
+ if plein:
|
|
|
|
|
+ tmp.append(coord)
|
|
|
|
|
+ else:
|
|
|
|
|
+ contenu = True
|
|
|
|
|
+ for i in range(0,len(self.cases[coord].polygon())):
|
|
|
|
|
+ if not forme.contains(self.cases[coord].polygon().at(i)):
|
|
|
|
|
+ contenu = False
|
|
|
|
|
+ break
|
|
|
|
|
+ if contenu == False:
|
|
|
|
|
+ tmp.append(coord)
|
|
|
|
|
+ #on applique l'epaisseur du pinceau (lignes ou formes vides seulement) si necessaire
|
|
|
|
|
+ if not plein and epaisseur > 0:
|
|
|
|
|
+ for coord in tmp:
|
|
|
|
|
+ zone = self.zone(coord, epaisseur)
|
|
|
|
|
+ for coord2 in zone:
|
|
|
|
|
+ if not coord2 in listeCases:
|
|
|
|
|
+ listeCases.append(coord2)
|
|
|
|
|
+ else:
|
|
|
|
|
+ listeCases = tmp
|
|
|
|
|
+ #si la liste est vide, on ajoute l'origine de la forme
|
|
|
|
|
+ if len(listeCases) == 0:
|
|
|
|
|
+ listeCases = [self.coordonneesAuPoint(point1)]
|
|
|
|
|
+ return listeCases
|
|
|
|
|
+
|
|
|
|
|
+ def preSelectionCollision(self, point1, point2):
|
|
|
|
|
+ """renvoie une liste des cases qui peuvent etre concernees par une collision avec
|
|
|
|
|
+ un graphicsItem (pour des raisons de performance)"""
|
|
|
|
|
+ preSelection = []
|
|
|
|
|
+ coord1 = self.coordonneesAuPoint(point1)
|
|
|
|
|
+ coord2 = self.coordonneesAuPoint(point2)
|
|
|
|
|
+ if coord1 != None and coord2 != None:
|
|
|
|
|
+ minX = min(coord1[0], coord2[0]) - 1
|
|
|
|
|
+ maxX = max(coord1[0], coord2[0]) + 1
|
|
|
|
|
+ minY = min(coord1[1], coord2[1]) - 1
|
|
|
|
|
+ maxY = max(coord1[1], coord2[1]) + 1
|
|
|
|
|
+ for coord in self.cases:
|
|
|
|
|
+ if coord[0] >= minX and coord[0] <= maxX and coord[1] >= minY and coord[1] <= maxY :
|
|
|
|
|
+ preSelection.append(coord)
|
|
|
|
|
+ else:
|
|
|
|
|
+ preSelection = self.cases
|
|
|
|
|
+ return preSelection
|
|
|
|
|
+
|
|
|
|
|
+ def selectionFrontiere(self):
|
|
|
|
|
+ """retourne les cases selectionnees lors de l'utilisation de la forme 'frontiere'"""
|
|
|
|
|
+ listeCases = []
|
|
|
|
|
+ ligne = self.modeParam["formeDessin"].line()
|
|
|
|
|
+ normale = ligne.normalVector()
|
|
|
|
|
+ normale = normale.unitVector()
|
|
|
|
|
+ coordOrigine = self.coordonneesAuPoint(self.modeParam["origineFormeDessin"])
|
|
|
|
|
+ dx = normale.p2().x() - normale.p1().x()
|
|
|
|
|
+ dy = normale.p2().y() - normale.p1().y()
|
|
|
|
|
+ for coord in self.cases:
|
|
|
|
|
+ if dx < 0 and dy == 0: #normale pointe vers la gauche
|
|
|
|
|
+ if (coord[0] - coordOrigine[0]) <= 0:
|
|
|
|
|
+ listeCases.append(coord)
|
|
|
|
|
+ if dx > 0 and dy == 0: #normale pointe vers la droite
|
|
|
|
|
+ if (coord[0] - coordOrigine[0]) >= 0:
|
|
|
|
|
+ listeCases.append(coord)
|
|
|
|
|
+ if dx == 0 and dy < 0: #pointe vers le haut (rappel: axe y vers le bas)
|
|
|
|
|
+ if (coord[1] - coordOrigine[1]) <= 0:
|
|
|
|
|
+ listeCases.append(coord)
|
|
|
|
|
+ elif dx == 0 and dy > 0: #pointe vers le bas
|
|
|
|
|
+ if (coord[1] - coordOrigine[1]) >= 0:
|
|
|
|
|
+ listeCases.append(coord)
|
|
|
|
|
+ if dx > 0 and dy < 0: #pointe vers le haut droite
|
|
|
|
|
+ if (coord[0] - coordOrigine[0]) + -1*(coord[1] - coordOrigine[1]) >= 0:
|
|
|
|
|
+ listeCases.append(coord)
|
|
|
|
|
+ elif dx > 0 and dy > 0: #pointe vers le bas droite
|
|
|
|
|
+ if -1*(coord[0] - coordOrigine[0]) + -1*(coord[1] - coordOrigine[1]) <= 0:
|
|
|
|
|
+ listeCases.append(coord)
|
|
|
|
|
+ if dx < 0 and dy < 0: #pointe vers le haut gauche
|
|
|
|
|
+ if (coord[0] - coordOrigine[0]) + (coord[1] - coordOrigine[1]) <= 0:
|
|
|
|
|
+ listeCases.append(coord)
|
|
|
|
|
+ elif dx < 0 and dy > 0: #pointe vers le bas gauche
|
|
|
|
|
+ if -1*(coord[0] - coordOrigine[0]) + (coord[1] - coordOrigine[1]) >= 0:
|
|
|
|
|
+ listeCases.append(coord)
|
|
|
|
|
+ return listeCases
|
|
|
|
|
+
|
|
|
|
|
+ def validerFormeDessin(self):
|
|
|
|
|
+ """la projection des cases a peindre a ete acceptee, on peint ces cases"""
|
|
|
|
|
+ if self.modeActif[0:7] == "caseMaj" or self.modeActif == "caseCopie" or self.modeActif == "cachePlacer" or self.modeActif == "majZonePlacement":
|
|
|
|
|
+ self.majListeCases(self.modeParam["listeCasesFormeDessin"])
|
|
|
|
|
+ self.majMode(self.modeActif)
|
|
|
|
|
+## self.majMode("standard")
|
|
|
|
|
+
|
|
|
|
|
+ def rectFormeDessin(self, point1, point2):
|
|
|
|
|
+ """retourne le rectangle repesentant la forme de selection
|
|
|
|
|
+ determine pour ce faire les points A et B, cad le point haut-droit et le point bas-gauche"""
|
|
|
|
|
+ pointA = QPointF(min(point1.x(), point2.x()), min(point1.y(), point2.y()))
|
|
|
|
|
+ pointB = QPointF(max(point1.x(), point2.x()), max(point1.y(), point2.y()))
|
|
|
|
|
+ rect = QRectF(pointA, pointB)
|
|
|
|
|
+ return rect
|
|
|
|
|
+
|
|
|
|
|
+ def majLigneMireAttaqueDist(self, coordCible = None):
|
|
|
|
|
+ """met a jour la ligne de mire representant l'attaque a distance"""
|
|
|
|
|
+ if self.modeParam["cibleAttaqueDist"] != None and self.modeParam["cibleAttaqueDist"] != coordCible:
|
|
|
|
|
+ self.cases[self.modeParam["cibleAttaqueDist"]].majEstCibleCurseur(False)
|
|
|
|
|
+## if self.modeParam["pionCibleAttaqueDist"] != None and self.modeParam["pionCibleAttaqueDist"] != self.cases[coordCible].pionOccupant():
|
|
|
|
|
+ if self.modeParam["pionCibleAttaqueDist"] != None:
|
|
|
|
|
+ self.modeParam["pionCibleAttaqueDist"].estCibleAttaque(False)
|
|
|
|
|
+
|
|
|
|
|
+ if coordCible != None and self.pionSelectionne() != None and self.modeCombat == "combatAttaqueDist":
|
|
|
|
|
+ if coordCible == None:
|
|
|
|
|
+ coordCible = pion.position
|
|
|
|
|
+
|
|
|
|
|
+ if coordCible != self.modeParam["cibleAttaqueDist"]:
|
|
|
|
|
+ if self.modeParam["ligneAttaqueDist"] == None:
|
|
|
|
|
+ self.modeParam["ligneAttaqueDist"] = QGraphicsLineItem()
|
|
|
|
|
+ self.modeParam["ligneAttaqueDist"].setZValue(100)
|
|
|
|
|
+ pinceau = QPen()
|
|
|
|
|
+ pinceau.setWidth(6)
|
|
|
|
|
+ self.modeParam["ligneAttaqueDist"].setPen(pinceau)
|
|
|
|
|
+ self.modeParam["ligneAttaqueDist"].prepareGeometryChange()
|
|
|
|
|
+ self.addItem(self.modeParam["ligneAttaqueDist"])
|
|
|
|
|
+
|
|
|
|
|
+ z = 0
|
|
|
|
|
+ pionSurCase = self.cases[coordCible].pionOccupant()
|
|
|
|
|
+ if pionSurCase != None:
|
|
|
|
|
+ z = pionSurCase.z
|
|
|
|
|
+ cibleValide = self.estCibleAttaqueDistValide(self.pionSelectionne().position, coordCible, z)
|
|
|
|
|
+
|
|
|
|
|
+ if pionSurCase != None:
|
|
|
|
|
+ pionSurCase.estCibleAttaque(True, cibleValide)
|
|
|
|
|
+ self.modeParam["pionCibleAttaqueDist"] = pionSurCase
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.cases[coordCible].majEstCibleCurseur(True, cibleValide)
|
|
|
|
|
+ self.modeParam["cibleAttaqueDist"] = coordCible
|
|
|
|
|
+
|
|
|
|
|
+ point1 = self.cases[self.pionSelectionne().position].centreGraphique
|
|
|
|
|
+ point2 = self.cases[coordCible].centreGraphique
|
|
|
|
|
+ ligne = QLineF(point1, point2)
|
|
|
|
|
+ self.modeParam["ligneAttaqueDist"].setLine(ligne)
|
|
|
|
|
+ else:
|
|
|
|
|
+ if self.modeParam["ligneAttaqueDist"] != None:
|
|
|
|
|
+ self.modeParam["ligneAttaqueDist"].prepareGeometryChange()
|
|
|
|
|
+ self.removeItem(self.modeParam["ligneAttaqueDist"])
|
|
|
|
|
+ self.modeParam["ligneAttaqueDist"] = None
|
|
|
|
|
+ self.modeParam["cibleAttaqueDist"] = None
|
|
|
|
|
+
|
|
|
|
|
+## if pion == None:
|
|
|
|
|
+## self.modeParam["pionCibleAttaqueDist"] = None
|
|
|
|
|
+
|
|
|
|
|
+ def estCibleAttaqueDistValide(self, coordOrigine, coordCible, zPion = 0):
|
|
|
|
|
+ """la case cible est elle valide pour une attaque a distance depuis la position et hauteur
|
|
|
|
|
+ du pion selectionne? on compare pour ce faire les altitudes des cases sur la ligne de mire"""
|
|
|
|
|
+ casesLigneMire = []
|
|
|
|
|
+ #on preselectionne les cases concernees
|
|
|
|
|
+ preSelection = self.preSelectionCollision(self.cases[coordOrigine].centreGraphique, self.cases[coordCible].centreGraphique)
|
|
|
|
|
+ if coordOrigine in preSelection:
|
|
|
|
|
+ preSelection.remove(coordOrigine)
|
|
|
|
|
+ if coordCible in preSelection:
|
|
|
|
|
+ preSelection.remove(coordCible)
|
|
|
|
|
+ for coord in preSelection:
|
|
|
|
|
+ ligne = QLineF(self.cases[coordOrigine].centreGraphique, self.cases[coordCible].centreGraphique)
|
|
|
|
|
+ ligneGraphique = QGraphicsLineItem(ligne)
|
|
|
|
|
+ ligneGraphique.prepareGeometryChange()
|
|
|
|
|
+ self.addItem(ligneGraphique)
|
|
|
|
|
+ if self.cases[coord].collidesWithItem(ligneGraphique, Qt.IntersectsItemShape):
|
|
|
|
|
+ casesLigneMire.append(coord)
|
|
|
|
|
+ self.removeItem(ligneGraphique)
|
|
|
|
|
+ del ligneGraphique
|
|
|
|
|
+
|
|
|
|
|
+ #on trie les cases par distance au point d'origine (de la plus proche a la plus eloignee)
|
|
|
|
|
+ casesLigneMireDistance = {} #distance: coord
|
|
|
|
|
+ for coord in casesLigneMire:
|
|
|
|
|
+ distance = sqrt((coordOrigine[0] - coord[0])**2 + (coordOrigine[1] - coord[1])**2)
|
|
|
|
|
+ casesLigneMireDistance[coord] = distance
|
|
|
|
|
+
|
|
|
|
|
+ #on compare enfin les altitudes de chaque case en fonction de la distance
|
|
|
|
|
+ zOrigine = self.cases[coordOrigine].altitude + self.pionSelectionne().z + self.pionSelectionne().creature.hauteur
|
|
|
|
|
+ zCible = self.cases[coordCible].altitude + zPion
|
|
|
|
|
+ distanceTot = sqrt((coordCible[0] - coordOrigine[0])**2 + (coordCible[1] - coordOrigine[1])**2)
|
|
|
|
|
+ valide = True
|
|
|
|
|
+ for coord in casesLigneMireDistance:
|
|
|
|
|
+ if self.cases[coord].terrain.visibilite == False:
|
|
|
|
|
+ valide = False
|
|
|
|
|
+ break
|
|
|
|
|
+ else:
|
|
|
|
|
+ if zOrigine >= zCible:
|
|
|
|
|
+ z = (zOrigine - zCible) * (casesLigneMireDistance[coord] / distanceTot)
|
|
|
|
|
+ else:
|
|
|
|
|
+ z = (zCible - zOrigine) * ((distanceTot - casesLigneMireDistance[coord]) / distanceTot)
|
|
|
|
|
+ if self.cases[coord].estOccupee(int(z)):
|
|
|
|
|
+ if self.modeParam["pionCibleAttaqueDist"] != None:
|
|
|
|
|
+ if self.cases[coord].estOccupeePar(int(z)) != self.modeParam["pionCibleAttaqueDist"]:
|
|
|
|
|
+ valide = False
|
|
|
|
|
+ else:
|
|
|
|
|
+ valide = False
|
|
|
|
|
+ break
|
|
|
|
|
+ return valide
|
|
|
|
|
+
|
|
|
|
|
+ def validerAttaqueDist(self):
|
|
|
|
|
+ """on essaie de valider une attaque a distance vers un pion ou une case"""
|
|
|
|
|
+ if self.modeParam["pionCibleAttaqueDist"] != None:
|
|
|
|
|
+ msg = "{} attaque a distance le pion {}".format(self.pionSelectionne().txtId(),
|
|
|
|
|
+ self.modeParam["pionCibleAttaqueDist"].txtId())
|
|
|
|
|
+ valide = self.estCibleAttaqueDistValide(self.pionSelectionne().position, self.modeParam["cibleAttaqueDist"], self.modeParam["pionCibleAttaqueDist"].z)
|
|
|
|
|
+ else:
|
|
|
|
|
+ msg = "{} attaque a distance la case {}".format(self.pionSelectionne().txtId(),
|
|
|
|
|
+ self.modeParam["cibleAttaqueDist"])
|
|
|
|
|
+ valide = self.estCibleAttaqueDistValide(self.pionSelectionne().position, self.modeParam["cibleAttaqueDist"])
|
|
|
|
|
+ if not valide:
|
|
|
|
|
+ msg += " [INVALIDE]"
|
|
|
|
|
+ print(msg)
|
|
|
|
|
+ self.majModeCombat("aucun")
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ def rectEllipseCirculaire(self, centre, rayon):
|
|
|
|
|
+ """renvoie le QRectF definissant une ellipse ayant le QPointF pour centre et le rayon en cases entres en param
|
|
|
|
|
+ attention: l'ellipse n'est pas tout a fait circulaire, elle couvre horizontalement et
|
|
|
|
|
+ verticalement le nombre de cases demandees"""
|
|
|
|
|
+ rect = QRectF()
|
|
|
|
|
+ if rayon > 0:
|
|
|
|
|
+ p1 = QPointF((centre.x() - (rayon*self.hCase)), (centre.y() - (rayon*self.hCase)))
|
|
|
|
|
+ p2 = QPointF((centre.x() + (rayon*self.hCase)), (centre.y() + (rayon*self.hCase)))
|
|
|
|
|
+ rect.setTopLeft(p1)
|
|
|
|
|
+ rect.setBottomRight(p2)
|
|
|
|
|
+ else:
|
|
|
|
|
+ rect = None
|
|
|
|
|
+ return rect
|
|
|
|
|
+
|
|
|
|
|
+ def polygoneCone(self, point1, point2):
|
|
|
|
|
+ """renvoie le polygone du cone defini par les deux points (origine, distance)"""
|
|
|
|
|
+ ligne1 = QLineF(point1, point2)
|
|
|
|
|
+ longueur = ligne1.length()
|
|
|
|
|
+ ligne1.setAngle(ligne1.angle() + 22.5)
|
|
|
|
|
+ ligne1.setLength(1.1547*longueur)
|
|
|
|
|
+ ligne2 = QLineF(point1, point2)
|
|
|
|
|
+ ligne2.setAngle(ligne2.angle() - 22.5)
|
|
|
|
|
+ ligne2.setLength(1.1547*longueur)
|
|
|
|
|
+ polygone = QPolygonF()
|
|
|
|
|
+ polygone.append(point1)
|
|
|
|
|
+ polygone.append(ligne1.p2())
|
|
|
|
|
+ polygone.append(ligne2.p2())
|
|
|
|
|
+ return polygone
|
|
|
|
|
+
|
|
|
|
|
+ def majFormeAttaqueZone(self):
|
|
|
|
|
+ """cree la forme de l'attaque de zone"""
|
|
|
|
|
+ for coord in self.modeParam["listeCasesAttaqueZone"]:
|
|
|
|
|
+ self.cases[coord].majEstCibleAttaque(False)
|
|
|
|
|
+ for numPion in self.pionsSurListeCase(self.modeParam["listeCasesAttaqueZone"]):
|
|
|
|
|
+ self.pions[numPion].estCibleAttaque(False)
|
|
|
|
|
+
|
|
|
|
|
+ if self.modeCombat == "combatAttaqueZone" and self.pionSelectionne() != None:
|
|
|
|
|
+ if self.modeParam["typeAttaqueZone"] == "ligne":
|
|
|
|
|
+ if self.modeParam["formeAttaqueZone"] == None:
|
|
|
|
|
+ self.modeParam["origineAttaqueZone"] = self.cases[self.pionSelectionne().position].centreGraphique
|
|
|
|
|
+ self.modeParam["point2AttaqueZone"] = self.cases[self.pionSelectionne().position].centreGraphique
|
|
|
|
|
+ self.modeParam["formeAttaqueZone"] = QGraphicsLineItem()
|
|
|
|
|
+ self.modeParam["formeAttaqueZone"].setPen(QPen(QColor("black")))
|
|
|
|
|
+ self.modeParam["formeAttaqueZone"].prepareGeometryChange()
|
|
|
|
|
+ self.addItem(self.modeParam["formeAttaqueZone"])
|
|
|
|
|
+ if self.modeParam["origineAttaqueZone"] != self.modeParam["point2AttaqueZone"]:
|
|
|
|
|
+ ligne = QLineF(self.modeParam["origineAttaqueZone"], self.modeParam["point2AttaqueZone"])
|
|
|
|
|
+ self.modeParam["formeAttaqueZone"].setLine(ligne)
|
|
|
|
|
+ self.modeParam["listeCasesAttaqueZone"] = []
|
|
|
|
|
+ lst = self.casesSousForme(self.modeParam["formeAttaqueZone"],False)
|
|
|
|
|
+ for coord in lst:
|
|
|
|
|
+ self.modeParam["listeCasesAttaqueZone"].append(coord)
|
|
|
|
|
+ #on retire la case du pion selectionne si besoin:
|
|
|
|
|
+ if self.pionSelectionne().position in self.modeParam["listeCasesAttaqueZone"]:
|
|
|
|
|
+ self.modeParam["listeCasesAttaqueZone"].remove(self.pionSelectionne().position)
|
|
|
|
|
+
|
|
|
|
|
+ elif self.modeParam["typeAttaqueZone"] == "disque":
|
|
|
|
|
+ if self.modeParam["ligneMireAttaqueZone"] == None:
|
|
|
|
|
+ self.modeParam["origineAttaqueZone"] = self.cases[self.pionSelectionne().position].centreGraphique
|
|
|
|
|
+ self.modeParam["point2AttaqueZone"] = self.cases[self.pionSelectionne().position].centreGraphique
|
|
|
|
|
+ self.modeParam["ligneMireAttaqueZone"] = QGraphicsLineItem()
|
|
|
|
|
+ self.modeParam["ligneMireAttaqueZone"].setPen(QPen(QColor("black")))
|
|
|
|
|
+ self.modeParam["ligneMireAttaqueZone"].prepareGeometryChange()
|
|
|
|
|
+ self.addItem(self.modeParam["ligneMireAttaqueZone"])
|
|
|
|
|
+
|
|
|
|
|
+ if self.modeParam["origineAttaqueZone"] != self.modeParam["point2AttaqueZone"]:
|
|
|
|
|
+ ligne = QLineF(self.modeParam["origineAttaqueZone"], self.modeParam["point2AttaqueZone"])
|
|
|
|
|
+ self.modeParam["ligneMireAttaqueZone"].setLine(ligne)
|
|
|
|
|
+ coordCible = self.coordonneesAuPoint(self.modeParam["point2AttaqueZone"])
|
|
|
|
|
+ cibleValide = self.estCibleAttaqueDistValide(self.pionSelectionne().position, coordCible)
|
|
|
|
|
+
|
|
|
|
|
+ if cibleValide:
|
|
|
|
|
+ rayon = self.fenetre.ui.combatZone_disqueRayon.value()
|
|
|
|
|
+ if self.modeParam["formeAttaqueZone"] == None:
|
|
|
|
|
+ self.modeParam["formeAttaqueZone"] = QGraphicsEllipseItem()
|
|
|
|
|
+ self.modeParam["formeAttaqueZone"].setPen(QPen(QColor("black")))
|
|
|
|
|
+ self.modeParam["formeAttaqueZone"].prepareGeometryChange()
|
|
|
|
|
+ self.addItem(self.modeParam["formeAttaqueZone"])
|
|
|
|
|
+ rect = self.rectEllipseCirculaire(self.modeParam["point2AttaqueZone"], rayon)
|
|
|
|
|
+ self.modeParam["listeCasesAttaqueZone"] = []
|
|
|
|
|
+ if rect != None and rect.bottomRight() != rect.topLeft():
|
|
|
|
|
+ self.modeParam["formeAttaqueZone"].setRect(rect)
|
|
|
|
|
+ lst = self.zone(coordCible, rayon, 0) #zone bcp plus rapide que casesSousforme
|
|
|
|
|
+ self.modeParam["listeCasesAttaqueZone"] = lst
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.cases[coordCible].majEstCibleCurseur(True, False)
|
|
|
|
|
+ self.modeParam["listeCasesAttaqueZone"] = []
|
|
|
|
|
+
|
|
|
|
|
+ if self.modeParam["formeAttaqueZone"] != None:
|
|
|
|
|
+ self.modeParam["formeAttaqueZone"].setVisible(cibleValide == True and rect != None)
|
|
|
|
|
+
|
|
|
|
|
+ elif self.modeParam["typeAttaqueZone"] == "cone":
|
|
|
|
|
+ if self.modeParam["formeAttaqueZone"] == None:
|
|
|
|
|
+ self.modeParam["origineAttaqueZone"] = self.cases[self.pionSelectionne().position].centreGraphique
|
|
|
|
|
+ self.modeParam["point2AttaqueZone"] = self.cases[self.pionSelectionne().position].centreGraphique
|
|
|
|
|
+ self.modeParam["formeAttaqueZone"] = QGraphicsPolygonItem()
|
|
|
|
|
+ self.modeParam["formeAttaqueZone"].setPen(QPen(QColor("black")))
|
|
|
|
|
+ self.modeParam["formeAttaqueZone"].prepareGeometryChange()
|
|
|
|
|
+ self.addItem(self.modeParam["formeAttaqueZone"])
|
|
|
|
|
+
|
|
|
|
|
+ if self.modeParam["origineAttaqueZone"] != self.modeParam["point2AttaqueZone"]:
|
|
|
|
|
+ cone = self.polygoneCone(self.modeParam["origineAttaqueZone"], self.modeParam["point2AttaqueZone"])
|
|
|
|
|
+ self.modeParam["formeAttaqueZone"].setPolygon(cone)
|
|
|
|
|
+ lst = self.casesSousForme(self.modeParam["formeAttaqueZone"], True, True)
|
|
|
|
|
+ self.modeParam["listeCasesAttaqueZone"] = []
|
|
|
|
|
+ for coord in lst:
|
|
|
|
|
+ if coord != self.pionSelectionne().position:
|
|
|
|
|
+ self.modeParam["listeCasesAttaqueZone"].append(coord)
|
|
|
|
|
+
|
|
|
|
|
+ for coord in self.modeParam["listeCasesAttaqueZone"]:
|
|
|
|
|
+ self.cases[coord].majEstCibleAttaque(True)
|
|
|
|
|
+ for numPion in self.pionsSurListeCase(self.modeParam["listeCasesAttaqueZone"]):
|
|
|
|
|
+ self.pions[numPion].estCibleAttaque(True)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ def validerAttaqueZone(self):
|
|
|
|
|
+ """l'attaque de zone est validee"""
|
|
|
|
|
+ if self.modeActif == "pionSelectionne" and self.modeCombat == "combatAttaqueZone":
|
|
|
|
|
+ for numPion in self.pionsSurListeCase(self.modeParam["listeCasesAttaqueZone"]):
|
|
|
|
|
+ print("{} a lance une attaque de zone sur {}".format(self.pionSelectionne().nom, self.pionSelectionne().numero , \
|
|
|
|
|
+ self.pions[numPion].nom, self.pions[numPion].numero))
|
|
|
|
|
+ self.majModeCombat("aucun")
|
|
|
|
|
+
|
|
|
|
|
+ def reinitAttaqueZone(self):
|
|
|
|
|
+ if self.modeParam["formeAttaqueZone"] != None:
|
|
|
|
|
+ self.modeParam["formeAttaqueZone"].prepareGeometryChange()
|
|
|
|
|
+ self.removeItem(self.modeParam["formeAttaqueZone"])
|
|
|
|
|
+ self.modeParam["formeAttaqueZone"] = None
|
|
|
|
|
+ if self.modeParam["ligneMireAttaqueZone"] != None:
|
|
|
|
|
+ self.modeParam["ligneMireAttaqueZone"].prepareGeometryChange()
|
|
|
|
|
+ self.removeItem(self.modeParam["ligneMireAttaqueZone"])
|
|
|
|
|
+ self.modeParam["ligneMireAttaqueZone"] = None
|
|
|
|
|
+ if self.modeParam["point2AttaqueZone"] != None:
|
|
|
|
|
+ self.cases[self.coordonneesAuPoint(self.modeParam["point2AttaqueZone"])].majEstCibleCurseur(False)
|
|
|
|
|
+ for coord in self.modeParam["listeCasesAttaqueZone"]:
|
|
|
|
|
+ self.cases[coord].majEstCibleAttaque(False)
|
|
|
|
|
+ for numPion in self.pionsSurListeCase(self.modeParam["listeCasesAttaqueZone"]):
|
|
|
|
|
+ self.pions[numPion].estCibleAttaque(False)
|
|
|
|
|
+
|
|
|
|
|
+ def pionSurCase(self, coord):
|
|
|
|
|
+ """renvoie le pion present sur la case, none sinon"""
|
|
|
|
|
+ retour = None
|
|
|
|
|
+ for num in self.pions:
|
|
|
|
|
+ if self.pions[num].position == coord:
|
|
|
|
|
+ retour = num
|
|
|
|
|
+ return retour
|
|
|
|
|
+
|
|
|
|
|
+ def pionsSurListeCase(self, listeCases):
|
|
|
|
|
+ """renvoie la liste des pions presents sur la liste de cases"""
|
|
|
|
|
+ retour = []
|
|
|
|
|
+ for coord in listeCases:
|
|
|
|
|
+ pion = self.cases[coord].pionOccupant()
|
|
|
|
|
+ if pion != None and not pion.numero in retour:
|
|
|
|
|
+ retour.append(pion.numero)
|
|
|
|
|
+ return retour
|
|
|
|
|
+
|
|
|
|
|
+ def majZonePlacement(self, listeCases):
|
|
|
|
|
+ """met a jour la forme et l'affichage de la zone de placement initale des joueurs"""
|
|
|
|
|
+ if len(listeCases) > 0:
|
|
|
|
|
+ if self.polygoneZonePlacement == None:
|
|
|
|
|
+ self.polygoneZonePlacement = QGraphicsPolygonItem(scene=self)
|
|
|
|
|
+ self.polygoneZonePlacement.setZValue(0)
|
|
|
|
|
+ qCouleurFond = QColor("white")
|
|
|
|
|
+ qCouleurFond.setAlpha(50)
|
|
|
|
|
+ self.polygoneZonePlacement.setBrush(qCouleurFond)
|
|
|
|
|
+ pinceau = QPen(QColor("orange"))
|
|
|
|
|
+ pinceau.setWidth(20)
|
|
|
|
|
+ self.polygoneZonePlacement.setPen(pinceau)
|
|
|
|
|
+ self.polygoneZonePlacement.setAcceptedMouseButtons(Qt.NoButton)
|
|
|
|
|
+ self.polygoneZonePlacement.setAcceptHoverEvents(False)
|
|
|
|
|
+ self.addItem(self.polygoneZonePlacement)
|
|
|
|
|
+ listeCases2 = []
|
|
|
|
|
+ for coord in listeCases:
|
|
|
|
|
+ if self.cases[coord].estFranchissable():
|
|
|
|
|
+ listeCases2.append(coord)
|
|
|
|
|
+ self.polygoneZonePlacement.setPolygon(self.polygoneAgglo(listeCases2))
|
|
|
|
|
+ self.listeCasesZonePlacement = listeCases
|
|
|
|
|
+
|
|
|
|
|
+ def materialiserPions(self,actif):
|
|
|
|
|
+ """avtive/desactive la reception par les pions (autres que le pion selectionne) des hover events"""
|
|
|
|
|
+ for numPion in self.pions:
|
|
|
|
|
+ if numPion != self.modeParam["numPionSelectionne"]:
|
|
|
|
|
+ self.pions[numPion].setAcceptsHoverEvents(actif)
|
|
|
|
|
+ self.pions[numPion].polygoneGraphique.setAcceptsHoverEvents(actif)
|
|
|
|
|
+ for numPion in self.decors:
|
|
|
|
|
+ self.decors[numPion].setAcceptsHoverEvents(actif)
|
|
|
|
|
+ self.decors[numPion].polygoneGraphique.setAcceptsHoverEvents(actif)
|
|
|
|
|
+
|
|
|
|
|
+ #######################
|
|
|
|
|
+
|
|
|
|
|
+ ######## interaction avec les cases, decors et pions #############
|
|
|
|
|
+ def pionSelectionne(self):
|
|
|
|
|
+ """renvoie le pion actuellement selectionne"""
|
|
|
|
|
+ if self.modeParam["numPionSelectionne"] in self.pions:
|
|
|
|
|
+ retour = self.pions[self.modeParam["numPionSelectionne"]]
|
|
|
|
|
+ else:
|
|
|
|
|
+ retour = None
|
|
|
|
|
+ return retour
|
|
|
|
|
+
|
|
|
|
|
+ def pionDecorSelectionne(self):
|
|
|
|
|
+ """renvoie le pion actuellement selectionne"""
|
|
|
|
|
+ if self.modeParam["numPionSelectionne"] in self.decors:
|
|
|
|
|
+ retour = self.decors[self.modeParam["numPionSelectionne"]]
|
|
|
|
|
+ else:
|
|
|
|
|
+ retour = None
|
|
|
|
|
+ return retour
|
|
|
|
|
+
|
|
|
|
|
+ def caseCliquee(self, coord):
|
|
|
|
|
+ """on a clique sur la case (clic gauche)"""
|
|
|
|
|
+ accepte = False
|
|
|
|
|
+ if coord in self.cases:
|
|
|
|
|
+ case = self.cases[coord]
|
|
|
|
|
+ if self.modeActif == "caseCopie":
|
|
|
|
|
+ if len(case.terrain.nom) > 0:
|
|
|
|
|
+ self.majMode("caseMajTerrain", case.terrain)
|
|
|
|
|
+ accepte = True
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.majMode("caseMajTerrain", case.couleur)
|
|
|
|
|
+ accepte = True
|
|
|
|
|
+
|
|
|
|
|
+ elif self.modeActif[0:7] == "caseMaj" or self.modeActif == "cachePlacer" or self.modeActif == "majZonePlacement":
|
|
|
|
|
+ self.creerOrigineFormeDessin(coord)
|
|
|
|
|
+ accepte = True
|
|
|
|
|
+
|
|
|
|
|
+ elif self.modeActif == "pionDecorSelectionne":
|
|
|
|
|
+ if coord != self.pionDecorSelectionne().position:
|
|
|
|
|
+ self.pionDeposer(coord)
|
|
|
|
|
+ accepte = True
|
|
|
|
|
+
|
|
|
|
|
+ elif self.modeActif == "pionSelectionne":
|
|
|
|
|
+ if self.modeCombat == "combatDeplacement":
|
|
|
|
|
+ if self.pionSelectionne() != None:
|
|
|
|
|
+ if coord != self.pionSelectionne().position:
|
|
|
|
|
+ self.pionDeposer(coord)
|
|
|
|
|
+ accepte = True
|
|
|
|
|
+ elif self.modeCombat == "combatAttaqueCaC":
|
|
|
|
|
+ if self.modeParam["cibleAttaqueCaC"] in self.modeParam["zoneAttaqueCaC"]:
|
|
|
|
|
+ print("{} attaque {} au corps a corps".format(self.pionSelectionne().nom, self.modeParam["cibleAttaqueCaC"]))
|
|
|
|
|
+ self.majMode("pionSelectionne", None)
|
|
|
|
|
+ accepte = True
|
|
|
|
|
+ else:
|
|
|
|
|
+ print("cette case est invalide pour une corps a corps")
|
|
|
|
|
+ accepte = True
|
|
|
|
|
+ elif self.modeCombat == "combatAttaqueDist":
|
|
|
|
|
+ self.validerAttaqueDist()
|
|
|
|
|
+ accepte = True
|
|
|
|
|
+
|
|
|
|
|
+ elif self.modeCombat == "combatAttaqueZone":
|
|
|
|
|
+ self.validerAttaqueZone()
|
|
|
|
|
+ accepte = True
|
|
|
|
|
+
|
|
|
|
|
+ elif self.modeActif == "pionCreation":
|
|
|
|
|
+ self.pionCreer(coord)
|
|
|
|
|
+ accepte = True
|
|
|
|
|
+
|
|
|
|
|
+ elif self.modeActif == "pionDecorCreation":
|
|
|
|
|
+ self.pionDecorCreer(coord)
|
|
|
|
|
+ accepte = True
|
|
|
|
|
+ return accepte
|
|
|
|
|
+
|
|
|
|
|
+ def caseSurvolClicEnfonce(self, coordCase):
|
|
|
|
|
+ """une case est survolee par le curseur (le clic gauche est enfonce)"""
|
|
|
|
|
+ if self.modeActif[0:7] == "caseMaj" or self.modeActif == "cachePlacer" or self.modeActif == "majZonePlacement":
|
|
|
|
|
+ if self.cases[coordCase].centreGraphique != self.modeParam["point2FormeDessin"]:
|
|
|
|
|
+ if self.modeParam["origineFormeDessin"] == None: self.modeParam["origineFormeDessin"] = self.cases[coordCase].centreGraphique
|
|
|
|
|
+ self.modeParam["point2FormeDessin"] = self.cases[coordCase].centreGraphique
|
|
|
|
|
+ self.majFormeDessin()
|
|
|
|
|
+
|
|
|
|
|
+ def clicGaucheRelache(self):
|
|
|
|
|
+ """si une forme de selection etait affichee, elle est validee"""
|
|
|
|
|
+ if len(self.modeParam["listeCasesFormeDessin"]) > 0:
|
|
|
|
|
+ self.validerFormeDessin()
|
|
|
|
|
+
|
|
|
|
|
+ def caseSurvol(self, case):
|
|
|
|
|
+ """une case est survole par le curseur, on affiche ses informations dans la zone prevue"""
|
|
|
|
|
+ self.majInfosCase(case)
|
|
|
|
|
+ if (self.modeActif == "pionSelectionne" and self.modeCombat == "combatDeplacement") or self.modeActif == "pionCreation"\
|
|
|
|
|
+ or self.modeActif == "pionDecorSelectionne" or self.modeActif == "pionDecorCreation":
|
|
|
|
|
+ self.majProjectionPosition(False)
|
|
|
|
|
+ self.modeParam["coordProjectionPosition"] = (case.x, case.y)
|
|
|
|
|
+ self.majProjectionPosition(True)
|
|
|
|
|
+ elif self.modeActif == "pionSelectionne" and self.modeCombat == "combatAttaqueDist" and self.modeParam["cibleAttaqueDist"] != (case.x, case.y):
|
|
|
|
|
+ self.majLigneMireAttaqueDist((case.x,case.y))
|
|
|
|
|
+ elif self.modeActif == "pionSelectionne" and self.pionSelectionne() != None and self.modeCombat == "combatAttaqueZone":
|
|
|
|
|
+ if case.centreGraphique != self.modeParam["point2AttaqueZone"]:
|
|
|
|
|
+ self.cases[self.coordonneesAuPoint(self.modeParam["point2AttaqueZone"])].majEstCibleCurseur(False)
|
|
|
|
|
+ self.modeParam["point2AttaqueZone"] = case.centreGraphique
|
|
|
|
|
+ self.majFormeAttaqueZone()
|
|
|
|
|
+
|
|
|
|
|
+ def afficherListeCases(self, listeCases, actif):
|
|
|
|
|
+ """met ou non en evidence les cases selectionnees"""
|
|
|
|
|
+ for coord in listeCases:
|
|
|
|
|
+ self.cases[coord].majEstCibleCurseur(actif)
|
|
|
|
|
+
|
|
|
|
|
+ def majListeCases(self, listeCases):
|
|
|
|
|
+ """met a jour les cases dont les coordonnees sont dans la liste"""
|
|
|
|
|
+ self.afficherListeCases(listeCases, False)
|
|
|
|
|
+
|
|
|
|
|
+ if self.modeActif[0:7] == "caseMaj":
|
|
|
|
|
+ for coord in listeCases:
|
|
|
|
|
+ self.caseMaj(coord)
|
|
|
|
|
+ elif self.modeActif == "cachePlacer":
|
|
|
|
|
+ self.majAffichageCache(self.cacheEnCours, False)
|
|
|
|
|
+ self.caches[self.cacheEnCours]["listeCases"] = listeCases
|
|
|
|
|
+ self.majAffichageCache(self.cacheEnCours, True)
|
|
|
|
|
+ elif self.modeActif == "majZonePlacement":
|
|
|
|
|
+ self.majZonePlacement(listeCases)
|
|
|
|
|
+
|
|
|
|
|
+ def caseMaj(self, coordCase):
|
|
|
|
|
+ """met a jour la case selon le mode actif (et les cases adjacentes selon l'epaisseur du pinceau)"""
|
|
|
|
|
+ if self.modeActif == "caseMajTerrain":
|
|
|
|
|
+ if self.modeParam["terrain"] != None:
|
|
|
|
|
+ if self.modeParam["terrain"].__class__.__name__ == "Terrain":
|
|
|
|
|
+ self.cases[coordCase].majTerrain(self.modeParam["terrain"])
|
|
|
|
|
+ elif self.modeParam["terrain"].__class__.__name__ == "QColor":
|
|
|
|
|
+ if self.modeParam["terrain"].isValid():
|
|
|
|
|
+ self.cases[coordCase].majTerrain(None)
|
|
|
|
|
+ self.cases[coordCase].majCouleur(self.modeParam["terrain"])
|
|
|
|
|
+ self.cases[coordCase].majAltitude(int(self.fenetre.ui.altitudeCase.value()))
|
|
|
|
|
+ elif self.modeActif == "caseMajEffet":
|
|
|
|
|
+ self.cases[coordCase].majEffet(self.modeParam["effet"])
|
|
|
|
|
+ elif self.modeActif == "caseMajAltitude":
|
|
|
|
|
+ self.cases[coordCase].majAltitude(int(self.fenetre.ui.altitudeCase.value()))
|
|
|
|
|
+
|
|
|
|
|
+ def majInfosCase(self, case=None):
|
|
|
|
|
+ """met a jour les informations d'un pion dans la zone prevue"""
|
|
|
|
|
+ if case != None:
|
|
|
|
|
+ if len(case.terrain.nom) > 0:
|
|
|
|
|
+ self.fenetre.ui.infoCaseEnCours_terrain.setText(QString.fromUtf8(case.terrain.nom))
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.fenetre.ui.infoCaseEnCours_terrain.setText(QString.fromUtf8("Case"))
|
|
|
|
|
+ self.fenetre.ui.infoCaseEnCours_coord.setText(QString.fromUtf8("X: {} Y: {}".format(case.x, case.y)))
|
|
|
|
|
+ self.fenetre.ui.infoCaseEnCours_altitude.setText(QString.fromUtf8("Alt.: {}".format(case.altitude)))
|
|
|
|
|
+ if case.effetActif != "":
|
|
|
|
|
+ pix = QPixmap(QString.fromUtf8("img\\"+case.imgEffet[case.effetActif]))
|
|
|
|
|
+ pix = pix.scaled(21, 21, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
|
|
|
|
+ self.fenetre.ui.infoCaseEnCours_effetImg.setPixmap(pix)
|
|
|
|
|
+ self.fenetre.ui.infoCaseEnCours_effetNom.setText(QString.fromUtf8(case.effetActif))
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.fenetre.ui.infoCaseEnCours_effetImg.clear()
|
|
|
|
|
+ self.fenetre.ui.infoCaseEnCours_effetNom.clear()
|
|
|
|
|
+ self.fenetre.ui.infoCase.setVisible(True)
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.fenetre.ui.infoCase.setVisible(False)
|
|
|
|
|
+
|
|
|
|
|
+ def pionClique(self, numPion):
|
|
|
|
|
+ """on a clique sur ce pion"""
|
|
|
|
|
+ accepte = False
|
|
|
|
|
+ if self.pionSelectionne() != None and self.modeCombat == "combatAttaqueDist":
|
|
|
|
|
+ self.validerAttaqueDist()
|
|
|
|
|
+ accepte = True
|
|
|
|
|
+
|
|
|
|
|
+ elif self.modeActif == "standard" and self.pionSelectionne() == None:
|
|
|
|
|
+ self.pionSaisir(numPion)
|
|
|
|
|
+ accepte = True
|
|
|
|
|
+ return accepte
|
|
|
|
|
+
|
|
|
|
|
+ def pionSurvol(self, numPion):
|
|
|
|
|
+ """le pion est survole par le curseur, on affiche ses informations dans la zone prevue"""
|
|
|
|
|
+ if numPion in self.pions:
|
|
|
|
|
+ pion = self.pions[numPion]
|
|
|
|
|
+ else:
|
|
|
|
|
+ pion = None
|
|
|
|
|
+ self.majInfosPion(pion)
|
|
|
|
|
+ if self.pionSelectionne() != None and self.modeCombat == "combatAttaqueCaC":
|
|
|
|
|
+ self.majProjectionAttaqueCaC(pion)
|
|
|
|
|
+ pass
|
|
|
|
|
+ if numPion in self.pions:
|
|
|
|
|
+ case = self.cases[self.pions[numPion].position]
|
|
|
|
|
+ self.caseSurvol(case)
|
|
|
|
|
+
|
|
|
|
|
+ def pionDoubleClic(self, numPion):
|
|
|
|
|
+ """on a double-clique sur le pion"""
|
|
|
|
|
+ accepte = False
|
|
|
|
|
+ if self.pionSelectionne() == self.pions[numPion] and self.modeCombat == "aucun":
|
|
|
|
|
+## self.pionSaisir(numPion)
|
|
|
|
|
+ self.majModeCombat("combatDeplacement")
|
|
|
|
|
+ accepte = True
|
|
|
|
|
+ return accepte
|
|
|
|
|
+
|
|
|
|
|
+ def pionCreer(self, coordCase):
|
|
|
|
|
+ """creer un jeton aux coordonnees indiquees"""
|
|
|
|
|
+ valide = True
|
|
|
|
|
+ for coord in self.modeParam["formeProjectionPosition"].listeCases(coordCase):
|
|
|
|
|
+ if not coord in self.cases:
|
|
|
|
|
+ valide = False
|
|
|
|
|
+ else:
|
|
|
|
|
+ if not self.cases[coord].estFranchissable():
|
|
|
|
|
+ valide = False
|
|
|
|
|
+ if valide:
|
|
|
|
|
+ numero = 1
|
|
|
|
|
+ if len(self.pions) > 0:
|
|
|
|
|
+ numero = max(self.pions) + 1
|
|
|
|
|
+ pion = Pion(self, numero)
|
|
|
|
|
+ if self.modeParam["creature"] != None:
|
|
|
|
|
+ nom = self.modeParam["creature"].nom
|
|
|
|
|
+ elif len(self.fenetre.ui.pionSimple_nom.text().toUtf8()) > 0:
|
|
|
|
|
+ nom = self.fenetre.ui.pionSimple_nom.text().toUtf8()
|
|
|
|
|
+ numTxt = self.numeroterNom(nom)
|
|
|
|
|
+ self.pions[numero] = pion
|
|
|
|
|
+ pion.creer(coordCase[0], coordCase[1], nom, numTxt, self.modeParam["creature"], self.modeParam["couleurPion"], self.modeParam["nbRotations"])
|
|
|
|
|
+ self.pionDeplacerDansOrdreJeu(numero, len(self.ordreJeu) + 2)
|
|
|
|
|
+
|
|
|
|
|
+ def numeroterNom(self, nom):
|
|
|
|
|
+ """renvoie le nom du pion avec un numero complementaire si necessaire """
|
|
|
|
|
+ i = 1
|
|
|
|
|
+ for numPion in self.pions:
|
|
|
|
|
+ if self.pions[numPion].nom == nom:
|
|
|
|
|
+ i += 1
|
|
|
|
|
+ if i == 1:
|
|
|
|
|
+ retour = ""
|
|
|
|
|
+ else:
|
|
|
|
|
+ retour = str(i)
|
|
|
|
|
+ return retour
|
|
|
|
|
+
|
|
|
|
|
+ def pionSaisir(self, numPion):
|
|
|
|
|
+ """on saisit un pion"""
|
|
|
|
|
+ if numPion != self.modeParam["numPionSelectionne"]:
|
|
|
|
|
+ self.majMode("pionSelectionne", numPion)
|
|
|
|
|
+
|
|
|
|
|
+ def pionDeposer(self, coordCase):
|
|
|
|
|
+ """on depose le pion sur la case voulue"""
|
|
|
|
|
+ if self.pionSelectionne() != None:
|
|
|
|
|
+ pion = self.pionSelectionne()
|
|
|
|
|
+ else:
|
|
|
|
|
+ pion = self.pionDecorSelectionne()
|
|
|
|
|
+
|
|
|
|
|
+ if pion != None:
|
|
|
|
|
+ valide = True
|
|
|
|
|
+ for coord in self.modeParam["formeProjectionPosition"].listeCases(coordCase, self.modeParam["nbRotations"]):
|
|
|
|
|
+ if coord in self.cases:
|
|
|
|
|
+ if not self.cases[coord].estFranchissable(pion.z):
|
|
|
|
|
+ if not self.cases[coord].estOccupeePar(pion.z) == pion:
|
|
|
|
|
+ #si la case est occupee par le pion qu'on depose, elle est donc valide pour un deplacement
|
|
|
|
|
+ valide = False
|
|
|
|
|
+ else:
|
|
|
|
|
+ valide = False
|
|
|
|
|
+ if valide:
|
|
|
|
|
+ positionPrecedente = pion.position
|
|
|
|
|
+ #mise a jour de la position du pion selon le mode
|
|
|
|
|
+ if self.modePrincipal == "combat":
|
|
|
|
|
+## if coordCase in pion.champDeplacement:
|
|
|
|
|
+## print("le pion a ete deplace de {} vers {} \n -> soit une distance de {} cases"\
|
|
|
|
|
+## "".format(positionPrecedente, coordCase, self.pionSelectionne().champDeplacement[coordCase]))
|
|
|
|
|
+ self.majInfosPion()
|
|
|
|
|
+ pion.majPosition(coordCase, self.modeParam["nbRotations"])
|
|
|
|
|
+ self.majModeCombat("aucun")
|
|
|
|
|
+ else:
|
|
|
|
|
+ print("Deplacement impossible!")
|
|
|
|
|
+
|
|
|
|
|
+ def afficherChampDeplacement(self, actif):
|
|
|
|
|
+ """cree et affiche ou efface et detruit le champ de deplacement du pion selectionne"""
|
|
|
|
|
+ if self.pionSelectionne() != None:
|
|
|
|
|
+ if actif:
|
|
|
|
|
+ self.pionSelectionne().champDeplacement = self.zone(self.pionSelectionne().position, \
|
|
|
|
|
+ self.pionSelectionne().deplacementRestant, \
|
|
|
|
|
+ True)
|
|
|
|
|
+ for coord in self.pionSelectionne().champDeplacement:
|
|
|
|
|
+ self.cases[coord].majEstDansChampDeplacement(actif)
|
|
|
|
|
+
|
|
|
|
|
+ if not actif:
|
|
|
|
|
+ self.pionSelectionne().champDeplacement = {}
|
|
|
|
|
+
|
|
|
|
|
+ def majInfosPion(self, pionSurvole=None):
|
|
|
|
|
+ """met a jour les informations d'un pion dans la zone prevue"""
|
|
|
|
|
+ if pionSurvole != None:
|
|
|
|
|
+ pion = pionSurvole
|
|
|
|
|
+ else:
|
|
|
|
|
+ if self.pionSelectionne() != None:
|
|
|
|
|
+ pion = self.pionSelectionne()
|
|
|
|
|
+ else:
|
|
|
|
|
+ pion = None
|
|
|
|
|
+
|
|
|
|
|
+ if pion != None:
|
|
|
|
|
+ self.fenetre.ui.infoPionEnCours_nom.setText(QString.fromUtf8(pion.nom))
|
|
|
|
|
+ self.fenetre.ui.infoPionEnCours_depRestant.setText(QString.fromUtf8("Dep.: {}".format(pion.deplacementRestant)))
|
|
|
|
|
+ if len(pion.creature.img["nom"]) > 0:
|
|
|
|
|
+ pix = QPixmap(QString.fromUtf8("img\\"+pion.creature.img["nom"]))
|
|
|
|
|
+ pix = pix.scaled(61, 51, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
|
|
|
|
+ self.fenetre.ui.infoPionEnCours_image.setPixmap(pix)
|
|
|
|
|
+ self.fenetre.ui.infoPion.setVisible(True)
|
|
|
|
|
+ self.fenetre.ui.infoPionEnCours_etourdi.setVisible(False)
|
|
|
|
|
+ self.fenetre.ui.infoPionEnCours_brule.setVisible(False)
|
|
|
|
|
+ self.fenetre.ui.infoPionEnCours_mouille.setVisible(False)
|
|
|
|
|
+ self.fenetre.ui.infoPionEnCours_vol.setVisible((pion.z != 0))
|
|
|
|
|
+ self.fenetre.ui.infoPionEnCours_endormi.setVisible(False)
|
|
|
|
|
+ self.fenetre.ui.infoPionEnCours_paralyse.setVisible(False)
|
|
|
|
|
+ self.fenetre.ui.infoPionEnCours_entrave.setVisible(False)
|
|
|
|
|
+ self.fenetre.ui.infoPionEnCours_mort.setVisible(False)
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.fenetre.ui.infoPion.setVisible(False)
|
|
|
|
|
+
|
|
|
|
|
+ def majZPion(self, valeur):
|
|
|
|
|
+ """met a jour l'altitude du pion selectionne"""
|
|
|
|
|
+ if self.pionSelectionne() != None:
|
|
|
|
|
+ self.pionSelectionne().majZ(valeur)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ def pionDecorSurvol(self, numPionDecor):
|
|
|
|
|
+ """le pion-decor est survole par le curseur, on affiche ses informations dans la zone prevue"""
|
|
|
|
|
+ if numPionDecor in self.decors:
|
|
|
|
|
+ self.majInfosDecor(self.decors[numPionDecor])
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.majInfosDecor(None)
|
|
|
|
|
+
|
|
|
|
|
+ def pionDecorSaisir(self, numPionDecor):
|
|
|
|
|
+ """on saisit un pion decor (mode creation seulement)"""
|
|
|
|
|
+ if numPionDecor != self.modeParam["numPionSelectionne"]:
|
|
|
|
|
+ self.majMode("pionDecorSelectionne", numPionDecor)
|
|
|
|
|
+
|
|
|
|
|
+ def majInfosDecor(self, pionDecor=None):
|
|
|
|
|
+ """met a jour les informations d'un pion dans la zone prevue"""
|
|
|
|
|
+ if pionDecor != None:
|
|
|
|
|
+ self.fenetre.ui.infoDecorEnCours_nom.setText(QString.fromUtf8(pionDecor.decor.nom))
|
|
|
|
|
+ self.fenetre.ui.infoDecorEnCours_hauteur.setText(QString.fromUtf8("Haut.: {}".format(pionDecor.decor.hauteur)))
|
|
|
|
|
+ if len(pionDecor.decor.img["nom"]) > 0:
|
|
|
|
|
+ pix = QPixmap(QString.fromUtf8("img\\"+pionDecor.decor.img["nom"]))
|
|
|
|
|
+ pix = pix.scaled(61, 51, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
|
|
|
|
+ self.fenetre.ui.infoDecorEnCours_image.setPixmap(pix)
|
|
|
|
|
+ self.fenetre.ui.infoDecor.setVisible(True)
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.fenetre.ui.infoDecor.setVisible(False)
|
|
|
|
|
+
|
|
|
|
|
+ def majProjectionPosition(self, activer, z=0):
|
|
|
|
|
+ """maj l'affichage de la projection de la position d'un objet avant creation ou deplacement (pion, decor...)"""
|
|
|
|
|
+ valide = True
|
|
|
|
|
+ possible = True
|
|
|
|
|
+
|
|
|
|
|
+ if self.modeParam["formeProjectionPosition"] != None and self.modeParam["coordProjectionPosition"] != None:
|
|
|
|
|
+ proj = self.modeParam["formeProjectionPosition"].listeCases(self.modeParam["coordProjectionPosition"], self.modeParam["nbRotations"])
|
|
|
|
|
+
|
|
|
|
|
+ for coord in proj:
|
|
|
|
|
+ if not coord in self.cases:
|
|
|
|
|
+ valide = False #deplacement valide? (pas d'occupation d'une case hors plateau)
|
|
|
|
|
+
|
|
|
|
|
+ if valide == True:
|
|
|
|
|
+ for coord in proj:
|
|
|
|
|
+ if self.cases[coord].estFranchissable(z) or self.cases[coord].estOccupeePar(z) == self.pionSelectionne():
|
|
|
|
|
+ #la case est franchissable, ou elle ne l'est pas mais est occupée par le pion meme qu'on deplace
|
|
|
|
|
+ self.cases[coord].majEstCibleCurseur(activer, True)
|
|
|
|
|
+
|
|
|
|
|
+ #on affiche la distance correspondante en bulle-info
|
|
|
|
|
+ if activer and self.modeActif == "pionSelectionne" and self.modePrincipal == "combat":
|
|
|
|
|
+ if coord in self.pionSelectionne().champDeplacement:
|
|
|
|
|
+ msg = "Distance {}".format(self.pionSelectionne().champDeplacement[coord])
|
|
|
|
|
+ QToolTip.showText(QCursor.pos(), msg, self.fenetre.ui.vuePlateau)
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.cases[coord].majEstCibleCurseur(activer, False)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ def majProjectionAttaqueCaC(self, pionCible):
|
|
|
|
|
+ """affiche ou non la cible de l'attaque au corps a corps, selon sa validite ou non"""
|
|
|
|
|
+ if self.modeActif == "pionSelectionne" and self.modeCombat == "combatAttaqueCaC":
|
|
|
|
|
+ if pionCible != self.pionSelectionne():
|
|
|
|
|
+ if pionCible != None:
|
|
|
|
|
+ conditionPossible = (pionCible.position in self.modeParam["zoneAttaqueCaC"])
|
|
|
|
|
+ pionCible.estCibleAttaque(True, conditionPossible)
|
|
|
|
|
+ else:
|
|
|
|
|
+ if self.modeParam["cibleAttaqueCaC"] != None:
|
|
|
|
|
+ self.modeParam["cibleAttaqueCaC"].estCibleAttaque(False)
|
|
|
|
|
+ self.modeParam["cibleAttaqueCaC"] = pionCible
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ def majZoneAttaqueCaC(self, actif = True):
|
|
|
|
|
+ """affiche ou non les cases a portee du pion selectionne pour une attaque au corps-a-corps"""
|
|
|
|
|
+ for coord in self.modeParam["zoneAttaqueCaC"]:
|
|
|
|
|
+ self.cases[coord].majEstDansChampDeplacement(actif)
|
|
|
|
|
+
|
|
|
|
|
+ def pionDecorCreer(self, coordCase):
|
|
|
|
|
+ """creer un jeton aux coordonnees indiquees"""
|
|
|
|
|
+ valide = True
|
|
|
|
|
+ for coord in self.modeParam["formeProjectionPosition"].listeCases(coordCase, self.modeParam["nbRotations"]):
|
|
|
|
|
+ if not self.cases[coord].estFranchissable():
|
|
|
|
|
+ valide = False
|
|
|
|
|
+ if valide:
|
|
|
|
|
+ numero = 10001
|
|
|
|
|
+ if len(self.decors) > 0:
|
|
|
|
|
+ numero = max(self.decors) + 10001
|
|
|
|
|
+ pionDecor = PionDecor(self, numero)
|
|
|
|
|
+ pionDecor.creer(coordCase[0], coordCase[1], self.modeParam["decor"], self.modeParam["nbRotations"])
|
|
|
|
|
+ self.decors[numero] = pionDecor
|
|
|
|
|
+
|
|
|
|
|
+ def pionSupprimer(self, num):
|
|
|
|
|
+ """supprime le pion entre en parametre"""
|
|
|
|
|
+ #settrace(trace_calls)
|
|
|
|
|
+ if num in self.pions:
|
|
|
|
|
+ for coord in self.pions[num].forme.listeCases(self.pions[num].position, self.pions[num].nbRotations):
|
|
|
|
|
+ self.cases[coord].majOccupation(self.pions[num])
|
|
|
|
|
+ self.pionSurvol(None)
|
|
|
|
|
+ self.pionDeplacerDansOrdreJeu(num, 0)
|
|
|
|
|
+ pionSuppr = self.pions.pop(num)
|
|
|
|
|
+ pionSuppr.supprimer()
|
|
|
|
|
+ else:
|
|
|
|
|
+ print("erreur: ce pion n'est pas dans la liste des pions")
|
|
|
|
|
+
|
|
|
|
|
+ def pionDecorSupprimer(self, num):
|
|
|
|
|
+ """supprime le pion entre en parametre"""
|
|
|
|
|
+ if num in self.decors:
|
|
|
|
|
+ for coord in self.decors[num].forme.listeCases(self.decors[num].position, self.decors[num].nbRotations):
|
|
|
|
|
+ self.cases[coord].majOccupation(self.decors[num])
|
|
|
|
|
+ self.pionDecorSurvol(None)
|
|
|
|
|
+ pionDecorASuppr = self.decors.pop(num)
|
|
|
|
|
+ pionDecorASuppr.supprimer()
|
|
|
|
|
+ else:
|
|
|
|
|
+ print("ce pion n'est pas dans la liste des decors")
|
|
|
|
|
+
|
|
|
|
|
+ ###############
|
|
|
|
|
+
|
|
|
|
|
+ ######### caches ###############
|
|
|
|
|
+ def voirCacheEnCours(self):
|
|
|
|
|
+ """centre la vue sur et met en evidence le cache actif"""
|
|
|
|
|
+ if len(self.caches[self.cacheEnCours]["listeCases"]) > 0:
|
|
|
|
|
+ #centre la vue sur le premier point du polygone d'une case du milieu de la liste
|
|
|
|
|
+ indiceMilieu = int((len(self.caches[self.cacheEnCours]["listeCases"])/2))
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.centerOn(self.cases[self.caches[self.cacheEnCours]["listeCases"][indiceMilieu]].polygon()[0])
|
|
|
|
|
+ #mettre en surbrillance
|
|
|
|
|
+ #for coord in self.caches[self.cacheEnCours]["listeCases"]:
|
|
|
|
|
+ # self.
|
|
|
|
|
+
|
|
|
|
|
+ def placerCacheEnCours(self):
|
|
|
|
|
+ """active le mode de mise a jour de la liste des cases cachees par ce cache"""
|
|
|
|
|
+ self.majMode("cachePlacer")
|
|
|
|
|
+ self.fenetre.ui.cacheActif.setChecked(True)
|
|
|
|
|
+ self.majEtatCacheEnCours()
|
|
|
|
|
+
|
|
|
|
|
+ def majEtatCacheEnCours(self):
|
|
|
|
|
+ """met a jour l'etat (actif ou non) du cache selon l'etat de la case correspondante"""
|
|
|
|
|
+ self.caches[self.cacheEnCours]["actif"] = self.fenetre.ui.cacheActif.isChecked()
|
|
|
|
|
+ self.majAffichageCache(self.cacheEnCours, self.caches[self.cacheEnCours]["actif"])
|
|
|
|
|
+
|
|
|
|
|
+ def majAffichageCache(self, numCache, afficher = True):
|
|
|
|
|
+ """met a jour l'affichage des cases selon les parametres enregistres pour le cache"""
|
|
|
|
|
+ if self.polygonesCaches[numCache] == None:
|
|
|
|
|
+ self.polygonesCaches[numCache] = Cache(self, numCache)
|
|
|
|
|
+ self.polygonesCaches[numCache].afficher(afficher, self.caches[numCache]["listeCases"])
|
|
|
|
|
+
|
|
|
|
|
+ ###############"
|
|
|
|
|
+
|
|
|
|
|
+ ######### gestion des evenements souris et clavier ###############
|
|
|
|
|
+ #*ES
|
|
|
|
|
+ def wheelEvent(self, event):
|
|
|
|
|
+ """zoom/dezoom avec la molette de la souris"""
|
|
|
|
|
+ #on zoom/dezoom et on recentre sur la position du curseur
|
|
|
|
|
+ #super (Plateau, self).wheelEvent(event)
|
|
|
|
|
+ zoom = 1.00
|
|
|
|
|
+ if event.delta() > 0:
|
|
|
|
|
+ if self.nbZoomActuel <= 10:
|
|
|
|
|
+ self.nbZoomActuel += 1
|
|
|
|
|
+ zoom = 1.25
|
|
|
|
|
+ elif event.delta() < 0:
|
|
|
|
|
+ if self.nbZoomActuel >= -10:
|
|
|
|
|
+ zoom = 0.8
|
|
|
|
|
+ self.nbZoomActuel -= 1
|
|
|
|
|
+ if zoom != 0.00:
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.scale(zoom, zoom)
|
|
|
|
|
+ self.fenetre.ui.vuePlateau.centerOn(event.scenePos())
|
|
|
|
|
+ event.accept() #pour considerer l'evenement comme resolu, sans ca les barres de defilement reagissent aussi
|
|
|
|
|
+
|
|
|
|
|
+ def mouseMoveEvent(self, event):
|
|
|
|
|
+ super(Plateau, self).mouseMoveEvent(event)
|
|
|
|
|
+ if event.buttons() == Qt.LeftButton and self.fenetre.ui.vuePlateau.dragMode() != QGraphicsView.ScrollHandDrag:
|
|
|
|
|
+ coord = self.coordonneesAuPoint(event.scenePos())
|
|
|
|
|
+ if coord != None:
|
|
|
|
|
+ self.caseSurvolClicEnfonce(coord)
|
|
|
|
|
+ else:
|
|
|
|
|
+ if self.modeActif == "placementEntreeSortie":
|
|
|
|
|
+ self.modeParam["entreeSortie"].majProjection(event.scenePos())
|
|
|
|
|
+ event.ignore()
|
|
|
|
|
+
|
|
|
|
|
+ def mousePressEvent(self, event):
|
|
|
|
|
+ super(Plateau, self).mousePressEvent(event)
|
|
|
|
|
+ if event.button() == 1 and self.fenetre.ui.vuePlateau.dragMode() != QGraphicsView.ScrollHandDrag:
|
|
|
|
|
+ if self.modeActif == "placementEntreeSortie" and not event.isAccepted():
|
|
|
|
|
+ self.modeParam["entreeSortie"].positionner()
|
|
|
|
|
+ self.entreesSorties.append(self.modeParam["entreeSortie"])
|
|
|
|
|
+ self.modeParam["entreeSortie"] = None
|
|
|
|
|
+ self.majMode("standard")
|
|
|
|
|
+ elif self.modeActif == "pionSupprimer":
|
|
|
|
|
+ for item in self.items(event.scenePos()):
|
|
|
|
|
+ if item.__class__.__name__ == "PionDecor":
|
|
|
|
|
+ self.pionDecorSupprimer(item.numero)
|
|
|
|
|
+ break
|
|
|
|
|
+ elif item.parentItem().__class__.__name__ == "Pion":
|
|
|
|
|
+ self.pionSupprimer(item.parentItem().numero)
|
|
|
|
|
+ break
|
|
|
|
|
+
|
|
|
|
|
+ else:
|
|
|
|
|
+## if not event.isAccepted():
|
|
|
|
|
+## self.caseCliquee(self.coordonneesAuPoint(event.scenePos()))
|
|
|
|
|
+ event.ignore()
|
|
|
|
|
+ elif event.button() == 2:
|
|
|
|
|
+ if self.pionSelectionne() != None and self.modeCombat != "" and self.modeCombat != "aucun":
|
|
|
|
|
+ self.majModeCombat("aucun")
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.majMode("standard")
|
|
|
|
|
+ event.accept()
|
|
|
|
|
+ #event.ignore()
|
|
|
|
|
+
|
|
|
|
|
+ def mouseReleaseEvent(self, event):
|
|
|
|
|
+ super(Plateau, self).mouseReleaseEvent(event)
|
|
|
|
|
+ self.clicGaucheRelache()
|
|
|
|
|
+
|
|
|
|
|
+ def keyPressEvent(self, event):
|
|
|
|
|
+ """gestion des evenements clavier"""
|
|
|
|
|
+ toucheClavier = event.key()
|
|
|
|
|
+ if self.modeActif == "pionCreation" or self.modeActif == "pionSelectionne" or self.modeActif == "pionDecorSelectionne" or self.modeActif == "pionDecorCreation":
|
|
|
|
|
+ #pivots de la projection du deplacement
|
|
|
|
|
+ if toucheClavier == Qt.Key_Right:
|
|
|
|
|
+ self.majProjectionPosition(False)
|
|
|
|
|
+ self.modeParam["nbRotations"] += 1
|
|
|
|
|
+ self.majProjectionPosition(True)
|
|
|
|
|
+ event.accept()
|
|
|
|
|
+ elif toucheClavier == Qt.Key_Left:
|
|
|
|
|
+ self.majProjectionPosition(False)
|
|
|
|
|
+ self.modeParam["nbRotations"] -= 1
|
|
|
|
|
+ self.majProjectionPosition(True)
|
|
|
|
|
+ event.accept()
|
|
|
|
|
+ elif self.modeActif == "creerEntreeSortie":
|
|
|
|
|
+ if toucheClavier == Qt.Key_Right: self.modeParam["entreeSortie"].nbRotations += 1
|
|
|
|
|
+ if toucheClavier == Qt.Key_Left: self.modeParam["entreeSortie"].nbRotations -= 1
|
|
|
|
|
+ self.modeParam["entreeSortie"].majProjection()
|
|
|
|
|
+ if self.modeActif[0:7] == "caseMaj":
|
|
|
|
|
+ if toucheClavier == Qt.Key_Up:
|
|
|
|
|
+ self.fenetre.ui.epaisseurPinceau.setValue(self.fenetre.ui.epaisseurPinceau.value()+1)
|
|
|
|
|
+ elif toucheClavier == Qt.Key_Down:
|
|
|
|
|
+ self.fenetre.ui.epaisseurPinceau.setValue(self.fenetre.ui.epaisseurPinceau.value()-1)
|
|
|
|
|
+ if toucheClavier == Qt.Key_Delete:
|
|
|
|
|
+ if self.pionSelectionne() != None:
|
|
|
|
|
+ num = self.pionSelectionne().numero
|
|
|
|
|
+ if self.modeActif == "pionSelectionne":
|
|
|
|
|
+ self.pionSupprimer(num)
|
|
|
|
|
+ elif self.modeActif == "pionDecorSelectionne":
|
|
|
|
|
+ self.pionDecorSupprimer(num)
|
|
|
|
|
+ self.majMode("standard")
|
|
|
|
|
+ elif self.modeActif == "placementEntreeSortie":
|
|
|
|
|
+ self.modeParam["entreeSortie"].plateau = None
|
|
|
|
|
+ self.removeItem(self.modeParam["entreeSortie"])
|
|
|
|
|
+ self.entreesSorties.remove(self.modeParam["entreeSortie"])
|
|
|
|
|
+ self.modeParam["entreeSortie"] = None
|
|
|
|
|
+ self.majMode("standard")
|
|
|
|
|
+
|
|
|
|
|
+ ################
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|