From 88f452df8f378c277e1dc89e277eae043d1c532b Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Mon, 14 Dec 2020 18:43:24 +0100 Subject: [PATCH 01/19] fun and debug stuff --- backend/__init__.py | 30 +++++++++++++++++++++++++++--- backend/bang/game.py | 2 ++ backend/bang/players.py | 6 +++++- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/backend/__init__.py b/backend/__init__.py index 66b42d1..2103ff9 100644 --- a/backend/__init__.py +++ b/backend/__init__.py @@ -171,18 +171,42 @@ def chat_message(sid, msg): elif '/suicide' in msg and ses.game.started and ses.lives > 0: ses.lives = 0 ses.notify_self() + elif '/notify' in msg and ses.game.started: + cmd = msg.split() + if len(cmd) == 3: + if cmd[1] in ses.game.players_map: + ses.game.get_player_named(cmd[1]).notify_card(ses, { + 'name': cmd[2], + 'icon': '🚨', + 'suit': 4, + 'number': cmd[2] + }) + else: + sio.emit('chat_message', room=sid, data={'color': f'','text':f'{msg} bad format'}) + elif '/debug_show_cards' in msg and ses.game.started: + cmd = msg.split() + if len(cmd) == 2: + if cmd[1] in ses.game.players_map: + sio.emit('chat_message', room=ses.game.name, data={'color': f'red','text':f'🚨 {ses.name} is in debug mode and is looking at {cmd[1]} hand'}) + for c in ses.game.get_player_named(cmd[1]).hand: + ses.notify_card(ses, c) + eventlet.sleep(0.3) + else: + sio.emit('chat_message', room=sid, data={'color': f'','text':f'{msg} bad format'}) elif '/togglecomp' in msg and ses.game: ses.game.toggle_competitive() elif '/togglebot' in msg and ses.game: ses.game.toggle_disconnect_bot() elif '/cancelgame' in msg and ses.game.started: ses.game.reset() + elif '/startgame' in msg and not ses.game.started: + ses.game.start_game() elif '/gameinfo' in msg: - sio.emit('chat_message', room=sid, data={'color': f'#black','text':f'info: {ses.game.__dict__}'}) + sio.emit('chat_message', room=sid, data={'color': f'','text':f'info: {ses.game.__dict__}'}) elif '/meinfo' in msg: - sio.emit('chat_message', room=sid, data={'color': f'#black','text':f'info: {ses.__dict__}'}) + sio.emit('chat_message', room=sid, data={'color': f'','text':f'info: {ses.__dict__}'}) else: - sio.emit('chat_message', room=sid, data={'color': f'#black','text':f'{msg} COMMAND NOT FOUND'}) + sio.emit('chat_message', room=sid, data={'color': f'','text':f'{msg} COMMAND NOT FOUND'}) else: color = sid.encode('utf-8').hex()[-3:] sio.emit('chat_message', room=ses.game.name, data={'color': f'#{color}','text':f'[{ses.name}]: {msg}'}) diff --git a/backend/bang/game.py b/backend/bang/game.py index 780bd2f..a723bb9 100644 --- a/backend/bang/game.py +++ b/backend/bang/game.py @@ -121,6 +121,8 @@ class Game: elif len(self.players) >= 4: 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)] + else: + available_roles = [roles.Renegade(), roles.Renegade()] random.shuffle(available_roles) for i in range(len(self.players)): self.players[i].set_role(available_roles[i]) diff --git a/backend/bang/players.py b/backend/bang/players.py index e90f2e9..d61dd3e 100644 --- a/backend/bang/players.py +++ b/backend/bang/players.py @@ -117,9 +117,13 @@ class Player: self.set_character(available[randrange(0, len(available))].name) def notify_card(self, player, card): + try: + card = card.__dict__ + except: + pass mess = { 'player': player.name, - 'card': card.__dict__ + 'card': card } print('notifying card') self.sio.emit('notify_card', room=self.sid, data=mess) From de303b7eb5602432613276d542348f8116e97997 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Wed, 16 Dec 2020 19:34:03 +0100 Subject: [PATCH 02/19] vera custer --- .../bang/expansions/dodge_city/characters.py | 9 ++++++ backend/bang/players.py | 32 ++++++++++++++----- backend/requirements.txt | 6 ++-- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/backend/bang/expansions/dodge_city/characters.py b/backend/bang/expansions/dodge_city/characters.py index 9a23a03..962c2e1 100644 --- a/backend/bang/expansions/dodge_city/characters.py +++ b/backend/bang/expansions/dodge_city/characters.py @@ -71,6 +71,14 @@ class BelleStar(Character): self.desc_eng = "During her turn the green cards of the other players do not work." self.icon = '❎' +class VeraCuster(Character): + def __init__(self): + super().__init__("Vera Custer", max_lives=3) + self.desc = "Prima di pescare le sue carte può scegliere l'abilità speciale di un altro giocatore fino al prossimo turno." + self.desc_eng = "Before drawing, she may choose the special ability on another alive player. This ability is used until next turn." + self.icon = '🎭' + + def all_characters() -> List[Character]: return [ PixiePete(), @@ -83,6 +91,7 @@ def all_characters() -> List[Character]: ApacheKid(), SeanMallory(), BelleStar(), + VeraCuster(), ] #Apache Kid: il suo effetto non conta nei duelli diff --git a/backend/bang/players.py b/backend/bang/players.py index d61dd3e..46a4afc 100644 --- a/backend/bang/players.py +++ b/backend/bang/players.py @@ -30,6 +30,7 @@ class Player: self.equipment: cs.Card = [] self.role: r.Role = None self.character: chars.Character = None + self.real_character: chars.Character = None self.lives = 0 self.max_lives = 0 self.game: g = None @@ -55,6 +56,7 @@ class Player: self.equipment: cs.Card = [] self.role: r.Role = None self.character: chars.Character = None + self.real_character: chars.Character = None self.lives = 0 self.max_lives = 0 self.is_my_turn = False @@ -92,13 +94,24 @@ class Player: def set_character(self, character: str): print(self.available_characters, character) - self.character = next( - x for x in self.available_characters if x.name == character) - self.available_characters = [] - print(f'I {self.name} chose character {self.character.name}') - self.sio.emit('chat_message', room=self.game.name, - data=f'_did_choose_character|{self.name}') - self.game.notify_character_selection() + if self.character == None: + self.character = next( + x for x in self.available_characters if x.name == character) + self.real_character = self.character + self.available_characters = [] + print(f'I {self.name} chose character {self.character.name}') + self.sio.emit('chat_message', room=self.game.name, + data=f'_did_choose_character|{self.name}') + self.game.notify_character_selection() + elif self.real_character and isinstance(self.real_character, chd.VeraCuster): + self.character = next( + x for x in self.available_characters if x.name == character) + self.available_characters = [] + self.sio.emit('chat_message', room=self.game.name, + data=f'_did_choose_character|{self.name}') + self.pending_action = PendingAction.DRAW + self.notify_self() + def prepare(self): self.max_lives = self.character.max_lives + self.role.health_mod @@ -281,7 +294,10 @@ class Player: if any([isinstance(c, cs.Dinamite) or isinstance(c, cs.Prigione) for c in self.equipment]): self.pending_action = PendingAction.PICK else: - self.pending_action = PendingAction.DRAW + if isinstance(self.real_character, chd.VeraCuster): + self.set_available_character([p.character for p in self.game.players if p != self]) + else: + self.pending_action = PendingAction.DRAW self.notify_self() def draw(self, pile): diff --git a/backend/requirements.txt b/backend/requirements.txt index 401095e..eb1853a 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -1,7 +1,7 @@ certifi==2020.11.8 dnspython==1.16.0 -eventlet==0.29.1 +eventlet==0.30.0 greenlet==0.4.17 -python-engineio==3.13.2 -python-socketio==4.6.0 +python-engineio==4.0.0 +python-socketio==5.0.3 six==1.15.0 From 950d588b669a99214a48d682a8f239a6c3493ae9 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Wed, 16 Dec 2020 19:49:03 +0100 Subject: [PATCH 03/19] chuck wengam --- backend/__init__.py | 5 +++++ backend/bang/expansions/dodge_city/characters.py | 7 +++++++ backend/bang/players.py | 7 +++++++ frontend/src/components/Player.vue | 6 +++++- 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/backend/__init__.py b/backend/__init__.py index 2103ff9..4d1ad8b 100644 --- a/backend/__init__.py +++ b/backend/__init__.py @@ -262,5 +262,10 @@ def scrap(sid, card_index): ses: Player = sio.get_session(sid) ses.scrap(card_index) +@sio.event +def chuck_lose_hp_draw(sid): + ses: Player = sio.get_session(sid) + ses.chuck_lose_hp_draw() + if __name__ == '__main__': eventlet.wsgi.server(eventlet.listen(('', 5001)), app) diff --git a/backend/bang/expansions/dodge_city/characters.py b/backend/bang/expansions/dodge_city/characters.py index 962c2e1..4298a5a 100644 --- a/backend/bang/expansions/dodge_city/characters.py +++ b/backend/bang/expansions/dodge_city/characters.py @@ -78,6 +78,12 @@ class VeraCuster(Character): self.desc_eng = "Before drawing, she may choose the special ability on another alive player. This ability is used until next turn." self.icon = '🎭' +class ChuckWengam(Character): + def __init__(self): + super().__init__("Chuck Wengam", max_lives=4) + self.desc = "Durante il suo turno può perdere una vita per pescare 2 carte dal mazzo." + self.desc_eng = "On his turn he may decide to lose 1 HP to draw 2 cards from the deck." + self.icon = '💰' def all_characters() -> List[Character]: return [ @@ -92,6 +98,7 @@ def all_characters() -> List[Character]: SeanMallory(), BelleStar(), VeraCuster(), + ChuckWengam(), ] #Apache Kid: il suo effetto non conta nei duelli diff --git a/backend/bang/players.py b/backend/bang/players.py index 46a4afc..6246799 100644 --- a/backend/bang/players.py +++ b/backend/bang/players.py @@ -660,6 +660,13 @@ class Player: self.game.deck.scrap(self.hand.pop(card_index)) self.notify_self() + def chuck_lose_hp_draw(self): + if isinstance(self.character, chd.ChuckWengam) and self.lives > 1 and self.is_my_turn: + self.lives -= 1 + self.hand.append(self.game.deck.draw()) + self.hand.append(self.game.deck.draw()) + self.notify_self() + def end_turn(self, forced=False): if not self.is_my_turn: return diff --git a/frontend/src/components/Player.vue b/frontend/src/components/Player.vue index 06a200c..2b28fc9 100644 --- a/frontend/src/components/Player.vue +++ b/frontend/src/components/Player.vue @@ -20,6 +20,8 @@

