Coverage for thb/characters/yukari.py : 31%
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 -*-
2from __future__ import annotations
4# -- stdlib --
5# -- third party --
6# -- own --
7from thb.actions import FinalizeStage, GenericAction, PrepareStage, UserAction, migrate_cards
8from thb.actions import random_choose_card
9from thb.cards.base import CardList, Skill, t_One
10from thb.characters.base import Character, register_character_to
11from thb.inputlets import ChoosePeerCardInputlet
12from thb.mode import THBEventHandler
15# -- code --
16class SpiritingAwayAction(UserAction):
17 def apply_action(self):
18 tgt = self.target
19 src = self.source
20 g = self.game
22 catnames = ('cards', 'showncards', 'equips', 'fatetell')
23 cats = [getattr(tgt, i) for i in catnames]
24 card = g.user_input([src], ChoosePeerCardInputlet(self, tgt, catnames))
25 card = card or random_choose_card(g, cats)
26 if not card:
27 return False
29 self.card = card
30 src.reveal(card)
32 src.tags['spirit_away_tag'] += 1
34 cl = tgt._.get('yukari_dimension')
35 if cl is None:
36 cl = CardList(tgt, 'yukari_dimension')
37 tgt._['yukari_dimension'] = cl
38 tgt.lists.append(cl)
40 migrate_cards([card], cl)
42 return True
44 def is_valid(self):
45 tgt = self.target
46 catnames = ['cards', 'showncards', 'equips', 'fatetell']
47 if not any(getattr(tgt, i) for i in catnames):
48 return False
50 return self.source.tags['spirit_away_tag'] < 2
53class SpiritingAwayReturningAction(GenericAction):
54 def apply_action(self):
55 g = self.game
56 for p in g.players:
57 cl = p._.get('yukari_dimension')
58 cl and migrate_cards(cl, p.cards, unwrap=True)
60 return True
63class SpiritingAway(Skill):
64 associated_action = SpiritingAwayAction
65 skill_category = ['character', 'active']
66 target = t_One()
68 def check(self):
69 return not self.associated_cards
72class SpiritingAwayHandler(THBEventHandler):
73 interested = ['action_after', 'action_apply']
75 def handle(self, evt_type, arg):
76 if evt_type == 'action_apply' and isinstance(arg, PrepareStage):
77 tgt = arg.target
78 if tgt.has_skill(SpiritingAway):
79 tgt.tags['spirit_away_tag'] = 0
81 elif evt_type == 'action_after' and isinstance(arg, FinalizeStage):
82 tgt = arg.target
83 if not tgt.has_skill(SpiritingAway):
84 return arg
86 g = self.game
87 g.process_action(SpiritingAwayReturningAction(tgt, tgt))
89 return arg
92@register_character_to('common')
93class Yukari(Character):
94 skills = [SpiritingAway]
95 eventhandlers = [SpiritingAwayHandler]
96 maxlife = 4