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

5from typing import Optional 

6import random 

7 

8# -- third party -- 

9# -- own -- 

10from thb import actions 

11from thb.actions import ttags 

12from thb.cards import definition, equipment 

13from thb.cards.base import Card 

14from thb.meta.common import ui_meta 

15from utils.misc import BatchList 

16 

17 

18# -- code -- 

19def equip_iav(self, c, tl): 

20 return (True, '配上好装备,不再掉节操!') 

21 

22 

23def suppress_launch_card_effect_string(self, act): 

24 return None 

25 

26 

27@ui_meta(equipment.WearEquipmentAction) 

28class WearEquipmentAction: 

29 

30 def effect_string(self, act): 

31 return '|G【%s】|r装备了%s。' % ( 

32 act.target.ui_meta.name, 

33 self.card_desc(act.associated_card), 

34 ) 

35 

36 

37@ui_meta(equipment.WeaponReforgeHandler) 

38class WeaponReforgeHandler: 

39 choose_option_prompt = '你希望重铸这张牌么?' 

40 choose_option_buttons = (('重铸', True), ('装备', False)) 

41 

42 

43@ui_meta(equipment.ReforgeWeapon) 

44class ReforgeWeapon: 

45 def effect_string(self, act): 

46 return '|G【%s】|r重铸了%s。' % ( 

47 act.target.ui_meta.name, 

48 self.card_desc(act.card), 

49 ) 

50 

51 

52@ui_meta(definition.OpticalCloakCard) 

53class OpticalCloakCard: 

54 # action_stage meta 

55 name = '光学迷彩' 

56 image = 'thb-card-opticalcloak' 

57 image_small = 'thb-card-small-opticalcloak' 

58 description = ( 

59 '|R光学迷彩|r\n\n' 

60 '装备后:当你需要使用或打出|G擦弹|r时,可以进行一次判定,若结果为红,视为你使用或打出了一张|G擦弹|r。\n\n' 

61 '|DB(画师:霏茶,CV:shourei小N)|r' 

62 ) 

63 

64 is_action_valid = equip_iav 

65 effect_string = suppress_launch_card_effect_string 

66 

67 

68@ui_meta(equipment.OpticalCloakSkill) 

69class OpticalCloakSkill: 

70 # Skill 

71 name = '光学迷彩' 

72 

73 def sound_effect(self, act): 

74 return 'thb-cv-card_opticalcloak' 

75 

76 def effect_string(self, act): 

77 return definition.GrazeCard.ui_meta.effect_string(act) 

78 

79 

80@ui_meta(equipment.OpticalCloakHandler) 

81class OpticalCloakHandler: 

82 # choose_option 

83 choose_option_buttons = (('发动', True), ('不发动', False)) 

84 choose_option_prompt = '你要发动【光学迷彩】吗?' 

85 

86 

87@ui_meta(equipment.OpticalCloak) 

88class OpticalCloak: 

89 fatetell_display_name = '光学迷彩' 

90 

91 def effect_string_before(self, act): 

92 return '|G【%s】|r祭起了|G光学迷彩|r…' % ( 

93 act.target.ui_meta.name, 

94 ) 

95 

96 def effect_string(self, act): 

97 if act.succeeded: 

98 return '效果拔群!' 

99 else: 

100 return '但是被看穿了…' 

101 

102 

103@ui_meta(definition.MomijiShieldCard) 

104class MomijiShieldCard: 

105 # action_stage meta 

106 name = '天狗盾' 

107 image = 'thb-card-momijishield' 

108 image_small = 'thb-card-small-momijishield' 

109 description = ( 

110 '|R天狗盾|r\n\n' 

111 '装备后:黑色|G弹幕|r对你无效。\n\n' 

112 '|DB(画师:霏茶)|r' 

113 ) 

114 

115 is_action_valid = equip_iav 

116 effect_string = suppress_launch_card_effect_string 

117 

118 

119@ui_meta(equipment.MomijiShieldSkill) 

120class MomijiShieldSkill: 

121 # Skill 

122 name = '天狗盾' 

123 

124 

125@ui_meta(equipment.MomijiShield) 

126class MomijiShield: 

127 def effect_string(self, act): 

128 return '被|G天狗盾|r挡下了…' 

129 

130 def sound_effect(self, act): 

131 return 'thb-cv-card_momijishield' 

132 

133 

134ufo_desc = ( 

135 '|R%s|r\n\n' 

136 'UFO用来改变自己与其他角色之间的距离。\n' 

137 '|B|R>> |r红色UFO为进攻用,当你计算和其他角色的距离时,在原有的基础上减少相应距离。两名角色之间的距离至少为1。\n' 

138 '|B|R>> |r绿色UFO为防守用,当其他角色计算和你的距离时,在原有的基础上增加相应距离。\n' 

139 '|B|R>> |r你可以同时装备两种UFO。\n\n' 

140 '|DB(画师:霏茶)|r' 

141) 

142 

143 

144@ui_meta(definition.GreenUFOCard) 

145class GreenUFOCard: 

146 # action_stage meta 

147 name = '绿色UFO' 

148 image = 'thb-card-greenufo' 

149 image_small = 'thb-card-small-greenufo' 

150 description = ufo_desc % name 

151 

152 is_action_valid = equip_iav 

