Coverage for thb/characters/tenshi.py : 30%
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 -*-
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
15# -- code --
17# 「抖M」技能,对应郭嘉的「遗计」
18class Masochist(Skill):
19 # 技能没有附带的动作,仅被动触发
20 associated_action = None
21 # 技能的分类
22 skill_category = ['character', 'passive']
23 # 技能的目标,因为没有附带动作所以也没有目标
24 target = t_None()
27# 「抖M」技能动作
28class MasochistAction(UserAction):
29 # 在请求玩家输入后,不要自动将牌面告知其他玩家
30 no_reveal = True
31 # 卡牌的使用场景是「交给其他人」
32 card_usage = 'handover'
34 # 参数分别是动作目标(自己)和受到伤害的数量
35 def __init__(self, target, n):
36 self.source, self.target, self.amount = target, target, n
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:
54 return True
56 # 玩家选择给出的牌和目标玩家
57 _, rst = ask_for_action(self, [tgt], ('cards',), pl)
58 if not rst:
59 return True
61 cl, pl = rst
62 # 告知目标牌面
63 pl[0].player.reveal(cl)
64 # 转移卡牌
65 migrate_cards(cl, pl[0].cards)
66 n -= len(cl)
68 return True
70 # ask_for_action 函数用的条件,给出的牌必须是拿到的牌
71 def cond(self, cl):
72 cards = self.cards
73 return all(c in cards for c in cl)
75 # ask_for_action 函数用的条件,给出的牌必须是拿到的牌
76 def choose_player_target(self, tl):
77 if not tl:
78 return (tl, False)
80 return (tl[-1:], True)
83# 「抖M」技能的事件触发逻辑
84class MasochistHandler(THBEventHandler):
85 interested = ['action_after']
86 execute_after = [
87 'DyingHandler',
88 'AyaRoundfanHandler',
89 'NenshaPhoneHandler',
90 ]
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
101 # 选择是否发动
102 g = self.game
103 if not g.user_input([tgt], ChooseOptionInputlet(self, (False, True))):
104 return act
106 # 实际发动技能
107 g.process_action(MasochistAction(tgt, act.amount))
109 return act
112# 「绯想」技能,对应郭嘉「天妒」
113# 锁定技,距离1以内的角色的红色判定牌置入弃牌堆时,你获得之。
114class ScarletPerception(Skill):
115 distance = 1
116 associated_action = None
117 skill_category = ['character', 'passive', 'compulsory']
118 target = t_None()
121class ScarletPerceptionAction(GenericAction):
122 def __init__(self, source, target, card):
123 self.source = source
124 self.target = target
125 self.card = card
127 def apply_action(self):
128 migrate_cards([self.card], self.source.cards)
129 return True
132class ScarletPerceptionHandler(THBEventHandler):
133 interested = ['action_after']
135 def handle(self, evt_type, act):
136 # 在判定结束后
137 if evt_type == 'action_after' and isinstance(act, Fatetell):
138 tgt = act.target
140 # 如果牌的颜色是红色,而且没有在某个牌区内(不属于任何人,或者牌堆)
141 if act.card.color != Card.RED: return act
142 g = self.game
143 if not act.card.detached:
144 return act
146 # 此处只有被小爱的技能 drop 掉这一种情况,没发现其他的
147 if isinstance(act.card, ShreddedCard):
148 return act
150 # 寻找场内身负「绯想」技能的人
151 g = self.game
152 pl = [p for p in g.players if p.has_skill(ScarletPerception) and not p.dead]
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
163 return act
166# 「比那名居天子」人物
167@register_character_to('common')
168class Tenshi(Character):
169 # 人物技能
170 skills = [Masochist, ScarletPerception]
171 # 需要的事件处理器
172 eventhandlers = [MasochistHandler, ScarletPerceptionHandler]
173 # 最大体力
174 maxlife = 3