commit
bb98b4493b
@ -4,8 +4,8 @@ from typing import List
|
|||||||
import eventlet
|
import eventlet
|
||||||
import socketio
|
import socketio
|
||||||
|
|
||||||
from game import Game
|
from bang.game import Game
|
||||||
from players import Player
|
from bang.players import Player
|
||||||
|
|
||||||
sio = socketio.Server(cors_allowed_origins="*")
|
sio = socketio.Server(cors_allowed_origins="*")
|
||||||
app = socketio.WSGIApp(sio, static_files={
|
app = socketio.WSGIApp(sio, static_files={
|
||||||
@ -69,6 +69,11 @@ def private(sid):
|
|||||||
g.set_private()
|
g.set_private()
|
||||||
advertise_lobbies()
|
advertise_lobbies()
|
||||||
|
|
||||||
|
@sio.event
|
||||||
|
def toggle_expansion(sid, expansion_name):
|
||||||
|
g = sio.get_session(sid).game
|
||||||
|
g.toggle_expansion(expansion_name)
|
||||||
|
|
||||||
@sio.event
|
@sio.event
|
||||||
def join_room(sid, room):
|
def join_room(sid, room):
|
||||||
room_name = room['name']
|
room_name = room['name']
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
from typing import List, Set, Dict, Tuple, Optional
|
from typing import List, Set, Dict, Tuple, Optional
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
import roles as r
|
import bang.roles as r
|
||||||
|
|
||||||
class Suit(IntEnum):
|
class Suit(IntEnum):
|
||||||
DIAMONDS = 0 # ♦
|
DIAMONDS = 0 # ♦
|
||||||
@ -57,7 +57,7 @@ class Card(ABC):
|
|||||||
for i in range(len(player.equipment)):
|
for i in range(len(player.equipment)):
|
||||||
print('tipo',type(self))
|
print('tipo',type(self))
|
||||||
if type(player.equipment[i]) == type(self):
|
if type(player.equipment[i]) == type(self):
|
||||||
player.game.deck.scrap(self.equipment[i])
|
player.game.deck.scrap(player.equipment[i])
|
||||||
player.equipment[i] = self
|
player.equipment[i] = self
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
@ -162,7 +162,7 @@ class Bang(Card):
|
|||||||
if player.has_played_bang and not any([isinstance(c, Volcanic) for c in player.equipment]) and against != None:
|
if player.has_played_bang and not any([isinstance(c, Volcanic) for c in player.equipment]) and against != None:
|
||||||
return False
|
return False
|
||||||
elif against != None:
|
elif against != None:
|
||||||
import 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.has_played_bang = not isinstance(
|
||||||
player.character, chars.WillyTheKid)
|
player.character, chars.WillyTheKid)
|
||||||
@ -199,7 +199,7 @@ class CatBalou(Card):
|
|||||||
def play_card(self, player, against):
|
def play_card(self, player, against):
|
||||||
if against != None and (len(player.game.get_player_named(against).hand) + len(player.game.get_player_named(against).equipment)) > 0:
|
if against != None and (len(player.game.get_player_named(against).hand) + len(player.game.get_player_named(against).equipment)) > 0:
|
||||||
super().play_card(player, against=against)
|
super().play_card(player, against=against)
|
||||||
from players import PendingAction
|
from bang.players import PendingAction
|
||||||
player.pending_action = PendingAction.CHOOSE
|
player.pending_action = PendingAction.CHOOSE
|
||||||
player.choose_action = 'discard'
|
player.choose_action = 'discard'
|
||||||
player.target_p = against
|
player.target_p = against
|
||||||
@ -281,7 +281,7 @@ class Mancato(Card):
|
|||||||
self.desc = "Usa questa carta per annullare un bang"
|
self.desc = "Usa questa carta per annullare un bang"
|
||||||
|
|
||||||
def play_card(self, player, against):
|
def play_card(self, player, against):
|
||||||
import 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 isinstance(player.character, chars.CalamityJanet)):
|
||||||
player.sio.emit('chat_message', room=player.game.name,
|
player.sio.emit('chat_message', room=player.game.name,
|
||||||
data=f'{player.name} ha giocato {self.name} come un BANG! contro {against}.')
|
data=f'{player.name} ha giocato {self.name} come un BANG! contro {against}.')
|
||||||
@ -301,7 +301,7 @@ class Panico(Card):
|
|||||||
def play_card(self, player, against):
|
def play_card(self, player, against):
|
||||||
if against != None and (len(player.game.get_player_named(against).hand) + len(player.game.get_player_named(against).equipment)) > 0:
|
if against != None and (len(player.game.get_player_named(against).hand) + len(player.game.get_player_named(against).equipment)) > 0:
|
||||||
super().play_card(player, against=against)
|
super().play_card(player, against=against)
|
||||||
from players import PendingAction
|
from bang.players import PendingAction
|
||||||
player.pending_action = PendingAction.CHOOSE
|
player.pending_action = PendingAction.CHOOSE
|
||||||
player.choose_action = 'steal'
|
player.choose_action = 'steal'
|
||||||
player.target_p = against
|
player.target_p = against
|
||||||
@ -339,8 +339,9 @@ class WellsFargo(Card):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def get_starting_deck() -> List[Card]:
|
def get_starting_deck(expansions:List[str]) -> List[Card]:
|
||||||
return [
|
from bang.expansions import DodgeCity
|
||||||
|
base_cards = [
|
||||||
Barile(Suit.SPADES, 'Q'),
|
Barile(Suit.SPADES, 'Q'),
|
||||||
Barile(Suit.SPADES, 'K'),
|
Barile(Suit.SPADES, 'K'),
|
||||||
Dinamite(Suit.HEARTS, 2),
|
Dinamite(Suit.HEARTS, 2),
|
||||||
@ -422,3 +423,7 @@ def get_starting_deck() -> List[Card]:
|
|||||||
Saloon(Suit.HEARTS, 5),
|
Saloon(Suit.HEARTS, 5),
|
||||||
WellsFargo(Suit.HEARTS, 3),
|
WellsFargo(Suit.HEARTS, 3),
|
||||||
]
|
]
|
||||||
|
if 'dodge_city' in expansions:
|
||||||
|
base_cards.extend(DodgeCity.get_cards())
|
||||||
|
return base_cards
|
||||||
|
|
@ -1,11 +1,11 @@
|
|||||||
from typing import List, Set, Dict, Tuple, Optional
|
from typing import List, Set, Dict, Tuple, Optional
|
||||||
import random
|
import random
|
||||||
import cards as cs
|
import bang.cards as cs
|
||||||
|
|
||||||
class Deck:
|
class Deck:
|
||||||
def __init__(self, game):
|
def __init__(self, game):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.cards: List[cs.Card] = cs.get_starting_deck()
|
self.cards: List[cs.Card] = cs.get_starting_deck(game.expansions)
|
||||||
self.game = game
|
self.game = game
|
||||||
random.shuffle(self.cards)
|
random.shuffle(self.cards)
|
||||||
self.scrap_pile: List[cs.Card] = []
|
self.scrap_pile: List[cs.Card] = []
|
5
backend/bang/expansions/__init__.py
Normal file
5
backend/bang/expansions/__init__.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
from bang.expansions.dodge_city import cards
|
||||||
|
class DodgeCity():
|
||||||
|
def get_cards():
|
||||||
|
return cards.get_starting_deck()
|
36
backend/bang/expansions/dodge_city/cards.py
Normal file
36
backend/bang/expansions/dodge_city/cards.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
from bang.cards import *
|
||||||
|
|
||||||
|
class Riparo(Mustang):
|
||||||
|
def __init__(self, suit, number):
|
||||||
|
super().__init__(suit, number)
|
||||||
|
self.name = 'Riparo'
|
||||||
|
self.icon = '⛰'
|
||||||
|
|
||||||
|
class Binocolo(Mirino):
|
||||||
|
def __init__(self, suit, number):
|
||||||
|
super().__init__(suit, number)
|
||||||
|
self.name = 'Binocolo'
|
||||||
|
self.icon = '🔍'
|
||||||
|
|
||||||
|
class Pugno(Card):
|
||||||
|
def __init__(self, suit, number):
|
||||||
|
super().__init__(suit, 'Pugno!', number, range=1)
|
||||||
|
self.icon = '👊'
|
||||||
|
self.desc = "Spara a un giocatore a distanta 1"
|
||||||
|
self.need_target = True
|
||||||
|
|
||||||
|
def play_card(self, player, against):
|
||||||
|
if against != None:
|
||||||
|
import bang.characters as chars
|
||||||
|
super().play_card(player, against=against)
|
||||||
|
player.game.attack(player, against)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_starting_deck() -> List[Card]:
|
||||||
|
return [
|
||||||
|
#TODO: aggiungere anche le carte normalmente presenti https://bang.dvgiochi.com/cardslist.php?id=3
|
||||||
|
Riparo(Suit.DIAMONDS, 'K'),
|
||||||
|
Binocolo(Suit.DIAMONDS, 10),
|
||||||
|
Pugno(Suit.SPADES, 10),
|
||||||
|
]
|
@ -2,10 +2,10 @@
|
|||||||
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 players
|
import bang.players as players
|
||||||
import characters
|
import bang.characters as characters
|
||||||
from deck import Deck
|
from bang.deck import Deck
|
||||||
import roles
|
import bang.roles as roles
|
||||||
|
|
||||||
class Game:
|
class Game:
|
||||||
def __init__(self, name, sio:socketio):
|
def __init__(self, name, sio:socketio):
|
||||||
@ -20,6 +20,25 @@ class Game:
|
|||||||
self.waiting_for = 0
|
self.waiting_for = 0
|
||||||
self.initial_players = 0
|
self.initial_players = 0
|
||||||
self.password = ''
|
self.password = ''
|
||||||
|
self.expansions = []
|
||||||
|
|
||||||
|
def notify_room(self):
|
||||||
|
self.sio.emit('room', room=self.name, data={
|
||||||
|
'name': self.name,
|
||||||
|
'started': self.started,
|
||||||
|
'players': [{'name':p.name, 'ready': False} for p in self.players],
|
||||||
|
'password': self.password,
|
||||||
|
'expansions': self.expansions,
|
||||||
|
})
|
||||||
|
|
||||||
|
def toggle_expansion(self, expansion_name):
|
||||||
|
if not self.started:
|
||||||
|
print('toggling', expansion_name)
|
||||||
|
if expansion_name in self.expansions:
|
||||||
|
self.expansions.remove(expansion_name)
|
||||||
|
else:
|
||||||
|
self.expansions.append(expansion_name)
|
||||||
|
self.notify_room()
|
||||||
|
|
||||||
def add_player(self, player: players.Player):
|
def add_player(self, player: players.Player):
|
||||||
if player in self.players or len(self.players) >= 7:
|
if player in self.players or len(self.players) >= 7:
|
||||||
@ -27,7 +46,7 @@ class Game:
|
|||||||
player.join_game(self)
|
player.join_game(self)
|
||||||
self.players.append(player)
|
self.players.append(player)
|
||||||
print(f'Added player {player.name} to game')
|
print(f'Added player {player.name} to game')
|
||||||
self.sio.emit('room', room=self.name, data={'name': self.name, 'started': self.started, 'players': [p.name for p in self.players], 'password': self.password})
|
self.notify_room()
|
||||||
self.sio.emit('chat_message', room=self.name, data=f'{player.name} è entrato nella lobby.')
|
self.sio.emit('chat_message', room=self.name, data=f'{player.name} è entrato nella lobby.')
|
||||||
|
|
||||||
def set_private(self):
|
def set_private(self):
|
||||||
@ -36,10 +55,11 @@ class Game:
|
|||||||
print(self.name, 'is now private pwd', self.password)
|
print(self.name, 'is now private pwd', self.password)
|
||||||
else:
|
else:
|
||||||
self.password = ''
|
self.password = ''
|
||||||
self.sio.emit('room', room=self.name, data={'name': self.name, 'started': self.started, 'players': [p.name for p in self.players], 'password': self.password})
|
self.notify_room()
|
||||||
|
|
||||||
def notify_character_selection(self):
|
def notify_character_selection(self):
|
||||||
self.readyCount += 1
|
self.readyCount += 1
|
||||||
|
self.notify_room()
|
||||||
if self.readyCount == len(self.players):
|
if self.readyCount == len(self.players):
|
||||||
self.distribute_roles()
|
self.distribute_roles()
|
||||||
|
|
||||||
@ -212,7 +232,7 @@ class Game:
|
|||||||
if self.started and index <= self.turn:
|
if self.started and index <= self.turn:
|
||||||
self.turn -= 1
|
self.turn -= 1
|
||||||
self.players.pop(index)
|
self.players.pop(index)
|
||||||
self.sio.emit('room', room=self.name, data={'name': self.name, 'started': self.started, 'players': [p.name for p in self.players]})
|
self.notify_room()
|
||||||
self.sio.emit('chat_message', room=self.name, data=f'{player.name} è morto.')
|
self.sio.emit('chat_message', room=self.name, data=f'{player.name} è morto.')
|
||||||
if self.started:
|
if self.started:
|
||||||
self.sio.emit('chat_message', room=self.name, data=f'{player.name} era {player.role.name}!')
|
self.sio.emit('chat_message', room=self.name, data=f'{player.name} era {player.role.name}!')
|
@ -2,10 +2,10 @@ from enum import IntEnum
|
|||||||
import json
|
import json
|
||||||
from random import randrange
|
from random import randrange
|
||||||
import socketio
|
import socketio
|
||||||
import deck
|
import bang.deck as deck
|
||||||
import roles as r
|
import bang.roles as r
|
||||||
import cards as cs
|
import bang.cards as cs
|
||||||
import characters as chars
|
import bang.characters as chars
|
||||||
|
|
||||||
class PendingAction(IntEnum):
|
class PendingAction(IntEnum):
|
||||||
PICK = 0
|
PICK = 0
|
||||||
@ -17,9 +17,9 @@ class PendingAction(IntEnum):
|
|||||||
|
|
||||||
|
|
||||||
class Player:
|
class Player:
|
||||||
import game as g
|
|
||||||
|
|
||||||
def __init__(self, name, sid, sio):
|
def __init__(self, name, sid, sio):
|
||||||
|
import bang.game as g
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.name = name
|
self.name = name
|
||||||
self.sid = sid
|
self.sid = sid
|
@ -27,6 +27,10 @@
|
|||||||
<!-- :style="p.style"/> -->
|
<!-- :style="p.style"/> -->
|
||||||
<!-- </div> -->
|
<!-- </div> -->
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="!started">
|
||||||
|
<h3>Espansioni (NON COMPLETE)</h3>
|
||||||
|
<PrettyCheck @click.native="toggleExpansions('dodge_city')" :disabled="!isRoomOwner" v-model="useDodgeCity" class="p-switch p-fill" style="margin-top:5px; margin-bottom:3px;">Dodge City</PrettyCheck>
|
||||||
|
</div>
|
||||||
<div v-if="started">
|
<div v-if="started">
|
||||||
<deck :endTurnAction="()=>{wantsToEndTurn = true}"/>
|
<deck :endTurnAction="()=>{wantsToEndTurn = true}"/>
|
||||||
<player :isEndingTurn="wantsToEndTurn" :cancelEndingTurn="()=>{wantsToEndTurn = false}" :chooseCardFromPlayer="choose"/>
|
<player :isEndingTurn="wantsToEndTurn" :cancelEndingTurn="()=>{wantsToEndTurn = false}" :chooseCardFromPlayer="choose"/>
|
||||||
@ -78,15 +82,18 @@ export default {
|
|||||||
selectedInfo: null,
|
selectedInfo: null,
|
||||||
privateRoom: false,
|
privateRoom: false,
|
||||||
password: '',
|
password: '',
|
||||||
|
useDodgeCity: false,
|
||||||
}),
|
}),
|
||||||
sockets: {
|
sockets: {
|
||||||
room(data) {
|
room(data) {
|
||||||
this.lobbyName = data.name
|
this.lobbyName = data.name
|
||||||
this.started = data.started
|
this.started = data.started
|
||||||
this.password = data.password
|
this.password = data.password
|
||||||
|
this.useDodgeCity = data.expansions.indexOf('dodge_city') !== -1
|
||||||
this.players = data.players.map(x => {
|
this.players = data.players.map(x => {
|
||||||
return {
|
return {
|
||||||
name: x,
|
name: x.name,
|
||||||
|
ready: x.ready,
|
||||||
ncards: 0,
|
ncards: 0,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -140,6 +147,10 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
toggleExpansions(name) {
|
||||||
|
if (!this.isRoomOwner) return;
|
||||||
|
this.$socket.emit('toggle_expansion', name)
|
||||||
|
},
|
||||||
getActionEmoji(p) {
|
getActionEmoji(p) {
|
||||||
if (p.is_my_turn === undefined || p.pending_action === undefined) return '';
|
if (p.is_my_turn === undefined || p.pending_action === undefined) return '';
|
||||||
if (p.pending_action != 4) {
|
if (p.pending_action != 4) {
|
||||||
@ -154,7 +165,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
name: player.name,
|
name: player.name,
|
||||||
number: ((this.username == player.name) ? 'YOU' : (this.players[0].name == player.name) ? 'OWNER' :'') + (player.dist ? `${player.dist}⛰` : ''),
|
number: ((this.username == player.name) ? 'YOU' : (this.players[0].name == player.name) ? 'OWNER' :'') + (player.dist ? `${player.dist}⛰` : ''),
|
||||||
icon: (player.lives === undefined || player.lives > 0) ? (player.is_sheriff ? '⭐' : player.icon || '🤠' ) : '☠️',
|
icon: (player.lives === undefined || player.lives > 0) ? (player.is_sheriff ? '⭐' : player.icon || ((player.ready)?'👍': '🤠') ) : '☠️',
|
||||||
is_character: true,
|
is_character: true,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -196,12 +196,10 @@ export default {
|
|||||||
let cant_play_bang = (this.has_played_bang && this.equipment.filter(x => x.name == 'Volcanic').length == 0)
|
let cant_play_bang = (this.has_played_bang && this.equipment.filter(x => x.name == 'Volcanic').length == 0)
|
||||||
if (this.pending_action == 2) {
|
if (this.pending_action == 2) {
|
||||||
if ((card.need_target || calamity_special) && !((card.name == 'Bang!' || (calamity_special && card.name=='Mancato!')) && cant_play_bang)) {
|
if ((card.need_target || calamity_special) && !((card.name == 'Bang!' || (calamity_special && card.name=='Mancato!')) && cant_play_bang)) {
|
||||||
if (card.name == 'Panico!' || (card.name == 'Bang!' && cant_play_bang))
|
if (card.name == 'Bang!' || calamity_special)
|
||||||
this.range = 1
|
|
||||||
else if (card.name == 'Bang!' || calamity_special)
|
|
||||||
this.range = this.sight
|
this.range = this.sight
|
||||||
else
|
else
|
||||||
this.range = 999
|
this.range = card.range
|
||||||
this.can_target_sheriff = (card.name !== 'Prigione')
|
this.can_target_sheriff = (card.name !== 'Prigione')
|
||||||
if (this.visiblePlayers.length == 0 && this.hand.length > this.lives) {
|
if (this.visiblePlayers.length == 0 && this.hand.length > this.lives) {
|
||||||
this.really_play_card(card, null)
|
this.really_play_card(card, null)
|
||||||
|
Loading…
Reference in New Issue
Block a user