#from __future__ import unicode_literals # -*- coding: utf-8 -*- import regles class Attaque(): """attaque pre-parametree affectee a un pion, un personnage ou une creature""" def __init__(self): self.nom = "Attaque" self.portee = 1 #portee max en cases self.attributs = regles.listeAttributsAttaques() self.notes = "" #variables de fonctionnement self._numPionCible = None self._coordCible = (-1, -1) self._casesCibles = [] #items graphiques self._itemLigne = None self._itemCible = None def activer(self, plateau): self.plateau = plateau self.plateau.materialiserPions(False) def desactiver(self): pass def effectuer(self): pass def annuler(self): pass def majCoordCible(self, coord): """met a jour les coordonnees de la cible, cad la case actuellement survolee par la souris""" if self.plateau.estCoordonneeValide(coord): self._coordCible = coord self.maj() class Cac(Attaque): """attaque au corps a corps""" def __init__(self): super(Cac, self).__init__(self) self.nom = "Attaque au corps-à-corps" self._pionCible = None def maj(self): pionCible = self_plateau.cases[self._coordCible].pionOccupant() if pionCible != None and pionCible != self._plateau.pionSelectionne(): self._pionCible = pionCible self._pionCible.estCibleAttaque(True, self.estValide()) else: self._pionCible.estCibleAttaque(False) self._pionCible = None def estValide(self): return (self._coordCible in self.plateau.zone(self.plateau.pionSelectionne().position, self.portee, 0, False, True)) class Distance(Attaque): """attaque a distance""" def __init__(self): super(Distance, self).__init__(self) self.nom = "Attaque à distance" self._itemLigne = None self._pionCible = None def activer(self, plateau): #creation de la ligne de mire ## self._pointOrigine = self.plateau.cases[self.plateau.pionSelectionne().position].centreGraphique self._itemLigne = QGraphicsLineItem() self._itemLigne.setZValue(100) pinceau = QPen() pinceau.setWidth(6) self._itemLigne.setPen(pinceau) self._itemLigne.prepareGeometryChange() self.plateau.addItem(self._itemLigne) super(Distance, self).activer(self, plateau) def majCoordCible(self, coord): if self._pionCible: self._pionCible.estCibleAttaque(False, self.estValide()) if self._coordCible in self.plateau.cases: self.plateau.cases[self._coordCible].majEstCibleCurseur(False) super(Distance, self).majCoord(self, coord) def desactiver(self): if self._itemLigne != None: self._itemLigne.prepareGeometryChange() self.removeItem(self._itemLigne) self._itemLigne = None super(Distance, self).desactiver(self) def maj(self): """met a jour la ligne de mire representant l'attaque a distance""" pionCible = self_plateau.cases[self._coordCible].pionOccupant() self._itemLigne.setLine(QLineF(self.plateau.cases[self.plateau.pionSelectionne().position].centreGraphique, \ self.plateau.cases[self._coordCible].centreGraphique)) if pionCible != None and pionCible != self._plateau.pionSelectionne(): self._pionCible = pionCible self._pionCible.estCibleAttaque(True, self.estValide()) else: self._pionCible.estCibleAttaque(False) self._pionCible = None #si pas de pion vise, on affiche la case cible comme visee self.plateau.cases[self._coordCible].majEstCibleCurseur(True, self.estValide()) def estValide(self): return self.plateau.estCibleAttaqueDistValide(self.plateau.pionSelectionne().position, self._coordCible, 0) class Ligne(Attaque): """attaque de zone de forme lineaire""" def __init__(self): super(Ligne, self).__init__(self) self.nom = "Attaque de zone: ligne" self._itemLigne = None self._casesCibles = [] def activer(self, plateau): self._itemLigne = QGraphicsLineItem() self._itemLigne.setPen(QPen(QColor("black"))) self._itemLigne.prepareGeometryChange() self.plateau.addItem(self._itemLigne) super(Ligne, self).activer(self, plateau) def desactiver(self): if self._itemLigne != None: self._itemLigne.prepareGeometryChange() self.removeItem(self._itemLigne) self._itemLigne = None super(Ligne, self).desactiver(self) def majCoordCible(self, coord): for coord in self._casesCibles: self.plateau.cases[coord].majEstCibleAttaque(False) for numCombattant in self.pionsSurListeCase(self._casesCibles): self.plateau.combattants[numCombattant].estCibleAttaque(False) super(Ligne, self).majCoord(self, coord) def maj(self): """cree la forme de l'attaque de zone""" self._itemLigne.setLine(QLineF(self.plateau.cases[self.plateau.pionSelectionne().position].centreGraphique, \ self.plateau.cases[self._coordCible].centreGraphique)) self._casesCibles = [] for coord in self.plateau.casesSousForme(self._itemLigne, False): if coord != self.plateau.pionSelectionne().position: self._casesCibles.append(coord) for coord in self._casesCibles: self.plateau.cases[coord].majEstCibleAttaque(True) for numCombattant in self.plateau.pionsSurListeCase(self._casesCibles): self.plateau.combattants[numCombattant].estCibleAttaque(True) class Disque(Attaque): """attaque de zone de forme circulaire""" def __init__(self): super(Disque, self).__init__(self) self.nom = "Attaque de zone: disque" self.rayon = 1 self._itemLigne = None self._casesCibles = [] self._itemLigne = None self._itemCible = None def activer(self, plateau): self._itemLigne = QGraphicsLineItem() self._itemLigne.setPen(QPen(QColor("black"))) self._itemLigne.prepareGeometryChange() self.plateau.addItem(self._itemLigne) self._itemCible = QGraphicsEllipseItem() self._itemCible.setPen(QPen(QColor("black"))) self._itemCible.prepareGeometryChange() self.plateau.addItem(self._itemCible) super(Disque, self).activer(self, plateau) def desactiver(self): if self._itemCible != None: self._itemCible.prepareGeometryChange() self.removeItem(self._itemCible) self._itemCible = None if self._itemLigne != None: self._itemLigne.prepareGeometryChange() self.removeItem(self._itemLigne) self._itemLigne = None super(Disque, self).desactiver(self) def majCoordCible(self, coord): for coord in self._casesCibles: self.plateau.cases[coord].majEstCibleAttaque(False) for numCombattant in self.pionsSurListeCase(self._casesCibles): self.plateau.combattants[numCombattant].estCibleAttaque(False) super(Disque, self).majCoord(self, coord) def maj(self): """cree la forme de l'attaque de zone""" self._itemLigne.setLine(QLineF(self.plateau.cases[self.plateau.pionSelectionne().position].centreGraphique, \ self.plateau.cases[self._coordCible].centreGraphique)) if self.estValide(): #maj du disque self.rectEllipseCirculaire(self.plateau.cases[self._coordCible].centreGraphique, self.rayon) self._casesCibles = [] if rect != None: self._itemCible.setRect(rect) #zone plus rapide que casesSousForme: self._casesCibles = self.plateau.zone(self._coordCible, self.rayon, 0) for coord in self._casesCibles: self.plateau.cases[coord].majEstCibleAttaque(True) for numCombattant in self.plateau.pionsSurListeCase(self._casesCibles): self.plateau.combattants[numCombattant].estCibleAttaque(True) else: self.plateau.cases[self._coordCible].majEstCibleCurseur(True, False) self._itemCible.setVisible(self.estvalide() and rect != None) def estValide(self): return self.plateau.estCibleAttaqueDistValide(self.plateau.pionSelectionne().position, self._coordCible) 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 = None 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))) if p1 != p2: rect = QRectF() rect.setTopLeft(p1) rect.setBottomRight(p2) return rect class Cone(Attaque): """attaque de zone de forme conique""" def __init__(self): super(Cone, self).__init__(self) self.nom = "Attaque de zone: cône" self._itemCible = None self._casesCibles = [] def activer(self, plateau): self._itemCible = QGraphicsPolygonItem() self._itemCible.setPen(QPen(QColor("black"))) self._itemCible.prepareGeometryChange() self.plateau.addItem(self._itemCible) super(Cone, self).activer(self, plateau) def desactiver(self): if self._itemCible != None: self._itemCible.prepareGeometryChange() self.removeItem(self._itemCible) self._itemCible = None super(Cone, self).desactiver(self) def majCoordCible(self, coord): for coord in self._casesCibles: self.plateau.cases[coord].majEstCibleAttaque(False) for numCombattant in self.pionsSurListeCase(self._casesCibles): self.plateau.combattants[numCombattant].estCibleAttaque(False) super(Cone, self).majCoord(self, coord) def maj(self): """cree la forme de l'attaque de zone""" self._itemCible.setPolygon(self.polygoneCone(self.plateau.cases[self.plateau.pionSelectionne().position].centreGraphique, \ self.plateau.cases[self._coordCible].centreGraphique)) self._casesCibles = [] for coord in self.plateau.casesSousForme(self._itemCible, True, True): if coord != self.plateau.pionSelectionne().position: self._casesCibles.append(coord) for coord in self._casesCibles: self.plateau.cases[coord].majEstCibleAttaque(True) for numCombattant in self.plateau.pionsSurListeCase(self._casesCibles): self.plateau.combattants[numCombattant].estCibleAttaque(True) 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