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 ActionStage, Damage, DropCards, UserAction, migrate_cards 

7from thb.actions import random_choose_card 

8from thb.cards.base import Skill 

9from thb.cards.classes import Attack, BaseDuel, LaunchGraze, UseAttack, t_None 

10from thb.characters.base import Character, register_character_to 

11from thb.inputlets import ChooseIndividualCardInputlet 

12from thb.mode import THBEventHandler 

13from utils.misc import classmix 

14 

15 

16# -- code -- 

17class MijincihangzhanAttack(Attack): 

18 pass 

19 

20 

21class MijincihangzhanDuelMixin(object): 

22 # 迷津慈航斩 弹幕战 

23 def apply_action(self): 

24 g = self.game 

25 source = self.source 

26 target = self.target 

27 

28 d = (source, target) 

29 while True: 

30 d = (d[1], d[0]) 

31 if d[1].has_skill(Nitoryuu): 

32 if not ( 

33 g.process_action(UseAttack(d[0])) and 

34 g.process_action(UseAttack(d[0])) 

35 ): break 

36 else: 

37 if not g.process_action(UseAttack(d[0])): break 

38 

39 g.process_action(Damage(d[1], d[0], amount=1)) 

40 return d[1] is source 

41 

42 

43class NitoryuuWearEquipmentAction(UserAction): 

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

45 self.source = source 

46 self.target = target 

47 self.card = card 

48 

49 def apply_action(self): 

50 g = self.game 

51 card = self.card 

52 tgt = self.target 

53 g = self.game 

54 

55 weapons = [e for e in tgt.equips if e.equipment_category == 'weapon'] 

56 if len(weapons) > 1: 

57 e = g.user_input([tgt], ChooseIndividualCardInputlet(self, weapons)) 

58 e = e or random_choose_card(g, [weapons]) 

59 g.process_action(DropCards(tgt, tgt, [e])) 

60 

61 migrate_cards([card], tgt.equips) 

62 

63 return True 

64 

65 

66class NitoryuuWearEquipmentHandler(THBEventHandler): 

67 interested = ['wear_equipment'] 

68 

69 def handle(self, evt_type, arg): 

70 we, tgt, c, rst = arg 

71 if not evt_type == 'wear_equipment': return arg 

72 if not tgt.has_skill(Nitoryuu): return arg 

73 if 'equipment' not in c.category: return arg 

74 if c.equipment_category != 'weapon': return arg 

75 

76 g = self.game 

77 g.process_action(NitoryuuWearEquipmentAction(tgt, tgt, c)) 

78 return we, tgt, c, 'handled' 

79 

80 

81class YoumuHandler(THBEventHandler): 

82 interested = ['action_apply', 'action_before', 'attack_aftergraze', 'card_migration'] 

83 execute_before = ['ScarletRhapsodySwordHandler', 'LaevateinHandler', 'HouraiJewelHandler'] 

84 execute_after = ['VitalityHandler'] 

85 

86 def handle(self, evt_type, act): 

87 if evt_type == 'action_before': 

88 if isinstance(act, Attack): 

89 if not act.source.has_skill(Mijincihangzhan): return act 

90 act.__class__ = classmix(MijincihangzhanAttack, act.__class__) 

91 elif isinstance(act, BaseDuel): 

92 if not isinstance(act, MijincihangzhanDuelMixin): 

93 act.__class__ = classmix(MijincihangzhanDuelMixin, act.__class__) 

94 

95 elif evt_type == 'action_apply' and isinstance(act, ActionStage): 

96 p = act.target 

97 p.tags['vitality'] += bool(p.has_skill(Nitoryuu) and self.weapons(p) >= 2) 

98 

99 elif evt_type == 'card_migration': 

100 

101 act, cards, _from, to, _ = arg = act 

102 

103 for cl in (_from, to): 

104 if cl.type != 'equips': continue 

105 p = cl.owner 

106 if not p.has_skill(Nitoryuu): continue 

107 

108 n = self.weapons(p) 

109 dn = len(cards) 

110 if not any(getattr(c, 'equipment_category', None) == 'weapon' for c in cards): continue 

111 

112 if cl is _from and (dn + n) >= 2 and n <= 1: 

113 adjust = -1 

114 elif cl is to and (n - dn) <= 1 and n >= 2: 

115 adjust = 1 

116 else: 

117 adjust = 0 

118 

119 p.tags['vitality'] += adjust 

120 

121 return arg 

122 

123 elif evt_type == 'attack_aftergraze': 

124 act, rst = arg = act 

125 if rst: return arg 

126 if not isinstance(act, MijincihangzhanAttack): return arg 

127 

128 g = self.game 

129 return act, not g.process_action(LaunchGraze(act.target)) 

130 

131 return act 

132 

133 @staticmethod 

134 def weapons(p): 

135 return sum([c.equipment_category == 'weapon' for c in p.equips]) 

136 

137 

138class Mijincihangzhan(Skill): 

139 # 迷津慈航斩 

140 associated_action = None 

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

142 target = t_None() 

143 

144 

145class Nitoryuu(Skill): 

146 # 二刀流 

147 associated_action = None 

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

149 target = t_None() 

150 

151 def check(self): 

152 return not self.associated_cards 

153 

154 

155# @register_character_to('common') 

156class Youmu(Character): 

157 skills = [Mijincihangzhan, Nitoryuu] 

158 eventhandlers = [YoumuHandler, NitoryuuWearEquipmentHandler] 

159 maxlife = 4