153 effect_string = suppress_launch_card_effect_string 

154 

155 

156@ui_meta(equipment.GreenUFOSkill) 

157class GreenUFOSkill: 

158 # Skill 

159 name = '绿色UFO' 

160 no_display = True 

161 

162 

163@ui_meta(definition.RedUFOCard) 

164class RedUFOCard: 

165 # action_stage meta 

166 name = '红色UFO' 

167 image = 'thb-card-redufo' 

168 image_small = 'thb-card-small-redufo' 

169 description = ufo_desc % name 

170 

171 is_action_valid = equip_iav 

172 effect_string = suppress_launch_card_effect_string 

173 

174 

175@ui_meta(equipment.RedUFOSkill) 

176class RedUFOSkill: 

177 # Skill 

178 name = '红色UFO' 

179 no_display = True 

180 

181 

182@ui_meta(definition.RoukankenCard) 

183class RoukankenCard: 

184 # action_stage meta 

185 name = '楼观剑' 

186 image = 'thb-card-roukanken' 

187 image_small = 'thb-card-small-roukanken' 

188 description = ( 

189 '|R楼观剑|r\n' 

190 '\n' 

191 '攻击范围3,装备后:你使用的|G弹幕|r无视防具。\n' 

192 '\n' 

193 '|R出牌阶段你可以消耗1点干劲重铸手牌中的武器|r\n' 

194 '\n' 

195 '|DB(画师:霏茶)|r' 

196 ) 

197 is_action_valid = equip_iav 

198 effect_string = suppress_launch_card_effect_string 

199 

200 

201@ui_meta(equipment.RoukankenSkill) 

202class RoukankenSkill: 

203 # Skill 

204 name = '楼观剑' 

205 

206 

207@ui_meta(equipment.Roukanken) 

208class Roukanken: 

209 def effect_string_apply(self, act): 

210 return '没有什么防具是|G楼观剑|r斩不断的!' 

211 

212 def sound_effect(self, act): 

213 return 'thb-cv-card_roukanken' 

214 

215 

216@ui_meta(definition.ElementalReactorCard) 

217class ElementalReactorCard: 

218 # action_stage meta 

219 name = '八卦炉' 

220 image = 'thb-card-reactor' 

221 image_small = 'thb-card-small-reactor' 

222 description = ( 

223 '|R八卦炉|r\n' 

224 '\n' 

225 '攻击范围1,装备后:出牌阶段你使用|G弹幕|r时不消耗干劲。\n' 

226 '\n' 

227 '|R出牌阶段你可以消耗1点干劲重铸手牌中的武器|r\n' 

228 '\n' 

229 '|DB(画师:霏茶)|r' 

230 ) 

231 

232 is_action_valid = equip_iav 

233 effect_string = suppress_launch_card_effect_string 

234 

235 

236@ui_meta(equipment.ElementalReactorSkill) 

237class ElementalReactorSkill: 

238 # Skill 

239 name = '八卦炉' 

240 

241 

242@ui_meta(definition.UmbrellaCard) 

243class UmbrellaCard: 

244 # action_stage meta 

245 name = '阳伞' 

246 image = 'thb-card-umbrella' 

247 image_small = 'thb-card-small-umbrella' 

248 description = ( 

249 '|R阳伞|r\n\n' 

250 '装备后:符卡效果造成的伤害对你无效。\n\n' 

251 '|DB(画师:霏茶)|r' 

252 ) 

253 

254 is_action_valid = equip_iav 

255 effect_string = suppress_launch_card_effect_string 

256 

257 

258@ui_meta(equipment.UmbrellaSkill) 

259class UmbrellaSkill: 

260 # Skill 

261 name = '紫的阳伞' 

262 

263 

264@ui_meta(equipment.UmbrellaEffect) 

265class UmbrellaEffect: 

266 def effect_string_before(self, act): 

267 a = act.action 

268 dmg = act.damage_act 

269 card = getattr(a, 'associated_card', None) 

270 if card and card.associated_action and isinstance(a, card.associated_action): 

271 # Some skills changes action 

272 s = '|G%s|r' % card.ui_meta.name 

273 else: 

274 s = '' 

275 

276 return '|G【%s】|r受到的%s效果被|G阳伞|r挡下了…' % ( 

277 dmg.target.ui_meta.name, s, 

278 ) 

279 

280 def sound_effect(self, act): 

281 return 'thb-cv-card_umbrella' 

282 

283 

284@ui_meta(definition.GungnirCard) 

285class GungnirCard: 

286 # action_stage meta 

287 name = '冈格尼尔' 

288 image = 'thb-card-gungnir' 

289 image_small = 'thb-card-small-gungnir' 

290 description = ( 

291 '|R冈格尼尔|r\n' 

292 '\n' 

293 '攻击范围3,装备后:你可以将两张手牌当|G弹幕|r使用或打出。\n' 

294 '\n' 

295 '|R出牌阶段你可以消耗1点干劲重铸手牌中的武器|r\n' 

296 '\n' 

297 '|DB(画师:霏茶)|r' 

298 ) 

299 

300 is_action_valid = equip_iav 

301 effect_string = suppress_launch_card_effect_string 

302 

303 

304@ui_meta(equipment.GungnirSkill) 

305class GungnirSkill: 

306 # Skill 

