# Coverage for thb/characters/yukari.py : 98%

## 64 statements 63 run 1 missing 0 excluded 1 partial

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 -*-

2

3# -- stdlib --

4# -- third party --

5# -- own --

6 from thb.actions import GenericAction, PlayerTurn, UserAction, migrate_cards, random_choose_card

7 from thb.cards.base import CardList, Skill, t_One

8 from thb.characters.base import Character, register_character_to

9 from thb.inputlets import ChoosePeerCardInputlet

10 from thb.mode import THBEventHandler

11

12

13# -- code --

14 class SpiritingAwayAction(UserAction):

15 def apply_action(self):

16 tgt = self.target

17 src = self.source

18 g = self.game

19

20 catnames = ('cards', 'showncards', 'equips', 'fatetell')

21 cats = [getattr(tgt, i) for i in catnames]

22 card = g.user_input([src], ChoosePeerCardInputlet(self, tgt, catnames))

23 card = card or random_choose_card(g, cats)

24 if not card: 24 ↛ 25 line 24 didn't jump to line 25, because the condition on line 24 was never true

25 return False

26

27 self.card = card

28 src.reveal(card)

29

30 src.tags['spirit_away_tag'] += 1

31

32 cl = getattr(tgt, 'yukari_dimension', None)

33 if cl is None:

34 cl = CardList(tgt, 'yukari_dimension')

35 tgt.yukari_dimension = cl

36 tgt.showncardlists.append(cl)

37

38 migrate_cards([card], cl)

39

40 return True

41

42 def is_valid(self):

43 tgt = self.target

44 catnames = ['cards', 'showncards', 'equips', 'fatetell']

45 if not any(getattr(tgt, i) for i in catnames):

46 return False

47

48 return self.source.tags['spirit_away_tag'] < 2

49

50

51 class SpiritingAwayReturningAction(GenericAction):

52 def apply_action(self):

53 g = self.game

54 for p in g.players:

55 cl = getattr(p, 'yukari_dimension', None)

56 cl and migrate_cards(cl, p.cards, unwrap=True)

57

58 return True

59

60

61 class SpiritingAway(Skill):

62 associated_action = SpiritingAwayAction

63 skill_category = ['character', 'active']

64 target = t_One()

65

66 def check(self):

67 return not self.associated_cards

68

69

70 class SpiritingAwayHandler(THBEventHandler):

71 interested = ['action_after', 'action_apply']

72

73 def handle(self, evt_type, arg):

74 if evt_type == 'action_apply' and isinstance(arg, PlayerTurn):

75 tgt = arg.target

76 if tgt.has_skill(SpiritingAway):

77 tgt.tags['spirit_away_tag'] = 0

78

79 elif evt_type == 'action_after' and isinstance(arg, PlayerTurn):

80 tgt = arg.target

81 if not tgt.has_skill(SpiritingAway):

82 return arg

83

84 g = self.game

85 g.process_action(SpiritingAwayReturningAction(tgt, tgt))

86

87 return arg

88

89

90@register_character_to('common')

91 class Yukari(Character):

92 skills = [SpiritingAway]

93 eventhandlers = [SpiritingAwayHandler]

94 maxlife = 4