From 72bb52d0370982b81116123cbb2ba923cf0fcb62 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Sun, 2 Apr 2023 14:56:52 +0100 Subject: [PATCH] fix Lemat --- backend/bang/cards.py | 6 +- .../expansions/the_valley_of_shadows/cards.py | 204 +++++++++++------- 2 files changed, 131 insertions(+), 79 deletions(-) diff --git a/backend/bang/cards.py b/backend/bang/cards.py index 75a1225..8719d59 100644 --- a/backend/bang/cards.py +++ b/backend/bang/cards.py @@ -93,9 +93,9 @@ class Card(ABC): return False if self.is_weapon: has_weapon = False - for i in range(len(player.equipment)): - if player.equipment[i].is_weapon: - player.game.deck.scrap(player.equipment[i]) + for i, card in enumerate(player.equipment): + if card.is_weapon: + player.game.deck.scrap(card, player=player) player.equipment[i] = self has_weapon = True break diff --git a/backend/bang/expansions/the_valley_of_shadows/cards.py b/backend/bang/expansions/the_valley_of_shadows/cards.py index ac742ee..aa74fe0 100644 --- a/backend/bang/expansions/the_valley_of_shadows/cards.py +++ b/backend/bang/expansions/the_valley_of_shadows/cards.py @@ -5,58 +5,75 @@ from bang.cards import Card, Suit, Bang, Mancato import bang.expansions.fistful_of_cards.card_events as ce from globals import G + class Fantasma(Card): def __init__(self, suit, number): - super().__init__(suit, 'Fantasma', number, is_equipment=True) - self.icon = '๐Ÿ‘ป๏ธ' #porta in vita i giocatori morti ma non - + super().__init__(suit, "Fantasma", number, is_equipment=True) + self.icon = "๐Ÿ‘ป๏ธ" # porta in vita i giocatori morti ma non + def play_card(self, player, against, _with=None): if (player.game.check_event(ce.IlGiudice)) or not self.can_be_used_now: return False if len(player.game.get_dead_players(include_ghosts=False)) > 0: player.pending_action = pl.PendingAction.CHOOSE - player.choose_text = 'choose_fantasma' - player.available_cards = [{ - 'name': p.name, - 'icon': p.role.icon if(player.game.initial_players == 3) else 'โญ๏ธ' if isinstance(p.role, r.Sheriff) else '๐Ÿค ', - 'avatar': p.avatar, - 'alt_text': ''.join(['โค๏ธ']*p.lives)+''.join(['๐Ÿ’€']*(p.max_lives-p.lives)), - 'is_character': True, - 'is_player': True - } for p in player.game.get_dead_players(include_ghosts=False)] + player.choose_text = "choose_fantasma" + player.available_cards = [ + { + "name": p.name, + "icon": p.role.icon + if (player.game.initial_players == 3) + else "โญ๏ธ" + if isinstance(p.role, r.Sheriff) + else "๐Ÿค ", + "avatar": p.avatar, + "alt_text": "".join(["โค๏ธ"] * p.lives) + + "".join(["๐Ÿ’€"] * (p.max_lives - p.lives)), + "is_character": True, + "is_player": True, + } + for p in player.game.get_dead_players(include_ghosts=False) + ] self.can_be_used_now = False player.game.deck.scrap(self, True) return True return False + class Lemat(Card): def __init__(self, suit, number): - super().__init__(suit, 'Lemat', number, is_equipment=True, is_weapon=True, range=1) - self.icon = '๐Ÿ”ซ' # ogni carta puรฒ essere usata come bang, conta per il conteggio dei bang per turno - + super().__init__( + suit, "Lemat", number, is_equipment=True, is_weapon=True, range=1 + ) + self.icon = "๐Ÿ”ซ" # ogni carta puรฒ essere usata come bang, conta per il conteggio dei bang per turno + def play_card(self, player, against, _with=None): - if (player.game.check_event(ce.IlGiudice) and self.can_be_used_now) or (not self.can_be_used_now and player.game.check_event(ce.Lazo)): + if not self.can_be_used_now and player.game.check_event(ce.Lazo): return False if self.can_be_used_now: + if not super().play_card(player, against, _with): + return False self.can_be_used_now = False - G.sio.emit('chat_message', room=player.game.name, - data=f'_play_card|{player.name}|{self.name}') - player.equipment.append(self) - player.notify_self() return True - elif not player.has_played_bang and any((player.get_sight() >= p['dist'] for p in player.game.get_visible_players(player))): + elif not player.has_played_bang and any( + ( + player.get_sight() >= p["dist"] + for p in player.game.get_visible_players(player) + ) + ): from bang.players import PendingAction + player.available_cards = player.hand.copy() player.pending_action = PendingAction.CHOOSE - player.choose_text = 'choose_play_as_bang' + player.choose_text = "choose_play_as_bang" player.notify_self() return False + class SerpenteASonagli(Card): def __init__(self, suit, number): - super().__init__(suit, 'SerpenteASonagli', number, is_equipment=True) + super().__init__(suit, "SerpenteASonagli", number, is_equipment=True) self.need_target = True - self.icon = '๐Ÿ๏ธ' # Ogni turno pesca se il seme picche -1hp + self.icon = "๐Ÿ๏ธ" # Ogni turno pesca se il seme picche -1hp self.alt_text = "โ™ ๏ธ =๐Ÿ’”" def play_card(self, player, against, _with=None): @@ -64,54 +81,66 @@ class SerpenteASonagli(Card): return False if against is not None: self.can_be_used_now = False - G.sio.emit('chat_message', room=player.game.name, - data=f'_play_card_against|{player.name}|{self.name}|{against}') + G.sio.emit( + "chat_message", + room=player.game.name, + data=f"_play_card_against|{player.name}|{self.name}|{against}", + ) player.game.get_player_named(against).equipment.append(self) player.game.get_player_named(against).notify_self() return True return False + class Shotgun(Card): def __init__(self, suit, number): - super().__init__(suit, 'Shotgun', number, is_equipment=True, is_weapon=True, range=1) - self.icon = '๐Ÿ”ซ' # Ogni volta che colpisci un giocatore deve scartare una carta + super().__init__( + suit, "Shotgun", number, is_equipment=True, is_weapon=True, range=1 + ) + self.icon = "๐Ÿ”ซ" # Ogni volta che colpisci un giocatore deve scartare una carta + class Taglia(Card): def __init__(self, suit, number): - super().__init__(suit, 'Taglia', number, is_equipment=True) + super().__init__(suit, "Taglia", number, is_equipment=True) self.need_target = True - self.icon = '๐Ÿ’ฐ' # chiunque colpisca il giocatore con la taglia pesca una carta dal mazzo, si toglie solo con panico, cat balou, dalton + self.icon = "๐Ÿ’ฐ" # chiunque colpisca il giocatore con la taglia pesca una carta dal mazzo, si toglie solo con panico, cat balou, dalton def play_card(self, player, against, _with=None): if (player.game.check_event(ce.IlGiudice)) or not self.can_be_used_now: return False if against is not None: self.can_be_used_now = False - G.sio.emit('chat_message', room=player.game.name, - data=f'_play_card_against|{player.name}|{self.name}|{against}') + G.sio.emit( + "chat_message", + room=player.game.name, + data=f"_play_card_against|{player.name}|{self.name}|{against}", + ) player.game.get_player_named(against).equipment.append(self) player.game.get_player_named(against).notify_self() return True return False + class UltimoGiro(Card): def __init__(self, suit, number): - super().__init__(suit, 'UltimoGiro', number) - self.icon = '๐Ÿฅ‚' + super().__init__(suit, "UltimoGiro", number) + self.icon = "๐Ÿฅ‚" # self.desc = 'Recupera 1 vita' # self.desc_eng = 'Regain 1 HP' self.alt_text = "๐Ÿบ" def play_card(self, player, against, _with=None): super().play_card(player, against) - player.lives = min(player.lives+1, player.max_lives) + player.lives = min(player.lives + 1, player.max_lives) player.notify_self() return True + class Tomahawk(Card): def __init__(self, suit, number): - super().__init__(suit, 'Tomahawk', number, range=2) - self.icon = '๐Ÿช“๏ธ' + super().__init__(suit, "Tomahawk", number, range=2) + self.icon = "๐Ÿช“๏ธ" self.alt_text = "2๐Ÿ”Ž ๐Ÿ’ฅ" # "Spara a un giocatore a distanza 2" self.need_target = True @@ -123,22 +152,26 @@ class Tomahawk(Card): return True return False + class Tornado(Card): def __init__(self, suit, number): - super().__init__(suit, 'Tornado', number) - self.icon = '๐ŸŒช๏ธ' + super().__init__(suit, "Tornado", number) + self.icon = "๐ŸŒช๏ธ" def play_card(self, player, against, _with=None): super().play_card(player, against=against) player.game.discard_others(player, card_name=self.name) return True -class Sventagliata(Bang): # : conta come un normale BANG! del turno. Il BANG! secondario รจ obbligatorio ed รจ sparato anche se il primo viene annullato, se si puรฒ, tu sei escluso come target + +class Sventagliata( + Bang +): # : conta come un normale BANG! del turno. Il BANG! secondario รจ obbligatorio ed รจ sparato anche se il primo viene annullato, se si puรฒ, tu sei escluso come target def __init__(self, suit, number): super().__init__(suit, number) - self.name = 'Sventagliata' - self.icon = '๐ŸŽ' - self.alt_text = "๐Ÿ’ฅ๐Ÿ’ฅ" # spara al target e anche, a uno a distanza 1 dal target + self.name = "Sventagliata" + self.icon = "๐ŸŽ" + self.alt_text = "๐Ÿ’ฅ๐Ÿ’ฅ" # spara al target e anche, a uno a distanza 1 dal target self.need_target = True def play_card(self, player, against, _with=None): @@ -146,37 +179,43 @@ class Sventagliata(Bang): # : conta come un normale BANG! del turno. Il BANG! se if player.has_played_bang: return False t = player.game.get_player_named(against) - player.available_cards = [dict(p, **{'original_target':against}) for p in player.game.get_visible_players(t) if p['name'] != player.name and p['name'] != t.name and p['dist']] + player.available_cards = [ + dict(p, **{"original_target": against}) + for p in player.game.get_visible_players(t) + if p["name"] != player.name and p["name"] != t.name and p["dist"] + ] if len(player.available_cards) > 0: player.pending_action = pl.PendingAction.CHOOSE - player.choose_text = 'choose_sventagliata' + player.choose_text = "choose_sventagliata" else: player.available_cards = [] super().play_card(player, against=against) return True return False -class Salvo(Card): # puoi anche prevenire un danno inferto da te, duello? + +class Salvo(Card): # puoi anche prevenire un danno inferto da te, duello? def __init__(self, suit, number): - super().__init__(suit, 'Salvo', number) - self.icon = '๐Ÿ˜‡๏ธ' - self.alt_text = "๐Ÿ‘ค๐Ÿ˜…" + super().__init__(suit, "Salvo", number) + self.icon = "๐Ÿ˜‡๏ธ" + self.alt_text = "๐Ÿ‘ค๐Ÿ˜…" self.need_target = True def play_card(self, player, against, _with=None): if against is not None: - #TODO + # TODO # super().play_card(player, against=against) # player.game.attack(player, against, card_name=self.name) return True return False + class Mira(Card): def __init__(self, suit, number): - super().__init__(suit, 'Mira', number) - self.icon = '๐Ÿ‘Œ๐Ÿป' - self.need_with_only = 'Bang' - self.alt_text = "๐Ÿ’ฅ๐Ÿƒ๐Ÿ’”๐Ÿ’”" + super().__init__(suit, "Mira", number) + self.icon = "๐Ÿ‘Œ๐Ÿป" + self.need_with_only = "Bang" + self.alt_text = "๐Ÿ’ฅ๐Ÿƒ๐Ÿ’”๐Ÿ’”" self.need_target = True self.need_with = True @@ -187,69 +226,82 @@ class Mira(Card): return True return False + class Bandidos(Card): def __init__(self, suit, number): - super().__init__(suit, 'Bandidos', number) - self.icon = '๐Ÿค ๏ธ' - self.alt_text = "๐Ÿ‘ค๐Ÿƒ๐Ÿƒ/๐Ÿ’”" - + super().__init__(suit, "Bandidos", number) + self.icon = "๐Ÿค ๏ธ" + self.alt_text = "๐Ÿ‘ค๐Ÿƒ๐Ÿƒ/๐Ÿ’”" + def play_card(self, player, against, _with=None): super().play_card(player, against=against) player.game.discard_others(player, card_name=self.name) return True -class Fuga(Card): #comprende indiani gatling etc, ma solo se carte marroni, le carte verdi valgono, attenzione alla classi ereditate + +class Fuga( + Card +): # comprende indiani gatling etc, ma solo se carte marroni, le carte verdi valgono, attenzione alla classi ereditate def __init__(self, suit, number): - super().__init__(suit, 'Fuga', number) - self.icon = '๐Ÿƒ๐Ÿป' - self.alt_text = "โŒ" - + super().__init__(suit, "Fuga", number) + self.icon = "๐Ÿƒ๐Ÿป" + self.alt_text = "โŒ" + def play_card(self, player, against, _with=None): return False + class Poker(Card): def __init__(self, suit, number): - super().__init__(suit, 'Poker', number) - self.icon = '๐Ÿƒ' + super().__init__(suit, "Poker", number) + self.icon = "๐Ÿƒ" self.alt_text = "๐Ÿ‘ค๐Ÿƒ ๐Ÿƒ๐Ÿƒ" - + def play_card(self, player, against, _with=None): super().play_card(player, against=against) player.game.discard_others(player, card_name=self.name) return True + class RitornoDiFiamma(Mancato): def __init__(self, suit, number): super().__init__(suit, number) - self.name = 'RitornoDiFiamma' - self.icon = '๐Ÿ”ฅ' + self.name = "RitornoDiFiamma" + self.icon = "๐Ÿ”ฅ" self.alt_text = "๐Ÿ˜… | ๐Ÿ’ฅ" - + def play_card(self, player, against, _with=None): return False def use_card(self, player): player.notify_self() + def get_starting_deck() -> List[Card]: cards = [ Fantasma(Suit.SPADES, 9), Fantasma(Suit.SPADES, 10), Lemat(Suit.DIAMONDS, 4), SerpenteASonagli(Suit.HEARTS, 7), - Shotgun(Suit.SPADES, 'K'), + Shotgun(Suit.SPADES, "K"), Taglia(Suit.CLUBS, 9), UltimoGiro(Suit.DIAMONDS, 8), - Tomahawk(Suit.DIAMONDS, 'A'), + Tomahawk(Suit.DIAMONDS, "A"), Sventagliata(Suit.SPADES, 2), # Salvo(Suit.HEARTS, 5), - Bandidos(Suit.DIAMONDS,'Q'), # gli altri giocatori scelgono se scartare 2 carte o perdere 1 punto vita - Fuga(Suit.HEARTS, 3), # evita l'effetto di carte marroni (tipo panico cat balou) di cui sei bersaglio + Bandidos( + Suit.DIAMONDS, "Q" + ), # gli altri giocatori scelgono se scartare 2 carte o perdere 1 punto vita + Fuga( + Suit.HEARTS, 3 + ), # evita l'effetto di carte marroni (tipo panico cat balou) di cui sei bersaglio Mira(Suit.CLUBS, 6), - Poker(Suit.HEARTS, 'J'), # tutti gli altri scartano 1 carta a scelta, se non ci sono assi allora pesca 2 - RitornoDiFiamma(Suit.CLUBS, 'Q'), # un mancato che fa bang + Poker( + Suit.HEARTS, "J" + ), # tutti gli altri scartano 1 carta a scelta, se non ci sono assi allora pesca 2 + RitornoDiFiamma(Suit.CLUBS, "Q"), # un mancato che fa bang Tornado(Suit.CLUBS, "A"), ] for c in cards: - c.expansion_icon = '๐Ÿ‘ป๏ธ' + c.expansion_icon = "๐Ÿ‘ป๏ธ" return cards