307 name = '冈格尼尔' 

308 

309 def clickable(self): 

310 me = self.me 

311 return self.accept_cards([equipment.GungnirSkill(me)]) 

312 

313 def is_complete(self, skill): 

314 me = self.me 

315 assert skill.is_card(equipment.GungnirSkill) 

316 acards = skill.associated_cards 

317 if len(acards) != 2: 

318 return (False, '请选择2张手牌!') 

319 elif any(c.resides_in not in (me.cards, me.showncards) for c in acards): 

320 return (False, '只能使用手牌发动!') 

321 return (True, '反正这条也看不到,偷个懒~~~') 

322 

323 def is_action_valid(self, sk, tl): 

324 assert sk.is_card(equipment.GungnirSkill) 

325 rst, reason = self.is_complete(sk) 

326 if not rst: 

327 return (rst, reason) 

328 else: 

329 return definition.AttackCard().ui_meta.is_action_valid(sk, tl) 

330 

331 def effect_string(self, act): 

332 # for LaunchCard.effect_string 

333 source = act.source 

334 target = act.target 

335 s = '|G【%s】|r发动了|G冈格尼尔|r之枪,将两张牌当作|G弹幕|r对|G【%s】|r使用。' % ( 

336 source.ui_meta.name, 

337 target.ui_meta.name, 

338 ) 

339 return s 

340 

341 def sound_effect(self, act): 

342 return definition.AttackCard.ui_meta.sound_effect(act) 

343 

344 

345@ui_meta(definition.ScarletRhapsodyCard) 

346class ScarletRhapsodyCard: 

347 # action_stage meta 

348 name = '绯想之剑' 

349 image = 'thb-card-scarletrhapsodysword' 

350 image_small = 'thb-card-small-scarletrhapsodysword' 

351 description = ( 

352 '|R绯想之剑|r\n' 

353 '\n' 

354 '攻击范围4,装备后:当你使用的|G弹幕|r是你的最后一张手牌时,你可以为此|G弹幕|r指定至多三名目标。\n' 

355 '\n' 

356 '|R出牌阶段你可以消耗1点干劲重铸手牌中的武器|r\n' 

357 '\n' 

358 '|DB(画师:霏茶,CV:VV)|r' 

359 ) 

360 

361 is_action_valid = equip_iav 

362 effect_string = suppress_launch_card_effect_string 

363 

364 

365@ui_meta(equipment.ScarletRhapsodySkill) 

366class ScarletRhapsodySkill: 

367 # Skill 

368 name = '绯想之剑' 

369 

370 def clickable(self): 

371 g = self.game 

372 me = self.me 

373 try: 

374 act = g.action_stack[-1] 

375 if isinstance(act, actions.ActionStage): 

376 return act.target is me 

377 

378 except IndexError: 

379 pass 

380 

381 return False 

382 

383 def is_action_valid(self, sk, tl): 

384 assert sk.is_card(equipment.ScarletRhapsodySkill) 

385 if not sk.check(): 

386 return (False, '请选择你的最后一张【弹幕】!') 

387 else: 

388 if not tl: 

389 return (False, '请选择弹幕的目标(最多可以选择3名玩家)') 

390 

391 if self.me in tl: 

392 return (True, '您真的要自残么?!') 

393 else: 

394 return (True, '全人类的绯想天!') 

395 

396 def effect_string(self, act: actions.LaunchCard) -> Optional[str]: 

397 # for LaunchCard.ui_meta.effect_string 

398 src = act.source 

399 tl = BatchList(act.target_list) 

400 

401 return '全人类的绯想天,当然不能只打一个!于是|G【%s】|r选了|G【%s】|r一共%d个目标!' % ( 

402 src.ui_meta.name, 

403 '】|r、|G【'.join(tl.ui_meta.name), 

404 len(tl), 

405 ) 

406 

407 def sound_effect(self, act): 

408 return 'thb-cv-card_srs' 

409 

410 

411@ui_meta(definition.RepentanceStickCard) 

412class RepentanceStickCard: 

413 # action_stage meta 

414 name = '悔悟棒' 

415 image = 'thb-card-repentancestick' 

416 image_small = 'thb-card-small-repentancestick' 

417 description = ( 

418 '|R悔悟棒|r\n' 

419 '\n' 

420 '攻击范围2,装备后:当你使用|G弹幕|r造成伤害时,你可以防止此伤害,改为依次弃置目标角色区域内的两张牌。\n' 

421 '|B|R>> |r 区域内的牌包括手牌,装备区的牌和判定区的牌。\n' 

422 '\n' 

423 '|R出牌阶段你可以消耗1点干劲重铸手牌中的武器|r\n' 

424 '\n' 

425 '|DB(画师:霏茶,CV:shourei小N)|r' 

426 ) 

427 

428 is_action_valid = equip_iav 

429 effect_string = suppress_launch_card_effect_string 

430 

431 

432@ui_meta(equipment.RepentanceStickSkill) 

433class RepentanceStickSkill: 

434 # Skill 

435 name = '悔悟棒' 

436 

437 

438@ui_meta(equipment.RepentanceStickHandler) 

439class RepentanceStickHandler: 

440 # choose_option 

441 choose_option_buttons = (('发动', True), ('不发动', False)) 

