add trains

This commit is contained in:
Alberto Xamin 2023-04-20 21:27:19 +01:00 committed by Alberto Xamin
parent 9e89092090
commit 1ee92afb9a
6 changed files with 261 additions and 16 deletions

View File

@ -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]

View File

@ -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

View File

@ -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):

View File

@ -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:

View File

@ -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;

View File

@ -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')