Coverage for thb/characters/parsee.py : 30%
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
4# -- stdlib --
5from typing import Any
7# -- third party --
8# -- own --
9from thb.actions import DropCards, LaunchCard, detach_cards, migrate_cards
10from thb.cards.base import Card, DummyCard, Skill
11from thb.cards.classes import Demolition, DemolitionCard, TreatAs
12from thb.characters.base import Character, register_character_to
13from thb.inputlets import ChooseOptionInputlet
14from thb.mode import THBEventHandler
15from utils.misc import classmix
18# -- code --
19class Envy(TreatAs, Skill):
20 treat_as = DemolitionCard
21 skill_category = ['character', 'active']
23 def check(self):
24 cards = self.associated_cards
25 if len(cards) != 1: return False
26 c = cards[0]
27 if c.resides_in is None: return False
28 if c.resides_in.type not in ('cards', 'showncards', 'equips'): return False
29 if c.suit not in (Card.SPADE, Card.CLUB): return False
30 return True
33class EnvyRecycleAction(object):
34 def apply_action(self: Any):
35 detach_cards(self.cards)
36 migrate_cards(self.cards, self.source.cards, unwrap=True)
37 return True
40class EnvyRecycle(DummyCard):
41 distance = 1
44class EnvyHandler(THBEventHandler):
45 interested = ['action_before']
47 def handle(self, evt_type, act):
48 if evt_type != 'action_before': return act
49 if not isinstance(act, DropCards): return act
51 g = self.game
52 pact = g.action_stack[-1]
53 if not isinstance(pact, Demolition): return act
54 if not pact.source.has_skill(Envy): return act
56 src = pact.source
57 tgt = pact.target
58 self.card = card = pact.card
60 assert len(act.cards) == 1
61 assert card is act.cards[0]
63 if card.resides_in is None:
64 return act
66 if card.resides_in.type not in ('cards', 'showncards', 'equips'):
67 return act
69 assert tgt is card.resides_in.owner
71 if src.dead: return act
72 if card.suit != Card.DIAMOND: return act
74 dist = LaunchCard.calc_distance(g, src, EnvyRecycle())
75 if not dist[tgt] <= 0: return act
77 g.emit_event('ui_show_disputed', [card])
79 if not g.user_input([src], ChooseOptionInputlet(self, (False, True))):
80 return act
82 act.__class__ = classmix(EnvyRecycleAction, act.__class__)
83 return act
86@register_character_to('common')
87class Parsee(Character):
88 skills = [Envy]
89 eventhandlers = [EnvyHandler]
90 maxlife = 4