From 3772d3cbf9761f1c80d9ab5f2c137bfef07bca19 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Thu, 26 Nov 2020 22:48:58 +0100 Subject: [PATCH 01/22] cardAgainst, ragTime --- .gitignore | 1 + backend/__init__.py | 24 ++++++++--------- backend/bang/cards.py | 29 +++++++++++---------- backend/bang/expansions/dodge_city/cards.py | 20 ++++++++++++-- backend/bang/players.py | 11 +++++--- frontend/src/components/Player.vue | 17 +++++++++--- 6 files changed, 68 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index b43fa6c..6e83984 100644 --- a/.gitignore +++ b/.gitignore @@ -138,3 +138,4 @@ dmypy.json cython_debug/ frontend/package-lock.json +bang-workspace.code-workspace diff --git a/backend/__init__.py b/backend/__init__.py index 6dfda89..773c53d 100644 --- a/backend/__init__.py +++ b/backend/__init__.py @@ -90,58 +90,58 @@ def join_room(sid, room): @sio.event def chat_message(sid, msg): - ses = sio.get_session(sid) + ses: Player = sio.get_session(sid) sio.emit('chat_message', room=ses.game.name, data=f'[{ses.name}]: {msg}') @sio.event def start_game(sid): - ses = sio.get_session(sid) + ses: Player = sio.get_session(sid) ses.game.start_game() advertise_lobbies() @sio.event def set_character(sid, name): - ses = sio.get_session(sid) + ses: Player = sio.get_session(sid) ses.set_character(name) @sio.event def refresh(sid): - ses = sio.get_session(sid) + ses: Player = sio.get_session(sid) ses.notify_self() @sio.event def draw(sid, pile): - ses = sio.get_session(sid) + ses: Player = sio.get_session(sid) ses.draw(pile) @sio.event def pick(sid): - ses = sio.get_session(sid) + ses: Player = sio.get_session(sid) ses.pick() @sio.event def end_turn(sid): - ses = sio.get_session(sid) + ses: Player = sio.get_session(sid) ses.end_turn() @sio.event def play_card(sid, data): - ses = sio.get_session(sid) - ses.play_card(data['index'], data['against']) + ses: Player = sio.get_session(sid) + ses.play_card(data['index'], data['against'], data['with']) @sio.event def respond(sid, data): - ses = sio.get_session(sid) + ses: Player = sio.get_session(sid) ses.respond(data) @sio.event def choose(sid, card_index): - ses = sio.get_session(sid) + ses: Player = sio.get_session(sid) ses.choose(card_index) @sio.event def scrap(sid, card_index): - ses = sio.get_session(sid) + ses: Player = sio.get_session(sid) ses.scrap(card_index) if __name__ == '__main__': diff --git a/backend/bang/cards.py b/backend/bang/cards.py index c10f400..5830144 100644 --- a/backend/bang/cards.py +++ b/backend/bang/cards.py @@ -35,13 +35,14 @@ class Card(ABC): self.alt_text = f'{self.range} 🔍' self.desc = desc self.need_target = False + self.need_with = False def __str__(self): char = ['♦️', '♣️', '♥️', '♠️'][int(self.suit)] return f'{self.name} {char}{self.number}' return super().__str__() - def play_card(self, player, against):#self --> carta + def play_card(self, player, against=None, _with=None):#self --> carta if self.is_equipment: if self.is_weapon: has_weapon = False @@ -106,7 +107,7 @@ class Prigione(Card): self.desc = "Equipaggia questa carta a un altro giocatore, tranne lo Sceriffo. Il giocatore scelto all'inizio del suo turno, prima di pescare dovrà estrarre: se esce Cuori scarta questa carta e gioca normalmente il turno, altrimenti scarta questa carta e salta il turno" self.need_target = True - def play_card(self, player, against): + def play_card(self, player, against, _with=None): if against != None and not isinstance(player.game.get_player_named(against).role, r.Sheriff): player.sio.emit('chat_message', room=player.game.name, data=f'{self.name} ha giocato {self.name} contro {against}.') @@ -161,7 +162,7 @@ class Bang(Card): self.desc = "Spara a un giocatore a distanta raggiungibile. Se non hai armi la distanza di default è 1" self.need_target = True - def play_card(self, player, against): + def play_card(self, player, against, _with=None): if player.has_played_bang and not any([isinstance(c, Volcanic) for c in player.equipment]) and against != None: return False elif against != None: @@ -180,7 +181,7 @@ class Birra(Card): self.icon = '🍺' self.desc = "Gioca questa carta per recuperare un punto vita. Non puoi andare oltre al limite massimo del tuo personaggio. Se stai per perdere l'ultimo punto vita puoi giocare questa carta anche nel turno dell'avversario. La birra non ha più effetto se ci sono solo due giocatori" - def play_card(self, player, against): + def play_card(self, player, against, _with=None): if len(player.game.players) != 2 and player.lives != player.max_lives: super().play_card(player, against=against) player.lives = min(player.lives+1, player.max_lives) @@ -199,7 +200,7 @@ class CatBalou(Card): self.desc = "Fai scartare una carta a un qualsiasi giocatore, scegli a caso dalla mano, oppure fra quelle che ha in gioco" self.need_target = True - def play_card(self, player, against): + def play_card(self, player, against, _with=None): if against != None and (len(player.game.get_player_named(against).hand) + len(player.game.get_player_named(against).equipment)) > 0: super().play_card(player, against=against) from bang.players import PendingAction @@ -217,7 +218,7 @@ class Diligenza(Card): self.icon = '🚡' self.desc = "Pesca 2 carte dalla cima del mazzo" - def play_card(self, player, against): + def play_card(self, player, against, _with=None): super().play_card(player, against=against) player.sio.emit('chat_message', room=player.game.name, data=f'{player.name} ha giocato {self.name} e ha pescato 2 carte.') @@ -233,7 +234,7 @@ class Duello(Card): self.icon = '⚔️' self.desc = "Gioca questa carta contro un qualsiasi giocatore. A turno, cominciando dal tuo avversario, potete scartare una carta Bang!, il primo giocatore che non lo fa perde 1 vita" - def play_card(self, player, against): + def play_card(self, player, against, _with=None): if against != None: super().play_card(player, against=against) player.game.duel(player, against) @@ -247,7 +248,7 @@ class Emporio(Card): self.icon = '🏪' self.desc = "Scopri dal mazzo tante carte quanto il numero di giocatori, a turno, partendo da te, scegliete una carta e aggiungetela alla vostra mano" - def play_card(self, player, against): + def play_card(self, player, against, _with=None): super().play_card(player, against=against) player.game.emporio() return True @@ -259,7 +260,7 @@ class Gatling(Card): self.icon = '🛰' self.desc = "Spara a tutti gli altri giocatori" - def play_card(self, player, against): + def play_card(self, player, against, _with=None): super().play_card(player, against=against) player.game.attack_others(player) return True @@ -271,7 +272,7 @@ class Indiani(Card): self.icon = '🏹' self.desc = "Tutti gli altri giocatori devono scartare un Bang! o perdere una vita" - def play_card(self, player, against): + def play_card(self, player, against, _with=None): super().play_card(player, against=against) player.game.indian_others(player) return True @@ -283,7 +284,7 @@ class Mancato(Card): self.icon = '😅' self.desc = "Usa questa carta per annullare un bang" - def play_card(self, player, against): + def play_card(self, player, against, _with=None): import bang.characters as chars if (not player.has_played_bang and against != None and isinstance(player.character, chars.CalamityJanet)): player.sio.emit('chat_message', room=player.game.name, @@ -301,7 +302,7 @@ class Panico(Card): self.need_target = True self.desc = "Pesca una carta da un giocatore a distanza 1, scegli a caso dalla mano, oppure fra quelle che ha in gioco" - def play_card(self, player, against): + def play_card(self, player, against, _with=None): if against != None and (len(player.game.get_player_named(against).hand) + len(player.game.get_player_named(against).equipment)) > 0: super().play_card(player, against=against) from bang.players import PendingAction @@ -319,7 +320,7 @@ class Saloon(Card): self.desc = "Tutti i giocatori recuperano un punto vita compreso chi gioca la carta" self.icon = '🍻' - def play_card(self, player, against): + def play_card(self, player, against, _with=None): player.sio.emit('chat_message', room=player.game.name, data=f'{player.name} ha giocato {self.name} e ha curato 1 punto vita a tutti.') for p in player.game.players: @@ -334,7 +335,7 @@ class WellsFargo(Card): self.desc = "Pesca 3 carte dalla cima del mazzo" self.icon = '💸' - def play_card(self, player, against): + def play_card(self, player, against, _with=None): player.sio.emit('chat_message', room=player.game.name, data=f'{player.name} ha giocato {self.name} e ha pescato 3 carte.') for i in range(3): diff --git a/backend/bang/expansions/dodge_city/cards.py b/backend/bang/expansions/dodge_city/cards.py index 0e4c029..f129136 100644 --- a/backend/bang/expansions/dodge_city/cards.py +++ b/backend/bang/expansions/dodge_city/cards.py @@ -19,7 +19,7 @@ class Pugno(Card): self.desc = "Spara a un giocatore a distanta 1" self.need_target = True - def play_card(self, player, against): + def play_card(self, player, against, _with=None): if against != None: import bang.characters as chars super().play_card(player, against=against) @@ -34,13 +34,28 @@ class Schivata(Mancato): self.icon = '🙅‍♂️' self.desc += " e poi pesca una carta" - def play_card(self, player, against): + def play_card(self, player, against, _with=None): return False def use_card(self, player): player.hand.append(player.game.deck.draw()) player.notify_self() +class RagTime(Panico): + def __init__(self, suit, number): + Card.__init__(self, suit, 'Rag Time', number) + self.icon = '🎹' + self.desc = "Ruba 1 carta dalla mano di un giocatore" + self.need_target = True + self.need_with = True + + def play_card(self, player, against, _with): + if against != None and _with != None: + player.game.deck.scrap(_with) + super().play_card(player, against=against) + return True + return False + def get_starting_deck() -> List[Card]: return [ #TODO: aggiungere anche le carte normalmente presenti https://bang.dvgiochi.com/cardslist.php?id=3 @@ -65,4 +80,5 @@ def get_starting_deck() -> List[Card]: Pugno(Suit.SPADES, 10), Schivata(Suit.DIAMONDS, 7), Schivata(Suit.HEARTS, 'K'), + RagTime(Suit.HEARTS, 9) ] diff --git a/backend/bang/players.py b/backend/bang/players.py index 381f702..69d6fdc 100644 --- a/backend/bang/players.py +++ b/backend/bang/players.py @@ -248,18 +248,23 @@ class Player: s += f"equipment {[str(c) for c in self.equipment]}" return s - def play_card(self, hand_index: int, against=None): + def play_card(self, hand_index: int, against=None, _with=None): if not (0 <= hand_index < len(self.hand)): print('illegal') return card: cs.Card = self.hand.pop(hand_index) - print(self.name, 'is playing ', card, ' against:', against) - did_play_card = card.play_card(self, against) + withCard: cs.Card = None + if _with: + withCard = self.hand.pop(_with) if hand_index > _with else self.hand.pop(_with - 1) + print(self.name, 'is playing ', card, ' against:', against, ' with:', _with) + did_play_card = card.play_card(self, against, withCard) if not card.is_equipment: if did_play_card: self.game.deck.scrap(card) else: self.hand.insert(hand_index, card) + if withCard: + self.hand.insert(_with, withCard) self.notify_self() def choose(self, card_index): diff --git a/frontend/src/components/Player.vue b/frontend/src/components/Player.vue index 6d3ebeb..9dace6e 100644 --- a/frontend/src/components/Player.vue +++ b/frontend/src/components/Player.vue @@ -32,8 +32,9 @@ - + + @@ -66,6 +67,7 @@ export default { hint: '', pending_action: null, card_against: null, + card_with: null, has_played_bang: false, playersDistances: [], is_my_turn: false, @@ -195,7 +197,9 @@ export default { let calamity_special = (card.name === 'Mancato!' && this.character.name === 'Calamity Janet') let cant_play_bang = (this.has_played_bang && this.equipment.filter(x => x.name == 'Volcanic').length == 0) if (this.pending_action == 2) { - if ((card.need_target || calamity_special) && !((card.name == 'Bang!' || (calamity_special && card.name=='Mancato!')) && cant_play_bang)) { + if (card.need_with && !this.card_with) { + this.card_with = card + } else if ((card.need_target || calamity_special) && !((card.name == 'Bang!' || (calamity_special && card.name=='Mancato!')) && cant_play_bang)) { if (card.name == 'Bang!' || calamity_special) this.range = this.sight else @@ -217,14 +221,21 @@ export default { this.really_play_card(this.card_against, player.name) this.card_against = null }, + selectWith(card) { + this.card_against = this.card_with + this.card_with = card + }, cancelCardAgainst() { this.card_against = null + this.card_with = null }, really_play_card(card, against) { let card_data = { index: this.hand.indexOf(card), - against: against + against: against, + with: this.hand.indexOf(this.card_with), } + this.card_with = null console.log(card_data) this.$socket.emit('play_card', card_data) }, From 67abec99ba4281228b2ec841711f4d87751bf995 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Thu, 26 Nov 2020 23:19:53 +0100 Subject: [PATCH 02/22] add all cards with scrap --- backend/bang/expansions/dodge_city/cards.py | 69 ++++++++++++++++++++- backend/bang/players.py | 2 +- frontend/src/components/Player.vue | 19 +++++- 3 files changed, 84 insertions(+), 6 deletions(-) diff --git a/backend/bang/expansions/dodge_city/cards.py b/backend/bang/expansions/dodge_city/cards.py index f129136..c5d1fb0 100644 --- a/backend/bang/expansions/dodge_city/cards.py +++ b/backend/bang/expansions/dodge_city/cards.py @@ -21,7 +21,6 @@ class Pugno(Card): def play_card(self, player, against, _with=None): if against != None: - import bang.characters as chars super().play_card(player, against=against) player.game.attack(player, against) return True @@ -56,6 +55,68 @@ class RagTime(Panico): return True return False +class Rissa(Gatling): + def __init__(self, suit, number): + super().__init__(suit, number) + self.name = 'Rissa' + self.icon = '🥊' + self.need_with = True + + def play_card(self, player, against, _with): + if _with != None: + player.game.deck.scrap(_with) + super().play_card(player, against=against) + return True + return False + +class SpringField(Card): + def __init__(self, suit, number): + super().__init__(suit, 'Springfield', number) + self.icon = '🌵' + self.desc = "Spara a un giocatore" + self.need_target = True + self.need_with = True + + def play_card(self, player, against, _with=None): + if against != None and _with != None: + player.game.deck.scrap(_with) + super().play_card(player, against=against) + player.game.attack(player, against) + return True + return False + +class Tequila(Card): + def __init__(self, suit, number): + super().__init__(suit, 'Tequila', number) + self.icon = '🍹' + self.desc = "Fai recuperare 1 vita a un giocatore" + self.need_target = True + self.need_with = True + + def play_card(self, player, against, _with=None): + if against != None and _with != None: + player.game.deck.scrap(_with) + player.game.get_player_named(against).lives = min(player.game.get_player_named(against).lives+1, player.game.get_player_named(against).max_lives) + player.game.get_player_named(against).notify_self() + return True + return False + +class Whisky(Card): + def __init__(self, suit, number): + super().__init__(suit, 'Whisky', number) + self.icon = '🥃' + self.desc = "Recupera 2 vite" + self.need_with = True + + def play_card(self, player, against, _with=None): + if _with != None: + player.game.deck.scrap(_with) + player.lives = min(player.lives+2, player.max_lives) + player.notify_self() + return True + return False + + def get_starting_deck() -> List[Card]: return [ #TODO: aggiungere anche le carte normalmente presenti https://bang.dvgiochi.com/cardslist.php?id=3 @@ -80,5 +141,9 @@ def get_starting_deck() -> List[Card]: Pugno(Suit.SPADES, 10), Schivata(Suit.DIAMONDS, 7), Schivata(Suit.HEARTS, 'K'), - RagTime(Suit.HEARTS, 9) + RagTime(Suit.HEARTS, 9), + Rissa(Suit.SPADES, 'J'), + SpringField(Suit.SPADES, 'K'), + Tequila(Suit.CLUBS, 9), + Whisky(Suit.HEARTS, 'Q'), ] diff --git a/backend/bang/players.py b/backend/bang/players.py index 69d6fdc..98ad2bf 100644 --- a/backend/bang/players.py +++ b/backend/bang/players.py @@ -254,7 +254,7 @@ class Player: return card: cs.Card = self.hand.pop(hand_index) withCard: cs.Card = None - if _with: + if _with != None: withCard = self.hand.pop(_with) if hand_index > _with else self.hand.pop(_with - 1) print(self.name, 'is playing ', card, ' against:', against, ' with:', _with) did_play_card = card.play_card(self, against, withCard) diff --git a/frontend/src/components/Player.vue b/frontend/src/components/Player.vue index 9dace6e..e77e288 100644 --- a/frontend/src/components/Player.vue +++ b/frontend/src/components/Player.vue @@ -124,6 +124,9 @@ export default { }, notify_card(mess) { this.notifycard = mess + setTimeout(function(){ + this.notifycard = null + }.bind(this), 4000) } }, computed:{ @@ -222,8 +225,18 @@ export default { this.card_against = null }, selectWith(card) { - this.card_against = this.card_with - this.card_with = card + if (this.card_with.need_target) { + this.card_against = this.card_with + this.card_with = card + } else { + let card_data = { + index: this.hand.indexOf(this.card_with), + against: null, + with: this.hand.indexOf(card), + } + this.card_with = null + this.$socket.emit('play_card', card_data) + } }, cancelCardAgainst() { this.card_against = null @@ -233,7 +246,7 @@ export default { let card_data = { index: this.hand.indexOf(card), against: against, - with: this.hand.indexOf(this.card_with), + with: this.hand.indexOf(this.card_with) > -1 ? this.hand.indexOf(this.card_with):null, } this.card_with = null console.log(card_data) From ae8ee20fd56ca2acbe35f2b8f2ff879c68d21004 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Thu, 26 Nov 2020 23:28:22 +0100 Subject: [PATCH 03/22] cards with scrap alt-text --- backend/bang/expansions/dodge_city/cards.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/backend/bang/expansions/dodge_city/cards.py b/backend/bang/expansions/dodge_city/cards.py index c5d1fb0..c624826 100644 --- a/backend/bang/expansions/dodge_city/cards.py +++ b/backend/bang/expansions/dodge_city/cards.py @@ -47,6 +47,7 @@ class RagTime(Panico): self.desc = "Ruba 1 carta dalla mano di un giocatore" self.need_target = True self.need_with = True + self.alt_text = '‼️' def play_card(self, player, against, _with): if against != None and _with != None: @@ -61,6 +62,7 @@ class Rissa(Gatling): self.name = 'Rissa' self.icon = '🥊' self.need_with = True + self.alt_text = '‼️' def play_card(self, player, against, _with): if _with != None: @@ -76,6 +78,7 @@ class SpringField(Card): self.desc = "Spara a un giocatore" self.need_target = True self.need_with = True + self.alt_text = '‼️' def play_card(self, player, against, _with=None): if against != None and _with != None: @@ -92,6 +95,7 @@ class Tequila(Card): self.desc = "Fai recuperare 1 vita a un giocatore" self.need_target = True self.need_with = True + self.alt_text = '‼️' def play_card(self, player, against, _with=None): if against != None and _with != None: @@ -107,6 +111,7 @@ class Whisky(Card): self.icon = '🥃' self.desc = "Recupera 2 vite" self.need_with = True + self.alt_text = '‼️' def play_card(self, player, against, _with=None): if _with != None: From 5bfa7494236adcafbb2eb7d2c50afe5c2c2870ec Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Fri, 27 Nov 2020 12:19:54 +0100 Subject: [PATCH 04/22] rissa --- backend/bang/expansions/dodge_city/cards.py | 6 ++++-- backend/bang/players.py | 11 ++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/backend/bang/expansions/dodge_city/cards.py b/backend/bang/expansions/dodge_city/cards.py index c624826..49007af 100644 --- a/backend/bang/expansions/dodge_city/cards.py +++ b/backend/bang/expansions/dodge_city/cards.py @@ -56,18 +56,20 @@ class RagTime(Panico): return True return False -class Rissa(Gatling): +class Rissa(CatBalou): def __init__(self, suit, number): super().__init__(suit, number) self.name = 'Rissa' self.icon = '🥊' self.need_with = True + self.need_target = False self.alt_text = '‼️' def play_card(self, player, against, _with): if _with != None: player.game.deck.scrap(_with) - super().play_card(player, against=against) + player.event_type = 'rissa' + super().play_card(player, against=[p.name for p in player.game.players if p != player][0]) return True return False diff --git a/backend/bang/players.py b/backend/bang/players.py index 98ad2bf..1de8216 100644 --- a/backend/bang/players.py +++ b/backend/bang/players.py @@ -282,9 +282,14 @@ class Player: self.hand.append(card) else: self.game.deck.scrap(card) - self.target_p = '' - self.choose_action = '' - self.pending_action = PendingAction.PLAY + if self.event_type != 'rissa' or self.target_p == [p.name for p in self.game.players if p != self][-1]: + self.target_p = '' + self.choose_action = '' + self.pending_action = PendingAction.PLAY + else: + self.target_p = self.game.players[self.game.players_map[self.target_p]+1].name + if self.target_p == self.name: + self.target_p = self.game.players[self.game.players_map[self.target_p]+1].name self.notify_self() # specifico per personaggio elif self.is_drawing and isinstance(self.character, chars.KitCarlson): From 0e0f3271bbdd5368aac5d79bc3ff23c9b4223d19 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Fri, 27 Nov 2020 12:30:20 +0100 Subject: [PATCH 05/22] room limit to 10 --- backend/bang/game.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/backend/bang/game.py b/backend/bang/game.py index 27bb909..db0658a 100644 --- a/backend/bang/game.py +++ b/backend/bang/game.py @@ -41,8 +41,11 @@ class Game: self.notify_room() def add_player(self, player: players.Player): - if player in self.players or len(self.players) >= 7: + if player in self.players or len(self.players) >= 10: return + if len(self.players) > 7: + if 'dodge_city' not in self.expansions: + self.expansions.append('dodge_city') player.join_game(self) self.players.append(player) print(f'Added player {player.name} to game') @@ -89,7 +92,7 @@ class Game: roles.Outlaw('Elimina il Vice 🎖, se non lo elimini tu elimina anche il Rinnegato') ] elif len(self.players) >= 4: - available_roles = [roles.Sheriff(), roles.Renegade(), roles.Outlaw(), roles.Outlaw(), roles.Vice(), roles.Outlaw(), roles.Vice()] + available_roles = [roles.Sheriff(), roles.Renegade(), roles.Outlaw(), roles.Outlaw(), roles.Vice(), roles.Outlaw(), roles.Vice(), roles.Outlaw(), roles.Vice(), roles.Outlaw()] available_roles = available_roles[:len(self.players)] random.shuffle(available_roles) for i in range(len(self.players)): From 18fdce103f55d1f8903c44ece03731ca7310d367 Mon Sep 17 00:00:00 2001 From: Giulio Date: Fri, 27 Nov 2020 12:52:49 +0100 Subject: [PATCH 06/22] updated descriptions and fix --- backend/bang/cards.py | 2 +- backend/bang/expansions/dodge_city/cards.py | 26 ++++++++++++--------- frontend/src/components/Player.vue | 2 +- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/backend/bang/cards.py b/backend/bang/cards.py index 5830144..769cfcc 100644 --- a/backend/bang/cards.py +++ b/backend/bang/cards.py @@ -110,7 +110,7 @@ class Prigione(Card): def play_card(self, player, against, _with=None): if against != None and not isinstance(player.game.get_player_named(against).role, r.Sheriff): player.sio.emit('chat_message', room=player.game.name, - data=f'{self.name} ha giocato {self.name} contro {against}.') + data=f'{player.name} ha giocato {self.name} contro {against}.') player.game.get_player_named(against).equipment.append(self) player.game.get_player_named(against).notify_self() return False diff --git a/backend/bang/expansions/dodge_city/cards.py b/backend/bang/expansions/dodge_city/cards.py index 49007af..0dc22de 100644 --- a/backend/bang/expansions/dodge_city/cards.py +++ b/backend/bang/expansions/dodge_city/cards.py @@ -44,10 +44,10 @@ class RagTime(Panico): def __init__(self, suit, number): Card.__init__(self, suit, 'Rag Time', number) self.icon = '🎹' - self.desc = "Ruba 1 carta dalla mano di un giocatore" + self.desc = "Ruba 1 carta dalla mano di un giocatore a prescindere dalla distanza" self.need_target = True self.need_with = True - self.alt_text = '‼️' + self.alt_text = '2🃏' def play_card(self, player, against, _with): if against != None and _with != None: @@ -61,9 +61,10 @@ class Rissa(CatBalou): super().__init__(suit, number) self.name = 'Rissa' self.icon = '🥊' + self.desc = "Fai scartare una carta a tutti gli altri giocatori, scegli a caso dalla mano, oppure fra quelle che hanno in gioco" self.need_with = True self.need_target = False - self.alt_text = '‼️' + self.alt_text = '2🃏' def play_card(self, player, against, _with): if _with != None: @@ -77,10 +78,10 @@ class SpringField(Card): def __init__(self, suit, number): super().__init__(suit, 'Springfield', number) self.icon = '🌵' - self.desc = "Spara a un giocatore" + self.desc = "Spara a un giocatore a prescindere dalla distanza" self.need_target = True self.need_with = True - self.alt_text = '‼️' + self.alt_text = '2🃏' def play_card(self, player, against, _with=None): if against != None and _with != None: @@ -94,13 +95,15 @@ class Tequila(Card): def __init__(self, suit, number): super().__init__(suit, 'Tequila', number) self.icon = '🍹' - self.desc = "Fai recuperare 1 vita a un giocatore" + self.desc = "Fai recuperare 1 vita a un giocatore a tua scelta, anche te stesso" self.need_target = True self.need_with = True - self.alt_text = '‼️' + self.alt_text = '2🃏' def play_card(self, player, against, _with=None): if against != None and _with != None: + beneficiario = f'{against}' if against != player.name else 'se stesso' + player.sio.emit('chat_message', room=player.game.name, data=f'{player.name} ha giocato {self.name} per {beneficiario}.') player.game.deck.scrap(_with) player.game.get_player_named(against).lives = min(player.game.get_player_named(against).lives+1, player.game.get_player_named(against).max_lives) player.game.get_player_named(against).notify_self() @@ -111,12 +114,13 @@ class Whisky(Card): def __init__(self, suit, number): super().__init__(suit, 'Whisky', number) self.icon = '🥃' - self.desc = "Recupera 2 vite" + self.desc = "Gioca questa carta per recuperare fino a 2 punti vita." self.need_with = True - self.alt_text = '‼️' + self.alt_text = '2🃏' def play_card(self, player, against, _with=None): if _with != None: + super().play_card(player, against=against) player.game.deck.scrap(_with) player.lives = min(player.lives+2, player.max_lives) player.notify_self() @@ -146,10 +150,10 @@ def get_starting_deck() -> List[Card]: Mancato(Suit.DIAMONDS, 8), Panico(Suit.HEARTS, 'J'), Pugno(Suit.SPADES, 10), - Schivata(Suit.DIAMONDS, 7), - Schivata(Suit.HEARTS, 'K'), RagTime(Suit.HEARTS, 9), Rissa(Suit.SPADES, 'J'), + Schivata(Suit.DIAMONDS, 7), + Schivata(Suit.HEARTS, 'K'), SpringField(Suit.SPADES, 'K'), Tequila(Suit.CLUBS, 9), Whisky(Suit.HEARTS, 'Q'), diff --git a/frontend/src/components/Player.vue b/frontend/src/components/Player.vue index e77e288..afd1599 100644 --- a/frontend/src/components/Player.vue +++ b/frontend/src/components/Player.vue @@ -34,7 +34,7 @@ - + From a4e3825ab10dc0fbc3af42bd25854cbdb97151b5 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Fri, 27 Nov 2020 13:24:42 +0100 Subject: [PATCH 07/22] fix cards with scrap --- backend/bang/expansions/dodge_city/cards.py | 1 + frontend/src/components/Player.vue | 1 + 2 files changed, 2 insertions(+) diff --git a/backend/bang/expansions/dodge_city/cards.py b/backend/bang/expansions/dodge_city/cards.py index 0dc22de..b9d65df 100644 --- a/backend/bang/expansions/dodge_city/cards.py +++ b/backend/bang/expansions/dodge_city/cards.py @@ -32,6 +32,7 @@ class Schivata(Mancato): self.name = 'Schivata' self.icon = '🙅‍♂️' self.desc += " e poi pesca una carta" + self.alt_text = '☝️🆓' def play_card(self, player, against, _with=None): return False diff --git a/frontend/src/components/Player.vue b/frontend/src/components/Player.vue index afd1599..7607bfe 100644 --- a/frontend/src/components/Player.vue +++ b/frontend/src/components/Player.vue @@ -227,6 +227,7 @@ export default { selectWith(card) { if (this.card_with.need_target) { this.card_against = this.card_with + this.range = this.card_against.range this.card_with = card } else { let card_data = { From 04715b2332d72c01bf5a14cb1f0c5abc9d93fbd0 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Fri, 27 Nov 2020 13:50:03 +0100 Subject: [PATCH 08/22] tequila self --- backend/bang/cards.py | 1 + backend/bang/expansions/dodge_city/cards.py | 1 + frontend/src/components/Player.vue | 13 ++++++++++++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/backend/bang/cards.py b/backend/bang/cards.py index 769cfcc..6667f89 100644 --- a/backend/bang/cards.py +++ b/backend/bang/cards.py @@ -35,6 +35,7 @@ class Card(ABC): self.alt_text = f'{self.range} 🔍' self.desc = desc self.need_target = False + self.can_target_self = False self.need_with = False def __str__(self): diff --git a/backend/bang/expansions/dodge_city/cards.py b/backend/bang/expansions/dodge_city/cards.py index b9d65df..ac35e8e 100644 --- a/backend/bang/expansions/dodge_city/cards.py +++ b/backend/bang/expansions/dodge_city/cards.py @@ -98,6 +98,7 @@ class Tequila(Card): self.icon = '🍹' self.desc = "Fai recuperare 1 vita a un giocatore a tua scelta, anche te stesso" self.need_target = True + self.can_target_self = True self.need_with = True self.alt_text = '2🃏' diff --git a/frontend/src/components/Player.vue b/frontend/src/components/Player.vue index 7607bfe..ac481de 100644 --- a/frontend/src/components/Player.vue +++ b/frontend/src/components/Player.vue @@ -85,6 +85,7 @@ export default { sidScrapForHealth: [], sidWantsScrapForHealth: false, mancato_needed: 0, + name: '', }), sockets: { role(role) { @@ -94,6 +95,7 @@ export default { }, self(self) { self = JSON.parse(self) + this.name = self.name this.pending_action = self.pending_action this.character = self.character this.character.is_character = true @@ -141,7 +143,7 @@ export default { }, visiblePlayers() { this.range; - return this.playersDistances.filter(x => { + let vis = this.playersDistances.filter(x => { if (!this.can_target_sheriff && x.is_sheriff) return false else @@ -153,6 +155,15 @@ export default { icon: player.is_sheriff ? '⭐' : '🤠', is_character: true, }}) + if (this.card_against && this.card_against.can_target_self) { + vis.push({ + name: this.name, + number: 0, + icon: 'TU', + is_character: true, + }) + } + return vis }, hasToPickResponse() { return !this.is_my_turn && this.pending_action == 0 From c6e0f957da6afefdec3529800da997d4be3400b1 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Fri, 27 Nov 2020 14:10:26 +0100 Subject: [PATCH 09/22] show name of player whom you are stealing/discarding --- frontend/src/components/Lobby.vue | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/Lobby.vue b/frontend/src/components/Lobby.vue index 073c40e..8df7db3 100644 --- a/frontend/src/components/Lobby.vue +++ b/frontend/src/components/Lobby.vue @@ -40,7 +40,7 @@ - + @@ -77,6 +77,7 @@ export default { availableCharacters: [], self: {}, hasToChoose: false, + target_p: '', chooseCards: [], wantsToEndTurn: false, selectedInfo: null, @@ -179,6 +180,7 @@ export default { }, choose(player_name) { console.log('choose from' + player_name) + this.target_p = player_name let pl = this.players.filter(x=>x.name === player_name)[0] console.log(pl) let arr = [] @@ -197,6 +199,7 @@ export default { console.log(card + ' ' + this.chooseCards.indexOf(card)) this.chooseCards = [] this.hasToChoose = false + this.target_p = '' }, drawFromPlayer(name) { console.log(name) From 3062bce6ca6310a6d42779d9de4030d65dd8501c Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Fri, 27 Nov 2020 17:59:33 +0100 Subject: [PATCH 10/22] localization --- frontend/package.json | 1 + frontend/src/App.vue | 36 +++++++++++-------- frontend/src/components/Chat.vue | 2 +- frontend/src/components/Chooser.vue | 9 +++-- frontend/src/components/Deck.vue | 2 +- frontend/src/components/Lobby.vue | 20 +++++------ frontend/src/components/Player.vue | 34 +++++++++--------- frontend/src/i18n/en.json | 55 +++++++++++++++++++++++++++++ frontend/src/i18n/index.js | 9 +++++ frontend/src/i18n/it.json | 55 +++++++++++++++++++++++++++++ frontend/src/main.js | 12 +++++++ frontend/yarn.lock | 5 +++ 12 files changed, 195 insertions(+), 45 deletions(-) create mode 100644 frontend/src/i18n/en.json create mode 100644 frontend/src/i18n/index.js create mode 100644 frontend/src/i18n/it.json diff --git a/frontend/package.json b/frontend/package.json index b552a24..9ad6b0c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -12,6 +12,7 @@ "pretty-checkbox-vue": "^1.1.9", "socket.io-client": "^3.0.3", "vue": "^2.6.11", + "vue-i18n": "^8.22.2", "vue-socket.io": "^3.0.10" }, "devDependencies": { diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 39f33c1..9052697 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -2,29 +2,29 @@
-

