class Card(Thing): def __init__(self, owner): Thing.__init__(self, owner._server) if hasattr(self, 'name'): self.name = self.name else: n = self.__class__.__name__ i = 1 while i < len(n): if n[i] in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ': n = n[:i] + ' ' + n[i:] i += 1 i += 1 self.name = n if hasattr(self, 'color'): self.color = self.color elif self.cost[-1].lower() in 'rgubw': self.color = self.cost[-1].lower() else: self.color = '' self.tapped = 0 self._isDoneCasting = 0 self._abilities = {} self.untapEvent = None def tap(self): if not self.tapped: self.tapped = 1 self.untapEvent = Event(self, 'Untapping', untapDelay, self.untap) def untap(self): if self.tapped: if self.untapEvent: self.untapEvent.cancel() self.tapped = 0
class Configurable(Card): def canCast(self, player): return player.hasMana(self.cost) def cast(self, player): player.drainMana(self.cost) self.owner = player self.setupEvent = Event(self, 'Configure Spell', configureDelay, self.timeOut) def doneSetup(self): self.setupEvent.cancel() def timeOut(self): self.destroy()
class TargettedAbility(Ability): def start(self): self.card.target = None self.card.setEditable('target', self.trySetTarget, ()) self.setupEvent = Event(self.card, 'Configure', configureDelay, self.timeOut) def doneSetup(self): self.setupEvent.cancel() def timeOut(self): self.card.setNoneditable('target') def trySetTarget(self, target): if target == None: return if target == self: return if self.card.canSetTarget(target): self.setTarget(target) def setTarget(self, target): self.card.setNoneditable('target') self.card.target = target self.doneSetup() Ability.start(self)
class MtGPlayer(Player, Damageable): _isDoneCasting = 1 maxCards = 7 started = False def initPlayer(self): self.life = playerStartHealth for k in dir(mtg_deck): v = getattr(mtg_deck, k) if isinstance(v, dict) and not k.startswith('_'): Action(self, k, lambda k=k: self.set_deck(k), secret=1) def set_deck(self, deck_name): self._deck = Deck(self, deck_name) for k, v in self._actions.items(): v.remove() Action(self, 'Start Game', self.start, args=(False, )) Action(self, 'Start Game (debug mode)', self.start, args=(True, )) def start(self, debug): for k, v in self._actions.items(): v.remove() self.started = True for p in self.getAllInPlay(MtGPlayer): if not p.started: Event(self, 'waiting for others to start', 0.01, self.start, args=(debug, )) return self._hand = Hand(self) self._hasCastLand = 0 self._mana = Mana(self) self._isManaBurning = 0 self.discardTimer = None for i in range(8): self.doDrawCard() self.drawCardEvent = Event(self, 'Drawing Next Card', cardDrawDelay, self.doDrawCard, repeat=1) if debug: Action(self, 'Draw card', self.doDrawCard) for m in 'BRGWU': Action(self, 'Gain %s mana' % m, self.addMana, args=(m, )) set_debug_timing() def addMana(self, mana): self._mana.add(mana) def doDamage(self, amount, source): self.life -= amount if self.life <= 0: self.destroy() def gainHealth(self, amount): self.life += amount def hasMana(self, mana): return self._mana.has(mana) def drainMana(self, mana): self._mana.drain(mana) def doDrawCard(self): self._hand.addCard(self._deck.draw()) self.checkCardCount() def checkCardCount(self): if self._hand.count() <= self.maxCards and self.discardTimer != None: self.discardTimer.cancel() self.discardTimer = None self.setNoneditable('discard') if self._hand.count() > self.maxCards and self.discardTimer == None: self.discardTimer = Event(self, 'Forced Discard', discardDelay, self.forceDiscard) cardNames = [''] for c in self._hand.cards.values(): if c.name not in cardNames: cardNames.append(c.name) cardNames.sort() self.discard = '' self.setEditable('discard', self.setDiscard, cardNames) def setDiscard(self, cardName): if self.discardTimer == None: return for c in self._hand.cards.values(): if c.name == cardName: self._hand.discard(c) break self.checkCardCount() def forceDiscard(self): self.discardTimer = None while self._hand.count() > self.maxCards: self._hand.discard(random.choice(self._hand.cards.values())) def setCastLand(self): if not self._hasCastLand: self._hasCastLand = 1 Event(self, 'Land Delay', landDelay, self.resetCastLand) def resetCastLand(self): self._hasCastLand = 0 def startManaBurn(self): self.manaBurn = Event(self, 'Mana Burn', manaBurnDelay, self.doManaBurn) self._isManaBurning = 1 def stopManaBurn(self): if self._isManaBurning: self.manaBurn.cancel() self._isManaBurning = 0 def doManaBurn(self): count = self._mana.count() self._mana.removeAll() self._isManaBurning = 0 self.doDamage(count, None)