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

## 66 statements 25 run 41 missing 0 excluded 0 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 from __future__ import annotations

3

4# -- stdlib --

5# -- third party --

6# -- own --

7 from thb.actions import FinalizeStage, GenericAction, PrepareStage, UserAction, migrate_cards

8 from thb.actions import random_choose_card

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

10 from thb.characters.base import Character, register_character_to

11 from thb.inputlets import ChoosePeerCardInputlet

12 from thb.mode import THBEventHandler

13

14

15# -- code --

16 class SpiritingAwayAction(UserAction):

17 def apply_action(self):

18 tgt = self.target

19 src = self.source

20 g = self.game

21

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

28

29 self.card = card

30 src.reveal(card)

31

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

33

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)

39

40 migrate_cards([card], cl)

41

42 return True

43

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

49

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

51

52

53 class 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)

59

60 return True

61

62

63 class SpiritingAway(Skill):

64 associated_action = SpiritingAwayAction

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

66 target = t_One()

67

68 def check(self):

69 return not self.associated_cards

70

71

72 class SpiritingAwayHandler(THBEventHandler):

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

74

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

80

81 elif evt_type == 'action_after' and isinstance(arg, FinalizeStage):

82 tgt = arg.target

83 if not tgt.has_skill(SpiritingAway):

84 return arg

85

86 g = self.game

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

88

89 return arg

90

91

92@register_character_to('common')

93 class Yukari(Character):

94 skills = [SpiritingAway]

95 eventhandlers = [SpiritingAwayHandler]

96 maxlife = 4