Coverage for thb/characters/parsee.py : 93%
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 -*-
3# -- stdlib --
4# -- third party --
5# -- own --
6from thb.actions import DropCards, LaunchCard, migrate_cards, detach_cards
7from thb.cards.base import Card, Skill, DummyCard
8from thb.cards.classes import Demolition, DemolitionCard, TreatAs
9from thb.characters.base import Character, register_character_to
10from thb.inputlets import ChooseOptionInputlet
11from thb.mode import THBEventHandler
12from utils.misc import classmix
15# -- code --
16class Envy(TreatAs, Skill):
17 treat_as = DemolitionCard
18 skill_category = ['character', 'active']
20 def check(self):
21 cards = self.associated_cards
22 if len(cards) != 1: return False
23 c = cards[0]
24 if c.resides_in is None: return False 24 ↛ exitline 24 didn't return from function 'check', because the return on line 24 wasn't executed
25 if c.resides_in.type not in ('cards', 'showncards', 'equips'): return False 25 ↛ exitline 25 didn't return from function 'check', because the return on line 25 wasn't executed
26 if c.suit not in (Card.SPADE, Card.CLUB): return False
27 return True
30class EnvyRecycleAction(object):
31 def apply_action(self):
32 detach_cards(self.cards)
33 migrate_cards(self.cards, self.source.cards, unwrap=True)
34 return True
37class EnvyRecycle(DummyCard):
38 distance = 1
41class EnvyHandler(THBEventHandler):
42 interested = ['action_before']
44 def handle(self, evt_type, act):
45 if evt_type != 'action_before': return act 45 ↛ exitline 45 didn't return from function 'handle', because the return on line 45 wasn't executed
46 if not isinstance(act, DropCards): return act
48 g = self.game
49 pact = g.action_stack[-1]
50 if not isinstance(pact, Demolition): return act
51 if not pact.source.has_skill(Envy): return act
53 src = pact.source
54 tgt = pact.target
55 self.card = card = pact.card
57 assert len(act.cards) == 1
58 assert card is act.cards[0]
60 if card.resides_in is None: 60 ↛ 61line 60 didn't jump to line 61, because the condition on line 60 was never true
61 return act
63 if card.resides_in.type not in ('cards', 'showncards', 'equips'):
64 return act
66 assert tgt is card.resides_in.owner
68 if src.dead: return act 68 ↛ exitline 68 didn't return from function 'handle', because the return on line 68 wasn't executed
69 if card.suit != Card.DIAMOND: return act
71 dist = LaunchCard.calc_distance(g, src, EnvyRecycle())
72 if not dist[tgt] <= 0: return act
74 g.emit_event('ui_show_disputed', [card])
76 if not g.user_input([src], ChooseOptionInputlet(self, (False, True))):
77 return act
79 act.__class__ = classmix(EnvyRecycleAction, act.__class__)
80 return act
83@register_character_to('common')
84class Parsee(Character):
85 skills = [Envy]
86 eventhandlers = [EnvyHandler]
87 maxlife = 4