| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390 |
- #from __future__ import unicode_literals
- # -*- coding: utf-8 -*-
- from __future__ import division
- from time import time
- from PyQt4.QtCore import Qt, SIGNAL, QPointF, QString
- from PyQt4.QtGui import QGraphicsScene, QColor, QPixmap, QPainter, QIcon, \
- QTableWidgetItem, QToolButton, QColorDialog, QMessageBox, \
- QApplication, QGraphicsPolygonItem, QPen, QGraphicsView, QTableWidget, \
- QLineEdit, QTextEdit, QSlider, QDoubleSpinBox
- import Actions
- from Cache import Cache
- from Case import Case
- from EcranAffichageTexte import EcranAffichageTexte
- from EcranCreerPlateau import EcranCreerPlateau
- from EcranGestionCombat import EcranGestionCombat
- import Modes
- from Pinceau import Pinceau
- from ProjectionDep import ProjectionDep
- from Terrain import Terrain
- from lib.Actions import choisirAttaqueZone
- from lib.EcranEditionMateriel import EcranEditionMateriel
- from lib.ListePions import ListePions
- from lib.commun import lstLibEtats
- from lib.dmF import contractTxt
- from lib.gC import GestionCombat
- from lib.gM import GestionMateriel
- from lib.geometrie import Geometrie
- from lib.mat import Materiel, chargerMat
- import regles as regles
- class Plateau(QGraphicsScene, Materiel):
- """plateau de jeu contenant les cases, decors et pions"""
- def __init__(self, fenetre, parent=None):
- super(Plateau, self).__init__()
- #parametres et variables
- self._type = "pl"
- self.fenetre = fenetre
- ##partie et infos plateau
- self.chapitre = 0
- self.creePar = ""
-
- self.enCours = False
- self.public = False
- self.dateCreation = ""
- self.dateSvg = ""
- self.notes = ""
- self.presentation = ""
-
- #carac
- self.nbCasesX = 0
- self.nbCasesY = 0
- self.hCase = 0
- self.couleurInit = QColor(0, 255, 0, 80)
- self.zP = None #plafond
- self._compteurPile = 0 #compteur d'empilement, pour gerer l'ordre de recreation des pions
- #objets
- self.pinceau = Pinceau(self)
- self.gM = GestionMateriel()
- self.gC = GestionCombat()
- self.geo = Geometrie()
- self.cases = {} #dict des cases du plateau (coordonnées: case)
- self.pions = ListePions()
- self.caches = {}
- self.listeCasesZonePlacement = []
- self.polygoneZonePlacement = None
- self.entreesSorties = []
- #infos combat
- self.numCombattantEnCours = 0
- self.ordreJeu = {} #numero du pion: ordre de jeu
- def estCreateur(self):
- """retourne vrai si l'utilisateur en cours est le createur du plateau"""
- return (self.fenetre.util == self.creePar)
- def __getstate__(self):
- self.dateSvg = time()
- state = {key:value for key, value in self.__dict__.items() if not key in ["fenetre", "modeActif", \
- "editionTerrain", "editionCreature", "editionDecor", \
- "polygoneZonePlacement", "gestionCombat", \
- "editionAttaques", "pinceau"]}
- return (state)
- def __setstate__(self, state):
- self.__dict__ = state
- def vue(self):
- return self.fenetre.ui.cbt_vue
- def combattants(self):
- return self.pions.combattants()
- def combattantsVisibles(self):
- return self.pions.combattantsVisibles()
- def decors(self):
- return self.pions.combattants()
- def creer(self):
- """cree le plateau"""
- self.dateCreation = time()
- self.creePar = self.fenetre.profil.pseudo()
- self.hCase = 120 #hauteur d'une case
- self.modeActif = Modes.ModeBase(self)
- self.gestionCombat = None
- self.initialisationGraphique()
- self.connexions()
-
- #cree les cases hexagonales
- for x, y in self.geo.listeCases():
- c = Case(self)
- c.creer(x, y, self.couleurInit)
- self.cases[(x, y)] = c
- self.plateauModeCreation()
- def incrementerPile(self):
- self._compteurPile += 1
- return self._compteurPile
- def recreer(self, fenetre):
- self.fenetre = fenetre
- self.gestionCombat = None
- super(Plateau, self).__init__()
- self.modeActif = Modes.ModeBase(self)
- self.connexions()
- self.initialisationGraphique()
- #recreation des cases
- for coord in self.cases:
- self.cases[coord].recreer(self)
- #recreation des caches
- for idCache in self.caches:
- self.caches[idCache].ajouter(self)
- self.majCaches()
- #recreation des pions
- #on recree les pions par ordre d'empilement (du bas vers le haut)
- ordre = [pion for pion in self.pions.pions().values()]
- ordre.sort(key=lambda x: x.posPile)
- for pion in ordre:
- pion.ajouterAuPlateau(self)
- self.gC.reinitialiser()
- #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)
-
- if self.public:
- self.plateauModeCombat()
- else:
- self.plateauModeCreation()
- def fermer(self):
- """ferme le plateau 'proprement'"""
- self.miniature()
- self.pinceau = None
- for item in self.items():
- item.prepareGeometryChange()
- self.removeItem(item)
- if self.gestionCombat != None:
- del self.gestionCombat
- self.reinitialiserPanneaux()
- def reinitialiserPanneaux(self):
- """remet a neuf les commandes liees au plateau"""
- for panneau in [self.fenetre.ui.cbt_panneauHaut, \
- self.fenetre.ui.cbt_panneauBas, \
- self.fenetre.ui.cbt_panneauGauche, \
- self.fenetre.ui.cbt_panneauDroite]:
- #listes
- for liste in panneau.findChildren(QTableWidget):
- while liste.rowCount() > 0:
- liste.removeRow(0)
- #textes
- for texte in panneau.findChildren(QLineEdit):
- texte.clear()
- for texte in panneau.findChildren(QTextEdit):
- texte.clear()
- #a cocher
- for bouton in panneau.findChildren(QToolButton):
- if bouton.isCheckable():
- bouton.setChecked(False)
- #autre
- for item in panneau.findChildren(QSlider):
- item.setValue(1)
- for item in panneau.findChildren(QDoubleSpinBox):
- item.setValue(0)
- def miniature(self):
- """renvoie une miniature du plateau (QPixMap compresse) qui sera enregistree avec les infos de la sauvegarde"""
- ## img = QImage(128, 128, QImage.Format_ARGB32_Premultiplied)
- img = QPixmap(1024, 768)
- img.fill(QColor("white"))
- peintre = QPainter(img)
- self.render(peintre)
- peintre.end()
- img.scaledToHeight(128, Qt.FastTransformation)
-
- def connexions(self):
- """connecte le plateau aux differents widgets de la fenetre principale"""
- #modes d'interaction
- self.fenetre.connect(self.fenetre.ui.cbt_modeCreation, SIGNAL("clicked()"), self.plateauModeCreation, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.cbt_modeCombat, SIGNAL("clicked()"), self.plateauModeCombat, Qt.UniqueConnection)
- #etapes du combat
- self.fenetre.connect(self.fenetre.ui.cbt_etapeSuivante, SIGNAL("clicked()"), self.etapeSuivante, Qt.UniqueConnection)
- self.connect(self.fenetre.ui.pc_listePJ, SIGNAL("cellClicked(int, int)"), self.ajouterPj)
-
- #affichage de fenetres
- self.fenetre.connect(self.fenetre.ui.cbt_nom, SIGNAL("clicked()"), self.afficherEcranPlateau, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.cbt_afficherGestion, SIGNAL("clicked()"), self.afficheEcranGestionCombat, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.pi_listeAttributs, SIGNAL("cellChanged(int,int)"), self.listeAttributCelluleModifiee, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.cp_dialogueCouleurs, SIGNAL("clicked()"), self.modePeintureCase, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.cp_afficherNotes, SIGNAL("clicked()"), self.agrandirNotesMjPlateau, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.pi_fiche, SIGNAL("clicked()"), self.afficherFichePion, Qt.UniqueConnection)
-
- #listes
- self.fenetre.connect(self.fenetre.ui.cp_listeTerrains, SIGNAL("cellClicked(int,int)"), self.modeMajTerrainCase, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.cp_listeCreatures, SIGNAL("cellClicked(int,int)"), self.modeCreationCombattant, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.cp_listeDecors, SIGNAL("cellClicked(int,int)"), self.modeCreationDecor, Qt.UniqueConnection)
- #creation
- self.fenetre.connect(self.fenetre.ui.cp_epaisseurPinceau, SIGNAL("valueChanged(int)"), self.majEpaisseurPinceau, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.cp_pipetteCouleur, SIGNAL("clicked()"), self.modeCopieTerrain, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.cp_effets, SIGNAL("activated(int)"), self.modeCaseEffet, Qt.UniqueConnection)
-
- #autres:
- self.fenetre.connect(self.fenetre.ui.cp_gomme, SIGNAL("clicked()"), self.majModeSupprimerPions, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.cp_placerEntree, SIGNAL("clicked()"), self.majModeDefinirEntree, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.cp_placerCache, SIGNAL("clicked()"), self.majModePlacerCache, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.cp_placerSortie, SIGNAL("clicked()"), self.majModeDefinirSortie, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.cp_defPlacement, SIGNAL("clicked()"), self.majModeZonePlacement, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.pi_notes, SIGNAL("textChanged()"), self.majNotesCombattant, Qt.UniqueConnection)
- #formes (dessin)
- self.fenetre.connect(self.fenetre.ui.cp_formeSimple, SIGNAL("clicked()"), self.majModeForme, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.cp_formeLigne, SIGNAL("clicked()"), self.majModeForme, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.cp_formeLigneOrientee, SIGNAL("clicked()"), self.majModeForme, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.cp_formePot, SIGNAL("clicked()"), self.majModeForme, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.cp_formeRectVide, SIGNAL("clicked()"), self.majModeForme, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.cp_formeRectPlein, SIGNAL("clicked()"), self.majModeForme, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.act_deplacement, SIGNAL("clicked()"), self.majModeCombatDeplacement, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.act_attaqueCac, SIGNAL("clicked()"), self.majModeCombatAttaqueCaC, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.act_attaqueDist, SIGNAL("clicked()"), self.majModeCombatAttaqueDist, Qt.UniqueConnection)
- self.fenetre.connect(self.fenetre.ui.act_attaqueZone, SIGNAL("clicked()"), self.majModeCombatZone, Qt.UniqueConnection)
- # self.fenetre.connect(self.fenetre.ui.pi_formeAttaqueZone, SIGNAL("activated (int)"), self.majModeCombatZone, Qt.UniqueConnection)
- # self.fenetre.connect(self.fenetre.ui.pi_rayonAttaqueZone, SIGNAL("valueChanged(int)"), self.majRayonZone, 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.vue().setScene(self)
- self.vue().scale(0.25, 0.25)
- self.vue().centerOn(QPointF(0,0))
- self.vue().setDragMode(1)
- self.setItemIndexMethod(QGraphicsScene.BspTreeIndex)
-
- self.polygoneZonePlacement = None
- #gestion du mode d'interaction avec le plateau
- self.pions.initialiser(self)
- self.pinceau = Pinceau(self)
- self.proj = ProjectionDep(self)
-
- #mise a jour de l'interface de creation
- self.majNomPlateau()
- self.majBoutonsCouleursPerso()
- self.gM.initialiser(self.fenetre)
- self.gC.initialiser(self)
- self.geo.initialiser(self)
-
- self.initListeAttaques()
- self.majBoutonEtape()
- self.fenetre.ui.act_deplacement.setCheckable(True)
- self.fenetre.ui.act_attaqueCac.setCheckable(True)
- self.fenetre.ui.act_attaqueDist.setCheckable(True)
- # self.fenetre.ui.act_attaqueZone.setCheckable(True)
- #mise a jour de l'interface d'informations
- self.majInfoCb(None)
- self.majInfoDc(None)
- def estCree(self):
- """renvoie vrai si des cases ont ete creees"""
- return (len(self.cases) > 0)
- def afficherEcranPlateau(self):
- """affiche la fenetre de description du plateau"""
- ecran = EcranCreerPlateau()
- ecran.afficher(self)
- r = ecran.exec_()
- if r == 1:
- res = ecran.resultat()
- self.majNom(res.nom())
- self.chapitre = res.chapitre
- self.description = res.description
- self.presentation = res.presentation
- self.majNomPlateau()
- def majNomPlateau(self):
- """met a jour l'affichage du nom du plateau"""
- txt = self.nom()
- if not self.public: txt += " [Non Publié]"
- self.fenetre.ui.cbt_nom.setText(QString().fromUtf8(" {} ".format(txt)))
-
- def majBoutonEtape(self):
- """met a jour le label et l'effet du bouton d'etape (en bas a droite)"""
- if not self.public:
- self.fenetre.ui.cbt_etapeSuivante.setText(QString().fromUtf8("Publier le plateau"))
- return
-
- if not self.gC.tour() > 0:
- self.fenetre.ui.cbt_etapeSuivante.setText(QString().fromUtf8("Démarrer le combat"))
- return
-
- self.fenetre.ui.cbt_etapeSuivante.setText(QString().fromUtf8("Tour {}\nFinir son tour".format(self.gC.tour())))
- def etapeSuivante(self):
- """apres clic sur le bouton d'etape, on passe a l'etape suivante (publication, demarrage du combat...)"""
- if not self.public:
- self.publier()
- return
- self.gC.pionSuivant()
- def publier(self):
- self.public = True
- self.majListePJ()
- self.majBoutonEtape()
-
- def majListePJ(self):
- """met a jour la liste des pj qui peuvent etre ajoutes au plateau"""
- self.fenetre.ui.pc_listePJ.setColumnWidth(0,0)
- self.fenetre.ui.pc_listePJ.vider()
-
- dejaCrees = []
- for numPj in self.pions.pjs():
- dejaCrees.append(self.pions[numPj].idM())
- for idM in self.fenetre.pjs:
- if not idM in dejaCrees:
- pj = chargerMat(idM, "grp")
- ligne = self.fenetre.ui.pc_listePJ.nouvelleLigneFin()
- self.fenetre.ui.pc_listePJ.majTexte(ligne, 0, idM)
- self.fenetre.ui.pc_listePJ.setItem(ligne, 1, QTableWidgetItem(QIcon(pj.icone().pix()), \
- QString(pj.nom())))
- self.fenetre.ui.pc_listePJ.setVisible((self.fenetre.ui.pc_listePJ.rowCount() > 0))
-
- def ajouterPj(self, ligne, col):
- idM = self.fenetre.ui.pc_listePJ.texte(ligne, 0)
- pj = chargerMat(idM, "grp")
- if pj: self.activerMode(Modes.CreationPion, pj)
- def couleursRapides(self):
- return [(255,255,255), (200,200,200), (130,130,130), (90,90,90), (15,15,15), \
- (0,85,0), (170,255,0), (170,255,127), (85,85,0), (85,0,0), (170,85,0), (100,50,0), \
- (255,255,127), (240,80,0), (85,170,255), (85,85,255), (85,0,255), (0,255,255)]
- 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,18):
- couleur = QColor()
- r, g, b = self.couleursRapides()[i]
- couleur.setRgb(r, g, b)
- bouton = self.fenetre.ui.cp_boiteCouleurs.findChild(QToolButton, "cp_couleur{}".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.vue()).getColor(QColor("white"), self.vue())
- return couleur
- def majListesPions(self, numCombattant = None):
- """met a jour les listes contenant des donnees liees aux pions"""
- ## self.majListeOrdreJeu()
- ##
- ## if numCombattant == None or numCombattant == self.pionSelectionne().numero:
- ## self.majListeAttributs()
- ## QApplication.processEvents()
- pass
- # def ajouterPj(self):
- # """affiche la fenetre de selection des pj, et recupere l'eventuel pj selectionne"""
- # self.ecranSelPj = EcranSelectionPj(self.fenetre)
- # self.ecranSelPj.setAttribute(Qt.WA_DeleteOnClose)
- # listePj = chargerUnique("parties\\{}\\groupe".format(self.fenetre.partie))
- # self.ecranSelPj.charger(listePj)
- # r = self.ecranSelPj.exec_()
- # if r == 1:
- # idPj = int(self.ecranSelPj.selection())
- # if idPj != None:
- # pj = listePj[idPj]
- # self.activerMode(Modes.CreationPion, pj)
- # self.ecranSelPj = None
- def agrandirNotesMjPlateau(self):
- """affiche les notes du plateau dans une QDialog, puis recupere les donnees qui y sont saisies"""
- affichageTexte = EcranAffichageTexte(self.notes)
- affichageTexte.exec_()
- self.notes = affichageTexte.recupererTexte()
- del affichageTexte
-
-
- ############### affichage des caches enregistres
-
- def majCaches(self):
- """charge la liste des caches avec les donnees en memoire"""
- traite = []
- for idCache in self.caches:
- for coord in self.caches[idCache].listeCases():
- if not coord in traite:
- self.cases[coord].majCache()
- traite.append(coord)
- #### affichage de la fiche du perso ou du decor
- def afficherFichePion(self):
- if self.pionSelectionne():
- fen = EcranEditionMateriel(self.pionSelectionne())
- fen.afficher()
- fen.exec_()
-
- ############### maj des infos du panneau Pi a la selection/deselection d'un pion
- #voir a balancer tout ca dans une classe a part
- def majPanneauPi(self):
- return
-
- if self.pionSelectionne():
- estCombattant = (self.pionSelectionne().numero > 0)
- #affichage
- # self.fenetre.ui.pi_actions.setEnabled(estCombattant)
- self.fenetre.ui.pi_ongletsListes.setTabEnabled(0, estCombattant)
- self.fenetre.ui.pi_ongletsListes.setTabEnabled(1, estCombattant)
-
- ### maj la selection dans la liste d'ordre de jeu
- if estCombattant:
- for i in range(0, self.fenetre.ui.inf_listeOrdreJeu.rowCount()):
- if str(self.fenetre.ui.inf_listeOrdreJeu.item(i, 0).text().toUtf8()) == str(self.pionSelectionne().numero):
- self.fenetre.ui.inf_listeOrdreJeu.setCurrentCell(i,0)
- ### maj de la liste des attributs
- if estCombattant:
- self.fenetre.ui.pi_listeAttributs.setColumnWidth(0, 50)
- self.disconnect(self.fenetre.ui.pi_listeAttributs, SIGNAL("cellChanged(int,int)"), self.listeAttributCelluleModifiee)
-
- #on vide la liste
- while self.fenetre.ui.pi_listeAttributs.rowCount() > 0:
- self.fenetre.ui.pi_listeAttributs.removeRow(0)
- #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.pi_listeAttributs.insertRow(i)
- item = QTableWidgetItem()
- if i < len(lignesBase):
- item.setText(QString.fromUtf8(lignesBase[i]))
- item.setFlags(Qt.NoItemFlags)
- self.fenetre.ui.pi_listeAttributs.setItem(i, 0, item)
- self.fenetre.ui.pi_listeAttributs.setRowHidden(i, (i >= len(lignesBase)))
- #maj des donnees de base
- self.fenetre.ui.pi_listeAttributs.setItem(lignesBase.index("Nom"), 1, QTableWidgetItem(QString.fromUtf8(str(self.pionSelectionne().nom()))))
- self.fenetre.ui.pi_listeAttributs.setItem(lignesBase.index("Etat"), 1, QTableWidgetItem(QString.fromUtf8(str(self.pionSelectionne().etat))))
- self.fenetre.ui.pi_listeAttributs.setItem(lignesBase.index("Alt."), 1, QTableWidgetItem(QString.fromUtf8(str(self.pionSelectionne().zR))))
-
- #attributs issus des regles utilisees
- ordre = regles.ordreAttributs()
- for elt in ordre:
- ligne = 10 + ordre.index(elt)
- self.fenetre.ui.pi_listeAttributs.insertRow(ligne)
- item = QTableWidgetItem(QString.fromUtf8(elt))
- item.setFlags(Qt.NoItemFlags)
- self.fenetre.ui.pi_listeAttributs.setItem(ligne, 0, item)
- self.fenetre.ui.pi_listeAttributs.setItem(ligne, 1, QTableWidgetItem(QString.fromUtf8(str(self.pionSelectionne().listeAttributs[elt]))))
-
- self.connect(self.fenetre.ui.pi_listeAttributs, SIGNAL("cellChanged(int,int)"), self.listeAttributCelluleModifiee)
-
- ###affiche les notes du combattant
- self.fenetre.ui.pi_notes.majTexte(self.pionSelectionne().notes)
- ###maj la liste des attaques du pion
- if estCombattant:
- #on vide la liste
- while self.fenetre.ui.pi_listeAttaques.rowCount() > 0:
- self.fenetre.ui.pi_listeAttaques.removeRow(0)
-
- i = 0
- for attaque in self.pionSelectionne().attaques:
- self.fenetre.ui.pi_listeAttaques.insertRow(i)
- self.fenetre.ui.pi_listeAttaques.setItem(i, 0, QTableWidgetItem(QString.fromUtf8(str(self.pionSelectionne().attaques.index(attaque)))))
- icone = None
- if attaque.typ == "cac":
- icone = QIcon(":/interface/16/ressource/epee_16.png")
- if attaque.typ == "dist":
- icone = QIcon(":/interface/16/ressource/arc_16.png")
- if attaque.typ == "zone":
- icone = QIcon(":/interface/16/ressource/baguette_16.png")
- if icone != None:
- self.fenetre.ui.pi_listeAttaques.setItem(i, 1, QTableWidgetItem(icone, QString.fromUtf8("")))
- self.fenetre.ui.pi_listeAttaques.setItem(i, 2, QTableWidgetItem(QString.fromUtf8(attaque.nom)))
- else:
- #maj des infos dans le panneau pi
-
- #vide la liste des attributs
- self.disconnect(self.fenetre.ui.pi_listeAttributs, SIGNAL("cellChanged(int,int)"), self.listeAttributCelluleModifiee)
- while self.fenetre.ui.pi_listeAttributs.rowCount() > 0:
- self.fenetre.ui.pi_listeAttributs.removeRow(0)
- #vide la liste des attaques du pion
- while self.fenetre.ui.pi_listeAttaques.rowCount() > 0:
- self.fenetre.ui.pi_listeAttaques.removeRow(0)
-
- self.majInfosAttaqueEC()
- ##### activation des differents modes d'interaction avec le plateau et mises a jour des principaux parametres #######
- def majArborescenceModes(self):
- self.fenetre.ui.cbt_arbo.majTexte(self.modeActif.arborescence())
- def plateauModeCreation(self):
- self.activerMode(Modes.StandardCp)
- def plateauModeCombat(self):
- self.activerMode(Modes.StandardPi)
- def activerMode(self, mode, param = None):
- """desactive le mode actif et active le nouveau a la place"""
- self.modeActif.desactiver()
- self.modeActif = mode(self)
- self.modeActif.activer(param)
- self.majArborescenceModes()
- def modePeintureCase(self):
- """enclenche le mode peinture de case a partir de la couleur selectionnee"""
- couleur = self.chercherCouleur()
- if couleur.isValid():
- terrain = Terrain()
- terrain.couleur = couleur
- self.activerMode(Modes.MajCases, terrain)
- else:
- self.activerMode(Modes.StandardCp)
- def modePeintureCase_perso(self):
- origine = self.sender().objectName()
- index = int(origine.replace("cp_couleur",""))-1
- couleur = QColor()
- r, g, b = self.couleursRapides()[index]
- couleur.setRgb(r, g, b)
- if couleur.isValid():
- terrain = Terrain()
- terrain.couleur = couleur
- self.activerMode(Modes.MajCases, terrain)
- else:
- self.activerMode(Modes.StandardCp)
- def modeCopieTerrain(self):
- """enclenche le mode copie de case"""
- self.activerMode(Modes.Pipette)
- def modeCaseEffet(self, index):
- """enclenche le mode de mise a jour de l'effet actif des cases"""
- effets = ["brule", "eau", "glace", "poison", "aucun"]
- self.activerMode(Modes.MajCasesEffet, effets[index])
- def modeCreationPion(self):
- """enclenche le mode de creation de pions simples"""
- self.majMode("pionCreation")
- def majModeSupprimerPions(self):
- """enclenche le mode suppression de pions sur clic gauche (creatures ou decors)"""
- self.activerMode(Modes.SuppressionPion)
-
- def modeCreationDecor(self, ligne, col):
- """enclenche le mode de creation de decors depuis la liste des decors"""
- decor = chargerMat(self.fenetre.ui.cp_listeDecors.selection())
- self.activerMode(Modes.CreationPion, decor)
-
- def modeCreationCombattant(self, ligne, col):
- """enclenche le mode de creation de pions depuis la liste des creatures"""
- creature = chargerMat(self.fenetre.ui.cp_listeCreatures.selection())
- self.activerMode(Modes.CreationPion, creature)
- def modeMajTerrainCase(self, ligne, col):
- """enclenche le mode permettant la mise a jour du terrain des cases"""
- terrain = chargerMat(self.fenetre.ui.cp_listeTerrains.selection())
- if terrain:
- self.activerMode(Modes.MajCases, terrain)
- else:
- print "terrain invalide"
- def majEpaisseurPinceau(self, epaisseur):
- """met a jour l'epaisseur du pinceau (en cases)"""
- self.fenetre.ui.cp_valeurEpaisseurPinceau.majTexte(str(epaisseur))
- self.pinceau.majEpaisseur(int(epaisseur))
- def majModeForme(self):
- """met a jour la forme utilisee pour la peinture"""
- formes = {"cp_formeSimple": "simple", \
- "cp_formeLigne": "ligne", \
- "cp_formeLigneOrientee": "frontiere", \
- "cp_formePot": "pot", \
- "cp_formeEllipseVide": "ellipseV", \
- "cp_formeEllipsePlein": "ellipseP", \
- "cp_formeRectVide": "rectV", \
- "cp_formeRectPlein": "rectP"}
- self.pinceau.majForme(formes[str(self.sender().objectName())])
- def majModePlacerCache(self):
- """active le mode de creation des caches"""
- if self.public:
- dial = QMessageBox()
- dial.setText(QString().fromUtf8("Vous ne pouvez pas placer de caches une fois le plateau publié"))
- dial.exec_()
- return
- self.activerMode(Modes.PlacerCaches)
- def majModeCombatDeplacement(self):
- """active le mode de combat 'deplacement' (mode standard)"""
- self.modeActif.nouvelleAction(Actions.Deplacement)
- def majModeCombatAttaqueCaC(self):
- """active le mode de combat 'corps-a-corps'"""
- self.modeActif.nouvelleAction(Actions.Cac)
- def majModeCombatAttaqueDist(self):
- """active le mode de combat 'attaque a distance'"""
- self.modeActif.nouvelleAction(Actions.Distance)
- def majModeCombatZone(self):
- action = choisirAttaqueZone()
- self.modeActif.nouvelleAction(action)
- # def majModeCombatLigne(self):
- # self.modeActif.nouvelleAction(Actions.Ligne)
- #
- # def majModeCombatDisque(self):
- # self.modeActif.nouvelleAction(Actions.Disque)
- #
- # def majModeCombatCone(self):
- # self.modeActif.nouvelleAction(Actions.Cone)
-
- def majModeDefinirEntree(self):
- self.activerMode(Modes.CreationEntreeSortie, "E")
- def majModeDefinirSortie(self):
- self.activerMode(Modes.CreationEntreeSortie, "S")
- def majModeZonePlacement(self):
- self.activerMode(Modes.ZonePlacement)
-
- ###############
- ########## Gestion du combat ##############
- def afficheEcranGestionCombat(self):
- """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 majAffichageTour(self):
- # """met a jour l'affichage du tour en cours"""
- # self.fenetre.ui.cbt_tour.majTexte("Tour: {}".format(self.tour))
- #
- # def initListeOrdreJeu(self):
- # """cree les colonnes et met en forme la table ordre jeu"""
- # self.fenetre.ui.inf_listeOrdreJeu.setColumnWidth(2, 30)
- # self.fenetre.ui.inf_listeOrdreJeu.hideColumn(0)
- # self.fenetre.ui.inf_listeOrdreJeu.hideColumn(2)
- # self.fenetre.ui.inf_listeOrdreJeu.setIconSize(QSize(30,20))
- #
- # def majListeOrdreJeu(self):
- # """met a jour la liste des pions infoOrdreJeu"""
- # while self.fenetre.ui.inf_listeOrdreJeu.rowCount() > 0:
- # self.fenetre.ui.inf_listeOrdreJeu.removeRow(0)
- # index = 0
- # for num in self.ordreJeu:
- # self.fenetre.ui.inf_listeOrdreJeu.insertRow(int(index))
- # self.fenetre.ui.inf_listeOrdreJeu.setItem(int(index), 0, QTableWidgetItem(QString.fromUtf8(str(num))))
- # icon = QIcon(self.combattants[num].icone().fichier())
- # item = QTableWidgetItem(icon, QString.fromUtf8(self.combattants[num].txtId()))
- # self.fenetre.ui.inf_listeOrdreJeu.setItem(int(index), 1, item)
- # self.fenetre.ui.inf_listeOrdreJeu.setItem(int(index), 2, QTableWidgetItem(QString.fromUtf8(str(self.ordreJeu[num]))))
- # index += 1
- #
- # self.fenetre.ui.inf_listeOrdreJeu.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"""
- # numCombattant = int(self.fenetre.ui.inf_listeOrdreJeu.item(ligne, 0).text().toUtf8())
- # self.vue().centerOn(self.cases[self.combattants[numCombattant].position].centreGraphique)
- # self.modeActif.clic_combattant(numCombattant)
- #
- # def pionSuivant(self):
- # """selection du pion suivant dans la liste d'ordre de jeu"""
- # if not len(self.combattants) > 0: return
- #
- # if self.numPionEnCours in self.combattants:
- # 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:
- # numCombattant = num
- # break
- #
- # for ligne in range(0, self.fenetre.ui.inf_listeOrdreJeu.rowCount()):
- # item = self.fenetre.ui.inf_listeOrdreJeu.item(ligne, 0)
- # item.setSelected(int(self.fenetre.ui.inf_listeOrdreJeu.item(ligne, 0).text().toUtf8()) == numCombattant)
- # if int(item.text().toUtf8()) == numCombattant:
- # self.fenetre.ui.inf_listeOrdreJeu.scrollToItem(item)
- #
- # self.vue().centerOn(self.cases[self.combattants[numCombattant].position].centreGraphique)
- # self.pionSaisir(numCombattant)
- #
- #
- # 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"""
- # if len(self.ordreJeu) > 0:
- # attribut = regles.attributOrdreJeu()
- # if attribut != None:
- # dico = {}
- # for numCombattant in self.combattants:
- # dico[numCombattant] = int(self.combattants[numCombattant].listeAttributs[attribut])
- # ordre = sorted(dico, key = dico.get, reverse=(regles.sensTriOrdreJeu() == 1))
- # self.ordreJeu = {}
- # for numCombattant in self.combattants:
- # self.ordreJeu[numCombattant] = ordre.index(numCombattant) + 1
- # self.majListeOrdreJeu()
- #
- # def pionDeplacerDansOrdreJeu(self, numCombattant, 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 numCombattant in self.ordreJeu:
- # if nouvellePosition == 0:
- # del self.ordreJeu[numCombattant]
- # if len(self.ordreJeu) > 0:
- # i = 0
- # tmp = sorted(self.ordreJeu, key=self.ordreJeu.get)
- # if numCombattant in tmp:
- # tmp.remove(numCombattant)
- # for num in tmp:
- # i += 1
- # if i == nouvellePosition:
- # self.ordreJeu[numCombattant] = i
- # i += 1
- # self.ordreJeu[num] = i
- # if i < nouvellePosition:
- # self.ordreJeu[numCombattant] = i + 1
- # elif nouvellePosition > 0:
- # self.ordreJeu[numCombattant] = 1
- # self.majOrdreJeu()
- def listeAttributCelluleModifiee(self, ligne, colonne):
- """une cellule de la liste des attributs a ete modifiee"""
- return
- 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.pi_listeAttributs.item(ligne, 1).text().toUtf8())
- valVerifiee = regles.listeControle()[attribut].controler(nouvelleVal)
- if valVerifiee != None:
- self.pionSelectionne().listeAttributs[attribut] = valVerifiee
- if attribut == regles.attributOrdreJeu():
- print("maj ordre (a implementer)")
- else:
- self.fenetre.ui.pi_listeAttributs.setItem(ligne, 1, QTableWidgetItem(QString.fromUtf8(str(self.pionSelectionne().listeAttributs[attribut]))))
- def initListeAttaques(self):
- """met en forme et connecte la liste des attaques du pion"""
- self.fenetre.ui.pi_listeAttaques.setColumnWidth(0, 0)
- self.fenetre.ui.pi_listeAttaques.setColumnWidth(1, (0.3*self.fenetre.ui.pi_listeAttaques.width()))
- self.fenetre.ui.pi_listeAttaques.setColumnWidth(2, (0.7*self.fenetre.ui.pi_listeAttaques.width()))
- self.connect(self.fenetre.ui.pi_listeAttaques, SIGNAL("itemSelectionChanged()"), self.majInfosAttaqueEC)
- self.connect(self.fenetre.ui.pi_listeAttaques, SIGNAL("cellClicked(int, int)"), self.listeAttaquesCelluleCliquee)
- self.connect(self.fenetre.ui.pi_notesAttaqueEC, SIGNAL("textChanged()"), self.majNotesAttaqueEC)
- self.fenetre.ui.pi_listeAttributsAttaqueEC.setColumnWidth(0, (0.49*self.fenetre.ui.pi_listeAttributsAttaqueEC.width()))
- self.fenetre.ui.pi_listeAttributsAttaqueEC.setColumnWidth(1, (0.5*self.fenetre.ui.pi_listeAttributsAttaqueEC.width()))
-
- def majListeAttaques(self):
- """met a jour la liste des attaques du pion dans le panneau de combat"""
- #on vide la liste
- while self.fenetre.ui.pi_listeAttaques.rowCount() > 0:
- self.fenetre.ui.pi_listeAttaques.removeRow(0)
-
- self.fenetre.ui.pi_listeAttaques.setVisible((self.pionSelectionne() != None))
- ## self.fenetre.ui.editerAttaques.setVisible((self.pionSelectionne() != None))
- self.fenetre.ui.pi_panneauAttaqueEC.setVisible((self.pionSelectionne() != None))
- i = 0
- if self.pionSelectionne() != None:
- for attaque in self.pionSelectionne().attaques:
- self.fenetre.ui.pi_listeAttaques.insertRow(i)
- self.fenetre.ui.pi_listeAttaques.setItem(i, 0, QTableWidgetItem(QString.fromUtf8(str(self.pionSelectionne().attaques.index(attaque)))))
- icone = None
- if attaque.typ == "cac":
- icone = QIcon(":/interface/16/ressource/epee_16.png")
- if attaque.typ == "dist":
- icone = QIcon(":/interface/16/ressource/arc_16.png")
- if attaque.typ == "zone":
- icone = QIcon(":/interface/16/ressource/baguette_16.png")
- if icone != None:
- self.fenetre.ui.pi_listeAttaques.setItem(i, 1, QTableWidgetItem(icone, QString.fromUtf8("")))
- self.fenetre.ui.pi_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.pi_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.majModeCombat("combatAttaqueZone")
- def majInfosAttaqueEC(self):
- """met a jour les infos de l'attaque en cours (selectionnee)"""
- selection = self.fenetre.ui.pi_listeAttaques.selectedItems()
- self.fenetre.ui.pi_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.pi_listeAttaques.item(ligne, 0).text().toUtf8()))
- self.disconnect(self.fenetre.ui.pi_panneauAttaqueEC, SIGNAL("cellChanged(int,int)"), self.attaqueECCelluleModifiee)
- #on vide la liste
- while self.fenetre.ui.pi_listeAttributsAttaqueEC.rowCount() > 0:
- self.fenetre.ui.pi_listeAttributsAttaqueEC.removeRow(0)
-
- self.fenetre.ui.pi_listeAttributsAttaqueEC.insertRow(0)
- self.fenetre.ui.pi_listeAttributsAttaqueEC.setItem(0, 0, QTableWidgetItem(QString.fromUtf8("numAtt")))
- self.fenetre.ui.pi_listeAttributsAttaqueEC.setItem(0, 1, QTableWidgetItem(QString.fromUtf8(str(numAttaque))))
- self.fenetre.ui.pi_listeAttributsAttaqueEC.setRowHidden(0, True)
-
- #attributs issus des regles utilisees
- ordre = regles.ordreAttributsAttaques()
- for elt in ordre:
- ligne = 1 + ordre.index(elt)
- self.fenetre.ui.pi_listeAttributsAttaqueEC.insertRow(ligne)
- item = QTableWidgetItem(QString.fromUtf8(elt))
- item.setFlags(Qt.NoItemFlags)
- self.fenetre.ui.pi_listeAttributsAttaqueEC.setItem(ligne, 0, item)
- self.fenetre.ui.pi_listeAttributsAttaqueEC.setItem(ligne, 1, QTableWidgetItem(QString.fromUtf8(str(self.pionSelectionne().attaques[numAttaque].attributs[elt]))))
-
- self.connect(self.fenetre.ui.pi_listeAttributsAttaqueEC, SIGNAL("cellChanged(int,int)"), self.attaqueECCelluleModifiee)
- #maj des notes
- self.disconnect(self.fenetre.ui.pi_notesAttaqueEC, SIGNAL("textChanged()"), self.majNotesAttaqueEC)
- self.fenetre.ui.pi_notesAttaqueEC.majTexte(self.pionSelectionne().attaques[numAttaque].notes)
- self.connect(self.fenetre.ui.pi_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.pi_listeAttaques.selectedItems()
- self.fenetre.ui.pi_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.pi_listeAttaques.item(ligne, 0).text().toUtf8()))
- self.pionSelectionne().attaques[numAttaque].notes = str(self.fenetre.ui.pi_notesAttaqueEC.toPlainText().toUtf8())
- def majNotesCombattant(self):
- """les notes du pion ont ete mises a jour"""
- if self.pionSelectionne() != None:
- self.pionSelectionne().notes = str(self.fenetre.ui.pi_notes.toPlainText().toUtf8())
- else:
- pass
-
- ###############
- ######### gestion des evenements souris et clavier ###############
- def clic_pion(self, num):
- if num > 0:
- return self.clic_combattant(num)
- else:
- return self.clic_decor(num)
- def clic_combattant(self, num):
- return self.modeActif.clic_combattant(num)
-
- def clic_decor(self, num):
- return self.modeActif.clic_decor(num)
- def clic_case(self, coord):
- return self.modeActif.clic_case(coord)
-
- def survol_pion(self, num):
- if num > 0:
- return self.survol_combattant(num)
- else:
- return self.survol_decor(num)
-
- def survol_combattant(self, num):
- """le pion est survole par le curseur, on affiche ses informations dans la zone prevue"""
- return self.modeActif.survol_decor(num)
- def survol_decor(self, num):
- """le pion est survole par le curseur, on affiche ses informations dans la zone prevue"""
- return self.modeActif.survol_decor(num)
- def survol_case(self, coord):
- self.majInfoTr(self.cases[coord])
- self.majInfoPion(self.pions[self.cases[coord].occupant()])
- return self.modeActif.survol_case(coord)
- def finSurvol_pion(self, num):
- self.majInfoPion(None)
- if num > 0:
- return self.finSurvol_combattant(num)
- else:
- return self.finSurvol_decor(num)
- def finSurvol_combattant(self, num):
- """le pion est survole par le curseur, on affiche ses informations dans la zone prevue"""
- return self.modeActif.finSurvol_combattant(num)
- def finSurvol_decor(self, num):
- """le pion est survole par le curseur, on affiche ses informations dans la zone prevue"""
- return self.modeActif.finSurvol_decor(num)
- def finSurvol_case(self, coord):
- return self.modeActif.finSurvol_case(coord)
- def survolClic_case(self, coord):
- return self.modeActif.survolClic_case(coord)
- def doubleClic_pion(self, num):
- if num > 0:
- return self.doubleClic_combattant(num)
- def doubleClic_combattant(self, num):
- return self.modeActif.doubleClic_combattant(num)
-
- def mouseMoveEvent(self, event):
- super(Plateau, self).mouseMoveEvent(event)
- if event.buttons() == Qt.LeftButton and self.vue().dragMode() != QGraphicsView.ScrollHandDrag:
- coord = self.coordonneesAuPoint(event.scenePos())
- if coord != None:
- self.survolClic_case(coord)
- else:
- self.modeActif.mouvementSouris(event)
- event.ignore()
- def mousePressEvent(self, event):
- super(Plateau, self).mousePressEvent(event)
- if event.button() == 1:
- self.modeActif.clicGauche(event)
- elif event.button() == 2:
- self.modeActif.clicDroit(event)
- event.accept()
- def mouseReleaseEvent(self, event):
- super(Plateau, self).mouseReleaseEvent(event)
- self.modeActif.finClicGauche(event)
- def keyPressEvent(self, event):
- """gestion des evenements clavier"""
- self.modeActif.toucheClavier(event)
- ################
- ############### Fonctions diverses
- def pionSelectionne(self):
- """renvoie le pion actuellement selectionne"""
- if self.modeActif.__class__.__name__ == "PionSelectionne": return self.modeActif.pion()
- return None
- def afficherListeCases(self, listeCases, actif):
- """met ou non en evidence les cases selectionnees"""
- for coord in listeCases:
- self.cases[coord].majEstCibleCurseur(actif)
- def pionDeposer(self, coordCase):
- """on depose le pion sur la case voulue"""
- if self.pionSelectionne() != None:
- pion = self.pionSelectionne()
- if pion != None:
- if self.proj.valide():
- pion.majPosition(self.proj.coord(), self.proj.nbRotations())
- def nouveauCache(self, listeCases):
- nouvelId = 0
- if len(self.caches) > 0:
- nouvelId = max(self.caches) + 1
- cache = Cache(nouvelId)
- cache.activer(True)
- cache.nom = "Cache {}".format(nouvelId + 1)
- self.caches[nouvelId] = cache
- self.ajouterCacheATable(cache)
- for coord in listeCases:
- self.cases[coord].ajouterCache(nouvelId)
- def supprimerCache(self):
- ligne = self.fenetre.ui.cp_listeCaches.currentRow()
- idCache = int(self.fenetre.ui.cp_listeCaches.texte(ligne, 0))
- for coord in self.cases:
- self.cases[coord].supprimerCache(idCache)
- self.fenetre.ui.cp_listeCaches.removeRow(idCache)
- del self.caches[idCache]
- def centrerSur(self, num):
- """centre la vue sur le pion"""
- self.vue().centerOn(self.cases[self.pions[num].position].centreGraphique)
- # 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 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":
- # if 1 == (x % 2):
- # voisins = [(x, y-1), (x+1, y), (x+1, y+1), (x, y+1), (x-1, y+1), (x-1, y)]
- # else:
- # voisins = [(x, y-1), (x+1, y-1), (x+1, y), (x, y+1), (x-1, y), (x-1, y-1)]
- # else:
- # voisins = [(x, y-1), (x+1, y), (x, y+1), (x-1, y)]
- # return voisins
- # def zone(self, origine, rayon, zR = 0):
- # """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"""
- # if not self.coordonneesValides(origine) or not rayon >= 0: return {}
- # if rayon == 0: return {origine: 0}
- # resultat = {}
- # aVerifier = [] ; aVerifier2 = [] ; k = 0
- # #on part de la premiere case, puis on itere a partir de chaque nouveau depart sur les voisins
- # aVerifier.append(origine)
- # while k <= rayon:
- # 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:
- # aVerifier2.append(coord)
- # for elt in aVerifier:
- # resultat[elt] = k
- # aVerifier = aVerifier2 ; aVerifier2 = [] ; k += 1
- # return resultat
- # def zone3d(self, origine, rayon, zCible=0):
- # """renvoie les cases de la zone au format (x, y, z)"""
- # retour = []
- # zone = self.zone(origine, rayon)
- # for coord in zone:
- # x, y = coord
- # dz = rayon - zone[coord]
- # for z in range(-dz, dz + 1):
- # retour.append( (x, y, (zCible+z) ) )
- # return retour
- # def cone(self, coord1, coord2):
- # """renvoie les coord des cases composant le cone (en 2d)"""
- # retour = []
- # x1, y1 = coord1 ; x2, y2 = coord2
- # if x1 % 2 == 1: y1 += 0.5
- # if x2 % 2 == 1: y2 += 0.5
- #
- # if abs(y2 - y1) - abs(x2 - x1) <= 0 :
- # #secteur horizontal
- # angleRef = (y2 - y1) / (x2 - x1)
- # dist2Ref = ( (x2 - x1)**2 + (y2 - y1)**2 )
- # for coord in self.cases:
- # x, y = coord
- # if x % 2 == 1: y += 0.5
- # if x != x1:
- # angle = (y - y1) / (x - x1)
- # if abs( angleRef - angle ) <= 0.5 and ( (x - x1)**2 + (y - y1)**2 ) <= dist2Ref \
- # and ( (x - x1) * (x2 - x1) ) > 0:
- # retour.append(coord)
- # else:
- # #secteur vertical
- # angleRef = (x2 - x1) / (y2 - y1)
- # dist2Ref = ( (x2 - x1)**2 + (y2 - y1)**2 )
- # for coord in self.cases:
- # x, y = coord
- # if x % 2 == 1: y += 0.5
- # if y != y1:
- # angle = (x - x1) / (y - y1)
- # if abs( angleRef - angle ) <= 0.5 and ( (x - x1)**2 + (y - y1)**2 ) <= dist2Ref \
- # and ( (y - y1) * (y2 - y1) ) > 0:
- # retour.append(coord)
- # return retour
- #
- # def cone3d(self, coord1, coord2, z1 = 0, z2 = 0):
- # return self.cone(coord1, coord2)
-
- # def blocAdjacent(self, listeCases):
- # """renvoie un bloc de cases adjacentes a partir de la liste en parametre"""
- # retour = []
- # tmp1 = [listeCases[0]]; tmp2 = [listeCases[0]]
- # while len(tmp2) > 0:
- # tmp2 = []
- # #on liste les cases voisines qui sont dans la liste et pas encore verifiees
- # for coord in tmp1:
- # for voisine in self.cases[coord].voisins:
- # if voisine in listeCases and not voisine in tmp1 and not voisine in tmp2:
- # tmp2.append(voisine)
- # #chacune de ces cases prend le statut de verifiee
- # for coord in tmp1:
- # listeCases.remove(coord)
- # retour.append(coord)
- # tmp1 = tmp2
- # return retour
-
- # def polygone(self, x, y):
- # """renvoie l'objet graphique hexagone de la case de coordonnees (x, y)"""
- # polygone = QPolygonF()
- # if self.formeCases == "H":
- # #si x est impair sur un plateau a cases hexagonales, le y est augmente de 0.5
- # if 1 == (x % 2):
- # y += 0.5
- # polygone << QPointF(((x*0.866)+0.2886)*120, y*120) \
- # << QPointF(((x*0.866)+0.866)*120, y*120) \
- # << QPointF(((x*0.866)+1.1547)*120, (y+0.5)*120) \
- # << QPointF(((x*0.866)+0.866)*120, (y+1)*120) \
- # << QPointF(((x*0.866)+0.2886)*120, (y+1)*120) \
- # << QPointF( (x*0.866)*120, (y+0.5)*120)
- # else:
- # polygone << QPointF(x*120, y*120) \
- # << QPointF((x+1)*120, y*120) \
- # << QPointF((x+1)*120, (y+1)*120) \
- # << QPointF(x*120, (y+1)*120)
- # return polygone
-
- # 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)"""
- # segments = []
- # #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 = self.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
- # if not len(segments) > 0: return None
- # 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)
- #
- # return polygone
- # 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"""
- item = self.itemAt(point)
- try:
- coord = item.coord()
- except:
- coord = None
- return coord
- def pionAuPoint(self, point):
- """retourne le premier pion de la pile s'il y en a plusieurs"""
- coord = self.coordonneesAuPoint(point)
- if not coord: return None
- pions = self.cases[coord].occupants()
- if len(pions) == 0: return None
- return pions[0]
- def ldmValide(self, origine, cible):
- """la ligne de mire entre les deux points est elle valide
- origine et cible sont toutes deux de la forme (x,y,z)"""
- if not cible != origine: return False
- ldm = self.geo.ligne(origine, cible)
- if len(ldm) == 0: return False
- ldm.remove(origine) ; ldm.remove(cible)
- x0, y0, z0 = origine ; x1, y1, z1 = cible
- for coord in ldm:
- x, y, z = coord
- occupant = self.cases[(x, y)].occupant(z)
- if occupant:
- #si une case de la ligne est occupee par autre chose que le tireur et sa cible
- if occupant != self.cases[(x0, y0)].occupant(z0) and \
- occupant != self.cases[(x1, y1)].occupant(z1):
- return False
- return True
-
- def coutDep(self, coord1, coord2, z2 = None):
- """renvoie le cout de deplacement de la case 1 a la case 2
- pour le pion actuellement selectionne /
- un cout egal a -1 implique un deplacement impossible"""
- retour = 0
- dist = 1
- if not self.cases[coord2].terrain.franchissable: return -1
-
- if self.cases[coord2].z1(): return -1
- if z2 == None: z2 = self.cases[coord2].z1()
- if self.cases[coord2].occupant(z2): return -1
- if self.pionSelectionne().zR == 0:
- dz = self.cases[coord2].z1() - self.cases[coord1].z1()
- if dz < (-1 * self.pionSelectionne().saut): return -1
-
- if dz > self.pionSelectionne().h:
- #si la diff de hauteur est superieure a la hauteur du combattant, il escalade
- if not self.pionSelectionne().depEscalade > 0: return -1
- retour += self.pionSelectionne().coutDep("depEscalade", dz)
-
- elif 0 < dz <= self.pionSelectionne().h:
- dist += dz
- if self.cases[coord2].terrain.nage:
- if not self.pionSelectionne().depNage > 0: return -1
- retour += self.pionSelectionne().coutDep("depNage", dist)
-
- else:
- if not self.pionSelectionne().depMarche > 0: return -1
- retour += self.pionSelectionne().coutDep("depMarche", dist)
- else:
- if not self.pionSelectionne().depVol > 0: return -1
- retour += self.pionSelectionne().coutDep("depVol", dist)
- 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].terrain.franchissable:
- listeCases2.append(coord)
- listeCases3 = self.geo.blocAdjacent(listeCases2)
- polygone = self.geo.polygoneAgglo(listeCases3)
- if not polygone: return
- self.polygoneZonePlacement.setPolygon(polygone)
- self.listeCasesZonePlacement = listeCases
- ####### maj des panneaux d'info
- def majInfoPion(self, pion = None):
- self.majInfoCb((pion if pion.numero > 0 else None) if pion else None)
- self.majInfoDc((pion if pion.numero < 0 else None) if pion else None)
-
- def majInfoCb(self, cb = None):
- self.fenetre.ui.icb_panneau.setVisible((cb != None))
- if cb:
- self.fenetre.ui.icb_image.chargerImage(cb.icone())
- self.fenetre.ui.icb_nom.majTexte(contractTxt(cb.nom(), 25))
- self.fenetre.ui.icb_mort.setVisible((cb.etat == 4))
- self.fenetre.ui.icb_image.setEnabled((cb.etat != 4))
- self.fenetre.ui.icb_etourdi.setVisible(0 in cb.statuts)
- self.fenetre.ui.icb_brule.setVisible(4 in cb.statuts)
- self.fenetre.ui.icb_paralyse.setVisible(2 in cb.statuts)
- self.fenetre.ui.icb_empoisonne.setVisible(3 in cb.statuts)
- self.fenetre.ui.icb_gele.setVisible(1 in cb.statuts)
- self.fenetre.ui.icb_etat.majTexte(lstLibEtats("cb")[cb.etat])
- self.fenetre.ui.icb_hauteur.majTexte("Hauteur: {}".format(cb.h))
- self.fenetre.ui.icb_vol.majTexte("En vol: {}".format(cb.zR) if cb.enVol else "")
-
- def majInfoDc(self, dc = None):
- self.fenetre.ui.idc_panneau.setVisible((dc != None))
- if dc:
- self.fenetre.ui.idc_image.chargerImage(dc.icone())
- self.fenetre.ui.idc_nom.majTexte(contractTxt(dc.nom(), 25))
- self.fenetre.ui.idc_detruit.setVisible((dc.etat == 4))
- self.fenetre.ui.idc_image.setEnabled((dc.etat != 4))
- self.fenetre.ui.idc_brule.setVisible(4 in dc.statuts)
- self.fenetre.ui.idc_verrouille.setVisible(5 in dc.statuts)
- self.fenetre.ui.idc_etat.majTexte(lstLibEtats("dc")[dc.etat])
- self.fenetre.ui.idc_hauteur.majTexte("Hauteur: {}".format(dc.h) if not (self.zP and dc.hMax) else "")
-
- def majInfoTr(self, case = None):
- if case:
- self.fenetre.ui.ic_coord.majTexte("X{} Y{}".format(case.x, case.y))
- self.fenetre.ui.ic_terrain.majTexte(case.terrain.nom() if (len(case.terrain.nom()) > 0) else "Case")
- self.fenetre.ui.ic_altitude.majTexte("{}".format(case.z0))
- if case.effetActif not in ["", "aucun"]:
- imgEffet = {"brule": "feu_16.png", "eau": "eau_16.png","glace": "glace_16.png","poison": "poison_16.png"}
- pix = QPixmap(":/interface/16/ressource/{}".format(imgEffet[case.effetActif]))
- self.fenetre.ui.ic_effet.setPixmap(pix)
- else:
- self.fenetre.ui.ic_effet.clear()
-
-
-
|