Hide keyboard shortcuts

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

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

7from thb.actions import user_choose_players 

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

9from thb.cards.classes import t_None, t_OtherOne 

10from thb.characters.base import Character, register_character_to 

11from thb.inputlets import ChooseOptionInputlet 

12from thb.mode import THBEventHandler 

13 

14 

15# -- code -- 

16class Jolly(Skill): 

17 associated_action = None 

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

19 target = t_None() 

20 

21 

22class 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 

58class 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 

79class 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 

87class 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') 

115class Kogasa(Character): 

116 skills = [Surprise, Jolly] 

117 eventhandlers = [JollyHandler] 

118 maxlife = 3