Skip to content

Commit

Permalink
Merge pull request #1853 from gereon77/multiple-things
Browse files Browse the repository at this point in the history
Multiple things
  • Loading branch information
gereon77 authored Jul 6, 2024
2 parents d29cd3c + b2faddf commit 7a8f951
Show file tree
Hide file tree
Showing 19 changed files with 152 additions and 27 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion agot-bg-game-server/src/client/EntireGameComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ export default class EntireGameComponent extends Component<EntireGameComponentPr
placement="auto"
overlay={
<Tooltip id="evolution-active-tooltip">
From round <b>5</b> onwards, each house returns its alternative deck when the last house card has been played.
From round <b>{this.settings.houseCardsEvolutionRound}</b> onwards, each house returns its alternative deck when the last house card has been played.
</Tooltip>}
popperConfig={{ modifiers: [preventOverflow] }}
>
Expand Down
10 changes: 9 additions & 1 deletion agot-bg-game-server/src/client/GameLogListComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -850,10 +850,18 @@ export default class GameLogListComponent extends Component<GameLogListComponent
const house = this.game.houses.get(data.house);
const affectedHouse = this.game.houses.get(data.affectedHouse);
const influenceTrack = this.game.getNameInfluenceTrack(data.influenceTrack);
const skippedHouse = data.skippedHouse
? this.game.houses.get(data.skippedHouse)
: null;

const skippedAddition = skippedHouse
? <>, causing House <b>{skippedHouse.name}</b>&apos;s turn to be skipped
until the next pass of the <b>Iron Throne</b> track</>
: null;

