Coverage for thb/characters/daiyousei.py : 95%
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 ActionStage, DrawCardStage, GenericAction, MigrateCardsTransaction
7from thb.actions import PlayerDeath, UserAction, migrate_cards
8from thb.cards.base import CardList, Skill, t_None, t_OtherOne
9from thb.cards.classes import Heal
10from thb.characters.base import Character, register_character_to
11from thb.inputlets import ChooseOptionInputlet
12from thb.mode import THBEventHandler
15# -- code --
16class SupportAction(UserAction):
17 def apply_action(self):
18 cl = self.associated_card.associated_cards
19 src = self.source
20 tgt = self.target
21 lst = src.tags.get('daiyousei_spnum', 0)
22 n = len(cl)
23 if lst < 3 <= lst + n:
24 g = self.game
25 g.process_action(Heal(src, src))
26 src.tags['daiyousei_spnum'] = lst + n
27 tgt.reveal(cl)
28 migrate_cards([self.associated_card], tgt.cards, unwrap=True)
29 self.cards = cl
30 return True
33class Support(Skill):
34 associated_action = SupportAction
35 skill_category = ['character', 'active']
36 target = t_OtherOne()
37 usage = 'handover'
38 no_drop = True
39 no_reveal = True
41 def check(self):
42 cl = self.associated_cards
43 return cl and all(
44 c.resides_in is not None and
45 c.resides_in.type in ('cards', 'showncards', 'equips')
46 for c in cl
47 )
50class SupportKOFAction(UserAction):
51 def apply_action(self):
52 tgt = self.target
53 cl = tgt.support_cl = CardList(tgt, 'support')
55 with MigrateCardsTransaction(self) as trans:
56 migrate_cards(tgt.cards, cl, unwrap=True, trans=trans)
57 migrate_cards(tgt.showncards, cl, unwrap=True, trans=trans)
58 migrate_cards(tgt.equips, cl, unwrap=True, trans=trans)
60 return True
63class SupportKOFReturningAction(GenericAction):
64 def apply_action(self):
65 migrate_cards(self.source.support_cl, self.target.cards, unwrap=True)
66 return True
69class SupportKOFHandler(THBEventHandler):
70 interested = ['character_debut', 'action_apply']
71 execute_after = ['DeathHandler']
73 def handle(self, evt_type, arg):
74 if evt_type == 'character_debut':
75 old, new = arg
76 if not old: return arg
77 if not getattr(old, 'support_cl', None): return arg 77 ↛ 79line 77 didn't jump to line 79, because the condition on line 77 was never false
79 g = self.game
80 g.process_action(SupportKOFReturningAction(old, new))
82 elif evt_type == 'action_apply' and isinstance(arg, PlayerDeath):
83 tgt = arg.target
84 if not tgt.has_skill(SupportKOF): return arg
86 if not (tgt.cards or tgt.showncards or tgt.equips):
87 return arg
89 g = self.game
90 if g.user_input([tgt], ChooseOptionInputlet(self, (False, True))):
91 g.process_action(SupportKOFAction(tgt, tgt))
93 return arg
96class SupportKOF(Skill):
97 associated_action = None
98 skill_category = ['character', 'passive']
99 target = t_None()
102class Moe(Skill):
103 associated_action = None
104 skill_category = ['character', 'passive', 'compulsory']
105 target = t_None()
108class MoeDrawCard(DrawCardStage):
109 pass
112class DaiyouseiHandler(THBEventHandler):
113 interested = ['action_before']
115 # Well, well, things are getting messy
116 def handle(self, evt_type, act):
117 if evt_type == 'action_before': 117 ↛ 127line 117 didn't jump to line 127, because the condition on line 117 was never false
118 if isinstance(act, DrawCardStage):
119 tgt = act.target
120 if tgt.has_skill(Moe):
121 act.amount += tgt.maxlife - tgt.life
122 act.__class__ = MoeDrawCard
123 elif isinstance(act, ActionStage):
124 tgt = act.target
125 if tgt.has_skill(Support):
126 tgt.tags['daiyousei_spnum'] = 0
127 return act
130@register_character_to('common', '-kof')
131class Daiyousei(Character):
132 skills = [Support, Moe]
133 eventhandlers = [DaiyouseiHandler]
134 maxlife = 3
137@register_character_to('kof')
138class DaiyouseiKOF(Character):
139 skills = [SupportKOF, Moe]
140 eventhandlers = [DaiyouseiHandler, SupportKOFHandler]
141 maxlife = 3