442 choose_option_prompt = '你要发动【悔悟棒】吗?' 

443 

444 

445@ui_meta(equipment.RepentanceStick) 

446class RepentanceStick: 

447 def effect_string_before(self, act): 

448 return ( 

449 '|G【%s】|r用|G悔悟棒|r狠狠地敲了|G【%s】|r一通…' 

450 ) % ( 

451 act.source.ui_meta.name, 

452 act.target.ui_meta.name, 

453 

454 ) 

455 

456 def effect_string(self, act: equipment.RepentanceStick) -> str: 

457 cl = BatchList[Card](act.cards) 

458 return '又抢过|G【%s】|r的|G%s|r扔了出去!' % ( 

459 act.target.ui_meta.name, 

460 '|r和|G'.join(cl.ui_meta.name) 

461 ) 

462 

463 def sound_effect(self, act): 

464 return 'thb-cv-card_repentancestick' 

465 

466 

467@ui_meta(definition.IbukiGourdCard) 

468class IbukiGourdCard: 

469 # action_stage meta 

470 name = '伊吹瓢' 

471 image = 'thb-card-ibukigourd' 

472 image_small = 'thb-card-small-ibukigourd' 

473 is_action_valid = equip_iav 

474 effect_string = suppress_launch_card_effect_string 

475 

476 description = ( 

477 '|R伊吹瓢|r\n\n' 

478 '装备后:获得立即|B喝醉|r状态。并且,若你在出牌阶段没有造成过伤害,在回合结束阶段获得|B喝醉|r状态。\n\n' 

479 '|DB(画师:霏茶)|r' 

480 ) 

481 

482 

483@ui_meta(equipment.IbukiGourdSkill) 

484class IbukiGourdSkill: 

485 # Skill 

486 name = '伊吹瓢' 

487 

488 

489@ui_meta(definition.HouraiJewelCard) 

490class HouraiJewelCard: 

491 # action_stage meta 

492 name = '蓬莱玉枝' 

493 image = 'thb-card-houraijewel' 

494 image_small = 'thb-card-small-houraijewel' 

495 description = ( 

496 '|R蓬莱玉枝|r\n' 

497 '\n' 

498 '攻击范围1。装备后,你使用的|G弹幕|r时,可以将弹幕的效果转化成如下的符卡效果:造成1点伤害。\n' 

499 '\n' 

500 '|R出牌阶段你可以消耗1点干劲重铸手牌中的武器|r\n' 

501 '\n' 

502 '|DB(画师:霏茶)|r' 

503 ) 

504 

505 is_action_valid = equip_iav 

506 effect_string = suppress_launch_card_effect_string 

507 

508 

509@ui_meta(equipment.HouraiJewelSkill) 

510class HouraiJewelSkill: 

511 # Skill 

512 name = '蓬莱玉枝' 

513 

514 

515@ui_meta(equipment.HouraiJewelHandler) 

516class HouraiJewelHandler: 

517 # choose_option 

518 choose_option_buttons = (('发动', True), ('不发动', False)) 

519 choose_option_prompt = '你要发动【蓬莱玉枝】吗?' 

520 

521 

522@ui_meta(equipment.HouraiJewelAttack) 

523class HouraiJewelAttack: 

524 def effect_string_apply(self, act): 

525 return ( 

526 '|G【%s】|r发动了|G蓬莱玉枝|r,包裹着魔法核心的弹幕冲向了|G【%s】|r!' 

527 ) % ( 

528 act.source.ui_meta.name, 

529 act.target.ui_meta.name, 

530 ) 

531 

532 

533@ui_meta(definition.MaidenCostumeCard) 

534class MaidenCostumeCard: 

535 # action_stage meta 

536 name = '巫女服' 

537 image = 'thb-card-maidencostume' 

538 image_small = 'thb-card-small-maidencostume' 

539 description = ( 

540 '|R巫女服|r\n\n' 

541 '装备后:当你成为一张符卡的目标时,你可以进行一次判定:若判定牌点数为9到K,则视为你使用了一张|G好人卡|r。\n\n' 

542 '|DB(画师:霏茶,CV:VV)|r' 

543 ) 

544 is_action_valid = equip_iav 

545 effect_string = suppress_launch_card_effect_string 

546 

547 

548@ui_meta(equipment.MaidenCostume) 

549class MaidenCostume: 

550 # Skill 

551 name = '巫女服' 

552 

553 def sound_effect(self, act): 

554 return 'thb-cv-card_maidencostume' 

555 

556 

557@ui_meta(equipment.MaidenCostumeHandler) 

558class MaidenCostumeHandler: 

559 # choose_option 

560 choose_option_buttons = (('发动', True), ('不发动', False)) 

561 choose_option_prompt = '你要发动【巫女服】吗?' 

562 

563 

564@ui_meta(equipment.MaidenCostumeAction) 

565class MaidenCostumeAction: 

566 fatetell_display_name = '巫女服' 

567 

568 def effect_string_before(self, act): 

569 return ( 

570 '|G【%s】|r穿了|G巫女服|r,春度爆表,不怕符卡!' 

571 ) % ( 

572 act.source.ui_meta.name, 

573 ) 

574 

575 def effect_string(self, act): 

576 if not act.succeeded: 

