Commits

Alexander Schremmer  committed f21a5f4

Implemented first gain_card hook call via on_buy_card, use this in the BorderVillage.

  • Participants
  • Parent commits 43d796e

Comments (0)

Files changed (3)

File domination/cards/__init__.py

 from domination.gameengine import Defended, TLS
 from domination.tools import _
 
+from domination.macros.__macros__ import generator_forward, generator_forward_ex
+
 
 class Edition(object):
     def __init__(self, key, name, optional=True):
     def defend_action(self, game, player, card):
         raise NotImplementedError
 
+    @classmethod
+    def on_buy_card(cls, game, player, card):
+        gen = game.fire_hook("on_gain_card", game, player, card)
+        generator_forward(gen)
+
 
 class ActionCard(Card):
     optional = True

File domination/cards/hinterlands.py

 from domination.gameengine import InfoRequest, SelectCard, SelectHandCards, \
      YesNoQuestion, Question, Defended, SelectActionCard
 from domination.tools import _
-from domination.macros.__macros__ import handle_defense, generator_forward
+from domination.macros.__macros__ import handle_defense, generator_forward, fetch_card_from_supply
 
 
 class BorderVillage(ActionCard):
     name = _("Border Village")
     edition = Hinterlands
-    implemented = False #FIXME Second half of the action should be triggered when card is gained.
     cost = 6
     desc = _("+1 Card +2 Actions. | When you gain this, gain a card costing less than this.")
 
         player.remaining_actions += 2
         player.draw_cards(1)
 
-    def gainedthis(self, game, player):
+    @classmethod
+    def on_gain_card(cls, game, player, card):
+        if not isinstance(card, BorderVillage):
+            return
+
         card_classes = [c for c in game.card_classes.itervalues()
-                        if c.cost < this.cost and
+                        if c.cost < cls.cost and
                         game.supply.get(c.__name__)]
         card_cls = yield SelectCard(game, player, card_classes=card_classes,
             msg=_("Select a card that you want to have."), show_supply_count=True)
-        new_card = game.supply[card_cls.__name__].pop()
-        player.hand.append(new_card)
-        for info_player in game.following_participants(player):
-            yield InfoRequest(game, info_player,
-                    _("%s gains:", (player.name, )), [new_card])
-        for val in game.check_empty_pile(card_cls.__name__):
-            yield val
+        with fetch_card_from_supply(game, card_cls) as new_card:
+            player.discard_pile.append(new_card)
+            for info_player in game.following_participants(player):
+                yield InfoRequest(game, info_player,
+                        _("%s gains:", (player.name, )), [new_card])
 
 class Cache(TreasureCard):
     name = _("Cache")
 class Cartographer(ActionCard):
     name = _("Cartographer")
     edition = Hinterlands
-    implemented = False #FIXME Second half of the action should be triggered when card is gained.
+    implemented = False
     cost = 5
-    desc = _("+1 Card +1 Action. | Look at the top 4 Cards of your deck "
+    desc = _("+1 Card +1 Action. Look at the top 4 Cards of your deck "
             "Discard any number of them. Put the rest back on top in any order.")
 
     def activate_action(self, game, player):
 class Scheme(ActionCard):
     name = _("Scheme")
     edition = Hinterlands
-    implemented = False #FIXME Second half of the action should be triggered when card is gained.
+    implemented = False
     cost = 3
-    desc = _("+1 Card +1 Action. | At the start of Clean-up this turn, "
+    desc = _("+1 Card +1 Action. At the start of Clean-up this turn, "
             "you may choose an Action Card you have in play. "
             "If you discard it from play this turn, put it on your deck.")
 

File domination/gameengine.py

             path = os.path.join(app.game_storage_path, taint_filename(self.game.name
             + app.game_storage_postfix))
         f = file(path, "wb")
-        pickle.dump(self, f, -1)
+        pickle.dump(self, f)#, -1)
         f.close()
 
-from domination.cards import DurationCard
+from domination.cards import DurationCard, Card
 
 class Game(object):
-    HOOKS = ["on_pre_buy_card", "on_end_of_game", "on_start_of_turn", "on_end_of_turn", "on_buy_card", "on_render_card_info"]
+    HOOKS = ["on_pre_buy_card", "on_end_of_game", "on_start_of_turn", "on_end_of_turn", "on_buy_card", "on_render_card_info",
+             "on_gain_card"]
 
     def __init__(self, name, selected_cards):
         from domination.cards import CardTypeRegistry
     def prepare_hooks(self, cards):
         for hook_name in Game.HOOKS:
             self._hooks[hook_name] = []
-            for card in cards:
-                if hasattr(card, hook_name):
+            for card in cards + [Card]:
+                if hook_name in card.__dict__:
                     self._hooks[hook_name].append(getattr(card, hook_name))
 
     def fire_hook(self, hook_name, *args):
                         else:
                             try:
                                 cardcls = CardTypeRegistry.keys2classes((card_key, ))[0]
-                                for elem in self.fire_hook("on_pre_buy_card", self, player, cardcls):
-                                    yield elem
+                                gen = self.fire_hook("on_pre_buy_card", self, player, cardcls)
+                                generator_forward(gen)
                             except AbortBuy:
                                 continue
                             player.remaining_deals -= 1
                                 if other_player is not player:
                                     yield InfoRequest(self, other_player,
                                             _("%s buys:", (player.name, )), [card])
-                            for elem in self.fire_hook("on_buy_card", self, player, card):
-                                yield elem
+                            gen = self.fire_hook("on_buy_card", self, player, card)
+                            generator_forward(gen)
 
                         reason = self.check_end_of_game()
                         if reason: