# Coverage for thb/characters/mamizou.py : 38%

## 72 statements 31 run 41 missing 0 excluded 2 partial

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

6 from thb.actions import ActionLimitExceeded, ActionStageLaunchCard

7 from thb.cards.base import DummyCard, PhysicalCard, Skill

8 from thb.cards.classes import TreatAs

9 from thb.characters.base import Character, register_character_to

10 from thb.mode import THBEventHandler

11

12

13# -- code --

14 class Morphing(TreatAs, Skill):

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

16

17 @property

18 def treat_as(self):

19 return self.get_morph_cls() or DummyCard

20

21 def check(self):

22 cl = self.associated_cards

23

24 if not all(

25 c.resides_in is not None and

26 c.resides_in.type in ('cards', 'showncards')

27 for c in cl

28 ): return False

29

30 return self.is_morph_valid()

31

32 def is_morph_valid(self):

33 cls = self.get_morph_cls()

34 if not cls or 'delayed_spellcard' in cls.category:

35 return False

36

37 cl = self.associated_cards

38 cats = set(cl[0].category)

39 cats.update(cl[1].category)

40

41 if 'skill' in cats:

42 return False

43

44 if not cats & set(cls.category) & {'basic', 'spellcard'}:

45 return False

46

47 return True

48

49 def get_morph_cls(self):

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

51 return PhysicalCard.classes.get(params.get('mamizou_morphing'))

52

53 @classmethod

54 def list_morph_cards(cls, cl):

55 if len(cl) != 2:

56 return []

57

58 cats = set(cl[0].category)

59 cats.update(cl[1].category)

60 if 'skill' in cats:

61 return []

62

63 cats &= {'basic', 'spellcard'}

64

65 if not cats:

66 return []

67

68 if 'spellcard' in cats:

69 cats.discard('spellcard')

70 cats.add('instant_spellcard')

71

72 rst = [c() for c in PhysicalCard.classes.values() if set(c.category) & cats]

73

74 def rank(c):

75 cat = (set(c.category) & cats).pop()

76 if cat == 'basic':

77 return 1

78 elif cat == 'instant_spellcard':

79 return 2

80 else:

81 return 100

82

83 rst.sort(key=rank)

84 return rst

85

86

87 class MorphingHandler(THBEventHandler):

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

89

90 def handle(self, evt_type, act):

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

92 c = act.card

93 if c.is_card(Morphing): 93 ↛ 94 line 93 didn't jump to line 94, because the condition on line 93 was never true

94 src = act.source

95 src.tags['mamizou_morphing_tag'] = src.tags['turn_count']

96

97 elif evt_type == 'action_shootdown':

98 if isinstance(act, ActionStageLaunchCard):

99 c = act.card

100 if c.is_card(Morphing): 100 ↛ 101 line 100 didn't jump to line 101, because the condition on line 100 was never true

101 t = act.source.tags

102 if t['mamizou_morphing_tag'] >= t['turn_count']:

103 raise ActionLimitExceeded

104

105 return act

106

107

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

109 class Mamizou(Character):

110 skills = [Morphing]

111 eventhandlers = [MorphingHandler]

112 maxlife = 4