diff --git a/backend/bang/cards.py b/backend/bang/cards.py
index 9e79994..fa446db 100644
--- a/backend/bang/cards.py
+++ b/backend/bang/cards.py
@@ -247,7 +247,7 @@ class Birra(Card):
import bang.expansions.gold_rush.characters as grch
madamYto = [p for p in player.game.get_alive_players() if p.character.check(player.game, grch.MadamYto) and self.number != 42]
for p in madamYto:
- p.hand.append(player.game.deck.draw(True))
+ player.game.deck.draw(True, player=p)
p.notify_self()
if 'gold_rush' in player.game.expansions and self.number != 42:
from bang.players import PendingAction
@@ -309,7 +309,7 @@ class Diligenza(Card):
G.sio.emit('chat_message', room=player.game.name,
data=f'_diligenza|{player.name}|{self.name}')
for i in range(2):
- player.hand.append(player.game.deck.draw(True))
+ player.game.deck.draw(True, player)
return True
@@ -442,7 +442,7 @@ class WellsFargo(Card):
G.sio.emit('chat_message', room=player.game.name,
data=f'_wellsfargo|{player.name}|{self.name}')
for i in range(3):
- player.hand.append(player.game.deck.draw(True))
+ player.game.deck.draw(True, player)
return True
diff --git a/backend/bang/deck.py b/backend/bang/deck.py
index 36b4bab..cde7d15 100644
--- a/backend/bang/deck.py
+++ b/backend/bang/deck.py
@@ -4,6 +4,7 @@ import bang.cards as cs
import bang.expansions.fistful_of_cards.card_events as ce
import bang.expansions.high_noon.card_events as ceh
import bang.expansions.gold_rush.shop_cards as grc
+from globals import G
class Deck:
def __init__(self, game):
@@ -81,12 +82,15 @@ class Deck:
def put_on_top(self, card: cs.Card):
self.cards.insert(0, card)
- def draw(self, ignore_event = False) -> cs.Card:
+ def draw(self, ignore_event = False, player=None) -> cs.Card:
if self.game.check_event(ce.MinieraAbbandonata) and len(self.scrap_pile) > 0 and not ignore_event:
return self.draw_from_scrap_pile()
card = self.cards.pop(0)
if len(self.cards) == 0:
self.reshuffle()
+ if player is not None:
+ G.sio.emit('card_drawn', room=self.game.name, data={'player': player.name, 'pile': 'deck'})
+ player.hand.append(card)
return card
def reshuffle(self):
diff --git a/backend/bang/expansions/dodge_city/cards.py b/backend/bang/expansions/dodge_city/cards.py
index 97f32dc..ff5e8fb 100644
--- a/backend/bang/expansions/dodge_city/cards.py
+++ b/backend/bang/expansions/dodge_city/cards.py
@@ -43,7 +43,7 @@ class Schivata(Mancato):
return False
def use_card(self, player):
- player.hand.append(player.game.deck.draw(True))
+ player.game.deck.draw(True, player=player)
player.notify_self()
class RagTime(Panico):
@@ -234,7 +234,7 @@ class Derringer(Pugnale):
def play_card(self, player, against, _with=None):
if self.can_be_used_now:
- player.hand.append(player.game.deck.draw(True))
+ player.game.deck.draw(True, player=player)
return super().play_card(player, against=against)
else:
if not self.is_duplicate_card(player) and not player.game.check_event(ce.IlGiudice):
@@ -245,7 +245,7 @@ class Derringer(Pugnale):
return False
def use_card(self, player):
- player.hand.append(player.game.deck.draw(True))
+ player.game.deck.draw(True, player=player)
player.notify_self()
class Borraccia(Card):
diff --git a/backend/bang/expansions/dodge_city/characters.py b/backend/bang/expansions/dodge_city/characters.py
index 6ba2360..75d0a88 100644
--- a/backend/bang/expansions/dodge_city/characters.py
+++ b/backend/bang/expansions/dodge_city/characters.py
@@ -89,8 +89,8 @@ class ChuckWengam(Character):
if super().special(player, data):
if player.lives > 1 and player.is_my_turn:
player.lives -= 1
- player.hand.append(player.game.deck.draw(True))
- player.hand.append(player.game.deck.draw(True))
+ player.game.deck.draw(True, player=player)
+ player.game.deck.draw(True, player=player)
player.notify_self()
return True
return False
diff --git a/backend/bang/expansions/gold_rush/characters.py b/backend/bang/expansions/gold_rush/characters.py
index 19ce2b1..72dc700 100644
--- a/backend/bang/expansions/gold_rush/characters.py
+++ b/backend/bang/expansions/gold_rush/characters.py
@@ -70,7 +70,7 @@ class RaddieSnake(Character):
if player.gold_nuggets >= 1 and player.is_my_turn and player.special_use_count < 2:
player.gold_nuggets -= 1
player.special_use_count += 1
- player.hand.append(player.game.deck.draw(True))
+ player.game.deck.draw(True, player=player)
player.notify_self()
return True
return False
diff --git a/backend/bang/expansions/gold_rush/shop_cards.py b/backend/bang/expansions/gold_rush/shop_cards.py
index 49ae8ed..5b4ef8f 100644
--- a/backend/bang/expansions/gold_rush/shop_cards.py
+++ b/backend/bang/expansions/gold_rush/shop_cards.py
@@ -117,7 +117,7 @@ class UnionPacific(ShopCard):
G.sio.emit('chat_message', room=player.game.name,
data=f'_UnionPacific|{player.name}|{self.name}')
for i in range(4):
- player.hand.append(player.game.deck.draw(True))
+ player.game.deck.draw(True, player=player)
return super().play_card(player, against, _with)
class Calumet(ShopCard):
@@ -191,7 +191,7 @@ class Setaccio(ShopCard):
G.sio.emit('chat_message', room=player.game.name, data=f'_play_card|{player.name}|{self.name}')
player.gold_nuggets -= 1
player.setaccio_count += 1
- player.hand.append(player.game.deck.draw(True))
+ player.game.deck.draw(True, player=player)
player.notify_self()
return True
return False
diff --git a/backend/bang/game.py b/backend/bang/game.py
index 72e44cb..d294c38 100644
--- a/backend/bang/game.py
+++ b/backend/bang/game.py
@@ -261,7 +261,7 @@ class Game:
G.sio.emit('chat_message', room=self.name, data=f'_choose_character|{self.players[i].name}|{self.players[i].character.name}')
self.players[i].prepare()
for k in range(self.players[i].max_lives):
- self.players[i].hand.append(self.deck.draw())
+ self.deck.draw(player=self.players[i])
self.players[i].notify_self()
current_roles = [x.role.name for x in self.players]
self.rng.shuffle(current_roles)
@@ -486,7 +486,7 @@ class Game:
if target_pl.character.check(self, grch.SimeonPicos):
target_pl.gold_nuggets += 1
if any((isinstance(c, grc.Stivali) for c in target_pl.gold_rush_equipment)):
- target_pl.hand.append(self.deck.draw(True))
+ self.deck.draw(True, player=target_pl)
target_pl.notify_self()
self.is_russian_roulette_on = False
self.players[self.turn].play_turn()
@@ -565,8 +565,8 @@ class Game:
pl.is_dead = False
pl.is_ghost = False
pl.lives = 2
- pl.hand.append(self.deck.draw())
- pl.hand.append(self.deck.draw())
+ self.deck.draw(player=pl)
+ self.deck.draw(player=pl)
if (ghost := next((c for c in pl.equipment if isinstance(c, tvosc.Fantasma)), None)) is not None:
self.deck.scrap(ghost)
pl.equipment.remove(ghost)
@@ -707,8 +707,8 @@ class Game:
Metrics.send_metric('player_death', points=[1], tags=[f"char:{player.character.name}", f"role:{player.role.name}"])
if any((isinstance(c, grc.Ricercato) for c in player.gold_rush_equipment)) and player.attacker and player.attacker in self.players:
player.attacker.gold_nuggets += 1
- player.attacker.hand.append(self.deck.draw(True))
- player.attacker.hand.append(self.deck.draw(True))
+ self.deck.draw(True, player=player.attacker)
+ self.deck.draw(True, player=player.attacker)
player.attacker.notify_self()
# se lo sceriffo uccide il proprio vice
if player.attacker and player.attacker in self.players and isinstance(player.attacker.role, roles.Sheriff) and isinstance(player.role, roles.Vice):
@@ -721,7 +721,7 @@ class Game:
player.attacker.notify_self()
elif player.attacker and player.attacker in self.players and (isinstance(player.role, roles.Outlaw) or self.initial_players == 3):
for i in range(3):
- player.attacker.hand.append(self.deck.draw(True))
+ self.deck.draw(True, player=player.attacker)
player.attacker.notify_self()
print(f'{self.name}: player {player.name} died')
if self.waiting_for > 0 and player.pending_action == pl.PendingAction.RESPOND:
@@ -806,8 +806,8 @@ class Game:
greg[i].lives = min(greg[i].lives+2, greg[i].max_lives)
herb = [p for p in self.get_alive_players() if p.character.check(self, chd.HerbHunter)]
for i in range(len(herb)):
- herb[i].hand.append(self.deck.draw(True))
- herb[i].hand.append(self.deck.draw(True))
+ self.deck.draw(True, player=herb[i])
+ self.deck.draw(True, player=herb[i])
herb[i].notify_self()
#se Vulture Sam o Herb Hounter è uno sceriffo e ha appena ucciso il suo Vice, deve scartare le carte che ha pescato con la sua abilità
diff --git a/backend/bang/players.py b/backend/bang/players.py
index 34b48a3..df00960 100644
--- a/backend/bang/players.py
+++ b/backend/bang/players.py
@@ -252,7 +252,7 @@ class Player:
self.choose_text = 'choose_ranch'
self.pending_action = PendingAction.CHOOSE
elif self.character and self.character.check(self.game, chars.SuzyLafayette) and self.lives > 0 and len(self.hand) == 0 and ( not self.is_my_turn or self.pending_action == PendingAction.PLAY):
- self.hand.append(self.game.deck.draw(True))
+ self.game.deck.draw(True, player=self)
if self.lives <= 0 and self.max_lives > 0 and not self.is_dead:
print('dying, attacker', self.attacker)
if self.gold_nuggets >= 2 and any((isinstance(c, grc.Zaino) for c in self.gold_rush_equipment)):
@@ -458,9 +458,9 @@ class Player:
if self.character.check(self.game, grch.SimeonPicos):
self.gold_nuggets += 1
if any((isinstance(c, grc.Stivali) for c in self.gold_rush_equipment)):
- self.hand.append(self.game.deck.draw(True))
+ self.game.deck.draw(True, player=self)
if self.character.check(self.game, chars.BartCassidy) and self.lives > 0:
- self.hand.append(self.game.deck.draw(True))
+ self.game.deck.draw(True, player=self)
G.sio.emit('chat_message', room=self.game.name, data=f'_special_bart_cassidy|{self.name}')
self.heal_if_needed()
if self.lives <= 0:
@@ -571,10 +571,11 @@ class Player:
if self.game.check_event(ce.LeggeDelWest):
card.must_be_used = True
if self.character.check(self.game, chars.BlackJack) and card.check_suit(self.game, [cs.Suit.HEARTS, cs.Suit.DIAMONDS]):
- self.hand.append(self.game.deck.draw())
+ self.game.deck.draw(player=self)
self.hand.append(card)
+ G.sio.emit('card_drawn', room=self.game.name, data={'player': self.name, 'pile': pile})
else:
- self.hand.append(self.game.deck.draw())
+ self.game.deck.draw(player=self)
self.manette()
self.notify_self()
@@ -611,16 +612,16 @@ class Player:
if self.character.check(self.game, grch.SimeonPicos):
self.gold_nuggets += 3
if any((isinstance(c, grc.Stivali) for c in self.gold_rush_equipment)):
- self.hand.append(self.game.deck.draw())
- self.hand.append(self.game.deck.draw())
- self.hand.append(self.game.deck.draw())
+ self.game.deck.draw(player=self)
+ self.game.deck.draw(player=self)
+ self.game.deck.draw(player=self)
self.attacker = None
self.game.deck.scrap(self.equipment.pop(i), True)
G.sio.emit('chat_message', room=self.game.name, data=f'_explode|{self.name}')
self.heal_if_needed()
if self.character.check(self.game, chars.BartCassidy) and self.lives > 0:
for i in range(3):
- self.hand.append(self.game.deck.draw(True))
+ self.game.deck.draw(True, player=self)
G.sio.emit('chat_message', room=self.game.name, data=f'_special_bart_cassidy|{self.name}')
print(f'{self.name} Boom, -3 hp')
break
@@ -664,13 +665,13 @@ class Player:
G.sio.emit('chat_message', room=self.game.name, data=f'_snake_bit|{self.name}')
if self.character.check(self.game, chars.BartCassidy):
G.sio.emit('chat_message', room=self.game.name, data=f'_special_bart_cassidy|{self.name}')
- self.hand.append(self.game.deck.draw(True))
+ self.game.deck.draw(True, player=self)
if any((isinstance(c, grc.Talismano) for c in self.gold_rush_equipment)):
self.gold_nuggets += 1
if self.character.check(self.game, grch.SimeonPicos):
self.gold_nuggets += 1
if any((isinstance(c, grc.Stivali) for c in self.gold_rush_equipment)):
- self.hand.append(self.game.deck.draw(True))
+ self.game.deck.draw(True, player=self)
break
if any((isinstance(c, cs.Prigione) for c in self.equipment)):
self.notify_self() #TODO perchè solo le prigioni? e multiple dinamiti come si comportano con veracuster?
@@ -870,8 +871,8 @@ class Player:
elif 'choose_tornado' in self.choose_text:
if card_index <= len(self.available_cards):
self.game.deck.scrap(self.hand.pop(card_index))
- self.hand.append(self.game.deck.draw())
- self.hand.append(self.game.deck.draw())
+ self.game.deck.draw(player=self)
+ self.game.deck.draw(player=self)
self.pending_action = PendingAction.WAIT
self.game.responders_did_respond_resume_turn()
self.notify_self()
@@ -961,7 +962,7 @@ class Player:
self.hand = [c for c in self.hand if c not in self.discarded_cards]
for i in range(len(self.discarded_cards)):
self.game.deck.scrap(self.discarded_cards[i], True)
- self.hand.append(self.game.deck.draw())
+ self.game.deck.draw(player=self)
self.discarded_cards = []
self.is_playing_ranch = False
self.pending_action = PendingAction.PLAY
@@ -1007,7 +1008,7 @@ class Player:
self.game.deck.scrap(self.available_cards.pop())
#se c'è sia treno che piccone pesco un'altra carta
if self.game.check_event(ceh.IlTreno) and any((isinstance(c, grc.Piccone) for c in self.gold_rush_equipment)):
- self.hand.append(self.game.deck.draw())
+ self.game.deck.draw(player=self)
self.is_drawing = False
self.pending_action = PendingAction.PLAY
self.manette()
@@ -1021,9 +1022,9 @@ class Player:
self.game.deck.scrap(self.available_cards.pop(0), True) #scarto l'altra
#legge del west non si applica perchè la seconda carta viene scartata
if self.game.check_event(ceh.IlTreno):
- self.hand.append(self.game.deck.draw())
+ self.game.deck.draw(player=self)
if any((isinstance(c, grc.Piccone) for c in self.gold_rush_equipment)):
- self.hand.append(self.game.deck.draw())
+ self.game.deck.draw(player=self)
self.gold_nuggets += 1
self.is_drawing = False
self.pending_action = PendingAction.PLAY
@@ -1212,7 +1213,7 @@ class Player:
for i in range(len(self.hand)):
if isinstance(self.hand[i], cs.Birra):
if self.character.check(self.game, chd.MollyStark) and not self.is_my_turn:
- self.hand.append(self.game.deck.draw(True))
+ self.game.deck.draw(True, player=self)
self.lives += 1 if not self.character.check(self.game, chd.TequilaJoe) else 2
self.lives = min(self.lives, self.max_lives)
self.game.deck.scrap(self.hand.pop(i), True)
@@ -1227,7 +1228,7 @@ class Player:
if self.character.check(self.game, chars.BartCassidy):
G.sio.emit('chat_message', room=self.game.name,
data=f'_special_bart_cassidy|{self.name}')
- self.hand.append(self.game.deck.draw(True))
+ self.game.deck.draw(True, player=self)
elif self.character.check(self.game, chars.ElGringo) and self.attacker and self.attacker in self.game.get_alive_players() and len(self.attacker.hand) > 0:
self.hand.append(self.attacker.hand.pop(randrange(0, len(self.attacker.hand))))
self.hand[-1].reset_card()
@@ -1236,7 +1237,7 @@ class Player:
self.attacker.notify_self()
if isinstance(self.attacker, Player) and not self.game.check_event(ce.Lazo):
if any((isinstance(c, tvosc.Taglia) for c in self.equipment)):
- self.attacker.hand.append(self.game.deck.draw(True))
+ self.game.deck.draw(True, player=self.attacker)
G.sio.emit('chat_message', room=self.game.name,
data=f'_taglia_reward|{self.name}|{self.attacker.name}')
self.attacker.notify_self()
@@ -1253,7 +1254,7 @@ class Player:
if self.character.check(self.game, grch.SimeonPicos):
self.gold_nuggets += 1
if any((isinstance(c, grc.Stivali) for c in self.gold_rush_equipment)):
- self.hand.append(self.game.deck.draw(True))
+ self.game.deck.draw(True, player=self)
self.heal_if_needed()
self.mancato_needed = 0
self.expected_response = []
@@ -1285,7 +1286,7 @@ class Player:
if hasattr(self.attacker,'character') and self.attacker.character.check(self.game, chars.SlabTheKiller) and isinstance(card, cs.Mancato):
self.molly_discarded_cards += 1
else:
- self.hand.append(self.game.deck.draw(True))
+ self.game.deck.draw(True, player=self)
card.use_card(self)
print(f'{self.game.name}: {self.name} responded with {card.name}')
G.sio.emit('chat_message', room=self.game.name, data=f'_respond|{self.name}|{card.name}')
@@ -1302,7 +1303,7 @@ class Player:
else:
if self.character.check(self.game, chd.MollyStark) and not self.is_my_turn:
for i in range(self.molly_discarded_cards):
- self.hand.append(self.game.deck.draw(True))
+ self.game.deck.draw(True, player=self)
self.molly_discarded_cards = 0
self.notify_self()
self.game.responders_did_respond_resume_turn(did_lose=False)
@@ -1317,12 +1318,12 @@ class Player:
else:
if self.character.check(self.game, chd.MollyStark) and not self.is_my_turn:
for i in range(self.molly_discarded_cards):
- self.hand.append(self.game.deck.draw(True))
+ self.game.deck.draw(True, player=self)
self.molly_discarded_cards = 0
self.notify_self()
elif self.attacker and self.attacker in self.game.get_alive_players() and self.attacker.character.check(self.game, chd.MollyStark) and self.is_my_turn:
for i in range(self.attacker.molly_discarded_cards):
- self.attacker.hand.append(self.attacker.game.deck.draw(True))
+ self.attacker.game.deck.draw(True, player=self.attacker)
self.attacker.molly_discarded_cards = 0
self.attacker.notify_self()
self.on_failed_response_cb()
@@ -1364,8 +1365,8 @@ class Player:
self.scrapped_cards = 0
self.lives = min(self.lives+1, self.max_lives)
elif self.character.check(self.game, chd.JoseDelgado) and card.is_equipment and self.special_use_count < 2:
- self.hand.append(self.game.deck.draw(True))
- self.hand.append(self.game.deck.draw(True))
+ self.game.deck.draw(True, player=self)
+ self.game.deck.draw(True, player=self)
self.special_use_count += 1
self.game.deck.scrap(card)
self.notify_self()
diff --git a/frontend/src/components/AnimatedCard.vue b/frontend/src/components/AnimatedCard.vue
new file mode 100644
index 0000000..9838935
--- /dev/null
+++ b/frontend/src/components/AnimatedCard.vue
@@ -0,0 +1,42 @@
+
+