diff --git a/agot-bg-game-server/src/client/CombatInfoComponent.tsx b/agot-bg-game-server/src/client/CombatInfoComponent.tsx index 59eb9e1d6..ea6d2964a 100644 --- a/agot-bg-game-server/src/client/CombatInfoComponent.tsx +++ b/agot-bg-game-server/src/client/CombatInfoComponent.tsx @@ -123,8 +123,8 @@ export default class CombatInfoComponent extends Component - :
} - + :
+ }
@@ -139,7 +139,8 @@ export default class CombatInfoComponent extends Component - :
} + :
+ }
diff --git a/agot-bg-game-server/src/client/GameLogListComponent.tsx b/agot-bg-game-server/src/client/GameLogListComponent.tsx index e4fcd6df1..c25198033 100644 --- a/agot-bg-game-server/src/client/GameLogListComponent.tsx +++ b/agot-bg-game-server/src/client/GameLogListComponent.tsx @@ -793,7 +793,7 @@ export default class GameLogListComponent extends Component - Melisandre: House {house.name} decided to return + Melisandre: House {house.name} discarded {houseCard.combatStrength} Power token{houseCard.combatStrength != 1 ? "s" : ""} to return {houseCard.name} to hand.

; } @@ -1376,7 +1376,7 @@ export default class GameLogListComponent extends Component{vassals.length > 0 ? (<>House {house.name} claimed {joinReactNodes(vassals.map(v => {v.name}), ", ")} as - vassal{vassals.length > 0 && "s"}.) + vassal{vassals.length > 1 && "s"}.) : (<>House {house.name} has declined to command a vassal and has handed their set of vassal order tokens to the next player on the Iron Throne track.) }