Scegli un username:

+

{{$t("choose_username")}}

-

Giocatori online: {{onlinePlayers}}

+

{{$t("online_players")}}{{onlinePlayers}}

-

Giocatori online: {{onlinePlayers}}

+

{{$t("online_players")}}{{onlinePlayers}}

-

Lobby disponibili:

+

{{$t("available_lobbies")}}

-

Nessuna lobby disponibile

+

{{$t("no_lobby_available")}}

-

Crea una lobby:

-

Nome:

+

{{$t("create_lobby")}}

+

{{$t("lobby_name")}}

@@ -33,9 +33,17 @@
-

Attenzione!

-

Connessione al server assente.

+

{{$t("warning")}}

+

{{$t("connection_error")}}

+
@@ -66,7 +74,7 @@ export default { getSelfCard() { return { name: this.username, - number: 'YOU', + number: this.$t('you'), icon: '🤠', is_character: true, } @@ -120,7 +128,7 @@ export default { e.preventDefault(); }, joinLobby(lobby) { - let password = lobby.locked ? prompt("Room password:", "") : ''; + let password = lobby.locked ? prompt(this.$t("room_password_prompt"), "") : ''; this.$socket.emit('join_room', {name:lobby.name,password:password}) }, init() { @@ -217,7 +225,7 @@ h1,h2,h3,h4,p,span,b,label{ transform: scale(0); } } -input { +input, select { border: 2px solid; border-radius: 4px; font-size: 1rem; @@ -227,7 +235,7 @@ input { transition: border-color 0.5s ease-out; } @media (prefers-color-scheme: dark) { - :root, #app, input { + :root, #app, input, select { background-color: #181a1b; color: rgb(174, 194, 211); } diff --git a/frontend/src/components/Chat.vue b/frontend/src/components/Chat.vue index 1528f07..1ec4706 100644 --- a/frontend/src/components/Chat.vue +++ b/frontend/src/components/Chat.vue @@ -1,6 +1,6 @@ @@ -133,7 +133,7 @@ export default { }, computed:{ respondText() { - return `Scegli come rispondere ${this.attacker?('a '+this.attacker):''}${(this.mancato_needed>1)?(' (NE OCCORRONO ' + this.mancato_needed + ')'):''}` + return `${this.$t('choose_response')}${this.attacker?(this.$t('choose_response_to')+this.attacker):''}${(this.mancato_needed>1)?(` (${this.$t('choose_response_needed')} ` + this.mancato_needed + ')'):''}` }, showScrapScreen() { return this.isEndingTurn && !this.canEndTurn && this.is_my_turn; @@ -159,7 +159,7 @@ export default { vis.push({ name: this.name, number: 0, - icon: 'TU', + icon: this.$t('you'), is_character: true, }) } @@ -171,7 +171,7 @@ export default { instruction() { if (this.pending_action == null) return '' - let x = ['▶️ Estrai una carta', '▶️ Pesca le tue carte', '▶️ Gioca le tue carte', '▶️ Rispondi alla carta', '⏸ Attendi', '▶️ Scegli una carta'] + let x = [this.$t('flip_card'), this.$t('draw_cards'), this.$t('play_cards'), this.$t('respond_card'), this.$t('wait'), this.$t('choose_cards')] return x[this.pending_action] }, canEndTurn() { @@ -179,7 +179,7 @@ export default { }, respondCards() { let cc = [{ - name: 'Prendi Danno', + name: this.$t('take_dmg'), icon: '❌', is_equipment: true, }] diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json new file mode 100644 index 0000000..7fd328b --- /dev/null +++ b/frontend/src/i18n/en.json @@ -0,0 +1,55 @@ +{ + "trademark": "Bang! is a trademark owned by DVGiochi", + "online_players": "Online players: ", + "choose_username": "Pick an username:", + "available_lobbies": "Available Lobbies:", + "no_lobby_available": "No lobbies available", + "create_lobby": "Open a lobby:", + "lobby_name": "Name:", + "warning": "Warning!", + "connection_error": "Cannot connect to server.", + "chat": "Chat", + "end_turn": "End Turn!", + "start_game": "Start!", + "expansions": "Expansions", + "details": "Details", + "ok": "OK", + "you": "YOU", + "owner": "OWNER", + "cancel": "CANCEL", + "password": "Password: ", + "room_password_prompt": "Lobby Password: ", + "private_room": "Private Lobby", + "room": "Lobby: ", + "room_players": "Players (you are {username})", + "choose_character": "Choose your character", + "choose_card": "Choose a card", + "choose_card_from": " from ", + "flip_card": "▶️ Flip a card", + "draw_cards": "▶️ Draw you cards from the deck", + "play_cards": "▶️ Play your cards", + "respond_card":"▶️ Respond to the card", + "wait": "⏸ Wait", + "choose_cards": "▶️ Choose a card", + "take_dmg": "Take damage", + "choose_response": "Choose your response ", + "choose_response_to": "to ", + "choose_response_needed": "NEEDED ", + "hand": "HAND", + "card_against": "Who will you play your card against?", + "choose_card_to_get": "Choose a card", + "you_died":"YOU DIED", + "spectate":"SPECTATE", + "you_win":"YOU WON", + "you_lose":"YOU LOST", + "special_ability": "SPECIAL ABILITY", + "discard": "DISCARD", + "to_regain_1_hp": "TO REGAIN 1 HP", + "play_your_turn": "PLAY YOUR TURN", + "you_are": "You are", + "did_pick_as": "picked this as second card", + "if_card_red":"If the card is diamonds or hearts, he picks another card.", + "choose_scarp_card_to": "CHOOSE WHICH CARD TO DISCARD TO USE", + "pick_a_card": "FLIP A CARD", + "to_defend_from": "TO DEFEND YOURSELF FROM" +} \ No newline at end of file diff --git a/frontend/src/i18n/index.js b/frontend/src/i18n/index.js new file mode 100644 index 0000000..56667db --- /dev/null +++ b/frontend/src/i18n/index.js @@ -0,0 +1,9 @@ +import it from './it.json' +import en from './en.json' + +export const defaultLocale = 'it' + +export const languages = { + it: it, + en: en, +} \ No newline at end of file diff --git a/frontend/src/i18n/it.json b/frontend/src/i18n/it.json new file mode 100644 index 0000000..7d256d5 --- /dev/null +++ b/frontend/src/i18n/it.json @@ -0,0 +1,55 @@ +{ + "trademark": "Bang! è un marchio registrato DVGiochi", + "online_players": "Giocatori online: ", + "choose_username": "Scegli un username:", + "available_lobbies": "Stanze disponibili:", + "no_lobby_available": "Nessuna stanza disponibile", + "create_lobby": "Crea una stanza:", + "lobby_name": "Nome:", + "warning": "Attenzione!", + "connection_error": "Connessione al server assente.", + "chat": "Chat", + "end_turn": "Termina turno!", + "start_game": "Avvia!", + "expansions": "Espansioni", + "details": "Dettagli", + "ok": "OK", + "you": "TU", + "owner": "GESTORE", + "cancel": "ANNULLA", + "password": "Password: ", + "room_password_prompt": "Password Stanza: ", + "private_room": "Stanza Privata", + "room": "Stanza: ", + "room_players": "Giocatori (tu sei {username})", + "choose_character": "Scegli il tuo personaggio", + "choose_card": "Scegli una carta", + "choose_card_from": " da ", + "flip_card": "▶️ Estrai una carta", + "draw_cards": "▶️ Pesca le tue carte", + "play_cards": "▶️ Gioca le tue carte", + "respond_card": "▶️ Rispondi alla carta", + "wait": "⏸ Attendi", + "choose_cards": "▶️ Scegli una carta", + "take_dmg": "Prendi Danno", + "choose_response": "Scegli come rispondere ", + "choose_response_to": "a ", + "choose_response_needed": "NE OCCORRONO ", + "hand": "MANO", + "card_against": "Contro chi vuoi giocare la carta", + "choose_card_to_get": "Scegli che carta pescare", + "you_died": "SEI MORTO", + "spectate": "SPETTATORE", + "you_win": "HAI VINTO", + "you_lose": "HAI PERSO", + "special_ability": "ABILITÀ SPECIALE", + "discard": "SCARTA", + "to_regain_1_hp": "PER RECUPERARE 1 VITA", + "play_your_turn": "GIOCA IL TUO TURNO", + "you_are": "Tu sei", + "did_pick_as": "ha pescato come seconda carta", + "if_card_red": "Se la carta è cuori o quadri ne pesca un'altra", + "choose_scarp_card_to": "SCEGLI CHE CARTA SCARTARE PER USARE", + "pick_a_card": "ESTRAI UNA CARTA", + "to_defend_from": "PER DIFENDERTI DA" +} \ No newline at end of file diff --git a/frontend/src/main.js b/frontend/src/main.js index d86bdbf..83cb373 100644 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -11,6 +11,18 @@ Vue.use(new VueSocketIO({ import PrettyCheckbox from 'pretty-checkbox-vue'; Vue.use(PrettyCheckbox) +import VueI18n from 'vue-i18n' +Vue.use(VueI18n) + +import { languages, defaultLocale } from './i18n'; +const messages = Object.assign(languages) + +const i18n = new VueI18n({ + locale: defaultLocale, + messages +}) + new Vue({ + i18n, render: h => h(App), }).$mount('#app') diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 9c6e53c..c6335a4 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -8310,6 +8310,11 @@ vue-hot-reload-api@^2.3.0: resolved "https://registry.npm.taobao.org/vue-hot-reload-api/download/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2" integrity sha1-UylVzB6yCKPZkLOp+acFdGV+CPI= +vue-i18n@^8.22.2: + version "8.22.2" + resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-8.22.2.tgz#58299a5a050e67b4f799d96fee7dd8bd269e0907" + integrity sha512-rb569fVJInPUgS/bbCxEQ9DrAoFTntuJvYoK4Fpk2VfNbA09WzdTKk57ppjz3S+ps9hW+p9H+2ASgMvojedkow== + "vue-loader-v16@npm:vue-loader@^16.0.0-beta.7": version "16.0.0-rc.2" resolved "https://registry.npm.taobao.org/vue-loader/download/vue-loader-16.0.0-rc.2.tgz?cache=0&sync_timestamp=1605670716799&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-loader%2Fdownload%2Fvue-loader-16.0.0-rc.2.tgz#b6a7e7f30d28f35659a83de41f4a1831a4232a04" From 8351bff0d8885fd1772dea51730a760ef47e822d Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Fri, 27 Nov 2020 18:04:29 +0100 Subject: [PATCH 11/22] fix errors --- frontend/src/components/Chooser.vue | 10 ++++++---- frontend/src/components/Deck.vue | 11 +++++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/Chooser.vue b/frontend/src/components/Chooser.vue index abcb66c..c8de680 100644 --- a/frontend/src/components/Chooser.vue +++ b/frontend/src/components/Chooser.vue @@ -5,7 +5,7 @@

{{hintText}}

-
{{cancelText}}
+
{{realCancelText}}

{{desc}}

@@ -30,7 +30,8 @@ export default { hintText: String, }, data: () => ({ - desc: '' + desc: '', + realCancelText: '' }), computed: { showCancelBtn() { @@ -45,8 +46,9 @@ export default { } }, mounted() { - if (this.cancelText == '') { - this.cancelText = this.$t('cancel') + this.realCancelText = this.cancelText + if (this.realCancelText == '') { + this.realCancelText = this.$t('cancel') } }, } diff --git a/frontend/src/components/Deck.vue b/frontend/src/components/Deck.vue index 911d950..eeeb2ec 100644 --- a/frontend/src/components/Deck.vue +++ b/frontend/src/components/Deck.vue @@ -30,10 +30,7 @@ export default { name: 'PewPew!', icon: '💥', }, - endTurnCard: { - name: this.$t('end_turn'), - icon: '⛔️' - }, + endTurnCard: null, lastScrap: null, previousScrap: null, pending_action: false, @@ -49,6 +46,12 @@ export default { this.lastScrap = card } }, + mounted() { + this.endTurnCard = { + name: this.$t('end_turn'), + icon: '⛔️' + } + }, methods: { action(pile) { if (this.pending_action !== false && this.pending_action < 2) { From 6c9dc746fd7a7fcee3de9be7520d717f3f3e1a78 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Fri, 27 Nov 2020 18:07:30 +0100 Subject: [PATCH 12/22] fix rissa causing bugs --- backend/bang/players.py | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/bang/players.py b/backend/bang/players.py index 1de8216..24d323f 100644 --- a/backend/bang/players.py +++ b/backend/bang/players.py @@ -283,6 +283,7 @@ class Player: else: self.game.deck.scrap(card) if self.event_type != 'rissa' or self.target_p == [p.name for p in self.game.players if p != self][-1]: + self.event_type = '' self.target_p = '' self.choose_action = '' self.pending_action = PendingAction.PLAY From e48fd93bb85fe5de9c7aebaa3d36a056cfcb859e Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Fri, 27 Nov 2020 18:09:48 +0100 Subject: [PATCH 13/22] one more conditions for rissa --- backend/bang/players.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/bang/players.py b/backend/bang/players.py index 24d323f..c6c8907 100644 --- a/backend/bang/players.py +++ b/backend/bang/players.py @@ -282,7 +282,7 @@ class Player: self.hand.append(card) else: self.game.deck.scrap(card) - if self.event_type != 'rissa' or self.target_p == [p.name for p in self.game.players if p != self][-1]: + if self.event_type != 'rissa' or (self.event_type == 'rissa' and self.target_p == [p.name for p in self.game.players if p != self][-1]): self.event_type = '' self.target_p = '' self.choose_action = '' From 07f4f5b92df7fbbde39e0153da7b6da11d99930a Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Fri, 27 Nov 2020 19:59:18 +0100 Subject: [PATCH 14/22] fix dinamite, prigione lucky duke --- backend/bang/players.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/bang/players.py b/backend/bang/players.py index c6c8907..6e274fb 100644 --- a/backend/bang/players.py +++ b/backend/bang/players.py @@ -74,7 +74,7 @@ class Player: self.max_lives = self.character.max_lives + self.role.health_mod self.lives = self.max_lives self.hand = [] - self.equipment = [] + self.equipment = [cs.Dinamite(1,1), cs.Prigione(1,1)] self.pending_action = PendingAction.WAIT def set_available_character(self, available): @@ -203,6 +203,7 @@ class Player: else: self.game.next_player().equipment.append(self.equipment.pop(i)) self.game.next_player().notify_self() + break if any([isinstance(c, cs.Dinamite) or isinstance(c, cs.Prigione) for c in self.equipment]): self.notify_self() return @@ -218,7 +219,7 @@ class Player: self.game.deck.scrap(self.equipment.pop(i)) self.end_turn(forced=True) return - else: + elif pickable_cards == 0: self.game.deck.scrap(self.equipment.pop(i)) break break From f4bc8d11428f7c5aa730fdab0dbb65e00277c2a9 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Fri, 27 Nov 2020 21:52:13 +0100 Subject: [PATCH 15/22] fix problems --- backend/bang/players.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/bang/players.py b/backend/bang/players.py index 6e274fb..15337db 100644 --- a/backend/bang/players.py +++ b/backend/bang/players.py @@ -74,7 +74,7 @@ class Player: self.max_lives = self.character.max_lives + self.role.health_mod self.lives = self.max_lives self.hand = [] - self.equipment = [cs.Dinamite(1,1), cs.Prigione(1,1)] + self.equipment = [] self.pending_action = PendingAction.WAIT def set_available_character(self, available): From 8b33fc0f4515bfe4ca2c0a98c98502d7f14fcebf Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Fri, 27 Nov 2020 23:05:09 +0100 Subject: [PATCH 16/22] fix max players --- backend/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/__init__.py b/backend/__init__.py index 773c53d..db07c6e 100644 --- a/backend/__init__.py +++ b/backend/__init__.py @@ -19,7 +19,7 @@ games: List[Game] = [] online_players = 0 def advertise_lobbies(): - sio.emit('lobbies', room='lobby', data=[{'name': g.name, 'players': len(g.players), 'locked': g.password != ''} for g in games if not g.started and len(g.players) < 7]) + sio.emit('lobbies', room='lobby', data=[{'name': g.name, 'players': len(g.players), 'locked': g.password != ''} for g in games if not g.started and len(g.players) < 10]) @sio.event def connect(sid, environ): From 7ed10dee677911b60ab6d0f8a1691911d2889c4e Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Sat, 28 Nov 2020 00:32:12 +0100 Subject: [PATCH 17/22] fix balance --- backend/bang/game.py | 2 +- backend/bang/roles.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/bang/game.py b/backend/bang/game.py index db0658a..7845820 100644 --- a/backend/bang/game.py +++ b/backend/bang/game.py @@ -92,7 +92,7 @@ class Game: roles.Outlaw('Elimina il Vice 🎖, se non lo elimini tu elimina anche il Rinnegato') ] elif len(self.players) >= 4: - available_roles = [roles.Sheriff(), roles.Renegade(), roles.Outlaw(), roles.Outlaw(), roles.Vice(), roles.Outlaw(), roles.Vice(), roles.Outlaw(), roles.Vice(), roles.Outlaw()] + available_roles = [roles.Sheriff(), roles.Renegade(), roles.Outlaw(), roles.Outlaw(), roles.Vice(), roles.Outlaw(), roles.Vice(), roles.Renegade(), roles.Outlaw(), roles.Vice(), roles.Outlaw()] available_roles = available_roles[:len(self.players)] random.shuffle(available_roles) for i in range(len(self.players)): diff --git a/backend/bang/roles.py b/backend/bang/roles.py index 834f173..e311a43 100644 --- a/backend/bang/roles.py +++ b/backend/bang/roles.py @@ -75,7 +75,7 @@ class Renegade(Role): return True elif initial_players == 3 and attacker_role != None: return isinstance(dead_role, Outlaw) and isinstance(attacker_role, Renegade) - elif initial_players != 3 and len(alive_players) == 1 and isinstance(alive_players[0].role, Renegade): + elif initial_players != 3 and len(alive_players) == 1 and alive_players[0].role == self: print("The Renegade won!") return True return False From 0c39a20b774a15ce1a2b7907e8e4239166446f9c Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Sat, 28 Nov 2020 00:38:23 +0100 Subject: [PATCH 18/22] fix stuff --- backend/bang/cards.py | 2 +- backend/bang/expansions/dodge_city/cards.py | 4 ++-- backend/bang/players.py | 7 ++++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/backend/bang/cards.py b/backend/bang/cards.py index 6667f89..e351ca5 100644 --- a/backend/bang/cards.py +++ b/backend/bang/cards.py @@ -160,7 +160,7 @@ class Bang(Card): def __init__(self, suit, number): super().__init__(suit, 'Bang!', number) self.icon = '💥' - self.desc = "Spara a un giocatore a distanta raggiungibile. Se non hai armi la distanza di default è 1" + self.desc = "Spara a un giocatore a distanza raggiungibile. Se non hai armi la distanza di default è 1" self.need_target = True def play_card(self, player, against, _with=None): diff --git a/backend/bang/expansions/dodge_city/cards.py b/backend/bang/expansions/dodge_city/cards.py index ac35e8e..661613c 100644 --- a/backend/bang/expansions/dodge_city/cards.py +++ b/backend/bang/expansions/dodge_city/cards.py @@ -16,7 +16,7 @@ class Pugno(Card): def __init__(self, suit, number): super().__init__(suit, 'Pugno!', number, range=1) self.icon = '👊' - self.desc = "Spara a un giocatore a distanta 1" + self.desc = "Spara a un giocatore a distanza 1" self.need_target = True def play_card(self, player, against, _with=None): @@ -71,7 +71,7 @@ class Rissa(CatBalou): if _with != None: player.game.deck.scrap(_with) player.event_type = 'rissa' - super().play_card(player, against=[p.name for p in player.game.players if p != player][0]) + super().play_card(player, against=[p.name for p in player.game.players if p != player and (len(p.hand)+len(p.equipment)) > 0][0]) return True return False diff --git a/backend/bang/players.py b/backend/bang/players.py index 15337db..fd9162d 100644 --- a/backend/bang/players.py +++ b/backend/bang/players.py @@ -283,15 +283,16 @@ class Player: self.hand.append(card) else: self.game.deck.scrap(card) - if self.event_type != 'rissa' or (self.event_type == 'rissa' and self.target_p == [p.name for p in self.game.players if p != self][-1]): + if self.event_type != 'rissa' or (self.event_type == 'rissa' and self.target_p == [p.name for p in self.game.players if p != self and (len(p.hand)+len(p.equipment)) > 0][-1]): self.event_type = '' self.target_p = '' self.choose_action = '' self.pending_action = PendingAction.PLAY else: - self.target_p = self.game.players[self.game.players_map[self.target_p]+1].name - if self.target_p == self.name: + while len(self.game.players[self.game.players_map[self.target_p]+1].hand) + len(self.game.players[self.game.players_map[self.target_p]+1].equipment) == 0: self.target_p = self.game.players[self.game.players_map[self.target_p]+1].name + if self.target_p == self.name: + self.target_p = self.game.players[self.game.players_map[self.target_p]+1].name self.notify_self() # specifico per personaggio elif self.is_drawing and isinstance(self.character, chars.KitCarlson): From 5f918299072d5c30f205e777df7383bbfd52a4d5 Mon Sep 17 00:00:00 2001 From: Giulio Date: Sat, 28 Nov 2020 01:44:23 +0100 Subject: [PATCH 19/22] fix birra e rissa --- backend/bang/cards.py | 5 +++-- backend/bang/expansions/dodge_city/cards.py | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/backend/bang/cards.py b/backend/bang/cards.py index e351ca5..46af5c2 100644 --- a/backend/bang/cards.py +++ b/backend/bang/cards.py @@ -183,7 +183,7 @@ class Birra(Card): self.desc = "Gioca questa carta per recuperare un punto vita. Non puoi andare oltre al limite massimo del tuo personaggio. Se stai per perdere l'ultimo punto vita puoi giocare questa carta anche nel turno dell'avversario. La birra non ha più effetto se ci sono solo due giocatori" def play_card(self, player, against, _with=None): - if len(player.game.players) != 2 and player.lives != player.max_lives: + if len(player.game.players) != 2: super().play_card(player, against=against) player.lives = min(player.lives+1, player.max_lives) return True @@ -203,7 +203,8 @@ class CatBalou(Card): def play_card(self, player, against, _with=None): if against != None and (len(player.game.get_player_named(against).hand) + len(player.game.get_player_named(against).equipment)) > 0: - super().play_card(player, against=against) + if self.name != 'Rissa' + super().play_card(player, against=against) from bang.players import PendingAction player.pending_action = PendingAction.CHOOSE player.choose_action = 'discard' diff --git a/backend/bang/expansions/dodge_city/cards.py b/backend/bang/expansions/dodge_city/cards.py index 661613c..a38afd0 100644 --- a/backend/bang/expansions/dodge_city/cards.py +++ b/backend/bang/expansions/dodge_city/cards.py @@ -72,6 +72,7 @@ class Rissa(CatBalou): player.game.deck.scrap(_with) player.event_type = 'rissa' super().play_card(player, against=[p.name for p in player.game.players if p != player and (len(p.hand)+len(p.equipment)) > 0][0]) + player.sio.emit('chat_message', room=player.game.name, data=f'{player.name} ha giocato {self.name}) return True return False @@ -105,7 +106,7 @@ class Tequila(Card): def play_card(self, player, against, _with=None): if against != None and _with != None: beneficiario = f'{against}' if against != player.name else 'se stesso' - player.sio.emit('chat_message', room=player.game.name, data=f'{player.name} ha giocato {self.name} per {beneficiario}.') + player.sio.emit('chat_message', room=player.game.name, data=f'{player.name} ha giocato {self.name} per {beneficiario}') player.game.deck.scrap(_with) player.game.get_player_named(against).lives = min(player.game.get_player_named(against).lives+1, player.game.get_player_named(against).max_lives) player.game.get_player_named(against).notify_self() @@ -116,7 +117,7 @@ class Whisky(Card): def __init__(self, suit, number): super().__init__(suit, 'Whisky', number) self.icon = '🥃' - self.desc = "Gioca questa carta per recuperare fino a 2 punti vita." + self.desc = "Gioca questa carta per recuperare fino a 2 punti vita" self.need_with = True self.alt_text = '2🃏' From 5907379db8bbf9bdaac7099f2a08272133cd5fa1 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Sat, 28 Nov 2020 11:20:19 +0100 Subject: [PATCH 20/22] distribute roles before available characters --- backend/bang/game.py | 14 ++++++++------ frontend/src/components/Lobby.vue | 12 ------------ frontend/src/components/Player.vue | 9 +++++++++ 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/backend/bang/game.py b/backend/bang/game.py index 7845820..7c69cbe 100644 --- a/backend/bang/game.py +++ b/backend/bang/game.py @@ -64,7 +64,13 @@ class Game: self.readyCount += 1 self.notify_room() if self.readyCount == len(self.players): - self.distribute_roles() + for i in range(len(self.players)): + self.sio.emit('chat_message', room=self.name, data=f'{self.players[i].name} ha come personaggio {self.players[i].character.name}, la sua abilità speciale è: {self.players[i].character.desc}') + self.players[i].prepare() + for k in range(self.players[i].max_lives): + self.players[i].hand.append(self.deck.draw()) + self.players[i].notify_self() + self.players[self.turn].play_turn() def choose_characters(self): char_cards = random.sample(characters.all_characters(), len(self.players)*2) @@ -81,6 +87,7 @@ class Game: self.started = True self.deck = Deck(self) self.initial_players = len(self.players) + self.distribute_roles() self.choose_characters() def distribute_roles(self): @@ -96,17 +103,12 @@ class Game: available_roles = available_roles[:len(self.players)] random.shuffle(available_roles) for i in range(len(self.players)): - self.sio.emit('chat_message', room=self.name, data=f'{self.players[i].name} ha come personaggio {self.players[i].character.name}, la sua abilità speciale è: {self.players[i].character.desc}') self.players[i].set_role(available_roles[i]) if isinstance(available_roles[i], roles.Sheriff) or (len(available_roles) == 3 and isinstance(available_roles[i], roles.Vice)): if isinstance(available_roles[i], roles.Sheriff): self.sio.emit('chat_message', room=self.name, data=f'{self.players[i].name} È lo sceriffo') self.turn = i - self.players[i].prepare() - for k in range(self.players[i].max_lives): - self.players[i].hand.append(self.deck.draw()) self.players[i].notify_self() - self.play_turn() def attack_others(self, attacker: players.Player): attacker.pending_action = players.PendingAction.WAIT diff --git a/frontend/src/components/Lobby.vue b/frontend/src/components/Lobby.vue index 9976d0f..8457c6e 100644 --- a/frontend/src/components/Lobby.vue +++ b/frontend/src/components/Lobby.vue @@ -39,7 +39,6 @@ - @@ -74,7 +73,6 @@ export default { players: [], messages: [], distances: {}, - availableCharacters: [], self: {}, hasToChoose: false, target_p: '', @@ -99,9 +97,6 @@ export default { } }) }, - characters(data) { - this.availableCharacters = JSON.parse(data) - }, start() { this.started = true; }, @@ -130,9 +125,6 @@ export default { } return null; }, - showChooser() { - return this.availableCharacters.length > 0; - }, playersTable() { console.log('update players') return this.players.map((x,i) => { @@ -174,10 +166,6 @@ export default { this.started = true; this.$socket.emit('start_game') }, - setCharacter(char) { - this.availableCharacters = [] - this.$socket.emit('set_character', char.name) - }, choose(player_name) { console.log('choose from' + player_name) this.target_p = player_name diff --git a/frontend/src/components/Player.vue b/frontend/src/components/Player.vue index a7da1f0..f996dba 100644 --- a/frontend/src/components/Player.vue +++ b/frontend/src/components/Player.vue @@ -33,6 +33,7 @@ + @@ -60,6 +61,7 @@ export default { data: () => ({ my_role: null, character: null, + availableCharacters: [], equipment: [], hand: [], lives: 0, @@ -93,6 +95,9 @@ export default { this.my_role.is_back = true this.show_role = true }, + characters(data) { + this.availableCharacters = JSON.parse(data) + }, self(self) { self = JSON.parse(self) this.name = self.name @@ -190,6 +195,10 @@ export default { } }, methods: { + setCharacter(char) { + this.availableCharacters = [] + this.$socket.emit('set_character', char.name) + }, sidScrap(c) { this.sidScrapForHealth.push(this.hand.indexOf(c)) if (this.sidScrapForHealth.length == 2) { From 7444fba0d399910244fa91fd923d4d4e08d28ea2 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Sat, 28 Nov 2020 11:25:57 +0100 Subject: [PATCH 21/22] fix errori giulio --- backend/bang/cards.py | 2 +- backend/bang/expansions/dodge_city/cards.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/bang/cards.py b/backend/bang/cards.py index 46af5c2..7cce19e 100644 --- a/backend/bang/cards.py +++ b/backend/bang/cards.py @@ -203,7 +203,7 @@ class CatBalou(Card): def play_card(self, player, against, _with=None): if against != None and (len(player.game.get_player_named(against).hand) + len(player.game.get_player_named(against).equipment)) > 0: - if self.name != 'Rissa' + if self.name == 'Cat Balou': super().play_card(player, against=against) from bang.players import PendingAction player.pending_action = PendingAction.CHOOSE diff --git a/backend/bang/expansions/dodge_city/cards.py b/backend/bang/expansions/dodge_city/cards.py index a38afd0..b5f57bc 100644 --- a/backend/bang/expansions/dodge_city/cards.py +++ b/backend/bang/expansions/dodge_city/cards.py @@ -72,7 +72,7 @@ class Rissa(CatBalou): player.game.deck.scrap(_with) player.event_type = 'rissa' super().play_card(player, against=[p.name for p in player.game.players if p != player and (len(p.hand)+len(p.equipment)) > 0][0]) - player.sio.emit('chat_message', room=player.game.name, data=f'{player.name} ha giocato {self.name}) + player.sio.emit('chat_message', room=player.game.name, data=f'{player.name} ha giocato {self.name}') return True return False From 1370efc98a8a29aaf9defae73f2801828726bd48 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Sat, 28 Nov 2020 11:41:11 +0100 Subject: [PATCH 22/22] show hint for scrapped card --- frontend/src/components/Deck.vue | 29 ++++++++++++++++++----------- frontend/src/components/Player.vue | 16 ++++++++++------ 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/frontend/src/components/Deck.vue b/frontend/src/components/Deck.vue index eeeb2ec..dec366f 100644 --- a/frontend/src/components/Deck.vue +++ b/frontend/src/components/Deck.vue @@ -1,16 +1,22 @@ @@ -35,6 +41,7 @@ export default { previousScrap: null, pending_action: false, isPlaying: true, + desc: '', }), sockets: { self(self){ diff --git a/frontend/src/components/Player.vue b/frontend/src/components/Player.vue index f996dba..6048977 100644 --- a/frontend/src/components/Player.vue +++ b/frontend/src/components/Player.vue @@ -7,15 +7,17 @@ @pointerenter.native="desc=my_role.goal" @pointerleave.native="desc=''"/> + + ❤️ + 💀 + -

{{desc}}

- - ❤️ - 💀 - + +

{{desc}}

+
{{$t('hand')}} @@ -24,7 +26,9 @@ @pointerenter.native="hint=card.desc" @pointerleave.native="hint=''"/>
-

{{hint}}

+ +

{{hint}}

+