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

2from __future__ import annotations 

3 

4# -- stdlib -- 

5# -- third party -- 

6# -- own -- 

7from thb.actions import ActionStage, DrawCardStage, GenericAction, MigrateCardsTransaction 

8from thb.actions import PlayerDeath, UserAction, migrate_cards 

9from thb.cards.base import CardList, Skill, t_None, t_OtherOne 

10from thb.cards.classes import Heal 

11from thb.characters.base import Character, register_character_to 

12from thb.inputlets import ChooseOptionInputlet 

13from thb.mode import THBEventHandler 

14 

15 

16# -- code -- 

17class SupportAction(UserAction): 

18 def apply_action(self): 

19 sk = self.associated_card 

20 assert isinstance(sk, Support) 

21 cl = sk.associated_cards 

22 src = self.source 

23 tgt = self.target 

24 lst = src.tags.get('daiyousei_spnum', 0) 

25 n = len(cl) 

26 if lst < 3 <= lst + n: 

27 g = self.game 

28 g.process_action(Heal(src, src)) 

29 src.tags['daiyousei_spnum'] = lst + n 

30 tgt.reveal(cl) 

31 migrate_cards([self.associated_card], tgt.cards, unwrap=True) 

32 self.cards = cl 

33 return True 

34 

35 

36class Support(Skill): 

37 associated_action = SupportAction 

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

39 target = t_OtherOne() 

40 usage = 'handover' 

41 no_drop = True 

42 no_reveal = True 

43 

44 def check(self): 

45 cl = self.associated_cards 

46 return cl and all( 

47 c.resides_in is not None and 

48 c.resides_in.type in ('cards', 'showncards', 'equips') 

49 for c in cl 

50 ) 

51 

52 

53class SupportKOFAction(UserAction): 

54 def apply_action(self): 

55 tgt = self.target 

56 p = tgt.player 

57 cl = p._['support-cards'] = CardList(tgt, 'support') 

58 

59 with MigrateCardsTransaction(self) as trans: 

60 migrate_cards(tgt.cards, cl, unwrap=True, trans=trans) 

61 migrate_cards(tgt.showncards, cl, unwrap=True, trans=trans) 

62 migrate_cards(tgt.equips, cl, unwrap=True, trans=trans) 

63 

64 return True 

65 

66 

67class SupportKOFReturningAction(GenericAction): 

68 def apply_action(self): 

69 src, tgt = self.source, self.target 

70 p = src.player 

71 assert p is tgt.player 

72 cl = p._['support-cards'] 

73 migrate_cards(cl, tgt.cards, unwrap=True) 

74 return True 

75 

76 

77class SupportKOFHandler(THBEventHandler): 

78 interested = ['character_debut', 'action_apply'] 

79 execute_after = ['DeathHandler'] 

80 

81 def handle(self, evt_type, arg): 

82 if evt_type == 'character_debut': 

83 old, new = arg 

84 if not old: return arg 

85 

86 assert isinstance(old, Character) 

87 assert isinstance(new, Character) 

88 

89 p = old.player 

90 

91 if not p._['support-cards']: 

92 return arg 

93 

94 g = self.game 

95 g.process_action(SupportKOFReturningAction(old, new)) 

96 

97 elif evt_type == 'action_apply' and isinstance(arg, PlayerDeath): 

98 tgt = arg.target 

99 if not tgt.has_skill(SupportKOF): return arg 

100 

101 if not (tgt.cards or tgt.showncards or tgt.equips): 

102 return arg 

103 

104 g = self.game 

105 if g.user_input([tgt], ChooseOptionInputlet(self, (False, True))): 

106 g.process_action(SupportKOFAction(tgt, tgt)) 

107 

108 return arg 

109 

110 

111class SupportKOF(Skill): 

112 associated_action = None 

113 skill_category = ['character', 'passive'] 

114 target = t_None() 

115 

116 

117class Moe(Skill): 

118 associated_action = None 

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

120 target = t_None() 

121 

122 

123class MoeDrawCard(DrawCardStage): 

124 pass 

125 

126 

127class DaiyouseiHandler(THBEventHandler): 

128 interested = ['action_before'] 

129 

130 # Well, well, things are getting messy 

131 def handle(self, evt_type, act): 

132 if evt_type == 'action_before': 

133 if isinstance(act, DrawCardStage): 

134 tgt = act.target 

135 if tgt.has_skill(Moe): 

136 act.amount += tgt.maxlife - tgt.life 

137 act.__class__ = MoeDrawCard 

138 elif isinstance(act, ActionStage): 

139 tgt = act.target 

140 if tgt.has_skill(Support): 

141 tgt.tags['daiyousei_spnum'] = 0 

142 return act 

143 

144 

145@register_character_to('common', '-kof') 

146class Daiyousei(Character): 

147 skills = [Support, Moe] 

148 eventhandlers = [DaiyouseiHandler] 

149 maxlife = 3 

150 

151 

152@register_character_to('kof') 

153class DaiyouseiKOF(Character): 

154 skills = [SupportKOF, Moe] 

155 eventhandlers = [DaiyouseiHandler, SupportKOFHandler] 

156 maxlife = 3