# Coverage for thb/characters/kogasa.py : 37%

## 78 statements 34 run 44 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

3# -- stdlib --

4# -- third party --

5# -- own --

6 from thb.actions import Damage, DrawCardStage, DrawCards, UserAction, detach_cards, migrate_cards

7 from thb.actions import user_choose_players

8 from thb.cards.base import Card, Skill, VirtualCard

9 from thb.cards.classes import t_None, t_OtherOne

10 from thb.characters.base import Character, register_character_to

11 from thb.inputlets import ChooseOptionInputlet

12 from thb.mode import THBEventHandler

13

14

15# -- code --

16 class Jolly(Skill):

17 associated_action = None

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

19 target = t_None()

20

21

22 class SurpriseAction(UserAction):

23

24 def apply_action(self):

25 src = self.source

26 tgt = self.target

27 options = (

28 Card.SPADE, Card.HEART,

29 Card.CLUB, Card.DIAMOND,

30 )

31

32 card = self.associated_card

33 assert isinstance(card, Surprise)

34 detach_cards([card])

35 g = self.game

36 suit = g.user_input([tgt], ChooseOptionInputlet(self, options))

37

38 src.tags['surprise_tag'] = src.tags['turn_count']

39 assert card

40

41 g.players.reveal(card.associated_cards)

42 migrate_cards([card], tgt.showncards, unwrap=True)

43

44 if card.suit != suit:

45 g.process_action(Damage(src, tgt))

46 rst = True

47 else:

48 rst = False

49

50 return rst

51

52 def is_valid(self):

53 t = self.source.tags

54 if t['turn_count'] <= t['surprise_tag']: return False

55 return True

56

57

58 class Surprise(Skill):

59 associated_action = SurpriseAction

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

61 target = t_OtherOne()

62 no_reveal = True

63 no_drop = True

64 usage = 'handover'

65

66 def check(self):

67 cl = self.associated_cards

68 if not len(cl) == 1: return False

69 c, = cl

70 if c.is_card(VirtualCard):

71 return False

72

73 if c.resides_in.type not in ('cards', 'showncards'):

74 return False

75

76 return True

77

78

79 class JollyDrawCard(DrawCards):

80 def __init__(self, source, target):

81 self.source = source

82 self.target = target

83 self.amount = 1

84 self.back = False

85

86

87 class JollyHandler(THBEventHandler):

88 interested = ['action_after']

89

90 def handle(self, evt_type, act):

91 if evt_type == 'action_after' and isinstance(act, DrawCardStage):

92 tgt = act.target

93

94 if not tgt.has_skill(Jolly): return act

95

96 g = self.game

97 pl = user_choose_players(self, tgt, [p for p in g.players if not p.dead])

98 if not pl: pl = [tgt]

99

100 p = pl[0]

101

102 g.process_action(JollyDrawCard(tgt, p))

103

104 return act

105

106 def cond(self, cards):

107 return not cards

108

109 def choose_player_target(self, tl):

110 if not tl: return (tl, False)

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

112

113

114@register_character_to('common')

115 class Kogasa(Character):

116 skills = [Surprise, Jolly]

117 eventhandlers = [JollyHandler]

118 maxlife = 3