Merge branch 'high_noon' into dev
This commit is contained in:
commit
fcfb27e5de
@ -81,7 +81,7 @@ def get_me(sid, room):
|
|||||||
sio.emit('role', room=sid, data=json.dumps(bot.role, default=lambda o: o.__dict__))
|
sio.emit('role', room=sid, data=json.dumps(bot.role, default=lambda o: o.__dict__))
|
||||||
bot.notify_self()
|
bot.notify_self()
|
||||||
else: #spectate
|
else: #spectate
|
||||||
de_games[0].dead_players.append(sio.get_session(sid))
|
de_games[0].spectators.append(sio.get_session(sid))
|
||||||
sio.get_session(sid).game = de_games[0]
|
sio.get_session(sid).game = de_games[0]
|
||||||
sio.enter_room(sid, de_games[0].name)
|
sio.enter_room(sid, de_games[0].name)
|
||||||
de_games[0].notify_room(sid)
|
de_games[0].notify_room(sid)
|
||||||
|
@ -75,6 +75,15 @@ class Card(ABC):
|
|||||||
def is_duplicate_card(self, player):
|
def is_duplicate_card(self, player):
|
||||||
return self.name in [c.name for c in player.equipment]
|
return self.name in [c.name for c in player.equipment]
|
||||||
|
|
||||||
|
def check_suit(self, game, accepted):
|
||||||
|
import bang.expansions.high_noon.card_events as ceh
|
||||||
|
if game.check_event(ceh.Benedizione):
|
||||||
|
return Suit.HEARTS in accepted
|
||||||
|
elif game.check_event(ceh.Maledizione):
|
||||||
|
return Suit.SPADES in accepted
|
||||||
|
return self.suit in accepted
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Barile(Card):
|
class Barile(Card):
|
||||||
def __init__(self, suit, number):
|
def __init__(self, suit, number):
|
||||||
@ -180,14 +189,19 @@ class Bang(Card):
|
|||||||
|
|
||||||
def play_card(self, player, against, _with=None):
|
def play_card(self, player, against, _with=None):
|
||||||
import bang.expansions.fistful_of_cards.card_events as ce
|
import bang.expansions.fistful_of_cards.card_events as ce
|
||||||
|
import bang.expansions.high_noon.card_events as ceh
|
||||||
|
if player.game.check_event(ceh.Sermone):
|
||||||
|
return False
|
||||||
if player.has_played_bang and (not any([isinstance(c, Volcanic) for c in player.equipment]) or player.game.check_event(ce.Lazo)) and against != None:
|
if player.has_played_bang and (not any([isinstance(c, Volcanic) for c in player.equipment]) or player.game.check_event(ce.Lazo)) and against != None:
|
||||||
return False
|
return False
|
||||||
elif against != None:
|
elif against != None:
|
||||||
import bang.characters as chars
|
import bang.characters as chars
|
||||||
super().play_card(player, against=against)
|
super().play_card(player, against=against)
|
||||||
player.has_played_bang = not isinstance(
|
player.bang_used += 1
|
||||||
player.character, chars.WillyTheKid)
|
player.has_played_bang = player.bang_used > 1
|
||||||
player.game.attack(player, against, double=isinstance(player.character, chars.SlabTheKiller))
|
if player.character.check(player.game, chars.WillyTheKid):
|
||||||
|
player.has_played_bang = False
|
||||||
|
player.game.attack(player, against, double=player.character.check(player.game, chars.SlabTheKiller))
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -200,11 +214,14 @@ class Birra(Card):
|
|||||||
self.desc_eng = "Play this card to regain a life point. You cannot heal more than your character's maximum limit. If you are about to lose your last life point, you can also play this card on your opponent's turn. Beer no longer takes effect if there are only two players"
|
self.desc_eng = "Play this card to regain a life point. You cannot heal more than your character's maximum limit. If you are about to lose your last life point, you can also play this card on your opponent's turn. Beer no longer takes effect if there are only two players"
|
||||||
|
|
||||||
def play_card(self, player, against, _with=None):
|
def play_card(self, player, against, _with=None):
|
||||||
|
import bang.expansions.high_noon.card_events as ceh
|
||||||
|
if player.game.check_event(ceh.IlReverendo):
|
||||||
|
return False
|
||||||
if len(player.game.players) != 2:
|
if len(player.game.players) != 2:
|
||||||
super().play_card(player, against=against)
|
super().play_card(player, against=against)
|
||||||
player.lives = min(player.lives+1, player.max_lives)
|
player.lives = min(player.lives+1, player.max_lives)
|
||||||
import bang.expansions.dodge_city.characters as chd
|
import bang.expansions.dodge_city.characters as chd
|
||||||
if isinstance(player.character, chd.TequilaJoe):
|
if player.character.check(player.game, chd.TequilaJoe):
|
||||||
player.lives = min(player.lives+1, player.max_lives)
|
player.lives = min(player.lives+1, player.max_lives)
|
||||||
return True
|
return True
|
||||||
elif len(player.game.players) == 2:
|
elif len(player.game.players) == 2:
|
||||||
@ -314,10 +331,14 @@ class Mancato(Card):
|
|||||||
|
|
||||||
def play_card(self, player, against, _with=None):
|
def play_card(self, player, against, _with=None):
|
||||||
import bang.characters as chars
|
import bang.characters as chars
|
||||||
if (not player.has_played_bang and against != None and isinstance(player.character, chars.CalamityJanet)):
|
if (not player.has_played_bang and against != None and player.character.check(player.game, chars.CalamityJanet)):
|
||||||
|
import bang.expansions.high_noon.card_events as ceh
|
||||||
|
if player.game.check_event(ceh.Sermone):
|
||||||
|
return False
|
||||||
player.sio.emit('chat_message', room=player.game.name,
|
player.sio.emit('chat_message', room=player.game.name,
|
||||||
data=f'_special_calamity|{player.name}|{self.name}|{against}')
|
data=f'_special_calamity|{player.name}|{self.name}|{against}')
|
||||||
player.has_played_bang = True
|
player.bang_used += 1
|
||||||
|
player.has_played_bang = True if not player.game.check_event(ceh.Sparatoria) else player.bang_used > 1
|
||||||
player.game.attack(player, against)
|
player.game.attack(player, against)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
@ -13,21 +13,11 @@ class Character(ABC):
|
|||||||
self.icon = '🤷♂️'
|
self.icon = '🤷♂️'
|
||||||
self.number = ''.join(['❤️']*self.max_lives)
|
self.number = ''.join(['❤️']*self.max_lives)
|
||||||
|
|
||||||
# @abstractmethod
|
def check(self, game, character):
|
||||||
# def on_hurt(self, dmg: int):
|
import bang.expansions.high_noon.card_events as ceh
|
||||||
# pass
|
if game.check_event(ceh.Sbornia):
|
||||||
|
return False
|
||||||
# @abstractmethod
|
return isinstance(self, character)
|
||||||
# def on_pick(self, card): # tipo dinamite e prigione
|
|
||||||
# pass
|
|
||||||
|
|
||||||
# @abstractmethod
|
|
||||||
# def on_empty_hand(self):
|
|
||||||
# pass
|
|
||||||
|
|
||||||
# @abstractmethod
|
|
||||||
# def on_empty_hand(self):
|
|
||||||
# pass
|
|
||||||
|
|
||||||
class BartCassidy(Character):
|
class BartCassidy(Character):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -2,6 +2,7 @@ from typing import List, Set, Dict, Tuple, Optional
|
|||||||
import random
|
import random
|
||||||
import bang.cards as cs
|
import bang.cards as cs
|
||||||
import bang.expansions.fistful_of_cards.card_events as ce
|
import bang.expansions.fistful_of_cards.card_events as ce
|
||||||
|
import bang.expansions.high_noon.card_events as ceh
|
||||||
|
|
||||||
class Deck:
|
class Deck:
|
||||||
def __init__(self, game):
|
def __init__(self, game):
|
||||||
@ -20,16 +21,23 @@ class Deck:
|
|||||||
self.all_cards_str.append(c.name)
|
self.all_cards_str.append(c.name)
|
||||||
self.game = game
|
self.game = game
|
||||||
self.event_cards: List[ce.CardEvent] = []
|
self.event_cards: List[ce.CardEvent] = []
|
||||||
|
endgame_cards = []
|
||||||
if 'fistful_of_cards' in game.expansions:
|
if 'fistful_of_cards' in game.expansions:
|
||||||
self.event_cards.extend(ce.get_all_events())
|
self.event_cards.extend(ce.get_all_events())
|
||||||
|
endgame_cards.append(ce.get_endgame_card())
|
||||||
|
if 'high_noon' in game.expansions:
|
||||||
|
self.event_cards.extend(ceh.get_all_events())
|
||||||
|
endgame_cards.append(ceh.get_endgame_card())
|
||||||
|
if len(self.event_cards) > 0:
|
||||||
self.event_cards.insert(0, None)
|
self.event_cards.insert(0, None)
|
||||||
self.event_cards.insert(0, None) # 2 perchè iniziale, e primo flip dallo sceriffo
|
self.event_cards.insert(0, None) # 2 perchè iniziale, e primo flip dallo sceriffo
|
||||||
|
self.event_cards.append(random.choice(endgame_cards))
|
||||||
random.shuffle(self.cards)
|
random.shuffle(self.cards)
|
||||||
self.scrap_pile: List[cs.Card] = []
|
self.scrap_pile: List[cs.Card] = []
|
||||||
print(f'Deck initialized with {len(self.cards)} cards')
|
print(f'Deck initialized with {len(self.cards)} cards')
|
||||||
|
|
||||||
def flip_event(self):
|
def flip_event(self):
|
||||||
if len(self.event_cards) > 0 and not isinstance(self.event_cards[0], ce.PerUnPugnoDiCarte):
|
if len(self.event_cards) > 0 and not (isinstance(self.event_cards[0], ce.PerUnPugnoDiCarte) or isinstance(self.event_cards[0], ceh.MezzogiornoDiFuoco)):
|
||||||
self.event_cards.append(self.event_cards.pop(0))
|
self.event_cards.append(self.event_cards.pop(0))
|
||||||
self.game.notify_event_card()
|
self.game.notify_event_card()
|
||||||
|
|
||||||
|
@ -97,6 +97,11 @@ class Vendetta(CardEvent):
|
|||||||
self.desc = "Alla fine del proprio turno il giocatore estrae dal mazzo, se esce ♥️ gioca un altro turno (ma non estrae di nuovo)"
|
self.desc = "Alla fine del proprio turno il giocatore estrae dal mazzo, se esce ♥️ gioca un altro turno (ma non estrae di nuovo)"
|
||||||
self.desc_eng = "When ending the turn, the player flips a card from the deck, if it's ♥️ he plays another turn (but he does not flip another card)"
|
self.desc_eng = "When ending the turn, the player flips a card from the deck, if it's ♥️ he plays another turn (but he does not flip another card)"
|
||||||
|
|
||||||
|
def get_endgame_card():
|
||||||
|
end_game = PerUnPugnoDiCarte()
|
||||||
|
end_game.expansion = 'fistful-of-cards'
|
||||||
|
return end_game
|
||||||
|
|
||||||
def get_all_events():
|
def get_all_events():
|
||||||
cards = [
|
cards = [
|
||||||
Agguato(),
|
Agguato(),
|
||||||
@ -115,7 +120,6 @@ def get_all_events():
|
|||||||
Vendetta(),
|
Vendetta(),
|
||||||
]
|
]
|
||||||
random.shuffle(cards)
|
random.shuffle(cards)
|
||||||
cards.append(PerUnPugnoDiCarte())
|
|
||||||
for c in cards:
|
for c in cards:
|
||||||
c.expansion = 'fistful-of-cards'
|
c.expansion = 'fistful-of-cards'
|
||||||
return cards
|
return cards
|
119
backend/bang/expansions/high_noon/card_events.py
Normal file
119
backend/bang/expansions/high_noon/card_events.py
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
import random
|
||||||
|
from bang.expansions.fistful_of_cards.card_events import CardEvent
|
||||||
|
|
||||||
|
class Benedizione(CardEvent):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Benedizione", "🙏")
|
||||||
|
self.desc = "Tutte le carte sono considerate di cuori ♥️"
|
||||||
|
self.desc_eng = ""
|
||||||
|
|
||||||
|
class Maledizione(CardEvent):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Maledizione", "🤬")
|
||||||
|
self.desc = "Tutte le carte sono considerate di picche ♠"
|
||||||
|
self.desc_eng = ""
|
||||||
|
|
||||||
|
class Sbornia(CardEvent):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Sbornia", "🥴")
|
||||||
|
self.desc = "I personaggi perdono le loro abilità speciali"
|
||||||
|
self.desc_eng = ""
|
||||||
|
|
||||||
|
class Sete(CardEvent):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Sete", "🥵")
|
||||||
|
self.desc = "I giocatori pescano 1 carta in meno nella loro fase 1"
|
||||||
|
self.desc_eng = ""
|
||||||
|
|
||||||
|
class IlTreno(CardEvent):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Il Treno", "🚂")
|
||||||
|
self.desc = "I giocatori pescano 1 carta extra nella loro fase 1"
|
||||||
|
self.desc_eng = ""
|
||||||
|
|
||||||
|
class IlReverendo(CardEvent):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Il Reverendo", "⛪️")
|
||||||
|
self.desc = "Non si possono giocare le carte Birra"
|
||||||
|
self.desc_eng = ""
|
||||||
|
|
||||||
|
class IlDottore(CardEvent):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Il Dottore", "👨⚕️")
|
||||||
|
self.desc = "Il/i giocatore/i con meno vite ne recupera/no una"
|
||||||
|
self.desc_eng = ""
|
||||||
|
|
||||||
|
class Sermone(CardEvent):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Sermone", "✝️")
|
||||||
|
self.desc = "I giocatori non possono giocare Bang! durante il loro turno"
|
||||||
|
self.desc_eng = ""
|
||||||
|
|
||||||
|
class Sparatoria(CardEvent):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Sparatoria", "🔫🔫")
|
||||||
|
self.desc = "Il limite di Bang! per turno è 2 invece che 1"
|
||||||
|
self.desc_eng = ""
|
||||||
|
|
||||||
|
class CorsaAllOro(CardEvent):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Corsa All'Oro", "🌟")
|
||||||
|
self.desc = "Si gioca per un intero giro in senso antiorario, tuttavia gli effetti delle carte rimangono invariati"
|
||||||
|
self.desc_eng = ""
|
||||||
|
|
||||||
|
class IDalton(CardEvent):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("I Dalton", "🙇♂️")
|
||||||
|
self.desc = "Chi ha carte blu in gioco ne scarta 1 a sua scelta"
|
||||||
|
self.desc_eng = ""
|
||||||
|
|
||||||
|
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 = ""
|
||||||
|
|
||||||
|
class NuovaIdentita(CardEvent):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Nuova Identità", "🕶")
|
||||||
|
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 = ""
|
||||||
|
|
||||||
|
class CittaFantasma(CardEvent):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Città Fantasma", "👻")
|
||||||
|
self.desc = "Tutti i giocatori morti tornano in vita al proprio turno, non possono morire e pescano 3 carte invece che 2. Quando terminano il turno tornano morti."
|
||||||
|
self.desc_eng = ""
|
||||||
|
|
||||||
|
class MezzogiornoDiFuoco(CardEvent):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Mezzogiorno di Fuoco", "🔥")
|
||||||
|
self.desc = "Ogni giocatore perde 1 punto vita all'inizio del turno"
|
||||||
|
self.desc_eng = "Every player loses 1 HP when their turn starts"
|
||||||
|
|
||||||
|
def get_endgame_card():
|
||||||
|
end_game = MezzogiornoDiFuoco()
|
||||||
|
end_game.expansion = 'high-noon'
|
||||||
|
return end_game
|
||||||
|
|
||||||
|
def get_all_events():
|
||||||
|
cards = [
|
||||||
|
Benedizione(),
|
||||||
|
Maledizione(),
|
||||||
|
CittaFantasma(),
|
||||||
|
CorsaAllOro(),
|
||||||
|
IDalton(),
|
||||||
|
IlDottore(),
|
||||||
|
IlReverendo(),
|
||||||
|
IlTreno(),
|
||||||
|
Sbornia(),
|
||||||
|
Sermone(),
|
||||||
|
Sete(),
|
||||||
|
Sparatoria(),
|
||||||
|
# Manette(),
|
||||||
|
# NuovaIdentita(),
|
||||||
|
]
|
||||||
|
random.shuffle(cards)
|
||||||
|
for c in cards:
|
||||||
|
c.expansion = 'high-noon'
|
||||||
|
return cards
|
@ -2,12 +2,14 @@
|
|||||||
from typing import List, Set, Dict, Tuple, Optional
|
from typing import List, Set, Dict, Tuple, Optional
|
||||||
import random
|
import random
|
||||||
import socketio
|
import socketio
|
||||||
|
import eventlet
|
||||||
|
|
||||||
import bang.players as pl
|
import bang.players as pl
|
||||||
import bang.characters as characters
|
import bang.characters as characters
|
||||||
from bang.deck import Deck
|
from bang.deck import Deck
|
||||||
import bang.roles as roles
|
import bang.roles as roles
|
||||||
import bang.expansions.fistful_of_cards.card_events as ce
|
import bang.expansions.fistful_of_cards.card_events as ce
|
||||||
import eventlet
|
import bang.expansions.high_noon.card_events as ceh
|
||||||
|
|
||||||
class Game:
|
class Game:
|
||||||
def __init__(self, name, sio:socketio):
|
def __init__(self, name, sio:socketio):
|
||||||
@ -15,7 +17,7 @@ class Game:
|
|||||||
self.sio = sio
|
self.sio = sio
|
||||||
self.name = name
|
self.name = name
|
||||||
self.players: List[pl.Player] = []
|
self.players: List[pl.Player] = []
|
||||||
self.dead_players: List[pl.Player] = []
|
self.spectators: List[pl.Player] = []
|
||||||
self.deck: Deck = None
|
self.deck: Deck = None
|
||||||
self.started = False
|
self.started = False
|
||||||
self.turn = 0
|
self.turn = 0
|
||||||
@ -24,13 +26,16 @@ class Game:
|
|||||||
self.initial_players = 0
|
self.initial_players = 0
|
||||||
self.password = ''
|
self.password = ''
|
||||||
self.expansions = []
|
self.expansions = []
|
||||||
self.available_expansions = ['dodge_city', 'fistful_of_cards']
|
self.available_expansions = ['dodge_city', 'fistful_of_cards', 'high_noon']
|
||||||
self.shutting_down = False
|
self.shutting_down = False
|
||||||
self.is_competitive = False
|
self.is_competitive = False
|
||||||
self.disconnect_bot = True
|
self.disconnect_bot = True
|
||||||
self.player_bangs = 0
|
self.player_bangs = 0
|
||||||
self.is_russian_roulette_on = False
|
self.is_russian_roulette_on = False
|
||||||
|
self.dalton_on = False
|
||||||
self.bot_speed = 1.5
|
self.bot_speed = 1.5
|
||||||
|
self.incremental_turn = 0
|
||||||
|
self.did_resuscitate_deadman = False
|
||||||
|
|
||||||
def notify_room(self, sid=None):
|
def notify_room(self, sid=None):
|
||||||
if len([p for p in self.players if p.character == None]) != 0 or sid:
|
if len([p for p in self.players if p.character == None]) != 0 or sid:
|
||||||
@ -148,7 +153,7 @@ class Game:
|
|||||||
attacker.notify_self()
|
attacker.notify_self()
|
||||||
self.waiting_for = 0
|
self.waiting_for = 0
|
||||||
self.readyCount = 0
|
self.readyCount = 0
|
||||||
for p in self.players:
|
for p in self.get_alive_players():
|
||||||
if p != attacker:
|
if p != attacker:
|
||||||
if p.get_banged(attacker=attacker):
|
if p.get_banged(attacker=attacker):
|
||||||
self.waiting_for += 1
|
self.waiting_for += 1
|
||||||
@ -162,7 +167,7 @@ class Game:
|
|||||||
attacker.notify_self()
|
attacker.notify_self()
|
||||||
self.waiting_for = 0
|
self.waiting_for = 0
|
||||||
self.readyCount = 0
|
self.readyCount = 0
|
||||||
for p in self.players:
|
for p in self.get_alive_players():
|
||||||
if p != attacker:
|
if p != attacker:
|
||||||
if p.get_indians(attacker=attacker):
|
if p.get_indians(attacker=attacker):
|
||||||
self.waiting_for += 1
|
self.waiting_for += 1
|
||||||
@ -196,7 +201,8 @@ class Game:
|
|||||||
self.get_player_named(target_username).notify_self()
|
self.get_player_named(target_username).notify_self()
|
||||||
|
|
||||||
def emporio(self):
|
def emporio(self):
|
||||||
self.available_cards = [self.deck.draw(True) for i in range(len([p for p in self.players if p.lives > 0]))]
|
pls = self.get_alive_players()
|
||||||
|
self.available_cards = [self.deck.draw(True) for i in range(len(pls))]
|
||||||
self.players[self.turn].pending_action = pl.PendingAction.CHOOSE
|
self.players[self.turn].pending_action = pl.PendingAction.CHOOSE
|
||||||
self.players[self.turn].choose_text = 'choose_card_to_get'
|
self.players[self.turn].choose_text = 'choose_card_to_get'
|
||||||
self.players[self.turn].available_cards = self.available_cards
|
self.players[self.turn].available_cards = self.available_cards
|
||||||
@ -207,13 +213,14 @@ class Game:
|
|||||||
player.available_cards = []
|
player.available_cards = []
|
||||||
player.pending_action = pl.PendingAction.WAIT
|
player.pending_action = pl.PendingAction.WAIT
|
||||||
player.notify_self()
|
player.notify_self()
|
||||||
nextPlayer = self.players[(self.turn + (len(self.players)-len(self.available_cards))) % len(self.players)]
|
pls = self.get_alive_players()
|
||||||
|
nextPlayer = pls[(pls.index(self.players[self.turn])+(len(pls)-len(self.available_cards))) % len(pls)]
|
||||||
if nextPlayer == self.players[self.turn]:
|
if nextPlayer == self.players[self.turn]:
|
||||||
self.players[self.turn].pending_action = pl.PendingAction.PLAY
|
self.players[self.turn].pending_action = pl.PendingAction.PLAY
|
||||||
self.players[self.turn].notify_self()
|
self.players[self.turn].notify_self()
|
||||||
else:
|
else:
|
||||||
nextPlayer.pending_action = pl.PendingAction.CHOOSE
|
nextPlayer.pending_action = pl.PendingAction.CHOOSE
|
||||||
self.players[self.turn].choose_text = 'choose_card_to_get'
|
nextPlayer.choose_text = 'choose_card_to_get'
|
||||||
nextPlayer.available_cards = self.available_cards
|
nextPlayer.available_cards = self.available_cards
|
||||||
nextPlayer.notify_self()
|
nextPlayer.notify_self()
|
||||||
|
|
||||||
@ -257,19 +264,35 @@ class Game:
|
|||||||
self.players[self.turn].notify_self()
|
self.players[self.turn].notify_self()
|
||||||
|
|
||||||
def next_player(self):
|
def next_player(self):
|
||||||
return self.players[(self.turn + 1) % len(self.players)]
|
pls = self.get_alive_players()
|
||||||
|
return pls[(pls.index(self.players[self.turn]) + 1) % len(pls)]
|
||||||
|
|
||||||
def play_turn(self):
|
def play_turn(self):
|
||||||
|
self.incremental_turn += 1
|
||||||
|
if self.players[self.turn].is_dead:
|
||||||
|
pl = sorted(self.get_dead_players(), key=lambda x:x.death_turn)[0]
|
||||||
|
if self.check_event(ce.DeadMan) and not self.did_resuscitate_deadman and pl != self.players[self.turn]:
|
||||||
|
print(f'{self.players[self.turn]} is dead, revive')
|
||||||
|
self.did_resuscitate_deadman = True
|
||||||
|
pl.is_dead = False
|
||||||
|
pl.is_ghost = False
|
||||||
|
pl.lives = 2
|
||||||
|
pl.hand.append(self.deck.draw())
|
||||||
|
pl.hand.append(self.deck.draw())
|
||||||
|
pl.notify_self()
|
||||||
|
elif self.check_event(ceh.CittaFantasma):
|
||||||
|
print(f'{self.players[self.turn]} is dead, event ghost')
|
||||||
|
self.players[self.turn].is_ghost = True
|
||||||
|
else:
|
||||||
|
print(f'{self.players[self.turn]} is dead, next turn')
|
||||||
|
return self.next_turn()
|
||||||
self.player_bangs = 0
|
self.player_bangs = 0
|
||||||
if isinstance(self.players[self.turn].role, roles.Sheriff):
|
if isinstance(self.players[self.turn].role, roles.Sheriff):
|
||||||
self.deck.flip_event()
|
self.deck.flip_event()
|
||||||
if self.check_event(ce.DeadMan) and len(self.dead_players) > 0:
|
if len(self.deck.event_cards) > 0 and self.deck.event_cards[0] != None:
|
||||||
self.players.append(self.dead_players.pop(0))
|
print(f'flip new event {self.deck.event_cards[0].name}')
|
||||||
self.players[-1].lives = 2
|
if self.check_event(ce.DeadMan):
|
||||||
self.players[-1].hand.append(self.deck.draw())
|
self.did_resuscitate_deadman = False
|
||||||
self.players[-1].hand.append(self.deck.draw())
|
|
||||||
self.players_map = {c.name: i for i, c in enumerate(self.players)}
|
|
||||||
self.players[-1].notify_self()
|
|
||||||
elif self.check_event(ce.RouletteRussa):
|
elif self.check_event(ce.RouletteRussa):
|
||||||
self.is_russian_roulette_on = True
|
self.is_russian_roulette_on = True
|
||||||
if self.players[self.turn].get_banged(self.deck.event_cards[0]):
|
if self.players[self.turn].get_banged(self.deck.event_cards[0]):
|
||||||
@ -277,6 +300,26 @@ class Game:
|
|||||||
else:
|
else:
|
||||||
self.responders_did_respond_resume_turn(did_lose=True)
|
self.responders_did_respond_resume_turn(did_lose=True)
|
||||||
return
|
return
|
||||||
|
elif self.check_event(ceh.IlDottore):
|
||||||
|
most_hurt = [p.lives for p in self.players if p.lives > 0 and p.max_lives > p.lives]
|
||||||
|
if len(most_hurt) > 0:
|
||||||
|
hurt_players = [p for p in self.players if p.lives == min(most_hurt)]
|
||||||
|
for p in hurt_players:
|
||||||
|
p.lives += 1
|
||||||
|
self.sio.emit('chat_message', room=self.name, data=f'_doctor_heal|{p.name}')
|
||||||
|
p.notify_self()
|
||||||
|
elif self.check_event(ceh.IDalton):
|
||||||
|
self.waiting_for = 0
|
||||||
|
self.readyCount = 0
|
||||||
|
self.dalton_on = True
|
||||||
|
for p in self.players:
|
||||||
|
if p.get_dalton():
|
||||||
|
self.waiting_for += 1
|
||||||
|
p.notify_self()
|
||||||
|
if self.waiting_for != 0:
|
||||||
|
return
|
||||||
|
self.dalton_on = False
|
||||||
|
|
||||||
if self.check_event(ce.PerUnPugnoDiCarte) and len(self.players[self.turn].hand) > 0:
|
if self.check_event(ce.PerUnPugnoDiCarte) and len(self.players[self.turn].hand) > 0:
|
||||||
self.player_bangs = len(self.players[self.turn].hand)
|
self.player_bangs = len(self.players[self.turn].hand)
|
||||||
if self.players[self.turn].get_banged(self.deck.event_cards[0]):
|
if self.players[self.turn].get_banged(self.deck.event_cards[0]):
|
||||||
@ -284,11 +327,17 @@ class Game:
|
|||||||
else:
|
else:
|
||||||
self.responders_did_respond_resume_turn()
|
self.responders_did_respond_resume_turn()
|
||||||
else:
|
else:
|
||||||
|
print(f'notifying {self.players[self.turn].name} about his turn')
|
||||||
self.players[self.turn].play_turn()
|
self.players[self.turn].play_turn()
|
||||||
|
|
||||||
def next_turn(self):
|
def next_turn(self):
|
||||||
if self.shutting_down: return
|
if self.shutting_down: return
|
||||||
if len(self.players) > 0:
|
print(f'{self.players[self.turn].name} invoked next turn')
|
||||||
|
pls = self.get_alive_players()
|
||||||
|
if len(pls) > 0:
|
||||||
|
if self.check_event(ceh.CorsaAllOro):
|
||||||
|
self.turn = (self.turn - 1) % len(self.players)
|
||||||
|
else:
|
||||||
self.turn = (self.turn + 1) % len(self.players)
|
self.turn = (self.turn + 1) % len(self.players)
|
||||||
self.play_turn()
|
self.play_turn()
|
||||||
|
|
||||||
@ -308,26 +357,29 @@ class Game:
|
|||||||
|
|
||||||
def handle_disconnect(self, player: pl.Player):
|
def handle_disconnect(self, player: pl.Player):
|
||||||
print(f'player {player.name} left the game {self.name}')
|
print(f'player {player.name} left the game {self.name}')
|
||||||
if player in self.players:
|
if player in self.spectators:
|
||||||
|
self.spectators.remove(player)
|
||||||
|
return
|
||||||
if self.disconnect_bot and self.started:
|
if self.disconnect_bot and self.started:
|
||||||
player.is_bot = True
|
player.is_bot = True
|
||||||
eventlet.sleep(15) # he may reconnect
|
eventlet.sleep(15) # he may reconnect
|
||||||
player.notify_self()
|
player.notify_self()
|
||||||
else:
|
else:
|
||||||
self.player_death(player=player, disconnected=True)
|
self.player_death(player=player, disconnected=True)
|
||||||
else:
|
# else:
|
||||||
self.dead_players.remove(player)
|
# player.lives = 0
|
||||||
if len([p for p in self.players if not p.is_bot])+len([p for p in self.dead_players if not p.is_bot]) == 0:
|
# self.players.remove(player)
|
||||||
|
if len([p for p in self.players if not p.is_bot]) == 0:
|
||||||
print(f'no players left in game {self.name}')
|
print(f'no players left in game {self.name}')
|
||||||
self.shutting_down = True
|
self.shutting_down = True
|
||||||
self.players = []
|
self.players = []
|
||||||
self.dead_players = []
|
self.spectators = []
|
||||||
self.deck = None
|
self.deck = None
|
||||||
return True
|
return True
|
||||||
else: return False
|
else: return False
|
||||||
|
|
||||||
def player_death(self, player: pl.Player, disconnected=False):
|
def player_death(self, player: pl.Player, disconnected=False):
|
||||||
if not player in self.players: return
|
if not player in self.players or player.is_ghost: return
|
||||||
import bang.expansions.dodge_city.characters as chd
|
import bang.expansions.dodge_city.characters as chd
|
||||||
print(player.attacker)
|
print(player.attacker)
|
||||||
if player.attacker and player.attacker in self.players and isinstance(player.attacker.role, roles.Sheriff) and isinstance(player.role, roles.Vice):
|
if player.attacker and player.attacker in self.players and isinstance(player.attacker.role, roles.Sheriff) and isinstance(player.role, roles.Vice):
|
||||||
@ -344,15 +396,23 @@ class Game:
|
|||||||
if (self.waiting_for > 0):
|
if (self.waiting_for > 0):
|
||||||
self.responders_did_respond_resume_turn()
|
self.responders_did_respond_resume_turn()
|
||||||
|
|
||||||
if not player in self.players: return
|
if player.is_dead: return
|
||||||
|
if not self.started:
|
||||||
|
self.players.remove(player)
|
||||||
|
elif disconnected:
|
||||||
index = self.players.index(player)
|
index = self.players.index(player)
|
||||||
died_in_his_turn = self.started and index == self.turn
|
|
||||||
if self.started and index <= self.turn:
|
if self.started and index <= self.turn:
|
||||||
self.turn -= 1
|
self.turn -= 1
|
||||||
|
self.players.remove(player)
|
||||||
|
self.players_map = {c.name: i for i, c in enumerate(self.players)}
|
||||||
|
player.lives = 0
|
||||||
|
player.is_dead = True
|
||||||
|
player.death_turn = self.incremental_turn
|
||||||
|
|
||||||
corpse = self.players.pop(index)
|
# corpse = self.players.pop(index)
|
||||||
if not disconnected:
|
corpse = player
|
||||||
self.dead_players.append(corpse)
|
# if not disconnected:
|
||||||
|
# self.dead_players.append(corpse)
|
||||||
self.notify_room()
|
self.notify_room()
|
||||||
self.sio.emit('chat_message', room=self.name, data=f'_died|{player.name}')
|
self.sio.emit('chat_message', room=self.name, data=f'_died|{player.name}')
|
||||||
if self.started:
|
if self.started:
|
||||||
@ -360,23 +420,23 @@ class Game:
|
|||||||
for p in self.players:
|
for p in self.players:
|
||||||
if not p.is_bot:
|
if not p.is_bot:
|
||||||
p.notify_self()
|
p.notify_self()
|
||||||
self.players_map = {c.name: i for i, c in enumerate(self.players)}
|
# self.players_map = {c.name: i for i, c in enumerate(self.players)}
|
||||||
if self.started:
|
if self.started:
|
||||||
print('Check win status')
|
print('Check win status')
|
||||||
attacker_role = None
|
attacker_role = None
|
||||||
if player.attacker and player.attacker in self.players:
|
if player.attacker and player.attacker in self.players:
|
||||||
attacker_role = player.attacker.role
|
attacker_role = player.attacker.role
|
||||||
winners = [p for p in self.players if p.role != None and p.role.on_player_death(self.players, initial_players=self.initial_players, dead_role=player.role, attacker_role=attacker_role)]
|
winners = [p for p in self.players if p.role != None and p.role.on_player_death(self.get_alive_players(), initial_players=self.initial_players, dead_role=player.role, attacker_role=attacker_role)]
|
||||||
if len(winners) > 0:
|
if len(winners) > 0:
|
||||||
print('WE HAVE A WINNER')
|
print('WE HAVE A WINNER')
|
||||||
for p in self.players:
|
for p in self.get_alive_players():
|
||||||
p.win_status = p in winners
|
p.win_status = p in winners
|
||||||
self.sio.emit('chat_message', room=self.name, data=f'_won|{p.name}')
|
self.sio.emit('chat_message', room=self.name, data=f'_won|{p.name}')
|
||||||
p.notify_self()
|
p.notify_self()
|
||||||
eventlet.sleep(5.0)
|
eventlet.sleep(5.0)
|
||||||
return self.reset()
|
return self.reset()
|
||||||
|
|
||||||
vulture = [p for p in self.players if isinstance(p.character, characters.VultureSam)]
|
vulture = [p for p in self.get_alive_players() if p.character.check(self, characters.VultureSam)]
|
||||||
if len(vulture) == 0:
|
if len(vulture) == 0:
|
||||||
for i in range(len(player.hand)):
|
for i in range(len(player.hand)):
|
||||||
self.deck.scrap(player.hand.pop(), True)
|
self.deck.scrap(player.hand.pop(), True)
|
||||||
@ -397,31 +457,32 @@ class Game:
|
|||||||
vulture[0].notify_self()
|
vulture[0].notify_self()
|
||||||
|
|
||||||
#se Vulture Sam è uno sceriffo e ha appena ucciso il suo Vice, deve scartare le carte che ha pescato con la sua abilità
|
#se Vulture Sam è uno sceriffo e ha appena ucciso il suo Vice, deve scartare le carte che ha pescato con la sua abilità
|
||||||
if player.attacker and player.attacker in self.players and isinstance(player.attacker.role, roles.Sheriff) and isinstance(player.role, roles.Vice):
|
if player.attacker and player.attacker in self.get_alive_players() and isinstance(player.attacker.role, roles.Sheriff) and isinstance(player.role, roles.Vice):
|
||||||
for i in range(len(player.attacker.hand)):
|
for i in range(len(player.attacker.hand)):
|
||||||
self.deck.scrap(player.attacker.hand.pop(), True)
|
self.deck.scrap(player.attacker.hand.pop(), True)
|
||||||
player.attacker.notify_self()
|
player.attacker.notify_self()
|
||||||
|
|
||||||
greg = [p for p in self.players if isinstance(p.character, chd.GregDigger)]
|
greg = [p for p in self.get_alive_players() if p.character.check(self, chd.GregDigger)]
|
||||||
if len(greg) > 0:
|
if len(greg) > 0:
|
||||||
greg[0].lives = min(greg[0].lives+2, greg[0].max_lives)
|
greg[0].lives = min(greg[0].lives+2, greg[0].max_lives)
|
||||||
herb = [p for p in self.players if isinstance(p.character, chd.HerbHunter)]
|
herb = [p for p in self.get_alive_players() if p.character.check(self, chd.HerbHunter)]
|
||||||
if len(herb) > 0:
|
if len(herb) > 0:
|
||||||
herb[0].hand.append(self.deck.draw(True))
|
herb[0].hand.append(self.deck.draw(True))
|
||||||
herb[0].hand.append(self.deck.draw(True))
|
herb[0].hand.append(self.deck.draw(True))
|
||||||
herb[0].notify_self()
|
herb[0].notify_self()
|
||||||
|
|
||||||
if died_in_his_turn:
|
if corpse.is_my_turn:
|
||||||
self.next_turn()
|
self.next_turn()
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
print('resetting lobby')
|
print('resetting lobby')
|
||||||
self.players.extend(self.dead_players)
|
self.players.extend(self.spectators)
|
||||||
self.dead_players = []
|
self.spectators = []
|
||||||
self.players = [p for p in self.players if not p.is_bot]
|
self.players = [p for p in self.players if not p.is_bot]
|
||||||
print(self.players)
|
print(self.players)
|
||||||
self.started = False
|
self.started = False
|
||||||
self.waiting_for = 0
|
self.waiting_for = 0
|
||||||
|
self.incremental_turn = 0
|
||||||
for p in self.players:
|
for p in self.players:
|
||||||
p.reset()
|
p.reset()
|
||||||
p.notify_self()
|
p.notify_self()
|
||||||
@ -433,17 +494,26 @@ class Game:
|
|||||||
return isinstance(self.deck.event_cards[0], ev)
|
return isinstance(self.deck.event_cards[0], ev)
|
||||||
|
|
||||||
def get_visible_players(self, player: pl.Player):
|
def get_visible_players(self, player: pl.Player):
|
||||||
i = self.players.index(player)
|
pls = self.get_alive_players()
|
||||||
|
if len(pls) == 0 or player not in pls: return []
|
||||||
|
i = pls.index(player)
|
||||||
sight = player.get_sight()
|
sight = player.get_sight()
|
||||||
mindist = 99 if not self.check_event(ce.Agguato) else 1
|
mindist = 99 if not self.check_event(ce.Agguato) else 1
|
||||||
return [{
|
return [{
|
||||||
'name': self.players[j].name,
|
'name': pls[j].name,
|
||||||
'dist': min([abs(i - j), (i+ abs(j-len(self.players))), (j+ abs(i-len(self.players))), mindist]) + self.players[j].get_visibility() - (player.get_sight(countWeapon=False)-1),
|
'dist': min([abs(i - j), (i+ abs(j-len(pls))), (j+ abs(i-len(pls))), mindist]) + pls[j].get_visibility() - (player.get_sight(countWeapon=False)-1),
|
||||||
'lives': self.players[j].lives,
|
'lives': pls[j].lives,
|
||||||
'max_lives': self.players[j].max_lives,
|
'max_lives': pls[j].max_lives,
|
||||||
'is_sheriff': isinstance(self.players[j].role, roles.Sheriff),
|
'is_sheriff': isinstance(pls[j].role, roles.Sheriff),
|
||||||
'cards': len(self.players[j].hand)+len(self.players[j].equipment)
|
'cards': len(pls[j].hand)+len(pls[j].equipment),
|
||||||
} for j in range(len(self.players)) if i != j]
|
'is_ghost': pls[j].is_ghost,
|
||||||
|
} for j in range(len(pls)) if i != j]
|
||||||
|
|
||||||
|
def get_alive_players(self):
|
||||||
|
return [p for p in self.players if not p.is_dead or p.is_ghost]
|
||||||
|
|
||||||
|
def get_dead_players(self):
|
||||||
|
return [p for p in self.players if p.is_dead]
|
||||||
|
|
||||||
def notify_all(self):
|
def notify_all(self):
|
||||||
if self.started:
|
if self.started:
|
||||||
@ -458,6 +528,7 @@ class Game:
|
|||||||
'pending_action': p.pending_action,
|
'pending_action': p.pending_action,
|
||||||
'character': p.character.__dict__ if p.character else None,
|
'character': p.character.__dict__ if p.character else None,
|
||||||
'real_character': p.real_character.__dict__ if p.real_character else None,
|
'real_character': p.real_character.__dict__ if p.real_character else None,
|
||||||
'icon': p.role.icon if self.initial_players == 3 and p.role else '🤠'
|
'icon': p.role.icon if self.initial_players == 3 and p.role else '🤠',
|
||||||
} for p in self.players]
|
'is_ghost': p.is_ghost,
|
||||||
|
} for p in self.get_alive_players()]
|
||||||
self.sio.emit('players_update', room=self.name, data=data)
|
self.sio.emit('players_update', room=self.name, data=data)
|
||||||
|
@ -9,6 +9,7 @@ import bang.expansions.dodge_city.cards as csd
|
|||||||
import bang.characters as chars
|
import bang.characters as chars
|
||||||
import bang.expansions.dodge_city.characters as chd
|
import bang.expansions.dodge_city.characters as chd
|
||||||
import bang.expansions.fistful_of_cards.card_events as ce
|
import bang.expansions.fistful_of_cards.card_events as ce
|
||||||
|
import bang.expansions.high_noon.card_events as ceh
|
||||||
import eventlet
|
import eventlet
|
||||||
|
|
||||||
class PendingAction(IntEnum):
|
class PendingAction(IntEnum):
|
||||||
@ -58,7 +59,11 @@ class Player:
|
|||||||
self.mancato_needed = 0
|
self.mancato_needed = 0
|
||||||
self.molly_discarded_cards = 0
|
self.molly_discarded_cards = 0
|
||||||
self.is_bot = bot
|
self.is_bot = bot
|
||||||
|
self.bang_used = 0
|
||||||
self.special_use_count = 0
|
self.special_use_count = 0
|
||||||
|
self.is_dead = False
|
||||||
|
self.death_turn = 0
|
||||||
|
self.is_ghost = False
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.hand: cs.Card = []
|
self.hand: cs.Card = []
|
||||||
@ -91,6 +96,9 @@ class Player:
|
|||||||
pass
|
pass
|
||||||
self.mancato_needed = 0
|
self.mancato_needed = 0
|
||||||
self.molly_discarded_cards = 0
|
self.molly_discarded_cards = 0
|
||||||
|
self.is_dead = False
|
||||||
|
self.is_ghost = False
|
||||||
|
self.death_turn = 0
|
||||||
|
|
||||||
def join_game(self, game):
|
def join_game(self, game):
|
||||||
self.game = game
|
self.game = game
|
||||||
@ -156,6 +164,7 @@ class Player:
|
|||||||
self.sio.emit('notify_card', room=self.sid, data=mess)
|
self.sio.emit('notify_card', room=self.sid, data=mess)
|
||||||
|
|
||||||
def notify_self(self):
|
def notify_self(self):
|
||||||
|
if self.is_ghost: self.lives = 0
|
||||||
if self.pending_action == PendingAction.DRAW and self.game.check_event(ce.Peyote):
|
if self.pending_action == PendingAction.DRAW and self.game.check_event(ce.Peyote):
|
||||||
self.available_cards = [{
|
self.available_cards = [{
|
||||||
'icon': '🔴'
|
'icon': '🔴'
|
||||||
@ -173,11 +182,11 @@ class Player:
|
|||||||
self.is_playing_ranch = True
|
self.is_playing_ranch = True
|
||||||
self.choose_text = 'choose_ranch'
|
self.choose_text = 'choose_ranch'
|
||||||
self.pending_action = PendingAction.CHOOSE
|
self.pending_action = PendingAction.CHOOSE
|
||||||
elif isinstance(self.character, chars.SuzyLafayette) and len(self.hand) == 0 and ( not self.is_my_turn or self.pending_action == PendingAction.PLAY):
|
elif self.character and self.character.check(self.game, chars.SuzyLafayette) and self.lives > 0 and len(self.hand) == 0 and ( not self.is_my_turn or self.pending_action == PendingAction.PLAY):
|
||||||
self.hand.append(self.game.deck.draw(True))
|
self.hand.append(self.game.deck.draw(True))
|
||||||
if self.lives <= 0 and self.max_lives > 0:
|
if self.lives <= 0 and self.max_lives > 0 and not self.is_dead:
|
||||||
print('dying, attacker', self.attacker)
|
print('dying, attacker', self.attacker)
|
||||||
if isinstance(self.character, chars.SidKetchum) and len(self.hand) > 1:
|
if self.character.check(self.game, chars.SidKetchum) and len(self.hand) > 1:
|
||||||
self.lives += 1
|
self.lives += 1
|
||||||
#TODO Sid dovrebbe poter decidere cosa scartare
|
#TODO Sid dovrebbe poter decidere cosa scartare
|
||||||
self.game.deck.scrap(self.hand.pop(
|
self.game.deck.scrap(self.hand.pop(
|
||||||
@ -197,7 +206,7 @@ class Player:
|
|||||||
ser['sight'] = self.get_sight()
|
ser['sight'] = self.get_sight()
|
||||||
ser['lives'] = max(ser['lives'], 0)
|
ser['lives'] = max(ser['lives'], 0)
|
||||||
|
|
||||||
if self.lives <= 0 and self.max_lives > 0:
|
if self.lives <= 0 and self.max_lives > 0 and not self.is_dead:
|
||||||
self.pending_action = PendingAction.WAIT
|
self.pending_action = PendingAction.WAIT
|
||||||
ser['hand'] = []
|
ser['hand'] = []
|
||||||
ser['equipment'] = []
|
ser['equipment'] = []
|
||||||
@ -228,8 +237,10 @@ class Player:
|
|||||||
self.draw('')
|
self.draw('')
|
||||||
elif self.pending_action == PendingAction.PLAY:
|
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])]
|
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) and not c.usable_next_turn) or isinstance(c, cs.Diligenza) or isinstance(c, cs.Emporio) or (isinstance(c, cs.Birra) and self.lives < self.max_lives)]
|
misc = [c for c in self.hand if (isinstance(c, cs.WellsFargo) and not c.usable_next_turn) 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))]
|
||||||
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 (self.has_played_bang and not (any([isinstance(c, cs.Volcanic) for c in self.equipment]) and not self.game.check_event(ce.Lazo))) and not ( isinstance(c, cs.Prigione) 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 (
|
||||||
|
(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]
|
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]
|
||||||
if len(equippables) > 0 and not self.game.check_event(ce.IlGiudice):
|
if len(equippables) > 0 and not self.game.check_event(ce.IlGiudice):
|
||||||
for c in equippables:
|
for c in equippables:
|
||||||
@ -271,7 +282,7 @@ class Player:
|
|||||||
if self.play_card(len(self.hand)+self.equipment.index(c), against=target['name']):
|
if self.play_card(len(self.hand)+self.equipment.index(c), against=target['name']):
|
||||||
return
|
return
|
||||||
break
|
break
|
||||||
maxcards = self.lives if not isinstance(self.character, chd.SeanMallory) else 10
|
maxcards = self.lives if not self.character.check(self.game, chd.SeanMallory) else 10
|
||||||
if len(self.hand) > maxcards:
|
if len(self.hand) > maxcards:
|
||||||
self.scrap(0)
|
self.scrap(0)
|
||||||
else:
|
else:
|
||||||
@ -302,7 +313,7 @@ class Player:
|
|||||||
self.choose(randrange(0, len(target.hand)+len(target.equipment)))
|
self.choose(randrange(0, len(target.hand)+len(target.equipment)))
|
||||||
|
|
||||||
def play_turn(self, can_play_vendetta = True):
|
def play_turn(self, can_play_vendetta = True):
|
||||||
if self.lives == 0:
|
if (self.lives == 0 or self.is_dead) and not self.is_ghost:
|
||||||
return self.end_turn(forced=True)
|
return self.end_turn(forced=True)
|
||||||
self.scrapped_cards = 0
|
self.scrapped_cards = 0
|
||||||
self.can_play_ranch = True
|
self.can_play_ranch = True
|
||||||
@ -316,12 +327,23 @@ class Player:
|
|||||||
self.is_waiting_for_action = True
|
self.is_waiting_for_action = True
|
||||||
self.has_played_bang = False
|
self.has_played_bang = False
|
||||||
self.special_use_count = 0
|
self.special_use_count = 0
|
||||||
if self.game.check_event(ce.FratelliDiSangue) and self.lives > 1 and not self.is_giving_life and len([p for p in self.game.players if p != self and p.lives < p.max_lives]):
|
self.bang_used = 0
|
||||||
|
if self.game.check_event(ceh.MezzogiornoDiFuoco):
|
||||||
|
self.lives -= 1
|
||||||
|
if self.character.check(self.game, chars.BartCassidy) and self.lives > 0:
|
||||||
|
self.hand.append(self.game.deck.draw(True))
|
||||||
|
self.sio.emit('chat_message', room=self.game.name, data=f'_special_bart_cassidy|{self.name}')
|
||||||
|
self.heal_if_needed()
|
||||||
|
if self.lives <= 0:
|
||||||
|
return self.notify_self()
|
||||||
|
|
||||||
|
#non è un elif perchè vera custer deve fare questo poi cambiare personaggio
|
||||||
|
if self.game.check_event(ce.FratelliDiSangue) and self.lives > 1 and not self.is_giving_life and len([p for p in self.game.get_alive_players() if p != self and p.lives < p.max_lives]):
|
||||||
self.available_cards = [{
|
self.available_cards = [{
|
||||||
'name': p.name,
|
'name': p.name,
|
||||||
'icon': '⭐️' if isinstance(p.role, r.Sheriff) else '🤠',
|
'icon': '⭐️' if isinstance(p.role, r.Sheriff) else '🤠',
|
||||||
'alt_text': ''.join(['❤️']*p.lives)+''.join(['💀']*(p.max_lives-p.lives))
|
'alt_text': ''.join(['❤️']*p.lives)+''.join(['💀']*(p.max_lives-p.lives))
|
||||||
} for p in self.game.players if p != self and p.lives < p.max_lives]
|
} for p in self.game.get_alive_players() if p != self and p.lives < p.max_lives]
|
||||||
self.available_cards.append({'icon': '❌'})
|
self.available_cards.append({'icon': '❌'})
|
||||||
self.choose_text = 'choose_fratelli_di_sangue'
|
self.choose_text = 'choose_fratelli_di_sangue'
|
||||||
self.pending_action = PendingAction.CHOOSE
|
self.pending_action = PendingAction.CHOOSE
|
||||||
@ -332,7 +354,7 @@ class Player:
|
|||||||
else:
|
else:
|
||||||
self.is_giving_life = False
|
self.is_giving_life = False
|
||||||
if isinstance(self.real_character, chd.VeraCuster):
|
if isinstance(self.real_character, chd.VeraCuster):
|
||||||
self.set_available_character([p.character for p in self.game.players if p != self])
|
self.set_available_character([p.character for p in self.game.get_alive_players() if p != self])
|
||||||
else:
|
else:
|
||||||
self.pending_action = PendingAction.DRAW
|
self.pending_action = PendingAction.DRAW
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
@ -353,7 +375,7 @@ class Player:
|
|||||||
self.available_cards = [{
|
self.available_cards = [{
|
||||||
'name': p.name,
|
'name': p.name,
|
||||||
'icon': '⭐️' if isinstance(p.role, r.Sheriff) else '🤠'
|
'icon': '⭐️' if isinstance(p.role, r.Sheriff) else '🤠'
|
||||||
} for p in self.game.players if len(p.equipment) > 0 and p != self]
|
} for p in self.game.get_alive_players() if len(p.equipment) > 0 and p != self]
|
||||||
self.available_cards.append({'icon': '❌'})
|
self.available_cards.append({'icon': '❌'})
|
||||||
self.choose_text = 'choose_rimbalzo_player'
|
self.choose_text = 'choose_rimbalzo_player'
|
||||||
self.pending_action = PendingAction.CHOOSE
|
self.pending_action = PendingAction.CHOOSE
|
||||||
@ -365,13 +387,13 @@ class Player:
|
|||||||
self.lives += 1
|
self.lives += 1
|
||||||
self.pending_action = PendingAction.PLAY
|
self.pending_action = PendingAction.PLAY
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
elif isinstance(self.character, chars.KitCarlson):
|
elif self.character.check(self.game, chars.KitCarlson):
|
||||||
self.is_drawing = True
|
self.is_drawing = True
|
||||||
self.available_cards = [self.game.deck.draw() for i in range(3)]
|
self.available_cards = [self.game.deck.draw() for i in range(3)]
|
||||||
self.choose_text = 'choose_card_to_get'
|
self.choose_text = 'choose_card_to_get'
|
||||||
self.pending_action = PendingAction.CHOOSE
|
self.pending_action = PendingAction.CHOOSE
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
elif isinstance(self.character, chd.PatBrennan) and type(pile) == str and pile != self.name and pile in self.game.players_map and len(self.game.get_player_named(pile).equipment) > 0:
|
elif self.character.check(self.game, chd.PatBrennan) and type(pile) == str and pile != self.name and pile in self.game.players_map and len(self.game.get_player_named(pile).equipment) > 0:
|
||||||
self.is_drawing = True
|
self.is_drawing = True
|
||||||
self.available_cards = self.game.get_player_named(pile).equipment
|
self.available_cards = self.game.get_player_named(pile).equipment
|
||||||
self.choose_text = 'choose_card_to_get'
|
self.choose_text = 'choose_card_to_get'
|
||||||
@ -379,33 +401,40 @@ class Player:
|
|||||||
self.notify_self()
|
self.notify_self()
|
||||||
else:
|
else:
|
||||||
self.pending_action = PendingAction.PLAY
|
self.pending_action = PendingAction.PLAY
|
||||||
if pile == 'scrap' and isinstance(self.character, chars.PedroRamirez):
|
if pile == 'scrap' and self.character.check(self.game, chars.PedroRamirez):
|
||||||
self.hand.append(self.game.deck.draw_from_scrap_pile())
|
self.hand.append(self.game.deck.draw_from_scrap_pile())
|
||||||
|
if not self.game.check_event(ceh.Sete):
|
||||||
self.hand.append(self.game.deck.draw())
|
self.hand.append(self.game.deck.draw())
|
||||||
self.sio.emit('chat_message', room=self.game.name,
|
self.sio.emit('chat_message', room=self.game.name,
|
||||||
data=f'_draw_from_scrap|{self.name}')
|
data=f'_draw_from_scrap|{self.name}')
|
||||||
elif type(pile) == str and pile != self.name and pile in self.game.players_map and isinstance(self.character, chars.JesseJones) and len(self.game.get_player_named(pile).hand) > 0:
|
elif type(pile) == str and pile != self.name and pile in self.game.players_map and self.character.check(self.game, chars.JesseJones) and len(self.game.get_player_named(pile).hand) > 0:
|
||||||
self.hand.append(self.game.get_player_named(pile).hand.pop(
|
self.hand.append(self.game.get_player_named(pile).hand.pop(
|
||||||
randrange(0, len(self.game.get_player_named(pile).hand))))
|
randrange(0, len(self.game.get_player_named(pile).hand))))
|
||||||
self.game.get_player_named(pile).notify_self()
|
self.game.get_player_named(pile).notify_self()
|
||||||
self.sio.emit('chat_message', room=self.game.name,
|
self.sio.emit('chat_message', room=self.game.name,
|
||||||
data=f'_draw_from_player|{self.name}|{pile}')
|
data=f'_draw_from_player|{self.name}|{pile}')
|
||||||
|
if not self.game.check_event(ceh.Sete):
|
||||||
self.hand.append(self.game.deck.draw())
|
self.hand.append(self.game.deck.draw())
|
||||||
elif isinstance(self.character, chd.BillNoface):
|
elif self.character.check(self.game, chd.BillNoface):
|
||||||
self.hand.append(self.game.deck.draw())
|
self.hand.append(self.game.deck.draw())
|
||||||
|
if not self.game.check_event(ceh.Sete):
|
||||||
for i in range(self.max_lives-self.lives):
|
for i in range(self.max_lives-self.lives):
|
||||||
self.hand.append(self.game.deck.draw())
|
self.hand.append(self.game.deck.draw())
|
||||||
else:
|
else:
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
card: cs.Card = self.game.deck.draw()
|
card: cs.Card = self.game.deck.draw()
|
||||||
self.hand.append(card)
|
self.hand.append(card)
|
||||||
if i == 1 and isinstance(self.character, chars.BlackJack) or self.game.check_event(ce.LeggeDelWest):
|
if i == 1 and self.character.check(self.game, chars.BlackJack) or self.game.check_event(ce.LeggeDelWest):
|
||||||
for p in self.game.players:
|
for p in self.game.get_alive_players():
|
||||||
if p != self:
|
if p != self:
|
||||||
p.notify_card(self, card, 'blackjack_special' if isinstance(self.character, chars.BlackJack) else 'foc.leggedelwest')
|
p.notify_card(self, card, 'blackjack_special' if self.character.check(self.game, chars.BlackJack) else 'foc.leggedelwest')
|
||||||
if card.suit == cs.Suit.HEARTS or card.suit == cs.Suit.DIAMONDS and isinstance(self.character, chars.BlackJack):
|
if card.check_suit(self.game, [cs.Suit.HEARTS, cs.Suit.DIAMONDS]) and self.character.check(self.game, chars.BlackJack):
|
||||||
self.hand.append(self.game.deck.draw())
|
self.hand.append(self.game.deck.draw())
|
||||||
if isinstance(self.character, chd.PixiePete):
|
if self.game.check_event(ceh.Sete):
|
||||||
|
return self.notify_self()
|
||||||
|
if self.character.check(self.game, chd.PixiePete):
|
||||||
|
self.hand.append(self.game.deck.draw())
|
||||||
|
if self.game.check_event(ceh.IlTreno):
|
||||||
self.hand.append(self.game.deck.draw())
|
self.hand.append(self.game.deck.draw())
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
|
|
||||||
@ -422,12 +451,12 @@ class Player:
|
|||||||
print(f'Did pick {picked}')
|
print(f'Did pick {picked}')
|
||||||
self.sio.emit('chat_message', room=self.game.name,
|
self.sio.emit('chat_message', room=self.game.name,
|
||||||
data=f'_flipped|{self.name}|{picked}')
|
data=f'_flipped|{self.name}|{picked}')
|
||||||
if picked.suit == cs.Suit.SPADES and 2 <= picked.number <= 9 and pickable_cards == 0:
|
if picked.check_suit(self.game, [cs.Suit.SPADES]) and 2 <= picked.number <= 9 and pickable_cards == 0:
|
||||||
self.lives -= 3
|
self.lives -= 3
|
||||||
self.game.deck.scrap(self.equipment.pop(i), True)
|
self.game.deck.scrap(self.equipment.pop(i), True)
|
||||||
self.sio.emit('chat_message', room=self.game.name, data=f'_explode|{self.name}')
|
self.sio.emit('chat_message', room=self.game.name, data=f'_explode|{self.name}')
|
||||||
self.heal_if_needed()
|
self.heal_if_needed()
|
||||||
if isinstance(self.character, chars.BartCassidy) and self.lives > 0:
|
if self.character.check(self.game, chars.BartCassidy) and self.lives > 0:
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
self.hand.append(self.game.deck.draw(True))
|
self.hand.append(self.game.deck.draw(True))
|
||||||
self.sio.emit('chat_message', room=self.game.name, data=f'_special_bart_cassidy|{self.name}')
|
self.sio.emit('chat_message', room=self.game.name, data=f'_special_bart_cassidy|{self.name}')
|
||||||
@ -448,7 +477,7 @@ class Player:
|
|||||||
print(f'Did pick {picked}')
|
print(f'Did pick {picked}')
|
||||||
self.sio.emit('chat_message', room=self.game.name,
|
self.sio.emit('chat_message', room=self.game.name,
|
||||||
data=f'_flipped|{self.name}|{picked}')
|
data=f'_flipped|{self.name}|{picked}')
|
||||||
if picked.suit != cs.Suit.HEARTS and pickable_cards == 0:
|
if not picked.check_suit(self.game, [cs.Suit.HEARTS]) and pickable_cards == 0:
|
||||||
self.game.deck.scrap(self.equipment.pop(i), True)
|
self.game.deck.scrap(self.equipment.pop(i), True)
|
||||||
self.end_turn(forced=True)
|
self.end_turn(forced=True)
|
||||||
return
|
return
|
||||||
@ -460,7 +489,7 @@ class Player:
|
|||||||
self.notify_self()
|
self.notify_self()
|
||||||
return
|
return
|
||||||
if isinstance(self.real_character, chd.VeraCuster):
|
if isinstance(self.real_character, chd.VeraCuster):
|
||||||
self.set_available_character([p.character for p in self.game.players if p != self])
|
self.set_available_character([p.character for p in self.game.get_alive_players() if p != self])
|
||||||
else:
|
else:
|
||||||
self.pending_action = PendingAction.DRAW
|
self.pending_action = PendingAction.DRAW
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
@ -497,7 +526,7 @@ class Player:
|
|||||||
print(self.name, 'is playing ', card, ' against:', against, ' with:', _with)
|
print(self.name, 'is playing ', card, ' against:', against, ' with:', _with)
|
||||||
did_play_card = False
|
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)
|
||||||
if not(against != None and isinstance(self.game.get_player_named(against).character, chd.ApacheKid) and card.suit == cs.Suit.DIAMONDS) and not event_blocks_card:
|
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):
|
if against == self.name and not isinstance(card, csd.Tequila):
|
||||||
did_play_card = False
|
did_play_card = False
|
||||||
else:
|
else:
|
||||||
@ -541,7 +570,7 @@ class Player:
|
|||||||
self.hand.append(card)
|
self.hand.append(card)
|
||||||
else:
|
else:
|
||||||
self.game.deck.scrap(card, True)
|
self.game.deck.scrap(card, True)
|
||||||
if self.event_type != 'rissa' or (self.event_type == 'rissa' and (len([p.name for p in self.game.players if p != self and (len(p.hand)+len(p.equipment)) > 0]) == 0 or self.target_p == [p.name for p in self.game.players if p != self and (len(p.hand)+len(p.equipment)) > 0][-1])):
|
if self.event_type != 'rissa' or (self.event_type == 'rissa' and (len([p.name for p in self.game.get_alive_players() if p != self and (len(p.hand)+len(p.equipment)) > 0]) == 0 or self.target_p == [p.name for p in self.game.get_alive_players() if p != self and (len(p.hand)+len(p.equipment)) > 0][-1])):
|
||||||
self.event_type = ''
|
self.event_type = ''
|
||||||
self.target_p = ''
|
self.target_p = ''
|
||||||
self.choose_action = ''
|
self.choose_action = ''
|
||||||
@ -604,6 +633,13 @@ class Player:
|
|||||||
else:
|
else:
|
||||||
self.discarded_cards.append(self.available_cards.pop(card_index))
|
self.discarded_cards.append(self.available_cards.pop(card_index))
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
|
elif self.game.dalton_on and self.game.check_event(ceh.IDalton):
|
||||||
|
card = next(c for c in self.equipment if c == self.available_cards[card_index])
|
||||||
|
self.equipment.remove(card)
|
||||||
|
self.game.deck.scrap(card, True)
|
||||||
|
self.pending_action = PendingAction.WAIT
|
||||||
|
self.notify_self()
|
||||||
|
self.game.responders_did_respond_resume_turn()
|
||||||
elif self.is_drawing and self.game.check_event(ce.Peyote):
|
elif self.is_drawing and self.game.check_event(ce.Peyote):
|
||||||
self.is_drawing = False
|
self.is_drawing = False
|
||||||
card = self.game.deck.draw()
|
card = self.game.deck.draw()
|
||||||
@ -619,14 +655,17 @@ class Player:
|
|||||||
self.pending_action = PendingAction.PLAY
|
self.pending_action = PendingAction.PLAY
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
# specifico per personaggio
|
# specifico per personaggio
|
||||||
elif self.is_drawing and isinstance(self.character, chars.KitCarlson):
|
elif self.is_drawing and self.character.check(self.game, chars.KitCarlson):
|
||||||
self.hand.append(self.available_cards.pop(card_index))
|
self.hand.append(self.available_cards.pop(card_index))
|
||||||
if len(self.available_cards) == 1:
|
pickable_stop = 1
|
||||||
|
if self.game.check_event(ceh.Sete): pickable_stop = 2
|
||||||
|
if self.game.check_event(ceh.IlTreno): pickable_stop = 0
|
||||||
|
if len(self.available_cards) == pickable_stop:
|
||||||
self.game.deck.put_on_top(self.available_cards.pop())
|
self.game.deck.put_on_top(self.available_cards.pop())
|
||||||
self.is_drawing = False
|
self.is_drawing = False
|
||||||
self.pending_action = PendingAction.PLAY
|
self.pending_action = PendingAction.PLAY
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
elif self.is_drawing and isinstance(self.character, chd.PatBrennan):
|
elif self.is_drawing and self.character.check(self.game, chd.PatBrennan):
|
||||||
card = self.available_cards.pop(card_index)
|
card = self.available_cards.pop(card_index)
|
||||||
if card.usable_next_turn:
|
if card.usable_next_turn:
|
||||||
card.can_be_used_now = False
|
card.can_be_used_now = False
|
||||||
@ -639,7 +678,7 @@ class Player:
|
|||||||
|
|
||||||
def barrel_pick(self):
|
def barrel_pick(self):
|
||||||
pickable_cards = 1 + self.character.pick_mod
|
pickable_cards = 1 + self.character.pick_mod
|
||||||
if len([c for c in self.equipment if isinstance(c, cs.Barile)]) > 0 and isinstance(self.character, chars.Jourdonnais):
|
if len([c for c in self.equipment if isinstance(c, cs.Barile)]) > 0 and self.character.check(self.game, chars.Jourdonnais):
|
||||||
pickable_cards = 2
|
pickable_cards = 2
|
||||||
while pickable_cards > 0:
|
while pickable_cards > 0:
|
||||||
pickable_cards -= 1
|
pickable_cards -= 1
|
||||||
@ -647,29 +686,29 @@ class Player:
|
|||||||
print(f'Did pick {picked}')
|
print(f'Did pick {picked}')
|
||||||
self.sio.emit('chat_message', room=self.game.name,
|
self.sio.emit('chat_message', room=self.game.name,
|
||||||
data=f'_flipped|{self.name}|{picked}')
|
data=f'_flipped|{self.name}|{picked}')
|
||||||
if picked.suit == cs.Suit.HEARTS:
|
if picked.check_suit(self.game, [cs.Suit.HEARTS]):
|
||||||
self.mancato_needed -= 1
|
self.mancato_needed -= 1
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
if self.mancato_needed <= 0:
|
if self.mancato_needed <= 0:
|
||||||
self.game.responders_did_respond_resume_turn(did_lose=False)
|
self.game.responders_did_respond_resume_turn(did_lose=False)
|
||||||
return
|
return
|
||||||
if not self.game.is_competitive and len([c for c in self.hand if isinstance(c, cs.Mancato) or (isinstance(self.character, chars.CalamityJanet) and isinstance(c, cs.Bang)) or isinstance(self.character, chd.ElenaFuente)]) == 0\
|
if not self.game.is_competitive and len([c for c in self.hand if isinstance(c, cs.Mancato) or (self.character.check(self.game, chars.CalamityJanet) and isinstance(c, cs.Bang)) or self.character.check(self.game, chd.ElenaFuente)]) == 0\
|
||||||
and len([c for c in self.equipment if c.can_be_used_now and isinstance(c, cs.Mancato)]) == 0:
|
and len([c for c in self.equipment if c.can_be_used_now and isinstance(c, cs.Mancato)]) == 0:
|
||||||
self.take_damage_response()
|
self.take_damage_response()
|
||||||
self.game.responders_did_respond_resume_turn(did_lose=True)
|
self.game.responders_did_respond_resume_turn(did_lose=True)
|
||||||
else:
|
else:
|
||||||
self.pending_action = PendingAction.RESPOND
|
self.pending_action = PendingAction.RESPOND
|
||||||
self.expected_response = self.game.deck.mancato_cards.copy()
|
self.expected_response = self.game.deck.mancato_cards.copy()
|
||||||
if isinstance(self.character, chars.CalamityJanet) and cs.Bang(0, 0).name not in self.expected_response:
|
if self.character.check(self.game, chars.CalamityJanet) and cs.Bang(0, 0).name not in self.expected_response:
|
||||||
self.expected_response.append(cs.Bang(0, 0).name)
|
self.expected_response.append(cs.Bang(0, 0).name)
|
||||||
elif isinstance(self.character, chd.ElenaFuente):
|
elif self.character.check(self.game, chd.ElenaFuente):
|
||||||
self.expected_response = self.game.deck.all_cards_str
|
self.expected_response = self.game.deck.all_cards_str.copy()
|
||||||
self.on_failed_response_cb = self.take_damage_response
|
self.on_failed_response_cb = self.take_damage_response
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
|
|
||||||
def barrel_pick_no_dmg(self):
|
def barrel_pick_no_dmg(self):
|
||||||
pickable_cards = 1 + self.character.pick_mod
|
pickable_cards = 1 + self.character.pick_mod
|
||||||
if len([c for c in self.equipment if isinstance(c, cs.Barile)]) > 0 and isinstance(self.character, chars.Jourdonnais):
|
if len([c for c in self.equipment if isinstance(c, cs.Barile)]) > 0 and self.character.check(self.game, chars.Jourdonnais):
|
||||||
pickable_cards = 2
|
pickable_cards = 2
|
||||||
while pickable_cards > 0:
|
while pickable_cards > 0:
|
||||||
pickable_cards -= 1
|
pickable_cards -= 1
|
||||||
@ -677,23 +716,23 @@ class Player:
|
|||||||
print(f'Did pick {picked}')
|
print(f'Did pick {picked}')
|
||||||
self.sio.emit('chat_message', room=self.game.name,
|
self.sio.emit('chat_message', room=self.game.name,
|
||||||
data=f'_flipped|{self.name}|{picked}')
|
data=f'_flipped|{self.name}|{picked}')
|
||||||
if picked.suit == cs.Suit.HEARTS:
|
if picked.check_suit(self.game, [cs.Suit.HEARTS]):
|
||||||
self.mancato_needed -= 1
|
self.mancato_needed -= 1
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
if self.mancato_needed <= 0:
|
if self.mancato_needed <= 0:
|
||||||
self.game.responders_did_respond_resume_turn(did_lose=False)
|
self.game.responders_did_respond_resume_turn(did_lose=False)
|
||||||
return
|
return
|
||||||
if not self.game.is_competitive and len([c for c in self.hand if isinstance(c, cs.Mancato) or (isinstance(self.character, chars.CalamityJanet) and isinstance(c, cs.Bang)) or isinstance(self.character, chd.ElenaFuente)]) == 0\
|
if not self.game.is_competitive and len([c for c in self.hand if isinstance(c, cs.Mancato) or (self.character.check(self.game, chars.CalamityJanet) and isinstance(c, cs.Bang)) or self.character.check(self.game, chd.ElenaFuente)]) == 0\
|
||||||
and len([c for c in self.equipment if c.can_be_used_now and isinstance(c, cs.Mancato)]) == 0:
|
and len([c for c in self.equipment if c.can_be_used_now and isinstance(c, cs.Mancato)]) == 0:
|
||||||
self.take_no_damage_response()
|
self.take_no_damage_response()
|
||||||
self.game.responders_did_respond_resume_turn(did_lose=True)
|
self.game.responders_did_respond_resume_turn(did_lose=True)
|
||||||
else:
|
else:
|
||||||
self.pending_action = PendingAction.RESPOND
|
self.pending_action = PendingAction.RESPOND
|
||||||
self.expected_response = self.game.deck.mancato_cards.copy()
|
self.expected_response = self.game.deck.mancato_cards.copy()
|
||||||
if isinstance(self.character, chars.CalamityJanet) and cs.Bang(0, 0).name not in self.expected_response:
|
if self.character.check(self.game, chars.CalamityJanet) and cs.Bang(0, 0).name not in self.expected_response:
|
||||||
self.expected_response.append(cs.Bang(0, 0).name)
|
self.expected_response.append(cs.Bang(0, 0).name)
|
||||||
elif isinstance(self.character, chd.ElenaFuente):
|
elif self.character.check(self.game, chd.ElenaFuente):
|
||||||
self.expected_response = self.game.deck.all_cards_str
|
self.expected_response = self.game.deck.all_cards_str.copy()
|
||||||
self.on_failed_response_cb = self.take_no_damage_response
|
self.on_failed_response_cb = self.take_no_damage_response
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
|
|
||||||
@ -707,8 +746,8 @@ class Player:
|
|||||||
for i in range(len(self.equipment)):
|
for i in range(len(self.equipment)):
|
||||||
if self.equipment[i].can_be_used_now:
|
if self.equipment[i].can_be_used_now:
|
||||||
print('usable', self.equipment[i])
|
print('usable', self.equipment[i])
|
||||||
if not self.game.is_competitive and len([c for c in self.equipment if isinstance(c, cs.Barile)]) == 0 and not isinstance(self.character, chars.Jourdonnais)\
|
if not self.game.is_competitive and len([c for c in self.equipment if isinstance(c, cs.Barile)]) == 0 and not self.character.check(self.game, chars.Jourdonnais)\
|
||||||
and len([c for c in self.hand if isinstance(c, cs.Mancato) or (isinstance(self.character, chars.CalamityJanet) and isinstance(c, cs.Bang)) or isinstance(self.character, chd.ElenaFuente)]) == 0\
|
and len([c for c in self.hand if isinstance(c, cs.Mancato) or (self.character.check(self.game, chars.CalamityJanet) and isinstance(c, cs.Bang)) or self.character.check(self.game, chd.ElenaFuente)]) == 0\
|
||||||
and len([c for c in self.equipment if c.can_be_used_now and isinstance(c, cs.Mancato)]) == 0:
|
and len([c for c in self.equipment if c.can_be_used_now and isinstance(c, cs.Mancato)]) == 0:
|
||||||
print('Cant defend')
|
print('Cant defend')
|
||||||
if not no_dmg:
|
if not no_dmg:
|
||||||
@ -717,7 +756,7 @@ class Player:
|
|||||||
self.take_no_damage_response()
|
self.take_no_damage_response()
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
if (not self.game.check_event(ce.Lazo) and len([c for c in self.equipment if isinstance(c, cs.Barile)]) > 0) or isinstance(self.character, chars.Jourdonnais):
|
if (not self.game.check_event(ce.Lazo) and len([c for c in self.equipment if isinstance(c, cs.Barile)]) > 0) or self.character.check(self.game, chars.Jourdonnais):
|
||||||
print('has barrel')
|
print('has barrel')
|
||||||
self.pending_action = PendingAction.PICK
|
self.pending_action = PendingAction.PICK
|
||||||
if not no_dmg:
|
if not no_dmg:
|
||||||
@ -728,22 +767,32 @@ class Player:
|
|||||||
print('has mancato')
|
print('has mancato')
|
||||||
self.pending_action = PendingAction.RESPOND
|
self.pending_action = PendingAction.RESPOND
|
||||||
self.expected_response = self.game.deck.mancato_cards.copy()
|
self.expected_response = self.game.deck.mancato_cards.copy()
|
||||||
if self.attacker and self.attacker in self.game.players and isinstance(self.attacker.character, chd.BelleStar) or self.game.check_event(ce.Lazo):
|
if self.attacker and self.attacker in self.game.get_alive_players() and isinstance(self.attacker.character, chd.BelleStar) or self.game.check_event(ce.Lazo):
|
||||||
self.expected_response = self.game.deck.mancato_cards_not_green
|
self.expected_response = self.game.deck.mancato_cards_not_green.copy()
|
||||||
elif isinstance(self.character, chars.CalamityJanet) and cs.Bang(0, 0).name not in self.expected_response:
|
elif self.character.check(self.game, chars.CalamityJanet) and cs.Bang(0, 0).name not in self.expected_response:
|
||||||
self.expected_response.append(cs.Bang(0, 0).name)
|
self.expected_response.append(cs.Bang(0, 0).name)
|
||||||
elif isinstance(self.character, chd.ElenaFuente):
|
elif self.character.check(self.game, chd.ElenaFuente):
|
||||||
self.expected_response = self.game.deck.all_cards_str
|
self.expected_response = self.game.deck.all_cards_str.copy()
|
||||||
if not no_dmg:
|
if not no_dmg:
|
||||||
self.on_failed_response_cb = self.take_damage_response
|
self.on_failed_response_cb = self.take_damage_response
|
||||||
else:
|
else:
|
||||||
self.on_failed_response_cb = self.take_no_damage_response
|
self.on_failed_response_cb = self.take_no_damage_response
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def get_dalton(self):
|
||||||
|
equipments = [c for c in self.equipment if not c.usable_next_turn]
|
||||||
|
if len(equipments) == 0:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
self.sio.emit('chat_message', room=self.game.name, data=f"_dalton|{self.name}")
|
||||||
|
self.pending_action = PendingAction.CHOOSE
|
||||||
|
self.available_cards = equipments
|
||||||
|
return True
|
||||||
|
|
||||||
def get_indians(self, attacker):
|
def get_indians(self, attacker):
|
||||||
self.attacker = attacker
|
self.attacker = attacker
|
||||||
if isinstance(self.character, chd.ApacheKid): return False
|
if self.character.check(self.game, chd.ApacheKid): return False
|
||||||
if not self.game.is_competitive and len([c for c in self.hand if isinstance(c, cs.Bang) or (isinstance(self.character, chars.CalamityJanet) and isinstance(c, cs.Mancato))]) == 0:
|
if not self.game.is_competitive and len([c for c in self.hand if isinstance(c, cs.Bang) or (self.character.check(self.game, chars.CalamityJanet) and isinstance(c, cs.Mancato))]) == 0:
|
||||||
print('Cant defend')
|
print('Cant defend')
|
||||||
self.take_damage_response()
|
self.take_damage_response()
|
||||||
return False
|
return False
|
||||||
@ -751,7 +800,7 @@ class Player:
|
|||||||
print('has bang')
|
print('has bang')
|
||||||
self.pending_action = PendingAction.RESPOND
|
self.pending_action = PendingAction.RESPOND
|
||||||
self.expected_response = [cs.Bang(0, 0).name]
|
self.expected_response = [cs.Bang(0, 0).name]
|
||||||
if isinstance(self.character, chars.CalamityJanet) and cs.Mancato(0, 0).name not in self.expected_response:
|
if self.character.check(self.game, chars.CalamityJanet) and cs.Mancato(0, 0).name not in self.expected_response:
|
||||||
self.expected_response.append(cs.Mancato(0, 0).name)
|
self.expected_response.append(cs.Mancato(0, 0).name)
|
||||||
self.event_type = 'indians'
|
self.event_type = 'indians'
|
||||||
self.on_failed_response_cb = self.take_damage_response
|
self.on_failed_response_cb = self.take_damage_response
|
||||||
@ -759,7 +808,7 @@ class Player:
|
|||||||
|
|
||||||
def get_dueled(self, attacker):
|
def get_dueled(self, attacker):
|
||||||
self.attacker = attacker
|
self.attacker = attacker
|
||||||
if not self.game.is_competitive and len([c for c in self.hand if isinstance(c, cs.Bang) or (isinstance(self.character, chars.CalamityJanet) and isinstance(c, cs.Mancato))]) == 0:
|
if (self.game.check_event(ceh.Sermone) and self.is_my_turn) or (not self.game.is_competitive and len([c for c in self.hand if isinstance(c, cs.Bang) or (self.character.check(self.game, chars.CalamityJanet) and isinstance(c, cs.Mancato))]) == 0):
|
||||||
print('Cant defend')
|
print('Cant defend')
|
||||||
self.take_damage_response()
|
self.take_damage_response()
|
||||||
self.game.responders_did_respond_resume_turn(did_lose=True)
|
self.game.responders_did_respond_resume_turn(did_lose=True)
|
||||||
@ -767,19 +816,19 @@ class Player:
|
|||||||
else:
|
else:
|
||||||
self.pending_action = PendingAction.RESPOND
|
self.pending_action = PendingAction.RESPOND
|
||||||
self.expected_response = [cs.Bang(0, 0).name]
|
self.expected_response = [cs.Bang(0, 0).name]
|
||||||
if isinstance(self.character, chars.CalamityJanet) and cs.Mancato(0, 0).name not in self.expected_response:
|
if self.character.check(self.game, chars.CalamityJanet) and cs.Mancato(0, 0).name not in self.expected_response:
|
||||||
self.expected_response.append(cs.Mancato(0, 0).name)
|
self.expected_response.append(cs.Mancato(0, 0).name)
|
||||||
self.event_type = 'duel'
|
self.event_type = 'duel'
|
||||||
self.on_failed_response_cb = self.take_damage_response
|
self.on_failed_response_cb = self.take_damage_response
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def heal_if_needed(self):
|
def heal_if_needed(self):
|
||||||
while self.lives <= 0 and len(self.game.players) > 2 and len([c for c in self.hand if isinstance(c, cs.Birra)]) > 0:
|
while self.lives <= 0 and len(self.game.get_alive_players()) > 2 and len([c for c in self.hand if isinstance(c, cs.Birra)]) > 0:
|
||||||
for i in range(len(self.hand)):
|
for i in range(len(self.hand)):
|
||||||
if isinstance(self.hand[i], cs.Birra):
|
if isinstance(self.hand[i], cs.Birra):
|
||||||
if isinstance(self.character, chd.MollyStark) and not self.is_my_turn:
|
if self.character.check(self.game, chd.MollyStark) and not self.is_my_turn:
|
||||||
self.hand.append(self.game.deck.draw(True))
|
self.hand.append(self.game.deck.draw(True))
|
||||||
self.lives += 1 if not isinstance(self.character, chd.TequilaJoe) else 2
|
self.lives += 1 if not self.character.check(self.game, chd.TequilaJoe) else 2
|
||||||
self.game.deck.scrap(self.hand.pop(i), True)
|
self.game.deck.scrap(self.hand.pop(i), True)
|
||||||
self.sio.emit('chat_message', room=self.game.name,
|
self.sio.emit('chat_message', room=self.game.name,
|
||||||
data=f'_beer_save|{self.name}')
|
data=f'_beer_save|{self.name}')
|
||||||
@ -788,11 +837,11 @@ class Player:
|
|||||||
def take_damage_response(self):
|
def take_damage_response(self):
|
||||||
self.lives -= 1
|
self.lives -= 1
|
||||||
if self.lives > 0:
|
if self.lives > 0:
|
||||||
if isinstance(self.character, chars.BartCassidy):
|
if self.character.check(self.game, chars.BartCassidy):
|
||||||
self.sio.emit('chat_message', room=self.game.name,
|
self.sio.emit('chat_message', room=self.game.name,
|
||||||
data=f'_special_bart_cassidy|{self.name}')
|
data=f'_special_bart_cassidy|{self.name}')
|
||||||
self.hand.append(self.game.deck.draw(True))
|
self.hand.append(self.game.deck.draw(True))
|
||||||
elif isinstance(self.character, chars.ElGringo) and self.attacker and self.attacker in self.game.players and len(self.attacker.hand) > 0:
|
elif self.character.check(self.game, chars.ElGringo) and self.attacker and self.attacker in self.game.get_alive_players() and len(self.attacker.hand) > 0:
|
||||||
self.hand.append(self.attacker.hand.pop(
|
self.hand.append(self.attacker.hand.pop(
|
||||||
randrange(0, len(self.attacker.hand))))
|
randrange(0, len(self.attacker.hand))))
|
||||||
self.sio.emit('chat_message', room=self.game.name,
|
self.sio.emit('chat_message', room=self.game.name,
|
||||||
@ -822,7 +871,7 @@ class Player:
|
|||||||
((hand_index < len(self.hand) and self.hand[hand_index].name in self.expected_response)) or
|
((hand_index < len(self.hand) and self.hand[hand_index].name in self.expected_response)) or
|
||||||
(hand_index-len(self.hand) < len(self.equipment) and self.equipment[hand_index-len(self.hand)].name in self.expected_response)):
|
(hand_index-len(self.hand) < len(self.equipment) and self.equipment[hand_index-len(self.hand)].name in self.expected_response)):
|
||||||
card = self.hand.pop(hand_index) if hand_index < len(self.hand) else self.equipment.pop(hand_index-len(self.hand))
|
card = self.hand.pop(hand_index) if hand_index < len(self.hand) else self.equipment.pop(hand_index-len(self.hand))
|
||||||
if isinstance(self.character, chd.MollyStark) and hand_index < len(self.hand)+1 and not self.is_my_turn and self.event_type != 'duel':
|
if self.character.check(self.game, chd.MollyStark) and hand_index < len(self.hand)+1 and not self.is_my_turn and self.event_type != 'duel':
|
||||||
self.hand.append(self.game.deck.draw(True))
|
self.hand.append(self.game.deck.draw(True))
|
||||||
card.use_card(self)
|
card.use_card(self)
|
||||||
self.game.deck.scrap(card, True)
|
self.game.deck.scrap(card, True)
|
||||||
@ -831,7 +880,7 @@ class Player:
|
|||||||
if self.mancato_needed <= 0:
|
if self.mancato_needed <= 0:
|
||||||
if self.event_type == 'duel':
|
if self.event_type == 'duel':
|
||||||
self.game.duel(self, self.attacker.name)
|
self.game.duel(self, self.attacker.name)
|
||||||
if isinstance(self.character, chd.MollyStark) and hand_index < len(self.hand)+1 and not self.is_my_turn:
|
if self.character.check(self.game, chd.MollyStark) and hand_index < len(self.hand)+1 and not self.is_my_turn:
|
||||||
self.molly_discarded_cards += 1
|
self.molly_discarded_cards += 1
|
||||||
else:
|
else:
|
||||||
self.game.responders_did_respond_resume_turn(did_lose=False)
|
self.game.responders_did_respond_resume_turn(did_lose=False)
|
||||||
@ -841,12 +890,12 @@ class Player:
|
|||||||
self.pending_action = PendingAction.RESPOND
|
self.pending_action = PendingAction.RESPOND
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
else:
|
else:
|
||||||
if isinstance(self.character, chd.MollyStark) and not self.is_my_turn:
|
if self.character.check(self.game, chd.MollyStark) and not self.is_my_turn:
|
||||||
for i in range(self.molly_discarded_cards):
|
for i in range(self.molly_discarded_cards):
|
||||||
self.hand.append(self.game.deck.draw(True))
|
self.hand.append(self.game.deck.draw(True))
|
||||||
self.molly_discarded_cards = 0
|
self.molly_discarded_cards = 0
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
elif self.attacker and self.attacker in self.game.players and isinstance(self.attacker.character, chd.MollyStark) and self.is_my_turn:
|
elif self.attacker and self.attacker in self.game.get_alive_players() and isinstance(self.attacker.character, chd.MollyStark) and self.is_my_turn:
|
||||||
for i in range(self.attacker.molly_discarded_cards):
|
for i in range(self.attacker.molly_discarded_cards):
|
||||||
self.attacker.hand.append(self.attacker.game.deck.draw(True))
|
self.attacker.hand.append(self.attacker.game.deck.draw(True))
|
||||||
self.attacker.molly_discarded_cards = 0
|
self.attacker.molly_discarded_cards = 0
|
||||||
@ -881,13 +930,13 @@ class Player:
|
|||||||
return self.character.visibility_mod + covers
|
return self.character.visibility_mod + covers
|
||||||
|
|
||||||
def scrap(self, card_index):
|
def scrap(self, card_index):
|
||||||
if self.is_my_turn or isinstance(self.character, chars.SidKetchum):
|
if self.is_my_turn or self.character.check(self.game, chars.SidKetchum):
|
||||||
self.scrapped_cards += 1
|
self.scrapped_cards += 1
|
||||||
card = self.hand.pop(card_index)
|
card = self.hand.pop(card_index)
|
||||||
if isinstance(self.character, chars.SidKetchum) and self.scrapped_cards == 2:
|
if self.character.check(self.game, chars.SidKetchum) and self.scrapped_cards == 2:
|
||||||
self.scrapped_cards = 0
|
self.scrapped_cards = 0
|
||||||
self.lives = min(self.lives+1, self.max_lives)
|
self.lives = min(self.lives+1, self.max_lives)
|
||||||
elif isinstance(self.character, chd.JoseDelgrado) and card.is_equipment and self.special_use_count < 2:
|
elif self.character.check(self.game, chd.JoseDelgrado) and card.is_equipment and self.special_use_count < 2:
|
||||||
self.hand.append(self.game.deck.draw(True))
|
self.hand.append(self.game.deck.draw(True))
|
||||||
self.hand.append(self.game.deck.draw(True))
|
self.hand.append(self.game.deck.draw(True))
|
||||||
self.special_use_count += 1
|
self.special_use_count += 1
|
||||||
@ -895,7 +944,7 @@ class Player:
|
|||||||
self.notify_self()
|
self.notify_self()
|
||||||
|
|
||||||
def holyday_special(self, data):
|
def holyday_special(self, data):
|
||||||
if isinstance(self.character, chd.DocHolyday) and self.special_use_count < 1:
|
if self.character.check(self.game, chd.DocHolyday) and self.special_use_count < 1:
|
||||||
self.special_use_count += 1
|
self.special_use_count += 1
|
||||||
cards = sorted(data['cards'], reverse=True)
|
cards = sorted(data['cards'], reverse=True)
|
||||||
for c in cards:
|
for c in cards:
|
||||||
@ -904,16 +953,17 @@ class Player:
|
|||||||
self.game.attack(self, data['against'])
|
self.game.attack(self, data['against'])
|
||||||
|
|
||||||
def chuck_lose_hp_draw(self):
|
def chuck_lose_hp_draw(self):
|
||||||
if isinstance(self.character, chd.ChuckWengam) and self.lives > 1 and self.is_my_turn:
|
if self.character.check(self.game, chd.ChuckWengam) and self.lives > 1 and self.is_my_turn:
|
||||||
self.lives -= 1
|
self.lives -= 1
|
||||||
self.hand.append(self.game.deck.draw(True))
|
self.hand.append(self.game.deck.draw(True))
|
||||||
self.hand.append(self.game.deck.draw(True))
|
self.hand.append(self.game.deck.draw(True))
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
|
|
||||||
def end_turn(self, forced=False):
|
def end_turn(self, forced=False):
|
||||||
|
print(f"{self.name} wants to end his turn")
|
||||||
if not self.is_my_turn:
|
if not self.is_my_turn:
|
||||||
return
|
return
|
||||||
maxcards = self.lives if not isinstance(self.character, chd.SeanMallory) else 10
|
maxcards = self.lives if not self.character.check(self.game, chd.SeanMallory) else 10
|
||||||
if len(self.hand) > maxcards and not forced:
|
if len(self.hand) > maxcards and not forced:
|
||||||
print(
|
print(
|
||||||
f"I {self.name} have to many cards in my hand and I can't end the turn")
|
f"I {self.name} have to many cards in my hand and I can't end the turn")
|
||||||
@ -921,13 +971,19 @@ class Player:
|
|||||||
if not forced and self.game.check_event(ce.Vendetta) and self.can_play_vendetta:
|
if not forced and self.game.check_event(ce.Vendetta) and self.can_play_vendetta:
|
||||||
picked: cs.Card = self.game.deck.pick_and_scrap()
|
picked: cs.Card = self.game.deck.pick_and_scrap()
|
||||||
self.sio.emit('chat_message', room=self.game.name, data=f'_flipped|{self.name}|{picked}')
|
self.sio.emit('chat_message', room=self.game.name, data=f'_flipped|{self.name}|{picked}')
|
||||||
if picked.suit == cs.Suit.HEARTS:
|
if picked.check_suit(self.game, [cs.Suit.HEARTS]):
|
||||||
self.play_turn(can_play_vendetta=False)
|
self.play_turn(can_play_vendetta=False)
|
||||||
return
|
return
|
||||||
self.is_my_turn = False
|
self.is_my_turn = False
|
||||||
for i in range(len(self.equipment)):
|
for i in range(len(self.equipment)):
|
||||||
if self.equipment[i].usable_next_turn and not self.equipment[i].can_be_used_now:
|
if self.equipment[i].usable_next_turn and not self.equipment[i].can_be_used_now:
|
||||||
self.equipment[i].can_be_used_now = True
|
self.equipment[i].can_be_used_now = True
|
||||||
|
if self.is_dead and self.is_ghost and self.game.check_event(ceh.CittaFantasma):
|
||||||
|
self.is_ghost = False
|
||||||
|
for i in range(len(self.hand)):
|
||||||
|
self.game.deck.scrap(self.hand.pop(), True)
|
||||||
|
for i in range(len(self.equipment)):
|
||||||
|
self.game.deck.scrap(self.equipment.pop(), True)
|
||||||
self.pending_action = PendingAction.WAIT
|
self.pending_action = PendingAction.WAIT
|
||||||
self.notify_self()
|
self.notify_self()
|
||||||
self.game.next_turn()
|
self.game.next_turn()
|
||||||
|
@ -52,7 +52,7 @@ export default {
|
|||||||
sockets: {
|
sockets: {
|
||||||
self(self){
|
self(self){
|
||||||
self = JSON.parse(self)
|
self = JSON.parse(self)
|
||||||
this.isPlaying = self.lives > 0
|
this.isPlaying = self.lives > 0 || self.is_ghost
|
||||||
this.pending_action = self.pending_action
|
this.pending_action = self.pending_action
|
||||||
},
|
},
|
||||||
scrap(card) {
|
scrap(card) {
|
||||||
|
@ -16,10 +16,13 @@
|
|||||||
<Card v-if="startGameCard" :card="startGameCard" @click.native="startGame"/>
|
<Card v-if="startGameCard" :card="startGameCard" @click.native="startGame"/>
|
||||||
<!-- <div style="position: relative;width:260pt;height:400pt;"> -->
|
<!-- <div style="position: relative;width:260pt;height:400pt;"> -->
|
||||||
<div v-for="p in playersTable" v-bind:key="p.card.name" style="position:relative;">
|
<div v-for="p in playersTable" v-bind:key="p.card.name" style="position:relative;">
|
||||||
<transition-group v-if="p.max_lives" name="list" tag="div" class="tiny-health">
|
<transition-group v-if="p.max_lives && !p.is_ghost" name="list" tag="div" class="tiny-health">
|
||||||
<span v-for="(n, i) in p.lives" v-bind:key="n" :alt="i">❤️</span>
|
<span v-for="(n, i) in p.lives" v-bind:key="n" :alt="i">❤️</span>
|
||||||
<span v-for="(n, i) in (p.max_lives-p.lives)" v-bind:key="n" :alt="i">💀</span>
|
<span v-for="(n, i) in (p.max_lives-p.lives)" v-bind:key="n" :alt="i">💀</span>
|
||||||
</transition-group>
|
</transition-group>
|
||||||
|
<div v-else-if="p.is_ghost" class="tiny-health">
|
||||||
|
<span :alt="i">👻</span>
|
||||||
|
</div>
|
||||||
<Card :card="p.card" :class="{is_my_turn:p.is_my_turn}"/>
|
<Card :card="p.card" :class="{is_my_turn:p.is_my_turn}"/>
|
||||||
<Card v-if="p.character" :card="p.character" class="character tiny-character" @click.native="selectedInfo = [p.character]"/>
|
<Card v-if="p.character" :card="p.character" class="character tiny-character" @click.native="selectedInfo = [p.character]"/>
|
||||||
<Card v-if="p.character && p.character.name !== p.real_character.name" style="transform:scale(0.5) translate(-90px, -50px);" :card="p.character" class="character tiny-character" @click.native="selectedInfo = [p.character]"/>
|
<Card v-if="p.character && p.character.name !== p.real_character.name" style="transform:scale(0.5) translate(-90px, -50px);" :card="p.character" class="character tiny-character" @click.native="selectedInfo = [p.character]"/>
|
||||||
@ -40,8 +43,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<h3>{{$t('mods')}}</h3>
|
<h3>{{$t('mods')}}</h3>
|
||||||
<PrettyCheck @click.native="toggleCompetitive" :disabled="!isRoomOwner" v-model="is_competitive" class="p-switch p-fill" style="margin-top:5px; margin-bottom:3px;">{{$t('mod_comp')}}</PrettyCheck>
|
<PrettyCheck @click.native="toggleCompetitive" :disabled="!isRoomOwner" v-model="is_competitive" class="p-switch p-fill" style="margin-top:5px; margin-bottom:3px;">{{$t('mod_comp')}}</PrettyCheck>
|
||||||
<br>
|
<!-- <br> -->
|
||||||
<PrettyCheck @click.native="toggleReplaceWithBot" :disabled="!isRoomOwner" v-model="disconnect_bot" class="p-switch p-fill" style="margin-top:5px; margin-bottom:3px;">{{$t('disconnect_bot')}}</PrettyCheck>
|
<!-- <PrettyCheck @click.native="toggleReplaceWithBot" :disabled="!isRoomOwner" v-model="disconnect_bot" class="p-switch p-fill" style="margin-top:5px; margin-bottom:3px;">{{$t('disconnect_bot')}}</PrettyCheck> -->
|
||||||
</div>
|
</div>
|
||||||
<div v-if="started">
|
<div v-if="started">
|
||||||
<deck :endTurnAction="()=>{wantsToEndTurn = true}"/>
|
<deck :endTurnAction="()=>{wantsToEndTurn = true}"/>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<p v-if="instruction && lives > 0" class="center-stuff">{{instruction}}</p>
|
<p v-if="instruction && (lives > 0 || is_ghost)" class="center-stuff">{{instruction}}</p>
|
||||||
<!-- <button v-if="canEndTurn" @click="end_turn">Termina Turno</button> -->
|
<!-- <button v-if="canEndTurn" @click="end_turn">Termina Turno</button> -->
|
||||||
<div class="equipment-slot">
|
<div class="equipment-slot">
|
||||||
<Card v-if="my_role" :card="my_role" class="back"
|
<Card v-if="my_role" :card="my_role" class="back"
|
||||||
@ -11,7 +11,7 @@
|
|||||||
<span v-for="(n, i) in lives" v-bind:key="n" :alt="i">❤️</span>
|
<span v-for="(n, i) in lives" v-bind:key="n" :alt="i">❤️</span>
|
||||||
<span v-for="(n, i) in (max_lives-lives)" v-bind:key="n" :alt="i">💀</span>
|
<span v-for="(n, i) in (max_lives-lives)" v-bind:key="n" :alt="i">💀</span>
|
||||||
</transition-group>
|
</transition-group>
|
||||||
<transition-group v-if="lives > 0" name="list" tag="div" style="margin: 0 0 0 10pt; display:flex;">
|
<transition-group v-if="lives > 0 || is_ghost" name="list" tag="div" style="margin: 0 0 0 10pt; display:flex;">
|
||||||
<Card v-for="card in equipment" v-bind:key="card.name+card.number" :card="card"
|
<Card v-for="card in equipment" v-bind:key="card.name+card.number" :card="card"
|
||||||
@pointerenter.native="desc=($i18n.locale=='it'?card.desc:card.desc_eng)" @pointerleave.native="desc=''"
|
@pointerenter.native="desc=($i18n.locale=='it'?card.desc:card.desc_eng)" @pointerleave.native="desc=''"
|
||||||
@click.native="play_card(card, true)" />
|
@click.native="play_card(card, true)" />
|
||||||
@ -24,7 +24,7 @@
|
|||||||
<button v-if="is_my_turn && character.name === 'Chuck Wengam' && lives > 1" @click="chuckSpecial">{{$t('special_ability')}}</button>
|
<button v-if="is_my_turn && character.name === 'Chuck Wengam' && lives > 1" @click="chuckSpecial">{{$t('special_ability')}}</button>
|
||||||
<button v-if="is_my_turn && character.name === 'José Delgrado' && special_use_count < 2 && hand.filter(x => x.is_equipment).length > 0" @click="joseScrap=true">{{$t('special_ability')}}</button>
|
<button v-if="is_my_turn && character.name === 'José Delgrado' && special_use_count < 2 && hand.filter(x => x.is_equipment).length > 0" @click="joseScrap=true">{{$t('special_ability')}}</button>
|
||||||
<button v-if="is_my_turn && character.name === 'Doc Holyday' && special_use_count < 1 && hand.length > 1" @click="holydayScrap=true">{{$t('special_ability')}}</button>
|
<button v-if="is_my_turn && character.name === 'Doc Holyday' && special_use_count < 1 && hand.length > 1" @click="holydayScrap=true">{{$t('special_ability')}}</button>
|
||||||
<div v-if="lives > 0" style="position:relative">
|
<div v-if="lives > 0 || is_ghost" style="position:relative">
|
||||||
<span id="hand_text">{{$t('hand')}}</span>
|
<span id="hand_text">{{$t('hand')}}</span>
|
||||||
<transition-group name="list" tag="div" class="hand">
|
<transition-group name="list" tag="div" class="hand">
|
||||||
<Card v-for="card in hand" v-bind:key="card.name+card.number" :card="card"
|
<Card v-for="card in hand" v-bind:key="card.name+card.number" :card="card"
|
||||||
@ -39,7 +39,7 @@
|
|||||||
<Chooser v-if="card_against" :text="$t('card_against')" :cards="visiblePlayers" :select="selectAgainst" :cancel="cancelCardAgainst"/>
|
<Chooser v-if="card_against" :text="$t('card_against')" :cards="visiblePlayers" :select="selectAgainst" :cancel="cancelCardAgainst"/>
|
||||||
<Chooser v-if="pending_action == 3" :text="respondText" :cards="respondCards" :select="respond"/>
|
<Chooser v-if="pending_action == 3" :text="respondText" :cards="respondCards" :select="respond"/>
|
||||||
<Chooser v-if="shouldChooseCard" :text="$t(choose_text)" :cards="available_cards" :select="choose"/>
|
<Chooser v-if="shouldChooseCard" :text="$t(choose_text)" :cards="available_cards" :select="choose"/>
|
||||||
<Chooser v-if="lives <= 0 && max_lives > 0" :text="$t('you_died')" :cancelText="$t('spectate')" :cancel="()=>{max_lives = 0}"/>
|
<Chooser v-if="lives <= 0 && max_lives > 0 && !is_ghost" :text="$t('you_died')" :cancelText="$t('spectate')" :cancel="()=>{max_lives = 0}"/>
|
||||||
<Chooser v-if="win_status !== undefined" :text="win_status?$t('you_win'):$t('you_lose')" />
|
<Chooser v-if="win_status !== undefined" :text="win_status?$t('you_win'):$t('you_lose')" />
|
||||||
<Chooser v-if="show_role" :text="$t('you_are')" :cards="[my_role]" :hintText="($i18n.locale=='it'?my_role.goal:my_role.goal_eng)" :select="() => {show_role=false}" :cancel="() => {show_role=false}" :cancelText="$t('ok')" />
|
<Chooser v-if="show_role" :text="$t('you_are')" :cards="[my_role]" :hintText="($i18n.locale=='it'?my_role.goal:my_role.goal_eng)" :select="() => {show_role=false}" :cancel="() => {show_role=false}" :cancelText="$t('ok')" />
|
||||||
<Chooser v-if="notifycard" :key="notifycard.card" :text="`${notifycard.player} ${$t('did_pick_as')}:`" :cards="[notifycard.card]" :hintText="$t(notifycard.message)" class="turn-notify-4s"/>
|
<Chooser v-if="notifycard" :key="notifycard.card" :text="`${notifycard.player} ${$t('did_pick_as')}:`" :cards="[notifycard.card]" :hintText="$t(notifycard.message)" class="turn-notify-4s"/>
|
||||||
@ -106,6 +106,7 @@ export default {
|
|||||||
holydayScrap: false,
|
holydayScrap: false,
|
||||||
special_use_count: 0,
|
special_use_count: 0,
|
||||||
mancato_needed: 0,
|
mancato_needed: 0,
|
||||||
|
is_ghost: false,
|
||||||
name: '',
|
name: '',
|
||||||
}),
|
}),
|
||||||
sockets: {
|
sockets: {
|
||||||
@ -141,6 +142,7 @@ export default {
|
|||||||
this.sight = self.sight
|
this.sight = self.sight
|
||||||
this.attacker = self.attacker
|
this.attacker = self.attacker
|
||||||
this.mancato_needed = self.mancato_needed
|
this.mancato_needed = self.mancato_needed
|
||||||
|
this.is_ghost = self.is_ghost
|
||||||
if (this.pending_action == 5 && self.target_p) {
|
if (this.pending_action == 5 && self.target_p) {
|
||||||
this.chooseCardFromPlayer(self.target_p)
|
this.chooseCardFromPlayer(self.target_p)
|
||||||
} else if (this.pending_action == 5) {
|
} else if (this.pending_action == 5) {
|
||||||
|
@ -90,7 +90,8 @@
|
|||||||
"guess": "{0} guesses {1}.",
|
"guess": "{0} guesses {1}.",
|
||||||
"guess_right": "{0} was right.",
|
"guess_right": "{0} was right.",
|
||||||
"guess_wrong": "{0} was wrong.",
|
"guess_wrong": "{0} was wrong.",
|
||||||
"fratelli_sangue": "{0} gave one of his lives to {1}."
|
"fratelli_sangue": "{0} gave one of his lives to {1}.",
|
||||||
|
"doctor_heal": "{0} was healed by the doctor."
|
||||||
},
|
},
|
||||||
"foc": {
|
"foc": {
|
||||||
"leggedelwest": "He must play this card on this turn if possible."
|
"leggedelwest": "He must play this card on this turn if possible."
|
||||||
|
@ -90,7 +90,8 @@
|
|||||||
"guess": "{0} pensa sia {1}.",
|
"guess": "{0} pensa sia {1}.",
|
||||||
"guess_right": "{0} ha indovinato.",
|
"guess_right": "{0} ha indovinato.",
|
||||||
"guess_wrong": "{0} ha sbagliato.",
|
"guess_wrong": "{0} ha sbagliato.",
|
||||||
"fratelli_sangue": "{0} ha donato una delle sue vite a {1}."
|
"fratelli_sangue": "{0} ha donato una delle sue vite a {1}.",
|
||||||
|
"doctor_heal": "{0} è stato curato dal dottore."
|
||||||
},
|
},
|
||||||
"foc": {
|
"foc": {
|
||||||
"leggedelwest": "Ed è obbligato a usarla nel suo turno, se possibile"
|
"leggedelwest": "Ed è obbligato a usarla nel suo turno, se possibile"
|
||||||
|
Loading…
Reference in New Issue
Block a user