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, DrawCards, Fatetell, GenericAction, LaunchCard, UserAction 

7from thb.actions import ask_for_action, migrate_cards 

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

9from thb.cards.classes import t_None 

10from thb.characters.base import Character, register_character_to 

11from thb.inputlets import ChooseOptionInputlet 

12from thb.mode import THBEventHandler 

13 

14 

15# -- code -- 

16 

17# 「抖M」技能,对应郭嘉的「遗计」 

18class Masochist(Skill): 

19 # 技能没有附带的动作,仅被动触发 

20 associated_action = None 

21 # 技能的分类 

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

23 # 技能的目标,因为没有附带动作所以也没有目标 

24 target = t_None() 

25 

26 

27# 「抖M」技能动作 

28class MasochistAction(UserAction): 

29 # 在请求玩家输入后,不要自动将牌面告知其他玩家 

30 no_reveal = True 

31 # 卡牌的使用场景是「交给其他人」 

32 card_usage = 'handover' 

33 

34 # 参数分别是动作目标(自己)和受到伤害的数量 

35 def __init__(self, target, n): 

36 self.source, self.target, self.amount = target, target, n 

37 

38 # 动作的逻辑 

39 def apply_action(self): 

40 g = self.game 

41 tgt = self.target 

42 # 构造自己摸两张牌的动作 

43 a = DrawCards(tgt, self.amount * 2) 

44 # 执行这个动作 

45 g.process_action(a) 

46 self.cards = cards = a.cards 

47 n = len(cards) 

48 # 如果牌还没有送完,继续执行 

49 while n > 0: 

50 # 选取其他没有阵亡的角色 

51 pl = [p for p in g.players if not p.dead] 

52 pl.remove(tgt) 

53 if not pl: 53 ↛ 54line 53 didn't jump to line 54, because the condition on line 53 was never true

54 return True 

55 

56 # 玩家选择给出的牌和目标玩家 

57 _, rst = ask_for_action(self, [tgt], ('cards',), pl) 

58 if not rst: 

59 return True 

60 

61 cl, pl = rst 

62 # 告知目标牌面 

63 pl[0].player.reveal(cl) 

64 # 转移卡牌 

65 migrate_cards(cl, pl[0].cards) 

66 n -= len(cl) 

67 

68 return True 

69 

70 # ask_for_action 函数用的条件,给出的牌必须是拿到的牌 

71 def cond(self, cl): 

72 cards = self.cards 

73 return all(c in cards for c in cl) 

74 

75 # ask_for_action 函数用的条件,给出的牌必须是拿到的牌 

76 def choose_player_target(self, tl): 

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

78 return (tl, False) 

79 

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

81 

82 

83# 「抖M」技能的事件触发逻辑 

84class MasochistHandler(THBEventHandler): 

85 interested = ['action_after'] 

86 execute_after = ( 

87 'DyingHandler', 

88 'AyaRoundfanHandler', 

89 'NenshaPhoneHandler', 

90 ) 

91 

92 def handle(self, evt_type, act): 

93 # 当受到伤害后 

94 if evt_type == 'action_after' and isinstance(act, Damage): 

95 # 如果目标没有阵亡,且身负「抖M」技能 

96 tgt = act.target 

97 if tgt.dead: return act 

98 if not tgt.has_skill(Masochist): return act 

99 if not act.amount: return act 

100 

101 # 选择是否发动 

102 g = self.game 

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

104 return act 

105 

106 # 实际发动技能 

107 g.process_action(MasochistAction(tgt, act.amount)) 

108 

109 return act 

110 

111 

112# 「绯想」技能,对应郭嘉「天妒」 

113# 锁定技,距离1以内的角色的红色判定牌置入弃牌堆时,你获得之。 

114class ScarletPerception(Skill): 

115 distance = 1 

116 associated_action = None 

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

118 target = t_None() 

119 

120 

121class ScarletPerceptionAction(GenericAction): 

122 def __init__(self, source, target, card): 

123 self.source = source 

124 self.target = target 

125 self.card = card 

126 

127 def apply_action(self): 

128 migrate_cards([self.card], self.source.cards) 

129 return True 

130 

131 

132class ScarletPerceptionHandler(THBEventHandler): 

133 interested = ['action_after'] 

134 

135 def handle(self, evt_type, act): 

136 # 在判定结束后 

137 if evt_type == 'action_after' and isinstance(act, Fatetell): 

138 tgt = act.target 

139 

140 # 如果牌的颜色是红色,而且没有在某个牌区内(不属于任何人,或者牌堆) 

141 if act.card.color != Card.RED: return act 

142 g = self.game 

143 if not act.card.detached: 143 ↛ 144line 143 didn't jump to line 144, because the condition on line 143 was never true

144 return act 

145 

146 # 此处只有被小爱的技能 drop 掉这一种情况,没发现其他的 

147 if isinstance(act.card, ShreddedCard): 147 ↛ 148line 147 didn't jump to line 148, because the condition on line 147 was never true

148 return act 

149 

150 # 寻找场内身负「绯想」技能的人 

151 g = self.game 

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

153 

154 for p in pl: 

155 p = pl[0] 

156 dist = LaunchCard.calc_distance(g, p, ScarletPerception(p)) 

157 # 若满足距离限制 

158 if dist.get(tgt, 1) <= 0: 

159 # 执行获得牌的动作 

160 g.process_action(ScarletPerceptionAction(p, tgt, act.card)) 

161 break 

162 

163 return act 

164 

165 

166# 「比那名居天子」人物 

167@register_character_to('common') 

168class Tenshi(Character): 

169 # 人物技能 

170 skills = [Masochist, ScarletPerception] 

171 # 需要的事件处理器 

172 eventhandlers = [MasochistHandler, ScarletPerceptionHandler] 

173 # 最大体力 

174 maxlife = 3