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.gold_rush.shop_cards as grc
|
||||
import bang.expansions.train_robbery.stations as trs
|
||||
import bang.expansions.train_robbery.trains as trt
|
||||
from globals import G
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -36,6 +37,8 @@ class Deck:
|
||||
self.event_cards: List[ce.CardEvent] = []
|
||||
self.event_cards_wildwestshow: List[ce.CardEvent] = []
|
||||
self.stations: List[trs.StationCard] = []
|
||||
self.train_pile: List[trt.TrainCard] = []
|
||||
self.current_train: List[trt.TrainCard] = []
|
||||
endgame_cards: List[ce.CardEvent] = []
|
||||
if "fistful_of_cards" in game.expansions:
|
||||
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())
|
||||
if "train_robbery" in game.expansions:
|
||||
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:
|
||||
game.rng.shuffle(self.event_cards)
|
||||
self.event_cards = self.event_cards[:12]
|
||||
@ -109,6 +116,15 @@ class Deck:
|
||||
self.shop_cards[i].reset_card()
|
||||
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:
|
||||
return self.cards[:n_cards]
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
import random
|
||||
from bang.cards import Card
|
||||
|
||||
|
||||
class TrainCard(Card):
|
||||
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.is_equipment = True
|
||||
self.is_locomotive = is_locomotive
|
||||
@ -92,10 +93,212 @@ class Leland(TrainCard):
|
||||
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):
|
||||
"""Scartalo: ogni altro giocatore deve scartare una carta che ha in gioco."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("Circus Wagon", is_locomotive=True)
|
||||
self.icon = "🚋🎪"
|
||||
|
||||
def play_card(self, player, against=None, _with=None) -> bool:
|
||||
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": "/meinfo", "help": "Get player 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": "/cardinfo", "help": "Get card data - sample /cardinfo handindex"},
|
||||
{"cmd": "/mebot", "help": "Toggles bot mode"},
|
||||
@ -844,6 +846,7 @@ class Game:
|
||||
)
|
||||
):
|
||||
self.deck.flip_event()
|
||||
self.deck.move_train_forward()
|
||||
if self.check_event(ce.RouletteRussa):
|
||||
self.is_russian_roulette_on = True
|
||||
if self.players[self.turn].get_banged(self.deck.event_cards[0]):
|
||||
@ -925,7 +928,13 @@ class Game:
|
||||
G.sio.emit(
|
||||
"stations",
|
||||
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):
|
||||
|
@ -1089,6 +1089,21 @@ def chat_message(sid, msg, pl=None):
|
||||
"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():
|
||||
sio.emit("mount_status", room=sid)
|
||||
elif "/meinfo" in msg:
|
||||
|
@ -355,6 +355,9 @@ export default {
|
||||
transform: scaleX(-1);
|
||||
/* filter: grayscale(1); */
|
||||
}
|
||||
.train-piece .suit, .train-piece .expansion {
|
||||
display: none;
|
||||
}
|
||||
.train-piece h4 {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
|
@ -11,18 +11,8 @@
|
||||
<card :card="goldRushCardBack" :donotlocalize="true" class="gold-rush back last-event" @click.native="goldRushShopOpen = !goldRushShopOpen"/>
|
||||
</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;`" >
|
||||
<station-card v-for="station, i in current_stations" :key="station.name" :card="station" :price="station.price" :trainPiece="
|
||||
i == 2 ? {
|
||||
name: 'Iron House',
|
||||
icon: '🚂',
|
||||
back: true,
|
||||
} : i > 2 ? {
|
||||
name: 'Passenger Car',
|
||||
icon: '🚃',
|
||||
back: true,
|
||||
} : undefined
|
||||
"/>
|
||||
<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 currentStations" :key="station.name" :card="{name:i}" :price="station.price" :trainPiece="trainPieceForStation(i)"/>
|
||||
</div>
|
||||
<div v-if="eventCard" style="position:relative">
|
||||
<div class="card fistful-of-cards" style="position:relative; bottom:-3pt;right:-3pt;"/>
|
||||
@ -105,7 +95,8 @@ export default {
|
||||
goldRushDesc: null,
|
||||
can_gold_rush_discard: false,
|
||||
gold_rush_discount: 0,
|
||||
current_stations: [],
|
||||
currentStations: [],
|
||||
currentTrain: [],
|
||||
}),
|
||||
sockets: {
|
||||
self(self){
|
||||
@ -140,7 +131,9 @@ export default {
|
||||
this.goldRushCards = JSON.parse(cards)
|
||||
},
|
||||
stations(stations) {
|
||||
this.current_stations = JSON.parse(stations)
|
||||
let msg = JSON.parse(stations)
|
||||
this.currentStations = msg.stations
|
||||
this.currentTrain = msg.current_train
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
@ -182,6 +175,12 @@ export default {
|
||||
},
|
||||
},
|
||||
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) {
|
||||
if (this.pending_action !== false && this.pending_action < 2) {
|
||||
// console.log('action')
|
||||
|
Loading…
Reference in New Issue
Block a user