Coverage for thb/characters/shinmyoumaru.py : 84%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
3# -- stdlib --
4# -- third party --
5# -- own --
6from thb.actions import Damage, DropCards, FatetellAction, FatetellMalleateHandler
7from thb.actions import MigrateCardsTransaction, PostCardMigrationHandler, UseCard, detach_cards
8from thb.actions import migrate_cards, user_choose_cards
9from thb.cards.base import Skill
10from thb.cards.classes import t_None
11from thb.characters.base import Character, register_character_to
12from thb.inputlets import ChooseOptionInputlet
13from thb.mode import THBEventHandler
16# -- code --
17class MiracleMallet(Skill):
18 associated_action = None
19 skill_category = ['character', 'passive']
20 target = t_None()
23class VengeOfTsukumogami(Skill):
24 associated_action = None
25 skill_category = ['character', 'passive']
26 target = t_None()
29class MiracleMalletAction(UseCard):
30 def __init__(self, source, target, ft, card):
31 self.source, self.target, self.ft, self.card = \
32 source, target, ft, card
34 def apply_action(self):
35 g = self.game
36 c = self.card
37 ft = self.ft
38 src = self.source
39 g.players.exclude(src).reveal(c)
40 with MigrateCardsTransaction(self) as trans:
41 migrate_cards([ft.card], src.cards, unwrap=True, trans=trans)
42 detach_cards([c], trans=trans)
43 self.ft.set_card(c, self)
45 return True
48class MiracleMalletHandler(THBEventHandler):
49 interested = ['fatetell']
50 execute_before = ['YinYangOrbHandler']
51 arbiter = FatetellMalleateHandler
52 card_usage = 'use'
54 def handle(self, p, act):
55 if p.dead: return act
56 if not p.has_skill(MiracleMallet): return act
58 self.number = act.card.number
59 self.act = act
60 cards = user_choose_cards(self, p, ('cards', 'showncards', 'equips'))
62 if cards: 62 ↛ 63line 62 didn't jump to line 63, because the condition on line 62 was never true
63 c = cards[0]
64 self.game.process_action(MiracleMalletAction(p, act.target, act, c))
66 return act
68 def cond(self, cards):
69 if len(cards) != 1 or cards[0].is_card(Skill): 69 ↛ 72line 69 didn't jump to line 72, because the condition on line 69 was never false
70 return False
72 return cards[0].number > self.number
74 def ask_for_action_verify(self, p, cl, tl):
75 act = self.act
76 return MiracleMalletAction(p, act.target, act, cl[0]).can_fire()
79class VengeOfTsukumogamiAction(FatetellAction):
80 def __init__(self, source, target, card):
81 self.source = source
82 self.target = target
83 self.card = card
84 self.fatetell_target = source
85 self.fatetell_cond = lambda c: 9 <= c.number <= 13
87 def fatetell_action(self, ft):
88 if ft.succeeded:
89 self.game.process_action(Damage(self.source, self.target))
91 return True
94class VengeOfTsukumogamiHandler(THBEventHandler):
95 interested = ['post_card_migration']
96 arbiter = PostCardMigrationHandler
98 def handle(self, p, trans):
99 if not p.has_skill(VengeOfTsukumogami) or p.dead:
100 return True
102 if not isinstance(trans.action, DropCards):
103 return True
105 g = self.game
106 for m in trans.movements:
107 if m.fr.type != 'equips':
108 continue
110 if m.fr.owner is p:
111 continue
113 if m.to.type != 'droppedcard': 113 ↛ 114line 113 didn't jump to line 114, because the condition on line 113 was never true
114 continue
116 self.target = tgt = m.fr.owner
117 self.card = m.card
119 if tgt.dead:
120 break
122 if not g.user_input([p], ChooseOptionInputlet(self, (False, True))):
123 break
125 self.game.process_action(VengeOfTsukumogamiAction(p, tgt, m.card))
127 return True
130@register_character_to('common')
131class Shinmyoumaru(Character):
132 skills = [MiracleMallet, VengeOfTsukumogami]
133 eventhandlers = [MiracleMalletHandler, VengeOfTsukumogamiHandler]
134 maxlife = 4