add trains
This commit is contained in:
parent
9e89092090
commit
1ee92afb9a
@ -6,6 +6,7 @@ import bang.expansions.wild_west_show.card_events as cew
|
|||||||
import bang.expansions.wild_west_show.characters as chw
|
import bang.expansions.wild_west_show.characters as chw
|
||||||
import bang.expansions.gold_rush.shop_cards as grc
|
import bang.expansions.gold_rush.shop_cards as grc
|
||||||
import bang.expansions.train_robbery.stations as trs
|
import bang.expansions.train_robbery.stations as trs
|
||||||
|
import bang.expansions.train_robbery.trains as trt
|
||||||
from globals import G
|
from globals import G
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@ -36,6 +37,8 @@ class Deck:
|
|||||||
self.event_cards: List[ce.CardEvent] = []
|
self.event_cards: List[ce.CardEvent] = []
|
||||||
self.event_cards_wildwestshow: List[ce.CardEvent] = []
|
self.event_cards_wildwestshow: List[ce.CardEvent] = []
|
||||||
self.stations: List[trs.StationCard] = []
|
self.stations: List[trs.StationCard] = []
|
||||||
|
self.train_pile: List[trt.TrainCard] = []
|
||||||
|
self.current_train: List[trt.TrainCard] = []
|
||||||
endgame_cards: List[ce.CardEvent] = []
|
endgame_cards: List[ce.CardEvent] = []
|
||||||
if "fistful_of_cards" in game.expansions:
|
if "fistful_of_cards" in game.expansions:
|
||||||
self.event_cards.extend(ce.get_all_events(game.rng))
|
self.event_cards.extend(ce.get_all_events(game.rng))
|
||||||
@ -50,6 +53,10 @@ class Deck:
|
|||||||
self.event_cards_wildwestshow.append(cew.get_endgame_card())
|
self.event_cards_wildwestshow.append(cew.get_endgame_card())
|
||||||
if "train_robbery" in game.expansions:
|
if "train_robbery" in game.expansions:
|
||||||
self.stations = game.rng.sample(trs.get_all_stations(), len(game.players))
|
self.stations = game.rng.sample(trs.get_all_stations(), len(game.players))
|
||||||
|
self.train_pile = trt.get_all_cards(game.rng)
|
||||||
|
self.current_train = [trt.get_locomotives(game.rng)[0]] + self.train_pile[
|
||||||
|
:3
|
||||||
|
]
|
||||||
if len(self.event_cards) > 0:
|
if len(self.event_cards) > 0:
|
||||||
game.rng.shuffle(self.event_cards)
|
game.rng.shuffle(self.event_cards)
|
||||||
self.event_cards = self.event_cards[:12]
|
self.event_cards = self.event_cards[:12]
|
||||||
@ -109,6 +116,15 @@ class Deck:
|
|||||||
self.shop_cards[i].reset_card()
|
self.shop_cards[i].reset_card()
|
||||||
self.game.notify_gold_rush_shop()
|
self.game.notify_gold_rush_shop()
|
||||||
|
|
||||||
|
def move_train_forward(self):
|
||||||
|
if len(self.stations) == 0:
|
||||||
|
return
|
||||||
|
if len(self.current_train) == len(self.stations) + 4:
|
||||||
|
return
|
||||||
|
if len(self.current_train) > 0:
|
||||||
|
self.current_train.append(None)
|
||||||
|
self.game.notify_stations()
|
||||||
|
|
||||||
def peek(self, n_cards: int) -> list:
|
def peek(self, n_cards: int) -> list:
|
||||||
return self.cards[:n_cards]
|
return self.cards[:n_cards]
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
|
import random
|
||||||
from bang.cards import Card
|
from bang.cards import Card
|
||||||
|
|
||||||
|
|
||||||
class TrainCard(Card):
|
class TrainCard(Card):
|
||||||
def __init__(self, name: str, is_locomotive: bool = False):
|
def __init__(self, name: str, is_locomotive: bool = False):
|
||||||
super().__init__(suit=5, number="", name=name)
|
super().__init__(suit=5, number=0, name=name)
|
||||||
self.expansion_icon = "🚂"
|
self.expansion_icon = "🚂"
|
||||||
self.is_equipment = True
|
self.is_equipment = True
|
||||||
self.is_locomotive = is_locomotive
|
self.is_locomotive = is_locomotive
|
||||||
@ -92,10 +93,212 @@ class Leland(TrainCard):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class BaggageCar(TrainCard):
|
||||||
|
"""Scartalo: ottieni l'effetto di un Mancato!, Panico!, Cat Balou o di un BANG! extra.
|
||||||
|
Discard this for a Missed!Panic!, Cat Balou, or an extra BANG!"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Baggage Car")
|
||||||
|
self.icon = "🚋🛄"
|
||||||
|
|
||||||
|
def play_card(self, player, against=None, _with=None) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class Caboose(TrainCard):
|
||||||
|
"""Pro scartare un aura tua carta bordo bin incuso un vagone come se fosse un Mancato!"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Caboose")
|
||||||
|
self.icon = "🚋"
|
||||||
|
|
||||||
|
def play_card(self, player, against=None, _with=None) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class CattleTruck(TrainCard):
|
||||||
|
"""Scartalo: guarda le 3 carte in cima agli scarti e pescane I"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Cattle Truck")
|
||||||
|
self.icon = "🚋🐄"
|
||||||
|
|
||||||
|
def play_card(self, player, against=None, _with=None) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class CircusWagon(TrainCard):
|
class CircusWagon(TrainCard):
|
||||||
|
"""Scartalo: ogni altro giocatore deve scartare una carta che ha in gioco."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__("Circus Wagon", is_locomotive=True)
|
super().__init__("Circus Wagon", is_locomotive=True)
|
||||||
self.icon = "🚋🎪"
|
self.icon = "🚋🎪"
|
||||||
|
|
||||||
def play_card(self, player, against=None, _with=None) -> bool:
|
def play_card(self, player, against=None, _with=None) -> bool:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class CoalHopper(TrainCard):
|
||||||
|
"""Scartalo: pesca una carta e scarta un vagone in gioco davanti a un giocatore a ma scelta."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Coal Hopper")
|
||||||
|
self.icon = "🚋🔥"
|
||||||
|
|
||||||
|
def play_card(self, player, against=None, _with=None) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class DiningCar(TrainCard):
|
||||||
|
"""A inizio turno, "estrai!": se è Cnori, recuperi I punto vita."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Dining Car")
|
||||||
|
self.icon = "🚋🍽"
|
||||||
|
|
||||||
|
def play_card(self, player, against=None, _with=None) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class ExpressCar(TrainCard):
|
||||||
|
"""Scarta tutte le carte in mano, poi gioca un altro turno"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Express Car")
|
||||||
|
self.icon = "🚋⚡"
|
||||||
|
|
||||||
|
def play_card(self, player, against=None, _with=None) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class GhostCar(TrainCard):
|
||||||
|
"""Giocalo su chiunque tranne lo Sceritfo. Se vieni eliminato, invece resti in gioco, ma non puol guada nare ne perdere punk vita."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Ghost Car")
|
||||||
|
self.icon = "🚋👻"
|
||||||
|
|
||||||
|
def play_card(self, player, against=None, _with=None) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class LoungeCar(TrainCard):
|
||||||
|
"""Scartalo: pesca 2 vagoni dal mazzo, mettine I in gioco di fronte a te e 1 di fronte a un altro giocatore."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Lounge Car")
|
||||||
|
self.icon = "🚋🛋"
|
||||||
|
|
||||||
|
def play_card(self, player, against=None, _with=None) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class LumberFlatcar(TrainCard):
|
||||||
|
"""Giocalo su un qualsiasi giocatore (compreso te). Finché questa carta è in gioco, quel giocatore vede gli altri giocatori a distanza aumentata di 1."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Lumber Flatcar")
|
||||||
|
self.icon = "🚋🪵"
|
||||||
|
|
||||||
|
def play_card(self, player, against=None, _with=None) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class MailCar(TrainCard):
|
||||||
|
"""Scartalo: pesca 3 carte e dai 1 di esse a un altro giocatore a tua scelta."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Mail Car")
|
||||||
|
self.icon = "🚋📮"
|
||||||
|
|
||||||
|
def play_card(self, player, against=None, _with=None) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class ObservationCar(TrainCard):
|
||||||
|
"""Tu vedi gli altri a distanza -1. Gli altri a vedono a distanza +1."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Observation Car")
|
||||||
|
self.icon = "🚋👀"
|
||||||
|
|
||||||
|
def play_card(self, player, against=None, _with=None) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class PassengerCar(TrainCard):
|
||||||
|
"""Scartalo: pesca una carta (in mano o in gioco) da un altro giocatore"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Passenger Car")
|
||||||
|
self.icon = "🚋🚶"
|
||||||
|
|
||||||
|
def play_card(self, player, against=None, _with=None) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class PrisonerCar(TrainCard):
|
||||||
|
"""Le carte Duello e Indiani! giocate dagli altri giocatori non hanno effetto su di te."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Prisoner Car")
|
||||||
|
self.icon = "🚋👮🏻♂️"
|
||||||
|
|
||||||
|
def play_card(self, player, against=None, _with=None) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class PrivateCar(TrainCard):
|
||||||
|
"""se non hai carte in mano. non puoi essere bersaelio di carte BANG"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Private Car")
|
||||||
|
self.icon = "🚋💁🏻"
|
||||||
|
|
||||||
|
def play_card(self, player, against=None, _with=None) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class SleeperCar(TrainCard):
|
||||||
|
"""Una volta per turno, puoi scartare un'altra tua carta a bordo blu incluso."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Sleeper Car")
|
||||||
|
self.icon = "🚋🛌"
|
||||||
|
|
||||||
|
def play_card(self, player, against=None, _with=None) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def get_all_cards(rng=random):
|
||||||
|
"""Return a list of all train cards in the expansion"""
|
||||||
|
cars = [
|
||||||
|
BaggageCar(),
|
||||||
|
Caboose(),
|
||||||
|
CattleTruck(),
|
||||||
|
CircusWagon(),
|
||||||
|
CoalHopper(),
|
||||||
|
DiningCar(),
|
||||||
|
ExpressCar(),
|
||||||
|
GhostCar(),
|
||||||
|
LoungeCar(),
|
||||||
|
LumberFlatcar(),
|
||||||
|
MailCar(),
|
||||||
|
ObservationCar(),
|
||||||
|
PassengerCar(),
|
||||||
|
PrisonerCar(),
|
||||||
|
PrivateCar(),
|
||||||
|
SleeperCar(),
|
||||||
|
]
|
||||||
|
rng.shuffle(cars)
|
||||||
|
return cars
|
||||||
|
|
||||||
|
|
||||||
|
def get_locomotives(rng=random):
|
||||||
|
"""Return a list of all locomotive cards in the expansion"""
|
||||||
|
locs = [
|
||||||
|
Ironhorse(),
|
||||||
|
Leland(),
|
||||||
|
]
|
||||||
|
rng.shuffle(locs)
|
||||||
|
return locs
|
||||||
|
@ -59,6 +59,8 @@ debug_commands = [
|
|||||||
{"cmd": "/getcard", "help": "Get a brand new card - sample /getcard Birra"},
|
{"cmd": "/getcard", "help": "Get a brand new card - sample /getcard Birra"},
|
||||||
{"cmd": "/meinfo", "help": "Get player data"},
|
{"cmd": "/meinfo", "help": "Get player data"},
|
||||||
{"cmd": "/gameinfo", "help": "Get game data"},
|
{"cmd": "/gameinfo", "help": "Get game data"},
|
||||||
|
{"cmd": "/deckinfo", "help": "Get deck data"},
|
||||||
|
{"cmd": "/trainfw", "help": "move train forward"},
|
||||||
{"cmd": "/playerinfo", "help": "Get player data - sample /playerinfo player"},
|
{"cmd": "/playerinfo", "help": "Get player data - sample /playerinfo player"},
|
||||||
{"cmd": "/cardinfo", "help": "Get card data - sample /cardinfo handindex"},
|
{"cmd": "/cardinfo", "help": "Get card data - sample /cardinfo handindex"},
|
||||||
{"cmd": "/mebot", "help": "Toggles bot mode"},
|
{"cmd": "/mebot", "help": "Toggles bot mode"},
|
||||||
@ -844,6 +846,7 @@ class Game:
|
|||||||
)
|
)
|
||||||
):
|
):
|
||||||
self.deck.flip_event()
|
self.deck.flip_event()
|
||||||
|
self.deck.move_train_forward()
|
||||||
if self.check_event(ce.RouletteRussa):
|
if 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]):
|
||||||
@ -925,7 +928,13 @@ class Game:
|
|||||||
G.sio.emit(
|
G.sio.emit(
|
||||||
"stations",
|
"stations",
|
||||||
room=room,
|
room=room,
|
||||||
data=json.dumps(self.deck.stations, default=lambda o: o.__dict__),
|
data=json.dumps(
|
||||||
|
{
|
||||||
|
"stations": self.deck.stations,
|
||||||
|
"current_train": self.deck.current_train,
|
||||||
|
},
|
||||||
|
default=lambda o: o.__dict__,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
def notify_scrap_pile(self, sid=None):
|
def notify_scrap_pile(self, sid=None):
|
||||||
|
@ -1089,6 +1089,21 @@ def chat_message(sid, msg, pl=None):
|
|||||||
"type": "json",
|
"type": "json",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
elif "/deckinfo" in msg:
|
||||||
|
sio.emit(
|
||||||
|
"chat_message",
|
||||||
|
room=sid,
|
||||||
|
data={
|
||||||
|
"color": "",
|
||||||
|
"text": json.dumps(
|
||||||
|
ses.game.deck.__dict__,
|
||||||
|
default=lambda o: f"<{o.__class__.__name__}() not serializable>",
|
||||||
|
),
|
||||||
|
"type": "json",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
elif "/trainfw" in msg:
|
||||||
|
ses.game.deck.move_train_forward()
|
||||||
elif "/status" in msg and ses.is_admin():
|
elif "/status" in msg and ses.is_admin():
|
||||||
sio.emit("mount_status", room=sid)
|
sio.emit("mount_status", room=sid)
|
||||||
elif "/meinfo" in msg:
|
elif "/meinfo" in msg:
|
||||||
|
@ -355,6 +355,9 @@ export default {
|
|||||||
transform: scaleX(-1);
|
transform: scaleX(-1);
|
||||||
/* filter: grayscale(1); */
|
/* filter: grayscale(1); */
|
||||||
}
|
}
|
||||||
|
.train-piece .suit, .train-piece .expansion {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
.train-piece h4 {
|
.train-piece h4 {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -11,18 +11,8 @@
|
|||||||
<card :card="goldRushCardBack" :donotlocalize="true" class="gold-rush back last-event" @click.native="goldRushShopOpen = !goldRushShopOpen"/>
|
<card :card="goldRushCardBack" :donotlocalize="true" class="gold-rush back last-event" @click.native="goldRushShopOpen = !goldRushShopOpen"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="current_stations.length > 0" class="deck" :style="`position:relative;border: 2px dashed #6a6a6a42;border-radius:8pt;align-items: flex-end;`" >
|
<div v-if="currentStations.length > 0" class="deck" :style="`position:relative;border: 2px dashed #6a6a6a42;border-radius:8pt;align-items: flex-end;flex-direction:row;`" >
|
||||||
<station-card v-for="station, i in current_stations" :key="station.name" :card="station" :price="station.price" :trainPiece="
|
<station-card v-for="station, i in currentStations" :key="station.name" :card="{name:i}" :price="station.price" :trainPiece="trainPieceForStation(i)"/>
|
||||||
i == 2 ? {
|
|
||||||
name: 'Iron House',
|
|
||||||
icon: '🚂',
|
|
||||||
back: true,
|
|
||||||
} : i > 2 ? {
|
|
||||||
name: 'Passenger Car',
|
|
||||||
icon: '🚃',
|
|
||||||
back: true,
|
|
||||||
} : undefined
|
|
||||||
"/>
|
|
||||||
</div>
|
</div>
|
||||||
<div v-if="eventCard" style="position:relative">
|
<div v-if="eventCard" style="position:relative">
|
||||||
<div class="card fistful-of-cards" style="position:relative; bottom:-3pt;right:-3pt;"/>
|
<div class="card fistful-of-cards" style="position:relative; bottom:-3pt;right:-3pt;"/>
|
||||||
@ -105,7 +95,8 @@ export default {
|
|||||||
goldRushDesc: null,
|
goldRushDesc: null,
|
||||||
can_gold_rush_discard: false,
|
can_gold_rush_discard: false,
|
||||||
gold_rush_discount: 0,
|
gold_rush_discount: 0,
|
||||||
current_stations: [],
|
currentStations: [],
|
||||||
|
currentTrain: [],
|
||||||
}),
|
}),
|
||||||
sockets: {
|
sockets: {
|
||||||
self(self){
|
self(self){
|
||||||
@ -140,7 +131,9 @@ export default {
|
|||||||
this.goldRushCards = JSON.parse(cards)
|
this.goldRushCards = JSON.parse(cards)
|
||||||
},
|
},
|
||||||
stations(stations) {
|
stations(stations) {
|
||||||
this.current_stations = JSON.parse(stations)
|
let msg = JSON.parse(stations)
|
||||||
|
this.currentStations = msg.stations
|
||||||
|
this.currentTrain = msg.current_train
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -182,6 +175,12 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
trainPieceForStation(i) {
|
||||||
|
let index = this.currentTrain.length-5-i;
|
||||||
|
if (index < 0 || index >= this.currentTrain.length)
|
||||||
|
return null;
|
||||||
|
return this.currentTrain[index];
|
||||||
|
},
|
||||||
action(pile) {
|
action(pile) {
|
||||||
if (this.pending_action !== false && this.pending_action < 2) {
|
if (this.pending_action !== false && this.pending_action < 2) {
|
||||||
// console.log('action')
|
// console.log('action')
|
||||||
|
Loading…
Reference in New Issue
Block a user