{{desc}}

+ +
{{$t('hand')}} @@ -46,7 +48,6 @@ -
@@ -220,6 +221,9 @@ export default { this.sidWantsScrapForHealth = false } }, + chuckSpecial(){ + this.$socket.emit('chuck_lose_hp_draw') + }, end_turn(){ console.log('ending turn') this.cancelEndingTurn() From cb3723febd1b153d936ef96db157fd122b1aff6b Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Wed, 16 Dec 2020 19:59:06 +0100 Subject: [PATCH 04/19] notify all roles on start --- backend/bang/characters.py | 2 +- backend/bang/game.py | 1 + frontend/src/i18n/en.json | 3 ++- frontend/src/i18n/it.json | 3 ++- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/backend/bang/characters.py b/backend/bang/characters.py index 3356c31..ea6c0ce 100644 --- a/backend/bang/characters.py +++ b/backend/bang/characters.py @@ -137,7 +137,7 @@ class VultureSam(Character): super().__init__("Vulture Sam", max_lives=4) self.desc = "Quando un personaggio viene eliminato prendi tutte le carte di quel giocatore e aggiungile alla tua mano, sia le carte in mano che quelle in gioco" self.desc_eng = "When a player dies, he gets all the cards in the dead's hand and equipments" - self.icon = '💰' + self.icon = '🦉' class WillyTheKid(Character): def __init__(self): diff --git a/backend/bang/game.py b/backend/bang/game.py index a723bb9..b3d1983 100644 --- a/backend/bang/game.py +++ b/backend/bang/game.py @@ -90,6 +90,7 @@ class Game: for k in range(self.players[i].max_lives): self.players[i].hand.append(self.deck.draw()) self.players[i].notify_self() + self.sio.emit('chat_message', room=self.name, data=f'_allroles|{", ".join([type(x.role).__name__ for x in self.players])}') self.players[self.turn].play_turn() def choose_characters(self): diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json index 2000565..515f63d 100644 --- a/frontend/src/i18n/en.json +++ b/frontend/src/i18n/en.json @@ -79,7 +79,8 @@ "saloon": "{0} player {1} and heals 1 HP to everyone alive.", "special_bart_cassidy": "{0} received a compensation because he was injured.", "special_el_gringo": "{0} stole a card from {1} when he was was injured.", - "special_calamity": "{0} played {1} as Bang! against {2}." + "special_calamity": "{0} played {1} as Bang! against {2}.", + "allroles": "In the game there are: {0}." }, "mods": "Modifiers", "mod_comp": "Competitive mode (disables automatic take damage)", diff --git a/frontend/src/i18n/it.json b/frontend/src/i18n/it.json index b3f4e0b..8cec599 100644 --- a/frontend/src/i18n/it.json +++ b/frontend/src/i18n/it.json @@ -79,7 +79,8 @@ "saloon": "{0} ha giocato {1} e ha curato 1 punto vita a tutti.", "special_bart_cassidy": "{0} ha ricevuto un risarcimento perchè è stato ferito.", "special_el_gringo": "{0} rubato una carta a {1} mentre veniva colpito.", - "special_calamity": "{0} ha giovato {1} come un Bang! contro {2}." + "special_calamity": "{0} ha giovato {1} come un Bang! contro {2}.", + "allroles": "Nella partita ci sono: {0}." }, "mods": "Modificatori", "mod_comp": "Modalità competitiva (disattiva il prendi danno automatico)", From d4bee9c3f267c53e211ecb5371b2f5de60e0cc03 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Wed, 16 Dec 2020 20:07:03 +0100 Subject: [PATCH 05/19] use again old socketio version --- backend/requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/requirements.txt b/backend/requirements.txt index eb1853a..401095e 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -1,7 +1,7 @@ certifi==2020.11.8 dnspython==1.16.0 -eventlet==0.30.0 +eventlet==0.29.1 greenlet==0.4.17 -python-engineio==4.0.0 -python-socketio==5.0.3 +python-engineio==3.13.2 +python-socketio==4.6.0 six==1.15.0 From d3bf18c9a2666f653262f372095c29915f3a3838 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Wed, 16 Dec 2020 20:29:25 +0100 Subject: [PATCH 06/19] fix reveal role --- .github/workflows/dev-image.yml | 2 ++ .github/workflows/docker-image.yml | 2 ++ .github/workflows/tests.yaml | 2 ++ backend/bang/game.py | 4 +++- 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dev-image.yml b/.github/workflows/dev-image.yml index b936f61..e9d8ec4 100644 --- a/.github/workflows/dev-image.yml +++ b/.github/workflows/dev-image.yml @@ -5,6 +5,8 @@ on: jobs: build: runs-on: ubuntu-latest + env: + DOCKER_BUILDKIT: '1' steps: - uses: actions/checkout@v2 - name: Build the Unified Docker image diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 32d50b2..cb13728 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -5,6 +5,8 @@ on: jobs: build: runs-on: ubuntu-latest + env: + DOCKER_BUILDKIT: '1' steps: - uses: actions/checkout@v2 - name: Build the Unified Docker image diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index c683393..d84f4b7 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -4,6 +4,8 @@ on: jobs: test_build: runs-on: ubuntu-latest + env: + DOCKER_BUILDKIT: '1' steps: - uses: actions/checkout@v2 - name: Build the Unified Docker image diff --git a/backend/bang/game.py b/backend/bang/game.py index b3d1983..0a1877e 100644 --- a/backend/bang/game.py +++ b/backend/bang/game.py @@ -90,7 +90,9 @@ class Game: for k in range(self.players[i].max_lives): self.players[i].hand.append(self.deck.draw()) self.players[i].notify_self() - self.sio.emit('chat_message', room=self.name, data=f'_allroles|{", ".join([type(x.role).__name__ for x in self.players])}') + current_roles = [type(x.role).__name__ for x in self.players] + current_roles = {x:current_roles.count(x) for x in current_roles} + self.sio.emit('chat_message', room=self.name, data=f'_allroles|{current_roles}') self.players[self.turn].play_turn() def choose_characters(self): From 996b4608cadc1581f6e28d92a25bc440a52a6c11 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Wed, 16 Dec 2020 21:10:53 +0100 Subject: [PATCH 07/19] modular expansion adding --- backend/__init__.py | 8 ++++++++ backend/bang/expansions/__init__.py | 9 +++++++-- backend/bang/game.py | 2 ++ frontend/src/components/Lobby.vue | 17 ++++++++++++++--- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/backend/__init__.py b/backend/__init__.py index 4d1ad8b..3dc02c4 100644 --- a/backend/__init__.py +++ b/backend/__init__.py @@ -201,6 +201,14 @@ def chat_message(sid, msg): ses.game.reset() elif '/startgame' in msg and not ses.game.started: ses.game.start_game() + elif '/addex' in msg and not ses.game.started: + cmd = msg.split() + if len(cmd) == 2: + if cmd[1] not in ses.game.available_expansions: + ses.game.available_expansions.append(cmd[1]) + ses.game.notify_room() + else: + sio.emit('chat_message', room=sid, data={'color': f'','text':f'{msg} bad format'}) elif '/gameinfo' in msg: sio.emit('chat_message', room=sid, data={'color': f'','text':f'info: {ses.game.__dict__}'}) elif '/meinfo' in msg: diff --git a/backend/bang/expansions/__init__.py b/backend/bang/expansions/__init__.py index 4409025..ab28b35 100644 --- a/backend/bang/expansions/__init__.py +++ b/backend/bang/expansions/__init__.py @@ -1,7 +1,12 @@ -from bang.expansions.dodge_city import cards, characters class DodgeCity(): def get_characters(): + from bang.expansions.dodge_city import characters return characters.all_characters() + def get_cards(): - return cards.get_starting_deck() \ No newline at end of file + from bang.expansions.dodge_city import cards + return cards.get_starting_deck() + +class HighNoon(): + pass \ No newline at end of file diff --git a/backend/bang/game.py b/backend/bang/game.py index 0a1877e..49057b9 100644 --- a/backend/bang/game.py +++ b/backend/bang/game.py @@ -23,6 +23,7 @@ class Game: self.initial_players = 0 self.password = '' self.expansions = [] + self.available_expansions = ['dodge_city'] self.shutting_down = False self.is_competitive = False self.disconnect_bot = True @@ -37,6 +38,7 @@ class Game: 'is_competitive': self.is_competitive, 'disconnect_bot': self.disconnect_bot, 'expansions': self.expansions, + 'available_expansions': self.available_expansions }) def toggle_expansion(self, expansion_name): diff --git a/frontend/src/components/Lobby.vue b/frontend/src/components/Lobby.vue index f548abb..4b8c426 100644 --- a/frontend/src/components/Lobby.vue +++ b/frontend/src/components/Lobby.vue @@ -33,7 +33,10 @@

