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 ActionLimitExceeded, ActionStageLaunchCard, DrawCards, Reforge, UserAction 

7from thb.actions import random_choose_card, ttags 

8from thb.cards.base import PhysicalCard, Skill, TreatAs, t_OtherOne 

9from thb.cards.definition import AttackCard 

10from thb.characters.base import Character, register_character_to 

11from thb.inputlets import ChoosePeerCardInputlet 

12from thb.mode import THBEventHandler 

13 

14 

15# -- code -- 

16class DismantleAction(UserAction): 

17 def apply_action(self): 

18 src, tgt = self.source, self.target 

19 ttags(src)['dismantle'] = True 

20 

21 g = self.game 

22 c = g.user_input([src], ChoosePeerCardInputlet(self, tgt, ('equips', ))) 

23 c = c or random_choose_card(g, [tgt.equips]) 

24 if not c: return False 24 ↛ exitline 24 didn't return from function 'apply_action', because the return on line 24 wasn't executed

25 

26 g.process_action(Reforge(src, tgt, c)) 

27 g.process_action(DrawCards(tgt, 1)) 

28 

29 return True 

30 

31 def is_valid(self): 

32 return not ttags(self.source)['dismantle'] and bool(self.target.equips) 

33 

34 

35class Dismantle(Skill): 

36 associated_action = DismantleAction 

37 skill_category = ['character', 'active'] 

38 target = t_OtherOne() 

39 

40 def check(self): 

41 return not self.associated_cards 

42 

43 

44class Craftsman(TreatAs, Skill): 

45 skill_category = ['character', 'active'] 

46 

47 @property 

48 def treat_as(self): 

49 params = getattr(self, 'action_params', {}) 

50 return PhysicalCard.classes.get(params.get('treat_as'), AttackCard) 

51 

52 def check(self): 

53 cl = self.associated_cards 

54 p = self.character 

55 

56 if 'basic' not in self.treat_as.category: 56 ↛ 57line 56 didn't jump to line 57, because the condition on line 56 was never true

57 return False 

58 

59 if not cl or set(cl) != (set(p.cards) | set(p.showncards)): 

60 return False 

61 

62 return True 

63 

64 @classmethod 

65 def list_treat_as(cls): 

66 return [c() for c in PhysicalCard.classes.values() if 'basic' in c.category] 

67 

68 

69class CraftsmanHandler(THBEventHandler): 

70 interested = ['action_after', 'action_shootdown'] 

71 

72 def handle(self, evt_type, act): 

73 if evt_type == 'action_after' and isinstance(act, ActionStageLaunchCard): 

74 c = act.card 

75 if c.is_card(Craftsman): 

76 src = act.source 

77 ttags(src)['craftsman'] = True 

78 

79 elif evt_type == 'action_shootdown': 

80 if not isinstance(act, ActionStageLaunchCard): return act 

81 c = act.card 

82 if not c.is_card(Craftsman): return act 

83 if ttags(act.source)['craftsman']: 83 ↛ 84line 83 didn't jump to line 84, because the condition on line 83 was never true

84 raise ActionLimitExceeded 

85 

86 return act 

87 

88 

89@register_character_to('common', '-kof') 

90class Nitori(Character): 

91 skills = [Dismantle, Craftsman] 

92 eventhandlers = [CraftsmanHandler] 

93 maxlife = 3