577 return ( 

578 '好像|G【%s】|r的春度还是不够用…' 

579 ) % ( 

580 act.source.ui_meta.name, 

581 ) 

582 

583 

584@ui_meta(definition.HakuroukenCard) 

585class HakuroukenCard: 

586 # action_stage meta 

587 name = '白楼剑' 

588 image = 'thb-card-hakurouken' 

589 image_small = 'thb-card-small-hakurouken' 

590 description = ( 

591 '|R白楼剑|r\n\n' 

592 '攻击范围2,装备后:当你使用的草花色|G弹幕|r指定一名目标角色后,你可以令其选择一项:\n' 

593 '|B|R>> |r弃置一张手牌。\n' 

594 '|B|R>> |r令你摸一张牌。\n' 

595 '\n' 

596 '|R出牌阶段你可以消耗1点干劲重铸手牌中的武器|r\n' 

597 '\n' 

598 '|DB(画师:霏茶,CV:小羽)|r' 

599 ) 

600 is_action_valid = equip_iav 

601 effect_string = suppress_launch_card_effect_string 

602 

603 

604@ui_meta(equipment.HakuroukenSkill) 

605class HakuroukenSkill: 

606 # Skill 

607 name = '白楼剑' 

608 

609 

610@ui_meta(equipment.Hakurouken) 

611class Hakurouken: 

612 # choose_card 

613 def choose_card_text(self, act, cards): 

614 if act.cond(cards): 

615 return (True, '弃置这张牌') 

616 else: 

617 return (False, '请弃掉一张牌(否则对方摸一张牌)') 

618 

619 def effect_string_before(self, act): 

620 return ( 

621 '|G【%s】|r祭起了|G白楼剑|r,试图斩断|G【%s】|r的迷惘!' 

622 ) % ( 

623 act.source.ui_meta.name, 

624 act.target.ui_meta.name, 

625 ) 

626 

627 def effect_string(self, act): 

628 if act.peer_action == 'drop': 

629 return '|G【%s】|r弃置了一张牌。' % act.target.ui_meta.name 

630 else: 

631 return None # DrawCards has it's own prompt 

632 

633 def sound_effect(self, act): 

634 return 'thb-cv-card_hakurouken' 

635 

636 

637@ui_meta(equipment.HakuroukenHandler) 

638class HakuroukenHandler: 

639 # choose_option 

640 choose_option_buttons = (('发动', True), ('不发动', False)) 

641 choose_option_prompt = '你要发动【白楼剑】吗?' 

642 

643 

644@ui_meta(definition.AyaRoundfanCard) 

645class AyaRoundfanCard: 

646 # action_stage meta 

647 name = '团扇' 

648 image = 'thb-card-ayaroundfan' 

649 image_small = 'thb-card-small-ayaroundfan' 

650 description = ( 

651 '|R团扇|r\n' 

652 '\n' 

653 '攻击距离5,装备后:当你使用的|G弹幕|r对目标角色造成伤害后,你可以弃置一张手牌,然后弃置其装备区里的一张牌。\n' 

654 '\n' 

655 '|R出牌阶段你可以消耗1点干劲重铸手牌中的武器|r\n' 

656 '\n' 

657 '|DB(画师:霏茶,CV:VV)|r' 

658 ) 

659 is_action_valid = equip_iav 

660 effect_string = suppress_launch_card_effect_string 

661 

662 

663@ui_meta(equipment.AyaRoundfanSkill) 

664class AyaRoundfanSkill: 

665 # Skill 

666 name = '团扇' 

667 

668 

669@ui_meta(equipment.AyaRoundfanHandler) 

670class AyaRoundfanHandler: 

671 # choose_card 

672 def choose_card_text(self, act, cards): 

673 if act.cond(cards): 

674 return (True, '这种妨碍拍摄的东西,统统脱掉!') 

675 else: 

676 return (False, '请弃掉一张手牌发动团扇(否则不发动)') 

677 

678 

679@ui_meta(equipment.AyaRoundfan) 

680class AyaRoundfan: 

681 def effect_string_before(self, act): 

682 return ( 

683 '|G【%s】|r觉得手中的|G团扇|r用起来好顺手,便加大力度试了试…' 

684 ) % ( 

685 act.source.ui_meta.name, 

686 ) 

687 

688 def effect_string(self, act): 

689 return ( 

690 '于是|G【%s】|r的|G%s|r就飞了出去!' 

691 ) % ( 

692 act.target.ui_meta.name, 

693 act.card.ui_meta.name, 

694 ) 

695 

696 def sound_effect(self, act): 

697 return random.choice([ 

698 'thb-cv-card_roundfan1', 

699 'thb-cv-card_roundfan2', 

700 ]) 

701 

702 

703@ui_meta(definition.NenshaPhoneCard) 

704class NenshaPhoneCard: 

705 # action_stage meta 

706 name = '念写机' 

707 image = 'thb-card-nenshaphone' 

708 image_small = 'thb-card-small-nenshaphone' 

709 description = ( 

710 '|R念写机|r\n' 

711 '\n' 

712 '攻击距离4,装备后:当你使用的|G弹幕|r对目标角色造成伤害后,可以将其两张手牌置入明牌区。\n' 

713 '\n' 

714 '|R出牌阶段你可以消耗1点干劲重铸手牌中的武器|r\n' 

715 '\n' 

716 '|DB(画师:霏茶)|r' 

717 

718 ) 

