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 cast 

6 

7# -- third party -- 

8# -- own -- 

9# -- errord -- 

10from thb.actions import DrawCards, MigrateCardsTransaction, UserAction 

11from thb.cards.base import Skill 

12from thb.cards.classes import Heal, t_None, t_OtherOne 

13from thb.characters.base import Character, register_character_to 

14from thb.mode import THBEventHandler 

15 

16 

17# -- code -- 

18class Psychopath(Skill): 

19 associated_action = None 

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

21 target = t_None() 

22 

23 

24class NetoruAction(UserAction): 

25 def apply_action(self): 

26 g = self.game 

27 src = self.source 

28 src.tags['netoru_tag'] = src.tags['turn_count'] 

29 tgt = self.target 

30 g.process_action(Heal(src, tgt)) 

31 if src.life < src.maxlife: 

32 g.process_action(Heal(src, src)) 

33 return True 

34 

35 def is_valid(self): 

36 src = self.source 

37 tgt = self.target 

38 if src.tags['netoru_tag'] >= src.tags['turn_count']: 

39 return False 

40 return not (tgt.dead or tgt.life >= tgt.maxlife) 

41 

42 

43class Netoru(Skill): 

44 associated_action = NetoruAction 

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

46 target = t_OtherOne() 

47 usage = 'drop' 

48 

49 def check(self): 

50 cl = self.associated_cards 

51 return cl and len(cl) == 2 and all( 

52 c.resides_in is not None and 

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

54 for c in cl 

55 ) 

56 

57 

58class PsychopathDrawCards(DrawCards): 

59 pass 

60 

61 

62class PsychopathHandler(THBEventHandler): 

63 interested = ['post_card_migration'] 

64 

65 def handle(self, evt_type, arg): 

66 if evt_type == 'post_card_migration': 

67 g = self.game 

68 trans = cast(MigrateCardsTransaction, arg) 

69 for m in trans.movements: 

70 if m.fr.type != 'equips': continue 

71 src = m.fr.owner 

72 assert src 

73 if src.dead: continue 

74 if not src.has_skill(Psychopath): continue 

75 g.process_action(PsychopathDrawCards(src, 2)) 

76 

77 return arg 

78 

79 

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

81class Rinnosuke(Character): 

82 skills = [Netoru, Psychopath] 

83 eventhandlers = [PsychopathHandler] 

84 maxlife = 3