Coverage for thb/meta/cards/basic.py : 47%
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
4# -- stdlib --
5# -- third party --
6# -- own --
7from thb import actions
8from thb.actions import PlayerTurn, ttags
9from thb.cards import basic, base, definition
10from thb.meta.common import ui_meta
13# -- code --
14@ui_meta(base.DummyCard)
15class DummyCard:
16 pass
19@ui_meta(definition.AttackCard)
20class AttackCard:
21 # action_stage meta
22 image = 'thb-card-attack'
23 name = '弹幕'
24 description = (
25 '|R弹幕|r\n\n'
26 '出牌阶段,消耗1点干劲,对你攻击范围内的一名其他角色使用,对该角色造成1点伤害。\n'
27 '|B|R>> |r默认情况下,你的攻击范围是1。\n'
28 '|B|R>> |r干劲在出牌阶段开始时恢复成1点。\n'
29 '\n'
30 '|DB(画师:霏茶,CV:VV)|r'
31 )
33 def is_action_valid(self, c, tl):
34 if not tl:
35 return (False, '请选择弹幕的目标')
37 return (True, '来一发!')
39 def sound_effect(self, act):
40 if not isinstance(act, actions.ActionStageLaunchCard):
41 return 'thb-cv-card_attack1'
43 g = self.game
44 current = PlayerTurn.get_current(g).target
46 if act.source is not current:
47 return 'thb-cv-card_attack1'
49 ttags(current)['__attack_graze_count'] += 1
51 return [
52 'thb-cv-card_attack1',
53 'thb-cv-card_attack2',
54 'thb-cv-card_attack3',
55 'thb-cv-card_attack4',
56 ][ttags(current)['__attack_graze_count'] % 4 - 1]
59@ui_meta(definition.GrazeCard)
60class GrazeCard:
61 # action_stage meta
62 name = '擦弹'
63 image = 'thb-card-graze'
64 description = (
65 '|R擦弹|r\n\n'
66 '当你受到|G弹幕|r的攻击时,你可以使用一张|G擦弹|r来抵消|G弹幕|r的效果。\n'
67 '|B|R>> |r默认情况下,|G擦弹|r只能在回合外使用或打出。\n\n'
68 '|DB(画师:霏茶,CV:小羽)|r'
69 )
71 def is_action_valid(self, c, tl):
72 return (False, '你不能主动使用擦弹')
74 def effect_string(self, act):
75 return '|G【%s】|r使用了|G%s|r。' % (
76 act.source.ui_meta.name,
77 act.card.ui_meta.name
78 )
80 def sound_effect(self, act):
81 if not isinstance(act, actions.LaunchCard):
82 return 'thb-cv-card_graze1'
84 g = self.game
85 try:
86 current = PlayerTurn.get_current(g).target
87 except IndexError:
88 return 'thb-cv-card_graze1'
90 if act.source is not current:
91 return 'thb-cv-card_graze1'
93 cnt = ttags(current)['__attack_graze_count']
94 if not cnt:
95 return 'thb-cv-card_graze1'
97 return [
98 'thb-cv-card_graze1',
99 'thb-cv-card_graze2',
100 'thb-cv-card_graze3',
101 'thb-cv-card_graze4',
102 ][cnt % 4 - 1]
105@ui_meta(definition.WineCard)
106class WineCard:
107 # action_stage meta
108 name = '酒'
109 image = 'thb-card-wine'
110 description = (
111 '|R酒|r\n\n'
112 '出牌阶段,对自己使用。使用后获得|B喝醉|r状态。\n'
113 '|B喝醉|r状态下,使用【弹幕】造成的伤害+1,受到致命伤害时伤害-1。\n'
114 '|B|R>> |r 效果触发或者到了自己的准备阶段开始时须弃掉|B喝醉|r状态。\n'
115 '|B|R>> |r 你可以于喝醉状态下继续使用酒,但效果不叠加。\n\n'
116 '|DB(画师:霏茶,CV:shourei小N)|r'
117 )
119 def is_action_valid(self, c, tl):
120 me = self.me
121 if me.tags.get('wine', False):
122 return (True, '你已经醉了,还要再喝吗?')
123 return (True, '青岛啤酒,神主也爱喝!')
125 def sound_effect(self, act):
126 return 'thb-cv-card_wine'
129@ui_meta(basic.Wine)
130class Wine:
131 def effect_string(self, act):
132 return '|G【%s】|r喝醉了…' % act.target.ui_meta.name
135@ui_meta(basic.WineRevive)
136class WineRevive:
137 def effect_string(self, act):
138 return '|G【%s】|r醒酒了。' % act.target.ui_meta.name
141@ui_meta(definition.ExinwanCard)
142class ExinwanCard:
143 # action_stage meta
144 name = '恶心丸'
145 image = 'thb-card-exinwan'
146 description = (
147 '|R恶心丸|r\n'
148 '\n'
149 '出牌阶段,对自己使用。使用时没有额外效果。当此牌以任意的方式进入弃牌堆时,引发弃牌动作的角色需选择其中一项执行:\n'
150 '|B|R>> |r受到1点无来源伤害。\n'
151 '|B|R>> |r弃置两张牌。\n'
152 '\n'
153 '|B|R! |r 当你因为其他角色装备效果(如他人发动白楼剑特效)或技能效果(如正邪挑拨,秦心暗黑能乐)而将恶心丸主动置入弃牌堆时,恶心丸的弃置者视为该角色。\n'
154 '\n'
155 '|DB(画师:霏茶,CV:shourei小N)|r'
156 )
158 def is_action_valid(self, c, tl):
159 return (True, '哼,哼,哼哼……')
162@ui_meta(basic.ExinwanEffect)
163class ExinwanEffect:
164 # choose_card meta
165 def choose_card_text(self, act, cards):
166 if act.cond(cards):
167 return (True, '节操给你,离我远点!')
168 else:
169 return (False, '请选择两张牌(不选则受到一点无源伤害)')
171 def effect_string_before(self, act):
172 return '|G【%s】|r被恶心到了!' % act.target.ui_meta.name
174 def sound_effect(self, act):
175 return 'thb-cv-card_exinwan'
178@ui_meta(basic.UseGraze)
179class UseGraze:
180 # choose_card meta
182 def choose_card_text(self, act, cards):
183 if act.cond(cards):
184 return (True, '我闪!')
185 else:
186 return (False, '请打出一张【擦弹】…')
188 def effect_string(self, act):
189 if not act.succeeded: return None
190 t = act.target
191 return '|G【%s】|r打出了|G%s|r。' % (
192 t.ui_meta.name,
193 act.card.ui_meta.name,
194 )
197@ui_meta(basic.LaunchGraze)
198class LaunchGraze:
199 # choose_card meta
201 def choose_card_text(self, act, cards):
202 if act.cond(cards):
203 return (True, '我闪!')
204 else:
205 return (False, '请使用一张【擦弹】抵消【弹幕】效果…')
208@ui_meta(basic.UseAttack)
209class UseAttack:
210 # choose_card meta
211 def choose_card_text(self, act, cards):
212 if act.cond(cards):
213 return (True, '打架?来吧!')
214 else:
215 return (False, '请打出一张弹幕…')
217 def effect_string(self, act):
218 if not act.succeeded: return None
219 t = act.target
220 return '|G【%s】|r打出了|G%s|r。' % (
221 t.ui_meta.name,
222 act.card.ui_meta.name,
223 )
226@ui_meta(definition.HealCard)
227class HealCard:
228 # action_stage meta
229 image = 'thb-card-heal'
230 name = '麻薯'
231 description = (
232 '|R麻薯|r\n'
233 '\n'
234 '你可以在如下状况中使用,回复1点体力:\n'
235 '|B|R>> |r在你的出牌阶段且你的当前体力小于最大体力。\n'
236 '|B|R>> |r当有角色处于濒死状态时。\n'
237 '\n'
238 '|DB(画师:霏茶,CV:VV)|r'
239 )
241 def is_action_valid(self, c, tl):
242 target = tl[0]
244 if target.life >= target.maxlife:
245 return (False, '您已经吃饱了')
246 else:
247 return (True, '来一口,精神焕发!')
249 def sound_effect(self, act):
250 return 'thb-cv-card_heal'
253@ui_meta(basic.AskForHeal)
254class AskForHeal:
255 # choose_card meta
256 def choose_card_text(self, act, cards):
257 if act.cond(cards):
258 return (True, '神说,你不能在这里被击坠(对%s使用)' % act.source.ui_meta.name)
259 else:
260 return (False, '请选择一张【麻薯】(对%s使用)…' % act.source.ui_meta.name)
263@ui_meta(basic.Heal)
264class Heal:
265 def effect_string(self, act):
266 if act.succeeded:
267 return '|G【%s】|r回复了%d点体力。' % (
268 act.target.ui_meta.name, act.amount
269 )