719 is_action_valid = equip_iav 

720 effect_string = suppress_launch_card_effect_string 

721 

722 

723@ui_meta(equipment.NenshaPhoneSkill) 

724class NenshaPhoneSkill: 

725 # Skill 

726 name = '念写机' 

727 

728 

729@ui_meta(equipment.NenshaPhoneHandler) 

730class NenshaPhoneHandler: 

731 # choose_option 

732 choose_option_buttons = (('发动', True), ('不发动', False)) 

733 choose_option_prompt = '你要发动【念写机】吗?' 

734 

735 

736@ui_meta(equipment.NenshaPhone) 

737class NenshaPhone: 

738 def effect_string(self, act): 

739 return ( 

740 '|G【%s】|r表示,将|G【%s】|r推倒后拍摄胖次,是记者的自我修养中不可或缺的一部分。' 

741 ) % ( 

742 act.source.ui_meta.name, 

743 act.target.ui_meta.name, 

744 ) 

745 

746 def sound_effect(self, act): 

747 return 'thb-cv-card_nenshaphone' 

748 

749 

750@ui_meta(definition.LaevateinCard) 

751class LaevateinCard: 

752 # action_stage meta 

753 name = '莱瓦汀' 

754 image = 'thb-card-laevatein' 

755 image_small = 'thb-card-small-laevatein' 

756 description = ( 

757 '|R莱瓦汀|r\n' 

758 '\n' 

759 '攻击距离3,装备后:当你使用的|G弹幕|r被目标角色使用的|G擦弹|r抵消时,你可以弃置两张牌,令此|G弹幕|r依然生效。\n' 

760 '\n' 

761 '|R出牌阶段你可以消耗1点干劲重铸手牌中的武器|r\n' 

762 '\n' 

763 '|DB(画师:霏茶,CV:VV)|r' 

764 ) 

765 is_action_valid = equip_iav 

766 effect_string = suppress_launch_card_effect_string 

767 

768 

769@ui_meta(equipment.LaevateinSkill) 

770class LaevateinSkill: 

771 # Skill 

772 name = '莱瓦汀' 

773 

774 

775@ui_meta(equipment.LaevateinHandler) 

776class LaevateinHandler: 

777 # choose_card 

778 def choose_card_text(self, act, cards): 

779 if act.cond(cards): 

780 return (True, '灭世之炎岂能轻易闪过!') 

781 else: 

782 return (False, '请弃掉两张牌发动莱瓦汀(否则不发动)') 

783 

784 

785@ui_meta(equipment.Laevatein) 

786class Laevatein: 

787 def effect_string_before(self, act): 

788 return '|G莱瓦汀|r的灭世之炎岂能轻易闪过!' 

789 

790 def sound_effect(self, act): 

791 return 'thb-cv-card_laevatein' 

792 

793 

794@ui_meta(definition.DeathSickleCard) 

795class DeathSickleCard: 

796 # action_stage meta 

797 name = '死神之镰' 

798 image = 'thb-card-deathsickle' 

799 image_small = 'thb-card-small-deathsickle' 

800 description = ( 

801 '|R死神之镰|r\n' 

802 '\n' 

803 '攻击范围2,装备后:当你使用的【弹幕】对目标角色造成伤害时,若其没有手牌,此伤害+1。\n' 

804 '\n' 

805 '|R出牌阶段你可以消耗1点干劲重铸手牌中的武器|r\n' 

806 '\n' 

807 '|DB(画师:霏茶,CV:小羽)|r' 

808 ) 

809 is_action_valid = equip_iav 

810 effect_string = suppress_launch_card_effect_string 

811 

812 

813@ui_meta(equipment.DeathSickleSkill) 

814class DeathSickleSkill: 

815 # Skill 

816 name = '死神之镰' 

817 

818 

819@ui_meta(equipment.DeathSickle) 

820class DeathSickle: 

821 def effect_string(self, act): 

822 return ( 

823 '|G【%s】|r看到|G【%s】|r一副丧家犬的模样,' 

824 '手中的|G死神之镰|r不自觉地一狠…' 

825 ) % ( 

826 act.source.ui_meta.name, 

827 act.target.ui_meta.name, 

828 ) 

829 

830 def sound_effect(self, act): 

831 return 'thb-cv-card_deathsickle' 

832 

833 

834@ui_meta(definition.KeystoneCard) 

835class KeystoneCard: 

836 # action_stage meta 

837 name = '要石' 

838 image = 'thb-card-keystone' 

839 image_small = 'thb-card-small-keystone' 

840 description = ( 

841 '|R要石|r\n\n' 

842 '特殊的绿色UFO装备,距离+1\n' 

843 '装备后跳过【罪袋】对你的结算。\n\n' 

844 '|DB(画师:霏茶,CV:shourei小N)|r' 

845 ) 

846 is_action_valid = equip_iav 

847 effect_string = suppress_launch_card_effect_string 

848 

849 

850@ui_meta(equipment.KeystoneSkill) 

851class KeystoneSkill: 

852 # Skill 

853 name = '要石' 

854 

855 

856@ui_meta(equipment.Keystone) 

857class Keystone: 

858 def effect_string(self, act): 

