Skip to content

Commit

Permalink
also add new animations
Browse files Browse the repository at this point in the history
  • Loading branch information
albertoxamin committed Jun 14, 2024
1 parent c171739 commit a474dfb
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 20 deletions.
32 changes: 24 additions & 8 deletions backend/bang/expansions/train_robbery/trains.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def __init__(self, name: str, is_locomotive: bool = False):
self.is_locomotive = is_locomotive
self.expansion = "train_robbery"
self.type = "train"
self.implemented = True


# Circus Wagon: gli altri giocatori
Expand Down Expand Up @@ -122,7 +123,7 @@ def play_card(self, player, against=None, _with=None) -> bool:


class Caboose(TrainCard):
"""Pro scartare un altra tua carta bordo blu incuso un vagone come se fosse un Mancato!"""
"""Puoi scartare un altra tua carta bordo blu incuso un vagone come se fosse un Mancato!"""

def __init__(self):
super().__init__("Caboose")
Expand Down Expand Up @@ -177,18 +178,21 @@ def choose_circus_wagon(cls, player: 'Player', card_index):


class CoalHopper(TrainCard):
"""Scartalo: pesca una carta e scarta un vagone in gioco davanti a un giocatore a ma scelta."""
"""Scartalo: pesca una carta e scarta un vagone in gioco davanti a un giocatore a tua scelta."""

def __init__(self):
super().__init__("Coal Hopper")
self.icon = "🚋🔥"
self.need_target = True

def play_card(self, player, against=None, _with=None) -> bool:
if against is not None and len(player.game.get_player_named(against).equipment) > 0:
player.game.steal_discard(player, against, self)
return True


class DiningCar(TrainCard):
"""A inizio turno, "estrai!": se è Cnori, recuperi I punto vita."""
"""A inizio turno, "estrai!": se è Cuori, recuperi I punto vita."""

def __init__(self):
super().__init__("Dining Car")
Expand All @@ -214,14 +218,15 @@ def play_card(self, player, against=None, _with=None) -> bool:


class GhostCar(TrainCard):
"""Giocalo su chiunque tranne lo Sceritfo. Se vieni eliminato, invece resti in gioco, ma non puo guadagnare ne perdere punti vita."""
"""Giocalo su chiunque tranne lo Sceritfo. Se vieni eliminato, invece resta in gioco, ma non puo guadagnare ne perdere punti vita."""

def __init__(self):
super().__init__("Ghost Car")
self.icon = "🚋👻"
self.implemented = False

def play_card(self, player, against=None, _with=None) -> bool:
return True
return False


class LoungeCar(TrainCard):
Expand All @@ -230,6 +235,7 @@ class LoungeCar(TrainCard):
def __init__(self):
super().__init__("Lounge Car")
self.icon = "🚋🛋"
self.implemented = False

def play_card(self, player, against=None, _with=None) -> bool:
return True
Expand Down Expand Up @@ -299,14 +305,23 @@ def play_card(self, player, against=None, _with=None) -> bool:


class PassengerCar(TrainCard):
"""Scartalo: pesca una carta (in mano o in gioco) da un altro giocatore"""
"""Scartalo: pesca una carta (o in mano o in gioco) da un altro giocatore"""

def __init__(self):
super().__init__("Passenger Car")
self.icon = "🚋🚶"
self.range = 99
self.need_target = True


def play_card(self, player, against=None, _with=None) -> bool:
return True
if (
against is not None
and (len(player.equipment) > 0 or len(player.equipment) > 0)
):
player.game.steal_discard(player, against, self)
return True
return False


class PrisonerCar(TrainCard):
Expand All @@ -321,7 +336,7 @@ def play_card(self, player, against=None, _with=None) -> bool:


class PrivateCar(TrainCard):
"""se non hai carte in mano. non puoi essere bersaelio di carte BANG"""
"""Se non hai carte in mano, non puoi essere bersaglio di carte BANG"""

def __init__(self):
super().__init__("Private Car")
Expand Down Expand Up @@ -376,6 +391,7 @@ def get_all_cards(rng=random):
PrivateCar(),
SleeperCar(),
]
cars = [c for c in cars if c.implemented]
rng.shuffle(cars)
return cars