return <p>
<b>Doran Martell</b>: House <b>{house.name}</b> decided to move House <b>
{affectedHouse.name}</b> to the bottom of the <b>{influenceTrack}</b> track.
{affectedHouse.name}</b> to the bottom of the <b>{influenceTrack}</b> track{skippedAddition}.
</p>;
}
case "ser-gerris-drinkwater-used": {
Expand Down
39 changes: 38 additions & 1 deletion agot-bg-game-server/src/client/GameSettingsComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ export default class GameSettingsComponent extends Component<GameSettingsCompone
onChange={() => this.changeGameSettings(() => this.gameSettings.asosHouseCards = !this.gameSettings.asosHouseCards)}
/>
</Col>
<Col xs="12">
<Col xs="auto" className="d-flex justify-content-between">
<FormCheck
id="decks-evolution-setting"
type="switch"
Expand All @@ -363,6 +363,29 @@ export default class GameSettingsComponent extends Component<GameSettingsCompone
checked={this.gameSettings.houseCardsEvolution}
onChange={() => this.changeGameSettings(() => this.gameSettings.houseCardsEvolution = !this.gameSettings.houseCardsEvolution)}
/>
{
this.gameSettings.houseCardsEvolution && (
<div>
<span className="ml-1">- Round:</span>
<select id="decks-evolution-setting-round"
className="ml-2"
value={this.gameSettings.houseCardsEvolutionRound}
onChange={(e) => this.onHouseCardsEvolutionRoundChange(e.target.value)}
style={{marginBottom: "8px"}}
>
<option key="2" value={2}>2</option>
<option key="3" value={3}>3</option>
<option key="4" value={4}>4</option>
<option key="5" value={5}>5</option>
<option key="6" value={6}>6</option>
<option key="7" value={7}>7</option>
<option key="8" value={8}>8</option>
<option key="9" value={9}>9</option>
<option key="10" value={10}>10</option>
</select>
</div>
)
}
</Col>
{this.props.entireGame.isCustomBalancingOptionAvailable(this.gameSettings) && <Col xs="12">
<FormCheck
Expand Down Expand Up @@ -991,6 +1014,20 @@ export default class GameSettingsComponent extends Component<GameSettingsCompone
this.changeGameSettings();
}

onHouseCardsEvolutionRoundChange(newVal: string): void {
if (!this.canChangeGameSettings) {
return;
}

if (!this.gameSettings.houseCardsEvolution) {
return;
}

this.gameSettings.houseCardsEvolutionRound = parseInt(newVal);

this.changeGameSettings();
}

onRandomChosenHousesChange(): void {
if (!this.entireGame.gameSettings.randomChosenHouses && this.entireGame.gameSettings.randomHouses) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ export default class PlanningComponent extends Component<GameStateComponentProps
render(): ReactNode {
return (
<>
{this.props.gameState.revealeadWesterosCards.length > 0 && (
{this.props.gameState.revealedWesterosCards.length > 0 && (
<Row className="justify-content-around mb-2">
{this.props.gameState.revealeadWesterosCards.map((wc, i) => (
{this.props.gameState.revealedWesterosCards.map((wc, i) => (
<Col xs="auto" key={`planning_revealed-wcs_${wc.id}_${i}`}>
<WesterosCardComponent
cardType={wc.type}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ export default class ResolveSinglePlaceOrdersForVassalsComponent extends Compone
const readyState = this.singlePlaceOrders.placeOrdersGameState.canSubmit(this.props.gameClient.authenticatedPlayer);

if (readyState.reason == "not-all-regions-filled") {
if (!window.confirm("You may place up to two order tokens. Are you sure you want to continue with fewer?")) {
if (!window.confirm("You may place up to two order tokens per vassal. Are you sure you want to continue with fewer?")) {
return;
}
}
Expand Down
2 changes: 2 additions & 0 deletions agot-bg-game-server/src/client/westerosCardImages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import feastForCrows from "../../public/images/westeros-cards/FeastForCrows.png"
import gameOfThrones from "../../public/images/westeros-cards/GameOfThrones.png";
import lastDaysOfSummer from "../../public/images/westeros-cards/LastDaysOfSummer.png";
import lastDaysOfSummerII from "../../public/images/westeros-cards/LastDaysOfSummerII.png";
import denseFog from "../../public/images/westeros-cards/DenseFog.png";
import mustering from "../../public/images/westeros-cards/Mustering.png";
import putToTheSword from "../../public/images/westeros-cards/PutToTheSword.png";
import rainsOfAutumn from "../../public/images/westeros-cards/RainsOfAutumn.png";
Expand Down Expand Up @@ -64,6 +65,7 @@ const westerosCardImages = new BetterMap([
["storm-of-swords", stormOfSwords],
["web-of-lies", webOfLies],
["wildlings-attack", wildlingsAttackIII],
['dense-fog', denseFog],
])],
[3, new BetterMap([
["domestic-disputes", domesticDisputes],
Expand Down
3 changes: 2 additions & 1 deletion agot-bg-game-server/src/common/EntireGame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default class EntireGame extends GameState<null, LobbyGameState | IngameG
lastMessageReceivedAt: Date | null = null;

@observable gameSettings: GameSettings = { setupId: "mother-of-dragons", playerCount: 8, pbem: true, onlyLive: false, startWhenFull: false, private: false,
addPortToTheEyrie: false, adwdHouseCards: false, asosHouseCards: false, houseCardsEvolution: false,
addPortToTheEyrie: false, adwdHouseCards: false, asosHouseCards: false, houseCardsEvolution: false, houseCardsEvolutionRound: 5,
vassals: true, ironBank: true, seaOrderTokens: true, allowGiftingPowerTokens: true, randomVassalAssignment: false, customBalancing: false,
randomHouses: false, randomChosenHouses: false, tidesOfBattle: false, removeTob3: false, removeTobSkulls: false, limitTob2: false,
draftHouseCards: false, thematicDraft: false, limitedDraft: false, randomDraft: false, blindDraft: false, draftMap: false, selectedDraftDecks: HouseCardDecks.All,
Expand Down Expand Up @@ -827,6 +827,7 @@ export interface GameSettings {
randomVassalAssignment: boolean;
customBalancing: boolean;
houseCardsEvolution: boolean;
houseCardsEvolutionRound: number;
initialLiveClock: number;
noPrivateChats: boolean;
tournamentMode: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export default class IngameGameState extends GameState<
@observable ordersOnBoard: BetterMap<Region, Order> = new BetterMap();
@observable visibleRegionsPerPlayer: BetterMap<Player, Region[]> = new BetterMap();
@observable publicVisibleRegions: Region[] = [];
unitVisibilityRange = 1;

votes: BetterMap<string, Vote> = new BetterMap();
@observable paused: Date | null = null;
Expand Down Expand Up @@ -336,6 +337,7 @@ export default class IngameGameState extends GameState<
});

if (this.fogOfWar) {
this.unitVisibilityRange = 1;
this.publicVisibleRegions = [];
this.entireGame.users.values.filter(u => u.connected).forEach(u => {
this.entireGame.sendMessageToClients([u], {
Expand Down Expand Up @@ -1658,7 +1660,7 @@ export default class IngameGameState extends GameState<
return this.visibleRegionsPerPlayer.get(player);
}

calculateVisibleRegionsForPlayer(player: Player | null, unitVisibilityRange = 1): Region[] {
calculateVisibleRegionsForPlayer(player: Player | null): Region[] {
if (!this.fogOfWar || !player) {
return [];
}
Expand All @@ -1676,7 +1678,7 @@ export default class IngameGameState extends GameState<
const checkedRegions: Region[] = [];

// Additionally we see regions adjacents to our regions with units
for(let i=0; i<unitVisibilityRange; i++) {
for(let i=0; i < this.unitVisibilityRange; i++) {
const additionalRegionsToCheck: Region[] = [];
for (let j=0; j<regionsWithUnits.length; j++) {
const region = regionsWithUnits[j];
Expand All @@ -1689,7 +1691,7 @@ export default class IngameGameState extends GameState<
}
}

if (unitVisibilityRange > 1) {
if (this.unitVisibilityRange > 1) {
regionsWithUnits.push(...additionalRegionsToCheck);
regionsWithUnits = _.uniq(regionsWithUnits);
}
Expand Down Expand Up @@ -2306,6 +2308,7 @@ export default class IngameGameState extends GameState<
? this.visibleRegionsPerPlayer.entries.map(([p, regions]) => [p.user.id, regions.map(r => r.id)])
: this.visibleRegionsPerPlayer.entries.filter(([p, _regions]) => p.user == user).map(([p, regions]) => [p.user.id, regions.map(r => r.id)]),
publicVisibleRegions: this.publicVisibleRegions.map(r => r.id),
unitVisibilityRange: this.unitVisibilityRange,
oldPlayerIds: this.oldPlayerIds,
replacerIds: this.replacerIds,
timeoutPlayerIds: this.timeoutPlayerIds,
Expand All @@ -2332,6 +2335,7 @@ export default class IngameGameState extends GameState<
data.visibleRegionsPerPlayer.map(([uid, rids]) => [ingameGameState.players.get(entireGame.users.get(uid)), rids.map(rid => ingameGameState.world.regions.get(rid))])
);
ingameGameState.publicVisibleRegions = data.publicVisibleRegions.map(rid => ingameGameState.world.regions.get(rid));
ingameGameState.unitVisibilityRange = data.unitVisibilityRange;
ingameGameState.oldPlayerIds = data.oldPlayerIds;
ingameGameState.replacerIds = data.replacerIds;
ingameGameState.timeoutPlayerIds = data.timeoutPlayerIds;
Expand Down Expand Up @@ -2378,6 +2382,7 @@ export interface SerializedIngameGameState {
players: SerializedPlayer[];
visibleRegionsPerPlayer: [string, string[]][];
publicVisibleRegions: string[];
unitVisibilityRange: number;
oldPlayerIds: string[];
replacerIds: string[];
timeoutPlayerIds: string[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,31 @@ export default class DoranMartellAbilityGameState extends GameState<
onSimpleChoiceGameStateEnd(choice: number, resolvedAutomatically: boolean): void {
const enemy = this.combatGameState.getEnemy(this.childGameState.house);

// Remember the house that currently would resolve next march order
const nextHouse = this.getHouseThatWouldResolveNextMarchOrder();

// Put the enemy at the end of the influence track
const influenceTrack = this.game.getInfluenceTrackByI(choice);
const newInfluenceTrack = _.concat(_.without(influenceTrack, enemy), enemy);
this.ingame.setInfluenceTrack(choice, newInfluenceTrack);

if (choice == 0) {
// Add the skippedTurnForHouse property if next player in order loses their turn.
const nextHouseAfterDoran = this.getHouseThatWouldResolveNextMarchOrder();

if (nextHouse && nextHouse != nextHouseAfterDoran) {
this.ingame.log({
type: "doran-used",
house: this.childGameState.house.id,
affectedHouse: enemy.id,
influenceTrack: choice,
skippedHouse: nextHouse.id,
}, resolvedAutomatically);
this.parentGameState.onHouseCardResolutionFinish(this.childGameState.house);
return;
}
}

this.ingame.log({
type: "doran-used",
house: this.childGameState.house.id,
Expand Down Expand Up @@ -62,6 +82,28 @@ export default class DoranMartellAbilityGameState extends GameState<
);
}

getHouseThatWouldResolveNextMarchOrder(): House | null {
const turnOrder = this.game.getTurnOrder();
const numberOfHouses = turnOrder.length;

let currentIndex = this.combatGameState.parentGameState.currentTurnOrderIndex;

// Check each house in order to find one that has an available March order.
// Check at most once for each house
for (let i = 0;i < numberOfHouses;i++) {
currentIndex = (currentIndex + 1) % numberOfHouses;
const currentHouseToCheck = turnOrder[currentIndex];

const regions = this.combatGameState.actionGameState.getRegionsWithMarchOrderOfHouse(currentHouseToCheck);
if (regions.length > 0) {
return currentHouseToCheck;
}
}

// If no house has any march order available, return null
return null;
}

onPlayerMessage(player: Player, message: ClientMessage): void {
this.childGameState.onPlayerMessage(player, message);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ export default class PostCombatGameState extends GameState<
if (house.houseCards.values.every(hc => hc.state == HouseCardState.USED)) {
if (this.entireGame.gameSettings.houseCardsEvolution
&& house.laterHouseCards != null
&& this.combat.ingameGameState.game.turn >= 5) {
&& this.combat.ingameGameState.game.turn >= this.entireGame.gameSettings.houseCardsEvolutionRound) {

// We need to swap to the new deck now
this.game.previousPlayerHouseCards.set(house, new BetterMap());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ interface DoranUsed {
house: string;
affectedHouse: string;
influenceTrack: number;
skippedHouse?: string;
}

interface SerGerrisDrinkwaterUsed {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,14 +410,13 @@ export default function createGame(ingame: IngameGameState, housesToCreate: stri
game.westerosDecks = baseGameData.westerosCards.map(westerosDeckData => {
const cards: WesterosCard[] = [];
westerosDeckData.forEach((westerosCardData: WesterosCardData) => {
const westerosCardType = westerosCardTypes.get(westerosCardData.type);
const quantity = westerosCardData.quantity ? westerosCardData.quantity : 1;
for (let i = 0;i < quantity;i++) {
const id = ++lastWesterosCardId;

cards.push(new WesterosCard(id, westerosCardType));
}
});
const westerosCardType = westerosCardTypes.get(westerosCardData.type);
const quantity = westerosCardData.quantity ? westerosCardData.quantity : 1;
for (let i = 0;i < quantity;i++) {
const id = ++lastWesterosCardId;
cards.push(new WesterosCard(id, westerosCardType));
}
});

return shuffleInPlace(cards);
});
Expand Down Expand Up @@ -467,6 +466,12 @@ export default function createGame(ingame: IngameGameState, housesToCreate: stri
game.westerosDecks[0] = cards;
}

if (gameSettings.fogOfWar) {
const id = ++lastWesterosCardId;
game.westerosDecks[2].push(new WesterosCard(id, westerosCardTypes.get("dense-fog")));
shuffleInPlace(game.westerosDecks[2]);
}

game.winterIsComingHappened = [];
game.westerosDecks.forEach(_wd => game.winterIsComingHappened.push(false));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import WesterosCardType from "./WesterosCardType";
import WesterosGameState from "../../westeros-game-state/WesterosGameState";

export default class DenseFogWesterosCardType extends WesterosCardType {
execute(westeros: WesterosGameState): void {
westeros.ingame.unitVisibilityRange = 0;
westeros.ingame.updateVisibleRegions(true);
westeros.onWesterosCardEnd();
}
}
Loading

0 comments on commit 7a8f951

Please sign in to comment.