859 return '|G【%s】|r站在|G要石|r上,照着|G罪袋|r的脸一脚踹了下去!' % ( 

860 act.target.ui_meta.name 

861 ) 

862 

863 def sound_effect(self, act): 

864 return 'thb-cv-card_keystone' 

865 

866 

867@ui_meta(definition.WitchBroomCard) 

868class WitchBroomCard: 

869 # action_stage meta 

870 name = '魔女扫把' 

871 image = 'thb-card-witchbroom' 

872 image_small = 'thb-card-small-witchbroom' 

873 is_action_valid = equip_iav 

874 effect_string = suppress_launch_card_effect_string 

875 description = ( 

876 '|R魔女扫把|r\n\n' 

877 '特殊的红色UFO装备,距离-2。\n\n' 

878 '|DB(画师:霏茶)|r' 

879 ) 

880 

881 

882@ui_meta(equipment.WitchBroomSkill) 

883class WitchBroomSkill: 

884 # Skill 

885 no_display = True 

886 

887 

888@ui_meta(definition.YinYangOrbCard) 

889class YinYangOrbCard: 

890 # action_stage meta 

891 name = '阴阳玉' 

892 image = 'thb-card-yinyangorb' 

893 image_small = 'thb-card-small-yinyangorb' 

894 description = ( 

895 '|R阴阳玉|r\n\n' 

896 '装备后:在你的判定牌生效前,你可以用装备区内的|G阴阳玉|r替换之。\n\n' 

897 '|DB(画师:霏茶)|r' 

898 ) 

899 is_action_valid = equip_iav 

900 effect_string = suppress_launch_card_effect_string 

901 

902 

903@ui_meta(equipment.YinYangOrbSkill) 

904class YinYangOrbSkill: 

905 # Skill 

906 name = '阴阳玉' 

907 

908 

909@ui_meta(equipment.YinYangOrbHandler) 

910class YinYangOrbHandler: 

911 # choose_option 

912 choose_option_buttons = (('替换', True), ('不替换', False)) 

913 choose_option_prompt = '你要使用【阴阳玉】替换当前的判定牌吗?' 

914 

915 

916@ui_meta(equipment.YinYangOrb) 

917class YinYangOrb: 

918 def effect_string(self, act): 

919 return '|G【%s】|r用|G%s|r替换了她的判定牌。' % ( 

920 act.target.ui_meta.name, 

921 self.card_desc(act.card), 

922 ) 

923 

924 

925@ui_meta(definition.SuwakoHatCard) 

926class SuwakoHatCard: 

927 # action_stage meta 

928 name = '青蛙帽' 

929 image = 'thb-card-suwakohat' 

930 image_small = 'thb-card-small-suwakohat' 

931 description = ( 

932 '|R青蛙帽|r\n\n' 

933 '装备后:手牌上限+2。\n\n' 

934 '|DB(画师:霏茶,CV:VV)|r' 

935 ) 

936 is_action_valid = equip_iav 

937 effect_string = suppress_launch_card_effect_string 

938 

939 

940@ui_meta(equipment.SuwakoHatSkill) 

941class SuwakoHatSkill: 

942 # Skill 

943 name = '青蛙帽' 

944 

945 

946@ui_meta(equipment.SuwakoHatEffect) 

947class SuwakoHatEffect: 

948 def sound_effect(self, act): 

949 return 'thb-cv-card_suwakohat' 

950 

951 

952@ui_meta(definition.YoumuPhantomCard) 

953class YoumuPhantomCard: 

954 # action_stage meta 

955 name = '半灵' 

956 image = 'thb-card-phantom' 

957 image_small = 'thb-card-small-phantom' 

958 description = ( 

959 '|R半灵|r\n\n' 

960 '装备后:增加1点体力上限,当失去装备区里的【半灵】时,你回复1点体力。\n\n' 

961 '|DB(画师:霏茶,CV:小羽)|r' 

962 ) 

963 

964 is_action_valid = equip_iav 

965 effect_string = suppress_launch_card_effect_string 

966 

967 

968@ui_meta(equipment.YoumuPhantomSkill) 

969class YoumuPhantomSkill: 

970 # Skill 

971 name = '半灵' 

972 

973 

974@ui_meta(equipment.YoumuPhantomHeal) 

975class YoumuPhantomHeal: 

976 def sound_effect(self, act): 

977 return 'thb-cv-card_phantom' 

978 

979 

980@ui_meta(definition.IceWingCard) 

981class IceWingCard: 

982 # action_stage meta 

983 name = '⑨的翅膀' 

984 image = 'thb-card-icewing' 

985 image_small = 'thb-card-small-icewing' 

986 description = ( 

987 '|R⑨的翅膀|r\n\n' 

988 '特殊的红色UFO装备,距离-1。\n\n' 

989 '装备后:|G封魔阵|r和|G冻青蛙|r对你无效。\n\n' 

990 '|DB(画师:霏茶,CV:VV)|r' 

991 ) 

992 

993 is_action_valid = equip_iav 

994 effect_string = suppress_launch_card_effect_string 

995 

996 

997@ui_meta(equipment.IceWingSkill) 

998class IceWingSkill: 

999 # Skill 

1000 name = '⑨的翅膀' 

1001 

1002 

1003@ui_meta(equipment.IceWing) 