Expand Down
3 changes: 2 additions & 1 deletion backend/bang/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import bang.expansions.gold_rush.shop_cards as grc
import bang.expansions.gold_rush.characters as grch
import bang.expansions.the_valley_of_shadows.cards as tvosc
import bang.expansions.train_robbery.trains as trt
from metrics import Metrics
from globals import G, PendingAction

Expand Down Expand Up @@ -558,7 +559,7 @@ def steal_discard(self, attacker: pl.Player, target_username: str, card: cs.Card
if p != attacker and p.get_discarded(
attacker,
card_name=card.name,
action="steal" if isinstance(card, cs.Panico) else "discard",
action="steal" if (isinstance(card, cs.Panico) or isinstance(card, trt.PassengerCar)) else "discard",
):
self.ready_count = 0
self.waiting_for = 1
Expand Down
42 changes: 42 additions & 0 deletions backend/bang/players.py
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,9 @@ def play_turn(self, can_play_vendetta=True, again=False):
self.has_played_bang = False
self.special_use_count = 0
self.bang_used = 0
if any((isinstance(c, trt.DiningCar) for c in self.equipment)):
if self.game.deck.pick_and_scrap().suit == cs.Suit.HEARTS:
self.lives = min(self.lives + 1, self.max_lives)
if self.game.check_event(cew.DarlingValentine):
hand = len(self.hand)
for _ in range(hand):
Expand Down Expand Up @@ -1866,6 +1869,8 @@ def barrel_pick(self):
self.expected_response.append(cs.Bang(0, 0).name)
if self.character.check(self.game, chw.BigSpencer):
self.expected_response = []
if any((isinstance(c, trt.Caboose) for c in self.equipment)):
self.expected_response.append([c.name for c in self.equipment if not c.usable_next_turn])
self.on_failed_response_cb = self.take_damage_response
self.notify_self()

Expand Down Expand Up @@ -1997,6 +2002,17 @@ def get_banged(
self.attacker = attacker
self.attacking_card = card_name
print(f"attacker -> {attacker}")
# check for trt.PrivateCar
if (card_name == "Bang!" and any(
(isinstance(c, trt.PrivateCar) for c in self.equipment)
) and len(self.hand) == 0):
self.take_no_damage_response()
G.sio.emit(
"chat_message",
room=self.game.name,
data=f"_in_private_car|{self.name}|{attacker.name}",
)
return False
if (
isinstance(attacker, Player)
and attacker.character.check(self.game, tvosch.ColoradoBill)
Expand Down Expand Up @@ -2112,6 +2128,11 @@ def get_indians(self, attacker):
(isinstance(c, grc.Calumet) for c in self.gold_rush_equipment)
):
return False
# check for trt.PrisonerCar
if any(
(isinstance(c, trt.PrisonerCar) for c in self.equipment)
):
return False
if (
not self.game.is_competitive
and not any(
Expand Down Expand Up @@ -2145,6 +2166,12 @@ def get_indians(self, attacker):
def get_dueled(self, attacker):
self.attacker = attacker
self.attacking_card = "Duello"
if any(
not self.is_my_turn and
(isinstance(c, trt.PrisonerCar) for c in self.equipment)
):
self.take_no_damage_response()
return False
if (self.game.check_event(ceh.Sermone) and self.is_my_turn) or (
not self.game.is_competitive
and not any(
Expand Down Expand Up @@ -2551,6 +2578,11 @@ def buy_gold_rush_card(self, index):
self.game.deck.shop_deck.append(card)
self.game.deck.shop_cards[index] = None
self.game.deck.fill_gold_rush_shop()
G.sio.emit(
"card_scrapped",
room=self.game.name,
data={"player": self.name, "pile": "gold_rush", "card": card.__dict__},
)
self.notify_self()

def buy_train(self, index):
Expand All @@ -2569,6 +2601,16 @@ def buy_train(self, index):
if station.check_price(self):
print(f"{station=} {train=}")
station.attached_train = train
G.sio.emit(
"chat_message",
room=self.game.name,
data=f"_bought_train|{self.name}|{station.name}|{train.name}",
)
G.sio.emit(
"card_scrapped",
room=self.game.name,
data={"player": self.name, "pile": "train_robbery", "card": train.__dict__},
)
# shift train forward
for i in range(train_index, len(self.game.deck.current_train) - 1):
self.game.deck.current_train[i] = self.game.deck.current_train[
Expand Down
1 change: 0 additions & 1 deletion backend/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -1317,7 +1317,6 @@ def get_trainrobberycards(sid):
import bang.expansions.train_robbery.trains as trt

chs = []
chs.extend(trs.get_all_stations())
chs.extend(trt.get_locomotives())
chs.extend(trt.get_all_cards())
sio.emit(
Expand Down
14 changes: 13 additions & 1 deletion frontend/src/components/Card.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default {
},
suit() {
if (this.card && !isNaN(this.card.suit)) {
let x = ["♦️", "♣️", "♥️", "♠️", "🤑"];
let x = ["♦️", "♣️", "♥️", "♠️", "🤑", "🚂"];
return x[this.card.suit];
} else if (this.card.suit) {
return this.card.suit;
Expand Down Expand Up @@ -232,6 +232,18 @@ export default {
padding: 4pt;
border-radius: 12pt;
}
.wip::after {
content: "WIP";
position: absolute;
bottom: -12pt;
right: -12pt;
background: red;
font-size: 10pt;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
font-weight: bold;
padding: 4pt;
border-radius: 12pt;
}
.avatar {
position: absolute;
width: 36pt;
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/Deck.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div >
<div class="deck">
<div class="deck" :style="`position:relative;${goldRushShopOpen?'border: 2px dashed #6a6a6a42;border-radius:8pt':''}`" v-if="goldRushCards.length > 0" >
<div class="deck" id="gold-rush-deck" :style="`position:relative;${goldRushShopOpen?'border: 2px dashed #6a6a6a42;border-radius:8pt':''}`" v-if="goldRushCards.length > 0" >
<card @pointerenter.native="()=>{setGoldRushDesc(goldRushCards[0])}" @pointerleave.native="goldRushDesc=null" :style="goldRushShopOpen?``:`position:absolute; top:0; right:0; transform: rotate(95deg) translate(30px, -40px) scale(0.6)`" v-if="goldRushCards.length > 0" :key="goldRushCards[0].name" :card="goldRushCards[0]" :class="{'shop-open':goldRushShopOpen, 'cant-play': pending_action !==2 || gold_nuggets < goldRushCards[0].number - gold_rush_discount}" @click.native="() => {buy_gold_rush_card(0)}"/>
<card @pointerenter.native="()=>{setGoldRushDesc(goldRushCards[1])}" @pointerleave.native="goldRushDesc=null" :style="goldRushShopOpen?``:`position:absolute; top:0; right:0; transform: rotate(90deg) translate(0, -40px) scale(0.6)`" v-if="goldRushCards.length > 1" :key="goldRushCards[1].name" :card="goldRushCards[1]" :class="{'shop-open':goldRushShopOpen, 'cant-play': pending_action !==2 || gold_nuggets < goldRushCards[1].number - gold_rush_discount}" @click.native="() => {buy_gold_rush_card(1)}"/>
<card @pointerenter.native="()=>{setGoldRushDesc(goldRushCards[2])}" @pointerleave.native="goldRushDesc=null" :style="goldRushShopOpen?``:`position:absolute; top:0; right:0; transform: rotate(85deg) translate(-30px, -40px) scale(0.6)`" v-if="goldRushCards.length > 2" :key="goldRushCards[2].name" :card="goldRushCards[2]" :class="{'shop-open':goldRushShopOpen, 'cant-play': pending_action !==2 || gold_nuggets < goldRushCards[2].number - gold_rush_discount}" @click.native="() => {buy_gold_rush_card(2)}"/>
Expand All @@ -11,7 +11,7 @@
<card :card="goldRushCardBack" :donotlocalize="true" class="gold-rush back last-event" @click.native="goldRushShopOpen = !goldRushShopOpen"/>
</div>
</div>
<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;`" >
<div v-if="currentStations.length > 0" id="train-robbery-deck" class="deck" :style="`position:relative;border: 2px dashed #6a6a6a42;border-radius:8pt;align-items: flex-end;flex-direction:row;`" >
<station-card @click.native="()=>{buyTrain(i)}" v-for="station, i in currentStations" :key="station.name" :card="station" :price="station.price" :trainPiece="trainPieceForStation(i)"
@pointerenter.native="()=>{setStationDesc(i)}" @pointerleave.native="stationDesc = null"/>
</div>
Expand Down
9 changes: 8 additions & 1 deletion frontend/src/components/Lobby.vue
Original file line number Diff line number Diff line change
Expand Up @@ -646,8 +646,15 @@ export default {
console.log("card_scrapped no deck");
return;
}
let decelOffset = cumulativeOffset(decel);
let phand = document.getElementById(`${data.player}-hand`);
if (data.pile == "train_robbery") {
decel = phand
phand = document.getElementById("train-robbery-deck");
} else if (data.pile == "gold_rush") {
decel = phand
phand = document.getElementById("gold-rush-deck");
}
let decelOffset = cumulativeOffset(decel);
if (!phand) {
console.log("card_scrapped no phand");
return;
Expand Down
11 changes: 8 additions & 3 deletions frontend/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
"choose_mail_car": "Choose which card to give to another player",
"choose_other_player": "Choose the player to give the card to",
"choose_sleeper_car": "Choose a card to discard for Sleeper Car",
"choose_buy_train": "Discard a card to rob the train, and get the carriage",
"chat": {
"spectators": " | A spectator is watching the game | {n} spectators are watching the game",
"chat": "Chat",
Expand Down Expand Up @@ -157,7 +158,9 @@
"choose_emporio": ";{0}; has chosen ;{1}; from General Store.",
"shotgun_scrap": "When the shotgun hit ;{0}; a card flew away from his hand (;{1};)",
"taglia_reward": "💰 ;{1}; got a card from the bounty on ;{0};",
"snake_bit": "🐍 ;{0}; was bitten by the Rattle Snake."
"snake_bit": "🐍 ;{0}; was bitten by the Rattle Snake.",
"in_private_car": "🚋💁🏻 ;{0}; is in a private car and couldn't get Bang!ed by ;{1};",
"bought_train": "🚂 ;{0}; robbed the train at ;{1}; and got the ;{2};"
},
"foc": {
"leggedelwest": "He must play this card on this turn if possible."
Expand Down Expand Up @@ -942,7 +945,7 @@
},
"Dining Car": {
"name": "Dining Car",
"desc": "At the beginning of your turn, \"draw!\": if it's Hearts, regain 1 life point."
"desc": "At the beginning of your turn, \"pick!\": if it's Hearts, regain 1 life point."
},
"Express Car": {
"name": "Express Car",
Expand Down Expand Up @@ -1034,7 +1037,9 @@
"highnooncards": "High Noon - Event Cards",
"foccards": "Fistful of Cards - Event Cards",
"goldrushcards": "Gold Rush Cards",
"valleyofshadowscards": "The Valley of Shadows Cards"
"valleyofshadowscards": "The Valley of Shadows Cards",
"wildwestshowcards": "Wild West Show Cards",
"trainrobberycards": "Train Robbery Cards"
},
"theme": {
"sepia": "Sepia",
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/i18n/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@
"choose_emporio": ";{0}; ha scelto ;{1}; da Emporio.",
"shotgun_scrap": "Quando lo shotgun ha colpito ;{0}; gli ha tolto una carta (;{1};)",
"taglia_reward": "💰 ;{1}; ha ottenuto ricompensa dalla taglia su ;{0};",
"snake_bit": "🐍 ;{0}; è stato morso dal Serpente a Sonagli."
"snake_bit": "🐍 ;{0}; è stato morso dal Serpente a Sonagli.",
"in_private_car": "🚋💁🏻 ;{0}; è in una carrozza privata e non è stato attaccato da ;{1};"
},
"foc": {
"leggedelwest": "Ed è obbligato a usarla nel suo turno, se possibile"
Expand Down Expand Up @@ -938,7 +939,7 @@
},
"Dining Car": {
"name": "Dining Car",
"desc": "A inizio turno, \"estrai!\": se è Cnori, recuperi I punto vita."
"desc": "A inizio turno, \"estrai!\": se è Cuori, recuperi I punto vita."
},
"Express Car": {
"name": "Express Car",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/utils/emoji-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export const emojiMap = {
'fistful_of_cards': '🎴',
'the_valley_of_shadows': '👻',
'wild_west_show': '🎪',
'train_robbery': '🚂',
}
2 changes: 1 addition & 1 deletion frontend/src/utils/expansions-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ export const expansionsMap = {
icon: '🚂',
back: true,
expansion: 'train-roobbery',
status: 'alpha',
status: 'wip',
}
}

0 comments on commit a474dfb

Please sign in to comment.