; diff --git a/agot-bg-game-server/src/client/HouseRowComponent.tsx b/agot-bg-game-server/src/client/HouseRowComponent.tsx index fa2c697d0..18a19fc98 100644 --- a/agot-bg-game-server/src/client/HouseRowComponent.tsx +++ b/agot-bg-game-server/src/client/HouseRowComponent.tsx @@ -37,6 +37,8 @@ import HouseIconComponent from "./game-state-panel/utils/HouseIconComponent"; import ThematicDraftHouseCardsGameState from "../common/ingame-game-state/thematic-draft-house-cards-game-state/ThematicDraftHouseCardsGameState"; import { toast } from "react-toastify"; import getUserLinkOrLabel from "./utils/getIngameUserLinkOrLabel"; +import CombatGameState from "../common/ingame-game-state/action-game-state/resolve-march-order-game-state/combat-game-state/CombatGameState"; +import houseCardsBackImages from "./houseCardsBackImages"; interface HouseRowComponentProps { house: House; @@ -114,9 +116,7 @@ export default class HouseRowComponent extends Component let player: Player | null = null; let clock: number | null = null; - const showAllOtherPlayerHouseCards = !this.ingame.hasChildGameState(ThematicDraftHouseCardsGameState); - - try { + try { if (!isVassal) { player = this.player; isWaitedFor = this.ingame.getWaitedUsers().includes(player.user); @@ -298,40 +298,7 @@ export default class HouseRowComponent extends Component )} - {!isVassal ? - (showAllOtherPlayerHouseCards || this.props.gameClient.doesControlHouse(this.house)) && - _.sortBy(this.house.houseCards.values, hc => hc.combatStrength).map(hc => ( - - {hc.state == HouseCardState.AVAILABLE ? ( - - ) : ( - - )} - - )) - : _.sortBy(this.game.vassalHouseCards.values, hc => hc.combatStrength).map(hc => ( - - {hc.state == HouseCardState.AVAILABLE ? ( - - ) : ( - - )} - - ))} + {this.renderHouseCards(isVassal)} {this.house.laterHouseCards != null && !isVassal && @@ -358,6 +325,55 @@ export default class HouseRowComponent extends Component ; } + private renderHouseCards(isVassal: boolean): ReactNode { + const showAllOtherPlayerHouseCards = !this.ingame.hasChildGameState(ThematicDraftHouseCardsGameState); + + return !isVassal + ? (showAllOtherPlayerHouseCards || this.props.gameClient.doesControlHouse(this.house)) + ? this.renderPlayerHouseCards() + : null + : _.sortBy(this.game.vassalHouseCards.values, hc => hc.combatStrength).map(hc => ( + + {hc.state == HouseCardState.AVAILABLE ? ( + + ) : ( + + )} + + )); + } + + renderPlayerHouseCards(): ReactNode { + const combat = this.ingame.hasChildGameState(CombatGameState) ? this.ingame.getChildGameState(CombatGameState) as CombatGameState : null; + const isCommandingVassalInCombat = combat?.isCommandingVassalInCombat(this.house) ?? false; + + return isCommandingVassalInCombat + ? _.range(0, 3).map(i => +
+ ) + : _.sortBy(this.house.houseCards.values, hc => hc.combatStrength).map(hc => ( + + {hc.state == HouseCardState.AVAILABLE ? ( + + ) : ( + + )} + + )); + } + renderVassalDropDownItems(): ReactNode { const ingame = this.props.ingame; const {result, reason} = ingame.canLaunchReplaceVassalVote(this.props.gameClient.authenticatedUser, this.house); diff --git a/agot-bg-game-server/src/client/game-state-panel/ChooseHouseCardComponent.tsx b/agot-bg-game-server/src/client/game-state-panel/ChooseHouseCardComponent.tsx index c0e23cf32..e7cf05c35 100644 --- a/agot-bg-game-server/src/client/game-state-panel/ChooseHouseCardComponent.tsx +++ b/agot-bg-game-server/src/client/game-state-panel/ChooseHouseCardComponent.tsx @@ -124,10 +124,11 @@ export default class ChooseHouseCardComponent extends Component { if (!this.burnValyrianSteelBlade && !window.confirm( - "Are you sure you want to use the VSB right now without knowing which House card the opponent has selected?\n\n" - + "This could be useful, for example, if you think Doran Martell or Ser Gerris Drinkwater will take your blade soon. " - + "Then it might make sense to burn the blade now in any case, because the game might not ask you later " - + "if the blade can't be used usefully." + "Are you sure you want to pre-mark the Valyrian Steel Blade for use without knowing which House card the opponent has selected?\n\n" + + "This could be useful if you anticipate effects like those of Doran Martell or Ser Gerris Drinkwater, " + + "potentially causing you to lose your first-place position on the fiefdoms track.\n" + + "However, exercise caution, as facing Doran in this battle would render it too late to hand over a used blade. " + + "Doran's immediate effect takes precedence and transfers the blade before you have the chance to burn it." )) { return; } diff --git a/agot-bg-game-server/src/common/ingame-game-state/action-game-state/resolve-march-order-game-state/combat-game-state/CombatGameState.ts b/agot-bg-game-server/src/common/ingame-game-state/action-game-state/resolve-march-order-game-state/combat-game-state/CombatGameState.ts index 615ec7910..cee1b40cf 100644 --- a/agot-bg-game-server/src/common/ingame-game-state/action-game-state/resolve-march-order-game-state/combat-game-state/CombatGameState.ts +++ b/agot-bg-game-server/src/common/ingame-game-state/action-game-state/resolve-march-order-game-state/combat-game-state/CombatGameState.ts @@ -572,6 +572,11 @@ export default class CombatGameState extends GameState< } } + isCommandingVassalInCombat(commanderHouse: House): boolean { + return (this.ingameGameState.isVassalHouse(this.attacker) && this.ingameGameState.getControllerOfHouse(this.attacker).house == commanderHouse) + || (this.ingameGameState.isVassalHouse(this.defender) && this.ingameGameState.getControllerOfHouse(this.defender).house == commanderHouse); + } + isCommandingHouseInCombat(commanderHouse: House): boolean { return this.ingameGameState.getControllerOfHouse(this.attacker).house == commanderHouse || this.ingameGameState.getControllerOfHouse(this.defender).house == commanderHouse; diff --git a/agot-bg-game-server/src/common/ingame-game-state/vote-system/VoteType.ts b/agot-bg-game-server/src/common/ingame-game-state/vote-system/VoteType.ts index e37fb274b..ad9fab1a6 100644 --- a/agot-bg-game-server/src/common/ingame-game-state/vote-system/VoteType.ts +++ b/agot-bg-game-server/src/common/ingame-game-state/vote-system/VoteType.ts @@ -182,6 +182,10 @@ export class ExtendPlayerClocks extends VoteType { return "extend all player clocks by 15 minutes"; } + getPositiveCountToPass(vote: Vote): number { + return vote.participatingHouses.length; + } + executeAccepted(vote: Vote): void { const ingame = vote.ingame;