diff --git a/backend/bang/expansions/high_noon/card_events.py b/backend/bang/expansions/high_noon/card_events.py index 2f42167..7f79fca 100644 --- a/backend/bang/expansions/high_noon/card_events.py +++ b/backend/bang/expansions/high_noon/card_events.py @@ -71,13 +71,13 @@ class Manette(CardEvent): def __init__(self): super().__init__("Manette", "🔗") #self.desc = "Dopo aver pescato in fase 1, il giocatore di turno dichiara un seme: potrà usare solamente carte di quel seme nel suo turno" - #self.desc_eng = "" + #self.desc_eng = "After drawing in phase 1, the player declares a suit. He will be able to use only cards of that suit for that turn" class NuovaIdentita(CardEvent): def __init__(self): super().__init__("Nuova Identita", "🕶") #self.desc = "All'inizio del proprio turno, ogni giocatore potrà decidere se sostituire il suo personaggio attuale con quello era stato proposto ad inizio partita, se lo fa riparte con 2 punti vita" - #self.desc_eng = "" + #self.desc_eng = "At the beginning of their turn, each player can choose to change its character with the other shown at the game start. If he does so he restarts from 2 HP." class CittaFantasma(CardEvent): def __init__(self): @@ -110,7 +110,7 @@ def get_all_events(): Sermone(), Sete(), Sparatoria(), - # Manette(), + Manette(), NuovaIdentita(), ] random.shuffle(cards) diff --git a/backend/bang/players.py b/backend/bang/players.py index 689955d..114c844 100644 --- a/backend/bang/players.py +++ b/backend/bang/players.py @@ -57,6 +57,7 @@ class Player: self.target_p: str = None self.is_drawing = False self.special_use_count = 0 + self.committed_suit_manette = None self.not_chosen_character = None try: del self.win_status @@ -218,10 +219,11 @@ class Player: elif self.pending_action == PendingAction.DRAW: self.draw('') elif self.pending_action == PendingAction.PLAY: - equippables = [c for c in self.hand if (c.is_equipment or c.usable_next_turn) and not isinstance(c, cs.Prigione) and not any([type(c) == type(x) for x in self.equipment])] - misc = [c for c in self.hand if (isinstance(c, cs.WellsFargo) or isinstance(c, cs.Indiani) or isinstance(c, cs.Gatling) or isinstance(c, cs.Diligenza) or isinstance(c, cs.Emporio) or (isinstance(c, cs.Birra) and self.lives < self.max_lives and not self.game.check_event(ceh.IlReverendo)) or (c.need_with and len(self.hand) > 1 and not c.need_target and not (isinstance(c, csd.Whisky) and self.lives == self.max_lives))) + non_blocked_cards = [card for card in self.hand if (self.game.check_event(ceh.Manette) and card.suit == self.committed_suit_manette)] + equippables = [c for c in non_blocked_cards if (c.is_equipment or c.usable_next_turn) and not isinstance(c, cs.Prigione) and not any([type(c) == type(x) for x in self.equipment])] + misc = [c for c in non_blocked_cards if (isinstance(c, cs.WellsFargo) or isinstance(c, cs.Indiani) or isinstance(c, cs.Gatling) or isinstance(c, cs.Diligenza) or isinstance(c, cs.Emporio) or (isinstance(c, cs.Birra) and self.lives < self.max_lives and not self.game.check_event(ceh.IlReverendo)) or (c.need_with and len(self.hand) > 1 and not c.need_target and not (isinstance(c, csd.Whisky) and self.lives == self.max_lives))) and not (not c.can_be_used_now and self.game.check_event(ce.IlGiudice))] - need_target = [c for c in self.hand if c.need_target and c.can_be_used_now and not (c.need_with and len(self.hand) < 2) and not ( + need_target = [c for c in non_blocked_cards if c.need_target and c.can_be_used_now and not (c.need_with and len(self.hand) < 2) and not ( (self.game.check_event(ceh.Sermone) or self.has_played_bang and not (any([isinstance(c, cs.Volcanic) for c in self.equipment]) and type(c) == type(cs.Bang) ) and not self.game.check_event(ce.Lazo))) and not ( isinstance(c, cs.Prigione) and self.game.check_event(ce.IlGiudice))] green_cards = [c for c in self.equipment if not self.game.check_event(ce.Lazo) and not isinstance(c, cs.Mancato) and c.usable_next_turn and c.can_be_used_now] @@ -430,9 +432,21 @@ class Player: self.hand.append(self.game.deck.draw()) if self.game.check_event(ceh.Sete): return self.notify_self() - if self.game.check_event(ceh.IlTreno) or (self.is_ghost and self.game.check_event(ceh.CittaFantasma)): - self.hand.append(self.game.deck.draw()) - self.notify_self() + if self.game.check_event(ceh.IlTreno) or (self.is_ghost and self.game.check_event(ceh.CittaFantasma)): + self.hand.append(self.game.deck.draw()) + self.manette() + self.notify_self() + + def manette(self): + if self.game.check_event(ceh.Manette): + self.choose_text = 'choose_manette' + self.available_cards = [{ + 'name': '', + 'icon': '♦♣♥♠'[s], + 'alt_text': '', + 'noDesc': True + } for s in [0,1,2,3]] + self.pending_action = PendingAction.CHOOSE def pick(self): if self.pending_action != PendingAction.PICK: @@ -519,7 +533,7 @@ class Player: 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 = False - event_blocks_card = (self.game.check_event(ce.IlGiudice) and (card.is_equipment or (card.usable_next_turn and not card.can_be_used_now))) or (self.game.check_event(ce.Lazo) and card.usable_next_turn and card.can_be_used_now) + event_blocks_card = (self.game.check_event(ce.IlGiudice) and (card.is_equipment or (card.usable_next_turn and not card.can_be_used_now))) or (self.game.check_event(ce.Lazo) and card.usable_next_turn and card.can_be_used_now) or (self.game.check_event(ceh.Manette) and card.suit != self.committed_suit_manette and not (card.usable_next_turn and card.can_be_used_now)) if not(against != None and isinstance(self.game.get_player_named(against).character, chd.ApacheKid) and card.check_suit(self.game, [cs.Suit.DIAMONDS])) and not event_blocks_card: if against == self.name and not isinstance(card, csd.Tequila): did_play_card = False @@ -581,6 +595,11 @@ class Player: self.lives = 2 self.sio.emit('chat_message', room=self.game.name, data=f'_choose_character|{self.name}|{self.character.name}') self.play_turn(again = True) + elif self.game.check_event(ceh.Manette) and self.choose_text == 'choose_manette': + self.committed_suit_manette = cs.Suit(card_index) + self.sio.emit('chat_message', room=self.game.name, data=f'_choose_manette|{self.name}|{"♦♣♥♠"[card_index]}') + self.pending_action = PendingAction.PLAY + self.notify_self() elif self.is_giving_life and self.game.check_event(ce.FratelliDiSangue): try: player = self.game.get_player_named(self.available_cards[card_index]['name']) @@ -666,6 +685,7 @@ class Player: self.game.deck.put_on_top(self.available_cards.pop()) self.is_drawing = False self.pending_action = PendingAction.PLAY + self.manette() self.notify_self() elif self.is_drawing and self.character.check(self.game, chd.PatBrennan): self.is_drawing = False @@ -675,6 +695,7 @@ class Player: self.available_cards = [] self.game.get_player_named(self.pat_target).notify_self() self.pending_action = PendingAction.PLAY + self.manette() self.notify_self() else: # emporio self.game.respond_emporio(self, card_index) @@ -995,6 +1016,7 @@ class Player: self.game.deck.scrap(self.hand.pop(), True) for i in range(len(self.equipment)): self.game.deck.scrap(self.equipment.pop(), True) + self.committed_suit_manette = None self.pending_action = PendingAction.WAIT self.notify_self() self.game.next_turn() diff --git a/frontend/src/components/Player.vue b/frontend/src/components/Player.vue index df3ccf4..3c12388 100644 --- a/frontend/src/components/Player.vue +++ b/frontend/src/components/Player.vue @@ -117,6 +117,7 @@ export default { emporioCards: {}, spectator: false, noStar: false, + committed_suit_manette: null, }), sockets: { role(role) { @@ -144,6 +145,7 @@ export default { this.special_use_count = self.special_use_count this.choose_text = self.choose_text this.is_my_turn = self.is_my_turn + this.committed_suit_manette = self.committed_suit_manette if (this.is_my_turn) document.title = this.$t('your_turn')+' | PewPew!' else if (this.pending_action == 3) document.title = this.$t('your_response')+' | PewPew!' else if (this.pending_action == 5) document.title = this.$t('your_choose')+' | PewPew!' @@ -257,7 +259,7 @@ export default { return cc }, handComputed() { - return this.hand.map(x=> { + return this.hand.map(x => { let cantBePlayed = false let calamity_special = (x.name === 'Mancato!' && this.character.name === 'Calamity Janet') let cant_play_bang = (this.has_played_bang && this.equipment.filter(x => x.name == 'Volcanic').length == 0) @@ -265,6 +267,7 @@ export default { else if (this.eventCard && this.eventCard.name == "Il Giudice" && (x.is_equipment || !x.can_be_used_now)) cantBePlayed = true; else if (this.eventCard && this.eventCard.name == "Il Reverendo" && (x.name == "Birra")) cantBePlayed = true; else if (this.need_with && this.hand.length === 1) cantBePlayed = true; + else if (this.committed_suit_manette !== null && this.committed_suit_manette !== x.suit) cantBePlayed = true; return { ...x, cantBePlayed: cantBePlayed diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json index 1e58ccf..6d79ec4 100644 --- a/frontend/src/i18n/en.json +++ b/frontend/src/i18n/en.json @@ -36,6 +36,7 @@ "choose_response": "Choose your response ", "choose_response_to": "to ", "choose_response_needed": "NEEDED ", + "choose_manette": "Choose a suit, you will be able to play only cards with that suit on this turn.", "hand": "HAND", "card_against": "Who will you play your card against?", "choose_card_to_get": "Choose a card", @@ -104,7 +105,8 @@ "lobby_reset": "Going back to lobby in {0} seconds...", "prison_free": "{0} got out of prison", "prison_turn": "{0} stayed in prison this turn", - "flip_event": "🎴 EVENT: {0} 🎴" + "flip_event": "🎴 EVENT: {0} 🎴", + "choose_manette": "{0} committed to play only cards of suit {1} in this turn." }, "foc": { "leggedelwest": "He must play this card on this turn if possible." @@ -538,11 +540,11 @@ }, "Nuova Identita": { "name": "New Identity", - "desc": "" + "desc": "At the beginning of their turn, each player can choose to change its character with the other shown at the game start. If he does so he restarts from 2 HP" }, "Manette": { "name": "Handcuffs", - "desc": "" + "desc": "After drawing in phase 1, the player declares a suit. He will be able to use only cards of that suit for that turn" }, "Mezzogiorno di Fuoco":{ "name": "High Noon", diff --git a/frontend/src/i18n/it.json b/frontend/src/i18n/it.json index 2650c4e..1d02cfa 100644 --- a/frontend/src/i18n/it.json +++ b/frontend/src/i18n/it.json @@ -36,6 +36,7 @@ "choose_response": "Scegli come rispondere ", "choose_response_to": "a ", "choose_response_needed": "NE OCCORRONO ", + "choose_manette": "Scegli un seme, potrai giocare solo carte di quel seme questo turno.", "hand": "MANO", "card_against": "Contro chi vuoi giocare la carta", "choose_card_to_get": "Scegli che carta pescare", @@ -104,7 +105,8 @@ "lobby_reset": "Si ritorna alla stanza in {0} secondi...", "prison_free": "{0} è uscito di prigione", "prison_turn": "{0} rimane in prigione questo turno", - "flip_event": "🎴 EVENTO: {0} 🎴" + "flip_event": "🎴 EVENTO: {0} 🎴", + "choose_manette": "{0} si è impegnato ad usare solo carte di seme {1} in questo turno." }, "foc": { "leggedelwest": "Ed è obbligato a usarla nel suo turno, se possibile"