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

## 88 statements 87 run 1 missing 0 excluded 2 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 DrawCardStage, UserAction, migrate_cards, user_choose_players

7 from thb.cards.base import Card, Skill

8 from thb.cards.classes import Harvest, HarvestCard, TreatAs, t_None

9 from thb.characters.base import Character, register_character_to

10 from thb.mode import THBEventHandler

11

12

13# -- code --

14 class Foison(Skill):

15 associated_action = None

16 skill_category = ['character', 'passive', 'compulsory']

17 target = t_None()

18

19

20 class FoisonDrawCardStage(DrawCardStage):

21 def apply_action(self):

22 self.amount = max(self.amount, 5 - len(self.target.cards) - len(self.target.showncards))

23 return DrawCardStage.apply_action(self)

24

25

26 class FoisonHandler(THBEventHandler):

27 interested = ['action_before']

28

29 def handle(self, evt_type, act):

30 if evt_type == 'action_before' and isinstance(act, DrawCardStage):

31 tgt = act.target

32 if tgt.has_skill(Foison):

33 act.__class__ = FoisonDrawCardStage

34 return act

35

36

37 class AutumnFeastAction(Harvest):

38 def apply_action(self):

39 tags = self.source.tags

40 tags['autumnfeast_tag'] = tags['turn_count']

41 return Harvest.apply_action(self)

42

43 def is_valid(self):

44 tags = self.source.tags

45 if tags['turn_count'] <= tags['autumnfeast_tag']:

46 return False

47 return Harvest.is_valid(self)

48

49

50 class AutumnFeast(TreatAs, Skill):

51 treat_as = HarvestCard

52 associated_action = AutumnFeastAction

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

54

55 def check(self):

56 cl = self.associated_cards

57 if cl and len(cl) == 2 and all(c.color == Card.RED for c in cl):

58 return True

59 return False

60

61

62 class AkiTribute(Skill):

63 associated_action = None

64 skill_category = ['character', 'passive', 'compulsory']

65 target = t_None()

66

67

68 class AkiTributeCollectCard(UserAction):

69 def __init__(self, source, target, cards):

70 self.source = source

71 self.target = target

72 self.cards = cards

73

74 def apply_action(self):

75 migrate_cards(self.cards, self.target.showncards)

76 return True

77

78

79 class AkiTributeHandler(THBEventHandler):

80 interested = ['choose_target', 'harvest_finish']

81

82 def handle(self, evt_type, act):

83 if evt_type == 'choose_target':

84 act, tl = arg = act

85 card = act.card

86 if not card.is_card(HarvestCard): return arg

87 pl = [p for p in tl if p.has_skill(AkiTribute) and not p.dead]

88 assert len(pl) <= 1, 'Multiple AkiTributes!'

89 if not pl: return arg

90 p = pl[0]

91 tl.remove(p)

92 tl.insert(0, p)

93 return act, tl

94

95 elif evt_type == 'harvest_finish': 95 ↛ 111 line 95 didn't jump to line 111, because the condition on line 95 was never false

96 g = self.game

97 pl = [p for p in g.players if p.has_skill(AkiTribute) and not p.dead]

98 assert len(pl) <= 1, 'Multiple AkiTributes!'

99 if not pl: return act

100

101 src = pl[0]

102 cards = [c for c in act.cards if c.detached]

103 if not cards: return act

104

105 candidates = [p for p in g.players if not p.dead]

106 tl = user_choose_players(self, src, candidates)

107

108 tgt = tl[0] if tl else src

109 g.process_action(AkiTributeCollectCard(src, tgt, cards))

110

111 return act

112

113 def choose_player_target(self, tl):

114 if not tl: 114 ↛ 115 line 114 didn't jump to line 115, because the condition on line 114 was never true

115 return (tl, False)

116

117 return (tl[-1:], True)

118

119

120@register_character_to('common')

121 class Minoriko(Character):

122 skills = [Foison, AutumnFeast, AkiTribute]

123 eventhandlers = [FoisonHandler, AkiTributeHandler]

124 maxlife = 3