{{$t("expansions")}}

- Dodge City +
+ {{get_expansion_name(ex)}} +
+

{{$t('mods')}}

{{$t('mod_comp')}}
@@ -90,7 +93,8 @@ export default { selectedInfo: null, privateRoom: false, password: '', - useDodgeCity: false, + togglable_expansions: [], + expansions: [], hasToSetUsername: false, is_competitive: false, disconnect_bot: false, @@ -103,7 +107,8 @@ export default { this.privateRoom = data.password !== '' this.is_competitive = data.is_competitive this.disconnect_bot = data.disconnect_bot - this.useDodgeCity = data.expansions.indexOf('dodge_city') !== -1 + this.togglable_expansions = data.available_expansions + this.expansions = data.expansions this.players = data.players.map(x => { return { name: x.name, @@ -168,6 +173,12 @@ export default { } }, methods: { + is_toggled_expansion(ex) { + return this.expansions.indexOf(ex) !== -1 + }, + get_expansion_name(ex) { + return ex.replace('_', ' ').replace(/\w\S*/g, m => m.charAt(0).toUpperCase()+m.substr(1).toLowerCase()) + }, leaveRoom() { window.location.replace(window.location.origin) }, From e94c1b634a204a51e11e047666f54258333a2163 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Wed, 16 Dec 2020 21:42:00 +0100 Subject: [PATCH 08/19] base for fistful of cards --- backend/bang/expansions/__init__.py | 3 - .../fistful_of_cards/card_events.py | 96 +++++++++++++++++++ frontend/src/components/Card.vue | 8 ++ 3 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 backend/bang/expansions/fistful_of_cards/card_events.py diff --git a/backend/bang/expansions/__init__.py b/backend/bang/expansions/__init__.py index ab28b35..eab027e 100644 --- a/backend/bang/expansions/__init__.py +++ b/backend/bang/expansions/__init__.py @@ -7,6 +7,3 @@ class DodgeCity(): def get_cards(): from bang.expansions.dodge_city import cards return cards.get_starting_deck() - -class HighNoon(): - pass \ No newline at end of file diff --git a/backend/bang/expansions/fistful_of_cards/card_events.py b/backend/bang/expansions/fistful_of_cards/card_events.py new file mode 100644 index 0000000..cd9d1f7 --- /dev/null +++ b/backend/bang/expansions/fistful_of_cards/card_events.py @@ -0,0 +1,96 @@ +from abc import ABC, abstractmethod + +def CardEvent(ABC): + def __init__(self, name, icon): + self.name = name + self.icon = icon + +def Agguato(CardEvent): + def __init__(self): + super.__init__('Agguato', '🛁') + self.desc = '' + self.desc_eng = '' + +def Cecchino(CardEvent): + def __init__(self): + super.__init__('Cecchino', '👁') + self.desc = '' + self.desc_eng = '' + +def DeadMan(CardEvent): + def __init__(self): + super.__init__('Dead Man', '⚰️') + self.desc = '' + self.desc_eng = '' + +def FratelliDiSangue(CardEvent): + def __init__(self): + super.__init__('Fratelli Di Sangue', '🩸') + self.desc = '' + self.desc_eng = '' + +def IlGiudice(CardEvent): + def __init__(self): + super.__init__('Il Giudice', '👨‍⚖️') + self.desc = '' + self.desc_eng = '' + +def Lazo(CardEvent): + def __init__(self): + super.__init__('Lazo', '📿') + self.desc = '' + self.desc_eng = '' + +def LeggeDelWest(CardEvent): + def __init__(self): + super.__init__('Legge Del West', '⚖️') + self.desc = '' + self.desc_eng = '' + +def LiquoreForte(CardEvent): + def __init__(self): + super.__init__('Liquore Forte', '🥃') + self.desc = '' + self.desc_eng = '' + +def MinieraAbbandonata(CardEvent): + def __init__(self): + super.__init__('Miniera Abbandonata', '⛏') + self.desc = '' + self.desc_eng = '' + +def PerUnPugnoDiCarte(CardEvent): + def __init__(self): + super.__init__('Per Un Pugno Di Carte', '🎴') + self.desc = '' + self.desc_eng = '' + +def Peyote(CardEvent): + def __init__(self): + super.__init__('Peyote', '🌵') + self.desc = '' + self.desc_eng = '' + +def Ranch(CardEvent): + def __init__(self): + super.__init__('Ranch', '🐮') + self.desc = '' + self.desc_eng = '' + +def Rimbalzo(CardEvent): + def __init__(self): + super.__init__('Rimbalzo', '⏮') + self.desc = '' + self.desc_eng = '' + +def RouletteRussa(CardEvent): + def __init__(self): + super.__init__('Roulette Russa', '🇷🇺') + self.desc = '' + self.desc_eng = '' + +def Vendetta(CardEvent): + def __init__(self): + super.__init__('Vendetta', '😤') + self.desc = '' + self.desc_eng = '' \ No newline at end of file diff --git a/frontend/src/components/Card.vue b/frontend/src/components/Card.vue index 3b95b94..d6b7f06 100644 --- a/frontend/src/components/Card.vue +++ b/frontend/src/components/Card.vue @@ -72,6 +72,14 @@ export default { box-shadow: 0 0 0 3pt #6aa16e, 0 0 0 6pt white, 0 0 5pt 6pt #aaa } +.card.high-noon{ + box-shadow: 0 0 0pt 6pt #181a1b, 0 0 5pt 6pt #aaa; + border: 2pt dotted rgb(198 78 45); +} +.card.fistful-of-cards{ + box-shadow: 0 0 0pt 6pt #181a1b, 0 0 5pt 6pt #aaa; + border: 2pt dotted rgb(50 122 172); +} .card h4 { position: absolute; text-align: center; From 9f15925bf10410bcc1711c50bf24a32823cb5596 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Thu, 17 Dec 2020 14:02:11 +0100 Subject: [PATCH 09/19] fix vera after pick and disconnect notify --- backend/bang/game.py | 2 ++ backend/bang/players.py | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/bang/game.py b/backend/bang/game.py index 49057b9..6242609 100644 --- a/backend/bang/game.py +++ b/backend/bang/game.py @@ -236,6 +236,8 @@ class Game: if player in self.players: if self.disconnect_bot and self.started: player.is_bot = True + eventlet.sleep(15) # he may reconnect + player.notify_self() else: self.player_death(player=player, disconnected=True) else: diff --git a/backend/bang/players.py b/backend/bang/players.py index 6246799..90c4fa7 100644 --- a/backend/bang/players.py +++ b/backend/bang/players.py @@ -391,7 +391,10 @@ class Player: if any([isinstance(c, cs.Prigione) for c in self.equipment]): self.notify_self() return - self.pending_action = PendingAction.DRAW + if isinstance(self.real_character, chd.VeraCuster): + self.set_available_character([p.character for p in self.game.players if p != self]) + else: + self.pending_action = PendingAction.DRAW self.notify_self() else: self.pending_action = PendingAction.WAIT From 6562f5c1e8df379f091374bede34ecd40f0e161f Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Thu, 17 Dec 2020 15:34:12 +0100 Subject: [PATCH 10/19] event cards --- backend/__init__.py | 1 + backend/bang/deck.py | 10 +++ .../fistful_of_cards/card_events.py | 83 ++++++++++++------- backend/bang/game.py | 8 +- frontend/src/components/Card.vue | 12 ++- frontend/src/components/Deck.vue | 34 ++++++-- 6 files changed, 107 insertions(+), 41 deletions(-) diff --git a/backend/__init__.py b/backend/__init__.py index 3dc02c4..d604504 100644 --- a/backend/__init__.py +++ b/backend/__init__.py @@ -82,6 +82,7 @@ def get_me(sid, room): sio.get_session(sid).game = de_games[0] sio.enter_room(sid, de_games[0].name) de_games[0].notify_room(sid) + de_games[0].notify_event_card() else: create_room(sid, room['name']) if sio.get_session(sid).game == None: diff --git a/backend/bang/deck.py b/backend/bang/deck.py index 88bb6ab..f484e8b 100644 --- a/backend/bang/deck.py +++ b/backend/bang/deck.py @@ -1,6 +1,7 @@ from typing import List, Set, Dict, Tuple, Optional import random import bang.cards as cs +import bang.expansions.fistful_of_cards.card_events as ce class Deck: def __init__(self, game): @@ -18,10 +19,19 @@ class Deck: if c.name not in self.all_cards_str: self.all_cards_str.append(c.name) self.game = game + self.event_cards: List[ce.CardEvent] = [] + if 'fistful_of_cards' in game.expansions: + self.event_cards.extend(ce.get_all_events()) + random.shuffle(self.event_cards) random.shuffle(self.cards) self.scrap_pile: List[cs.Card] = [] print(f'Deck initialized with {len(self.cards)} cards') + def flip_event(self): + if len(self.event_cards) > 0: + self.event_cards.append(self.event_cards.pop(0)) + self.game.notify_event_card() + def peek(self, n_cards: int) -> list: return self.cards[:n_cards] diff --git a/backend/bang/expansions/fistful_of_cards/card_events.py b/backend/bang/expansions/fistful_of_cards/card_events.py index cd9d1f7..27dc2e9 100644 --- a/backend/bang/expansions/fistful_of_cards/card_events.py +++ b/backend/bang/expansions/fistful_of_cards/card_events.py @@ -1,96 +1,115 @@ from abc import ABC, abstractmethod -def CardEvent(ABC): +class CardEvent(ABC): def __init__(self, name, icon): self.name = name self.icon = icon -def Agguato(CardEvent): +class Agguato(CardEvent): def __init__(self): - super.__init__('Agguato', '🛁') + super().__init__('Agguato', '🛁') self.desc = '' self.desc_eng = '' -def Cecchino(CardEvent): +class Cecchino(CardEvent): def __init__(self): - super.__init__('Cecchino', '👁') + super().__init__('Cecchino', '👁') self.desc = '' self.desc_eng = '' -def DeadMan(CardEvent): +class DeadMan(CardEvent): def __init__(self): - super.__init__('Dead Man', '⚰️') + super().__init__('Dead Man', '⚰️') self.desc = '' self.desc_eng = '' -def FratelliDiSangue(CardEvent): +class FratelliDiSangue(CardEvent): def __init__(self): - super.__init__('Fratelli Di Sangue', '🩸') + super().__init__('Fratelli Di Sangue', '🩸') self.desc = '' self.desc_eng = '' -def IlGiudice(CardEvent): +class IlGiudice(CardEvent): def __init__(self): - super.__init__('Il Giudice', '👨‍⚖️') + super().__init__('Il Giudice', '👨‍⚖️') self.desc = '' self.desc_eng = '' -def Lazo(CardEvent): +class Lazo(CardEvent): def __init__(self): - super.__init__('Lazo', '📿') + super().__init__('Lazo', '📿') self.desc = '' self.desc_eng = '' -def LeggeDelWest(CardEvent): +class LeggeDelWest(CardEvent): def __init__(self): - super.__init__('Legge Del West', '⚖️') + super().__init__('Legge Del West', '⚖️') self.desc = '' self.desc_eng = '' -def LiquoreForte(CardEvent): +class LiquoreForte(CardEvent): def __init__(self): - super.__init__('Liquore Forte', '🥃') + super().__init__('Liquore Forte', '🥃') self.desc = '' self.desc_eng = '' -def MinieraAbbandonata(CardEvent): +class MinieraAbbandonata(CardEvent): def __init__(self): - super.__init__('Miniera Abbandonata', '⛏') + super().__init__('Miniera Abbandonata', '⛏') self.desc = '' self.desc_eng = '' -def PerUnPugnoDiCarte(CardEvent): +class PerUnPugnoDiCarte(CardEvent): def __init__(self): - super.__init__('Per Un Pugno Di Carte', '🎴') + super().__init__('Per Un Pugno Di Carte', '🎴') self.desc = '' self.desc_eng = '' -def Peyote(CardEvent): +class Peyote(CardEvent): def __init__(self): - super.__init__('Peyote', '🌵') + super().__init__('Peyote', '🌵') self.desc = '' self.desc_eng = '' -def Ranch(CardEvent): +class Ranch(CardEvent): def __init__(self): - super.__init__('Ranch', '🐮') + super().__init__('Ranch', '🐮') self.desc = '' self.desc_eng = '' -def Rimbalzo(CardEvent): +class Rimbalzo(CardEvent): def __init__(self): - super.__init__('Rimbalzo', '⏮') + super().__init__('Rimbalzo', '⏮') self.desc = '' self.desc_eng = '' -def RouletteRussa(CardEvent): +class RouletteRussa(CardEvent): def __init__(self): - super.__init__('Roulette Russa', '🇷🇺') + super().__init__('Roulette Russa', '🇷🇺') self.desc = '' self.desc_eng = '' -def Vendetta(CardEvent): +class Vendetta(CardEvent): def __init__(self): - super.__init__('Vendetta', '😤') + super().__init__('Vendetta', '😤') self.desc = '' - self.desc_eng = '' \ No newline at end of file + self.desc_eng = '' + +def get_all_events(): + return [ + Agguato(), + Cecchino(), + DeadMan(), + FratelliDiSangue(), + IlGiudice(), + Lazo(), + LeggeDelWest(), + LiquoreForte(), + MinieraAbbandonata(), + PerUnPugnoDiCarte(), + Peyote(), + Ranch(), + Rimbalzo(), + RouletteRussa(), + Vendetta(), + ] \ No newline at end of file diff --git a/backend/bang/game.py b/backend/bang/game.py index 6242609..ddcc8be 100644 --- a/backend/bang/game.py +++ b/backend/bang/game.py @@ -95,7 +95,7 @@ class Game: current_roles = [type(x.role).__name__ for x in self.players] current_roles = {x:current_roles.count(x) for x in current_roles} self.sio.emit('chat_message', room=self.name, data=f'_allroles|{current_roles}') - self.players[self.turn].play_turn() + self.play_turn() def choose_characters(self): char_cards = random.sample(characters.all_characters(self.expansions), len(self.players)*2) @@ -216,6 +216,8 @@ class Game: return self.players[(self.turn + 1) % len(self.players)] def play_turn(self): + if isinstance(self.players[self.turn].role, roles.Sheriff): + self.deck.flip_event() self.players[self.turn].play_turn() def next_turn(self): @@ -224,6 +226,10 @@ class Game: self.turn = (self.turn + 1) % len(self.players) self.play_turn() + def notify_event_card(self): + if len(self.deck.event_cards) > 0: + self.sio.emit('event_card', room=self.name, data=self.deck.event_cards[0].__dict__) + def notify_scrap_pile(self): print('scrap') if self.deck.peek_scrap_pile(): diff --git a/frontend/src/components/Card.vue b/frontend/src/components/Card.vue index d6b7f06..0384c9a 100644 --- a/frontend/src/components/Card.vue +++ b/frontend/src/components/Card.vue @@ -73,12 +73,12 @@ export default { 0 0 0 3pt #6aa16e, 0 0 0 6pt white, 0 0 5pt 6pt #aaa } .card.high-noon{ - box-shadow: 0 0 0pt 6pt #181a1b, 0 0 5pt 6pt #aaa; + box-shadow: 0 0 0pt 4pt white, 0 0 5pt 4pt #aaa; border: 2pt dotted rgb(198 78 45); } .card.fistful-of-cards{ - box-shadow: 0 0 0pt 6pt #181a1b, 0 0 5pt 6pt #aaa; - border: 2pt dotted rgb(50 122 172); + box-shadow: 0 0 0pt 4pt white, 0 0 5pt 4pt #aaa; + border: 2pt dashed rgb(50 122 172); } .card h4 { position: absolute; @@ -143,5 +143,11 @@ export default { box-shadow: 0 0 0 3pt #6aa16e, 0 0 0 6pt #181a1b, 0 0 5pt 6pt #aaa } + .card.high-noon{ + box-shadow: 0 0 0pt 4pt #181a1b, 0 0 5pt 4pt #aaa; + } + .card.fistful-of-cards{ + box-shadow: 0 0 0pt 4pt #181a1b, 0 0 5pt 4pt #aaa; + } } \ No newline at end of file diff --git a/frontend/src/components/Deck.vue b/frontend/src/components/Deck.vue index 649cb1a..16766a3 100644 --- a/frontend/src/components/Deck.vue +++ b/frontend/src/components/Deck.vue @@ -2,6 +2,11 @@
+
+
+
+ +
@@ -15,6 +20,7 @@
+

{{($i18n.locale=='it'?eventCard.desc:eventCard.desc_eng)}}

{{desc}}

@@ -37,6 +43,7 @@ export default { icon: '💥', }, lastScrap: null, + eventCard: null, previousScrap: null, pending_action: false, isPlaying: true, @@ -50,7 +57,10 @@ export default { }, scrap(card) { this.lastScrap = card - } + }, + event_card(card) { + this.eventCard = card + }, }, computed: { endTurnCard() { @@ -81,10 +91,10 @@ export default {