1004class IceWing: 

1005 def effect_string(self, act): 

1006 return '|G【%s】|r借着|G⑨的翅膀|r飞了出来,|G%s|r没起到什么作用。' % ( 

1007 act.target.ui_meta.name, 

1008 act.action.associated_card.ui_meta.name, 

1009 ) 

1010 

1011 def sound_effect(self, act): 

1012 tgt = act.target 

1013 if ttags(tgt)['__icewing_se']: 

1014 return None 

1015 

1016 ttags(tgt)['__icewing_se'] = True 

1017 return 'thb-cv-card_icewing' 

1018 

1019 

1020@ui_meta(definition.GrimoireCard) 

1021class GrimoireCard: 

1022 # action_stage meta 

1023 name = '魔导书' 

1024 image = 'thb-card-grimoire' 

1025 image_small = 'thb-card-small-grimoire' 

1026 description = ( 

1027 '|R魔导书|r\n' 

1028 '\n' 

1029 '攻击距离1,装备后,你可以消耗一点干劲并将一张牌按照以下规则使用:\n' 

1030 '|B|R>> |r黑桃♠视为|G百鬼夜行|r。\n' 

1031 '|B|R>> |r红桃♥视为|G宴会|r。\n' 

1032 '|B|R>> |r梅花♣视为|G地图炮|r。\n' 

1033 '|B|R>> |r方片♦视为|G五谷丰登|r。\n' 

1034 '\n' 

1035 '|R出牌阶段你可以消耗1点干劲重铸手牌中的武器|r\n' 

1036 '\n' 

1037 '|DB(画师:霏茶,CV:shourei小N)|r' 

1038 ) 

1039 is_action_valid = equip_iav 

1040 effect_string = suppress_launch_card_effect_string 

1041 

1042 

1043@ui_meta(equipment.GrimoireSkill) 

1044class GrimoireSkill: 

1045 # Skill 

1046 name = '魔导书' 

1047 

1048 def clickable(self): 

1049 g = self.game 

1050 me = self.me 

1051 t = me.tags 

1052 if t['grimoire_tag'] >= t['turn_count']: 

1053 return False 

1054 

1055 try: 

1056 act = g.action_stack[-1] 

1057 if isinstance(act, actions.ActionStage): 

1058 if me.tags['freeattack'] >= me.tags['turn_count']: 

1059 return True 

1060 

1061 if me.tags['vitality'] > 0: 

1062 return True 

1063 

1064 if me.has_skill(equipment.ElementalReactorSkill): 

1065 return True 

1066 

1067 except IndexError: 

1068 pass 

1069 

1070 return False 

1071 

1072 def is_action_valid(self, sk, tl): 

1073 assert sk.is_card(equipment.GrimoireSkill) 

1074 acards = sk.associated_cards 

1075 if not (len(acards)) == 1: 

1076 return (False, '请选择一张牌') 

1077 else: 

1078 s = sk.lookup_tbl[acards[0].suit].ui_meta.name 

1079 return (True, '发动【%s】' % s) 

1080 

1081 def effect_string(self, act): 

1082 # for LaunchCard.ui_meta.effect_string 

1083 source = act.source 

1084 card = act.card 

1085 return ( 

1086 '|G【%s】|r抓起一张牌放入|G魔导书|r' + 

1087 ',念动咒语,发动了|G%s|r。' 

1088 ) % ( 

1089 source.ui_meta.name, 

1090 card.lookup_tbl[card.associated_cards[0].suit].ui_meta.name 

1091 ) 

1092 

1093 def sound_effect(self, act): 

1094 return 'thb-cv-card_grimoire' 

1095 

1096 

1097@ui_meta(equipment.SinsackHatAction) 

1098class SinsackHatAction: 

1099 fatetell_display_name = '头套' 

1100 

1101 def effect_string_before(self, act): 

1102 return '看着戴着|G头套|r的|G【%s】|r,真正的的罪袋们都兴奋了起来!' % ( 

1103 act.target.ui_meta.name, 

1104 ) 

1105 

1106 

1107@ui_meta(equipment.SinsackHat) 

1108class SinsackHat: 

1109 # Skill 

1110 name = '头套' 

1111 

1112 

1113@ui_meta(definition.SinsackHatCard) 

1114class SinsackHatCard: 

1115 # action_stage meta 

1116 name = '头套' 

1117 image = 'thb-card-sinsackhat' 

1118 image_small = 'thb-card-small-sinsackhat' 

1119 description = ( 

1120 '|R罪袋的头套|r\n\n' 

1121 '对距离2以内的一名角色使用。\n' 

1122 '装备|G罪袋的头套|r的角色需在判定阶段后进行一次判定,若为黑桃1-8,则目标角色受到2点伤害,并且将|G罪袋的头套|r收入手牌。\n' 

1123 '|DB(画师:霏茶,CV:大白)|r' 

1124 ) 

1125 

1126 def is_action_valid(self, c, tl): 

1127 if not tl: 

1128 return (False, '请选择目标') 

1129 t = tl[0] 

1130 if self.me is t: 

1131 return (True, '真的要自己戴上吗?') 

1132 return (True, '是这样的,这个不是胖次……不不,真的没有胖次') 

1133 

1134 effect_string = suppress_launch_card_effect_string