# Coverage for thb/characters/yugi.py : 96%

## 89 statements 88 run 1 missing 0 excluded 4 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 from __future__ import annotations

3

4# -- stdlib --

5# -- third party --

6# -- own --

7 from thb.actions import Damage, DropCards, FatetellAction, LaunchCard, random_choose_card

8 from thb.cards.base import Card, Skill, VirtualCard

9 from thb.cards.classes import AttackCard, BaseAttack, InevitableAttack, RedUFOSkill, TreatAs, t_None

10 from thb.characters.base import Character, register_character_to

11 from thb.inputlets import ChooseOptionInputlet, ChoosePeerCardInputlet

12 from thb.mode import THBEventHandler

13 from utils.misc import classmix

14

15

16# -- code --

17 class Assault(RedUFOSkill):

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

19 increment = 1

20

21

22 class AssaultKOF(Skill):

23 associated_action = None

24 skill_category = ['character', 'passive']

25 target = t_None()

26

27

28 class AssaultAttack(TreatAs, VirtualCard):

29 treat_as = AttackCard

30

31

32 class AssaultKOFHandler(THBEventHandler):

33 interested = ['character_debut']

34

35 def handle(self, evt_type, arg):

36 if evt_type == 'character_debut': 36 ↛ 50 line 36 didn't jump to line 50, because the condition on line 36 was never false

37 old, new = arg

38 if not new.has_skill(AssaultKOF):

39 return arg

40

41 g = self.game

42 op = g.get_opponent(new)

43 lc = LaunchCard(new, [op], AssaultAttack(new))

44 if not lc.can_fire(): 44 ↛ 45 line 44 didn't jump to line 45, because the condition on line 44 was never true

45 return arg

46

47 if g.user_input([new], ChooseOptionInputlet(self, (False, True))):

48 g.process_action(lc)

49

50 return arg

51

52

53 class FreakingPower(Skill):

54 associated_action = None

55 skill_category = ['character', 'passive']

56 target = t_None()

57

58

59 class FreakingPowerAction(FatetellAction):

60 def __init__(self, atkact):

61 self.atkact = atkact

62 self.source = atkact.source

63 self.target = atkact.target

64 self.fatetell_target = atkact.source

65

66 def fatetell_action(self, ft):

67 act = self.atkact

68 if ft.succeeded:

69 act.__class__ = classmix(InevitableAttack, act.__class__)

70 else:

71 act._['freaking_power'] = True

72

73 return True

74

75 @staticmethod

76 def fatetell_cond(c):

77 return c.color == Card.RED

78

79

80 class FreakingPowerHandler(THBEventHandler):

81 interested = ('action_after', 'action_before', )

82 execute_before = ('AyaRoundfanHandler',)

83

84 def handle(self, evt_type, act):

85 if evt_type == 'action_before' and isinstance(act, BaseAttack) and not act._['freaking_power']:

86 src = act.source

87 g = self.game

88 if not src.has_skill(FreakingPower): return act

89 if not g.user_input([src], ChooseOptionInputlet(self, (False, True))):

90 return act

91 tgt = act.target

92 g.process_action(FreakingPowerAction(act))

93

94 elif evt_type == 'action_after' and isinstance(act, Damage):

95 g = self.game

96

97 if act.cancelled: return act 97 ↛ exit line 97 didn't return from function 'handle', because the return on line 97 wasn't executed

98

99 pact = g.action_stack[-1]

100 if not pact._['freaking_power']:

101 return act

102

103 src, tgt = pact.source, act.target

104 if tgt.dead: return act

105

106 if not (tgt.cards or tgt.showncards or tgt.equips):

107 return act

108

109 catnames = ('cards', 'showncards', 'equips')

110 card = g.user_input([src], ChoosePeerCardInputlet(self, tgt, catnames))

111 card = card or random_choose_card(g, [tgt.cards, tgt.showncards, tgt.equips])

112 if card: 112 ↛ 116 line 112 didn't jump to line 116, because the condition on line 112 was never false

113 g.players.exclude(tgt).reveal(card)

114 g.process_action(DropCards(src, tgt, [card]))

115

116 return act

117

118

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

120 class Yugi(Character):

121 skills = [Assault, FreakingPower]

122 eventhandlers = [FreakingPowerHandler]

123 maxlife = 4

124

125

126@register_character_to('kof')

127 class YugiKOF(Character):

128 skills = [AssaultKOF, FreakingPower]

129 eventhandlers = [AssaultKOFHandler, FreakingPowerHandler]

130 maxlife = 4