- // ==UserScript==
- // @name BGA Pythia - 7 Wonders game helper
- // @description Visual aid that extends BGA game interface with useful information
- // @namespace https://github.com/dpavliuchkov/bga-pythia
- // @author https://github.com/dpavliuchkov
- // @version 1.3.3
- // @license MIT
- // @include *boardgamearena.com/*
- // @grant none
- // ==/UserScript==
- //
- // On boardgamearena.com, you can play an exciting board game of 7 wonders.
- // However, it is hard to remember which cards each player has. Pythia has
- // godlike powers and will share this information with you. It will also
- // display total player's score based on the current shields situation.
- // And it will mark leader and runner up players and their boards. And
- // Pythia will calculate how much points and coins some cards are worth to you.
- // Works with Tampermonkey only.
- // ==/UserScript==
-
- // System variables - don't edit
- const Enable_Logging = false;
- const Is_Inside_Game = /\?table=[0-9]*/.test(window.location.href);
- const Cards_Image = "https://x.boardgamearena.net/data/themereleases/current/games/sevenwonders/200914-1526/img/cards.jpg";
- const Cards_Image_V2 = "https://x.boardgamearena.net/data/themereleases/current/games/sevenwonders/200914-1526/img/cards_v2.jpg";
- const BGA_Player_Board_Id_Prefix = "player_board_wrap_";
- const BGA_Player_Score_Id_Prefix = "player_score_";
- const Card_Worth_Id_Prefix = "pythia_card_worth_container_";
- const Discard_Card_Worth_Id_Prefix = "pythia_discard_card_worth_container_";
- const Card_Worth_Class = "pythia_card_worth";
- const Card_Worth_Coins_Class = "pythia_card_coins_worth";
- const Player_Cards_Id_Prefix = "pythia_cards_wrap_";
- const Player_Hand_Card_Id_Prefix = "pythia_hand_card_";
- const Player_Score_Id_Prefix = "pythia_score_";
- const Player_Military_Power_Id_Prefix = "pythia_military_power_";
- const Player_War_Score_Id_Prefix = "pythia_player_war_score_";
- const Player_Cards_Div_Class = "pythia_cards_container";
- const Player_Score_Span_Class = "pythia_score";
- const Player_Leader_Class = "pythia_leader";
- const Player_Runnerup_Class = "pythia_runnerup";
- const War_Points_Per_Age = {
- "1": 1,
- "2": 3,
- "3": 5
- };
- const Victory_Points_Image = {
- "-1": "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/minus%201%20point.png?raw=true",
- "-2": "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/minus%202%20points.png?raw=true",
- 0: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/0%20points.png?raw=true",
- 1: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/1%20point.png?raw=true",
- 2: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/2%20points.png?raw=true",
- 3: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/3%20points.png?raw=true",
- 4: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/4%20points.png?raw=true",
- 5: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/5%20points.png?raw=true",
- 6: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/6%20points.png?raw=true",
- 7: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/7%20points.png?raw=true",
- 8: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/8%20points.png?raw=true",
- 9: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/9%20points.png?raw=true",
- 10: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/10%20points.png?raw=true",
- 11: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/11%20points.png?raw=true",
- 12: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/12%20points.png?raw=true",
- 13: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/13%20points.png?raw=true",
- 14: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/14%20points.png?raw=true",
- };
- const Coins_Image = {
- 0: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/0%20coins.png?raw=true",
- 1: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/1%20coin.png?raw=true",
- 2: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/2%20coins.png?raw=true",
- 3: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/3%20coins.png?raw=true",
- 4: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/4%20coins.png?raw=true",
- 5: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/5%20coins.png?raw=true",
- 6: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/6%20coins.png?raw=true",
- 7: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/7%20coins.png?raw=true",
- 8: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/8%20coins.png?raw=true",
- 9: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/9%20coins.png?raw=true",
- 10: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/10%20coins.png?raw=true",
- 11: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/11%20coins.png?raw=true",
- 12: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/12%20coins.png?raw=true",
- 13: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/13%20coins.png?raw=true",
- 14: "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/14%20coins.png?raw=true",
- };
- const Military_Power_Icon = "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/military-power-icon.png?raw=true";
- const HD_Boards = "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/boards_hd.jpg?raw=true";
- const HD_Cards = "https://github.com/dpavliuchkov/bga-pythia/blob/master/images/cards_hd.jpg?raw=true&version=1";
-
- // Main Pythia object
- var pythia = {
- isStarted: false,
- isFinished: false,
- dojo: null,
- game: null,
- edition: null,
- isNewEdition: null,
- mainPlayer: null,
- currentAge: 1,
- playersCount: 0,
- players: [],
-
- // Init Pythia
- init: function() {
- this.isStarted = true;
- // Check if the site was loaded correctly
- if (!window.parent || !window.parent.dojo || !window.parent.gameui.gamedatas ||
- !window.parent.gameui.gamedatas.playerorder || !window.parent.gameui.gamedatas.playerorder[0] ||
- !window.parent.gameui.gamedatas.card_types || !window.parent.gameui.gamedatas.wonders) {
- return;
- }
- this.dojo = window.parent.dojo;
- this.game = window.parent.gameui.gamedatas;
- this.edition = parseInt(this.game.game_edition);
- this.isNewEdition = this.edition == 1;
-
- var playerOrder = this.game.playerorder;
- this.playersCount = playerOrder.length;
- this.mainPlayer = playerOrder[0];
- // local storage stores value as strings, so we need to parse "false" and "true" to get boolean
- this.settings = {
- "enableWarScores": localStorage.getItem("pythia-seetings-warscores") === null ?
- true : String(localStorage.getItem("pythia-seetings-warscores")) == "true",
- "enableRichBoards": localStorage.getItem("pythia-seetings-richboards") === null ?
- true : String(localStorage.getItem("pythia-seetings-richboards")) == "true",
- "enableCardPoints": localStorage.getItem("pythia-seetings-cardpoints") === null ?
- true : String(localStorage.getItem("pythia-seetings-cardpoints")) == "true",
- "enableHD": localStorage.getItem("pythia-seetings-hd") === null ?
- true : String(localStorage.getItem("pythia-seetings-hd")) == "true",
- "enableFullwidth": localStorage.getItem("pythia-seetings-fullwidth") === null ?
- false : String(localStorage.getItem("pythia-seetings-fullwidth")) == "true",
- "showMenu": localStorage.getItem("pythia-seetings-showmenu") === null ?
- true : String(localStorage.getItem("pythia-seetings-showmenu")) == "true",
- };
-
- for (var i = 0; i < this.playersCount; i++) {
- var playerId = playerOrder[i];
- this.players[playerId] = {
- hand: {},
- coins: 3,
- shields: 0,
- defeats: 0,
- bgaScore: 1,
- warScore: 0,
- wonder: 0,
- wonderStages: 0,
- maxWonderStages: 0,
- playedTypes: {
- "raw": 0,
- "man": 0,
- "com": 0,
- "mil": 0,
- "civ": 0,
- "sci": 0,
- "gui": 0,
- },
- playedCards: {
- "lighthouse": false,
- "haven": false,
- "ludus": false,
- "chamberOfCommerce": false,
- "shipownersGuild": false,
- },
- science: {
- "gears": 0, // 1 in BGA
- "tablets": 0, // 2 in BGA
- "compasses": 0, // 3 in BGA
- "jokers": 0, // ? in BGA
- }
- };
-
- // Identify who sits to the left and to the right
- if (playerId == this.mainPlayer) {
- this.players[playerId].left = playerOrder[this.playersCount - 1];
- } else {
- this.players[playerId].left = playerOrder[i - 1];
- }
- if (playerId == playerOrder[this.playersCount - 1]) {
- this.players[playerId].right = this.mainPlayer;
- } else {
- this.players[playerId].right = playerOrder[i + 1];
- }
-
- this.renderPythiaContainers(playerId);
- }
-
- this.renderPythiaMenu();
- this.setStyles();
-
- // Configure Pythia according to settings
- this.togglePythiaSettingPlayerCardsDisplay(false);
- this.togglePythiaSettingWarScoresDisplay(this.settings.enableWarScores);
- this.togglePythiaSettingRichBoardsDisplay(this.settings.enableRichBoards);
- this.togglePythiaSettingCardPointsDisplay(this.settings.enableCardPoints);
- this.togglePythiaSettingHDDisplay(this.settings.enableHD);
- this.togglePythiaSettingFullwidthDisplay(this.settings.enableFullwidth);
-
- // Connect event handlers to follow game progress
- this.dojo.subscribe("newHand", this, "recordHand");
- this.dojo.subscribe("cardsPlayed", this, "recordTurn");
- this.dojo.subscribe("coinDelta", this, "recordCoins");
- this.dojo.subscribe("discard", this, "recordDiscard");
- this.dojo.subscribe("newWonders", this, "recordWonderChoice");
- this.dojo.subscribe("wonderBuild", this, "recordWonderStage");
- this.dojo.subscribe("updateScore", this, "recordScoreUpdate");
- this.dojo.subscribe("warVictory", this, "recordWarResults");
- this.dojo.subscribe("newAge", this, "changeAge");
-
- if (Enable_Logging) console.log("PYTHIA: My eyes can see everything!");
- return this;
- },
-
- // Record which wonder each player has chosen
- recordWonderChoice: function(data) {
- if (Enable_Logging) console.log("PYTHIA: wonders chosen - I got", data);
-
- // Input check
- if (!data || !data.args || !data.args.wonders || !this.game || !this.game.wonders) {
- return;
- }
-
- const wonders = Object.keys(data.args.wonders);
- for (const playerId of wonders) {
- const wonderId = data.args.wonders[playerId]
- this.players[playerId].wonder = wonderId;
- this.players[playerId].maxWonderStages = Object.keys(this.game.wonders[wonderId].stages).length;
- }
- },
-
- // Check what came to main player in the new hand
- recordHand: function(data) {
- if (Enable_Logging) console.log("PYTHIA: new hand - I got", data);
-
- // Input check
- if (!data || !data.args || !data.args.cards) {
- return;
- }
-
- // Rotate old hands and render cards
- if (!this.isFirstTurn()) {
- this.passCards();
- this.renderPlayerCards();
- this.renderPlayerCardTooltips();
- }
- // Save new hand to main player
- this.players[this.mainPlayer].hand = data.args.cards;
-
- // Get card worth in victory points and coins and render it
- for (var cardId in data.args.cards) {
- const playedCard = data.args.cards[cardId];
- const cardWorth = this.calculateCardWorth(this.mainPlayer, playedCard.type);
- this.renderCardPoints(cardId, false, cardWorth.points, cardWorth.coins);
- }
- },
-
- // Process all cards played by all players
- recordTurn: function(data) {
- if (Enable_Logging) console.log("PYTHIA: cards played - I got", data);
-
- // Input check
- if (!data || !data.args || !data.args.cards) {
- return;
- }
-
- var warPlayed = false;
-
- // Cycle all played cards
- for (var cardId in data.args.cards) {
- const playedCard = data.args.cards[cardId];
- const originalCard = this.game.card_types[playedCard.type];
- const playerId = playedCard.location_arg;
- if (!originalCard.category) return; // Input check
-
- const cardCategory = originalCard.category;
-
- // Track if played card was military
- if (originalCard.shield) {
- warPlayed = true;
- this.players[playerId].shields += originalCard.shield;
- this.renderMilitaryPower(playerId);
- }
-
- // Update played scientific symbols
- if (originalCard.science) {
- this.increaseScienceCounter(playerId, originalCard.science);
- }
-
- // Update played card types array of the player
- this.players[playerId].playedTypes[cardCategory] += 1;
-
- // Track cards that we need for points worth feature
- this.increaseCardCounter(playerId, playedCard.type);
-
- // Delete played card
- if (isObjectEmpty(this.players[playerId].hand)) {
- continue;
- }
- delete this.players[playerId].hand[cardId];
- }
- if (warPlayed) {
- this.calculateWarScores();
- }
- },
-
- // If there was a trade, update how many coins each player has
- recordCoins: function(data) {
- if (Enable_Logging) console.log("PYTHIA: coins changed - I got", data);
-
- // Input check
- if (!data || !data.args || !data.args.coinddelta) {
- return;
- }
-
- this.players[data.args.player_id].coins += data.args.coinddelta;
- },
-
- // If main player discarded - we know what card it was
- recordDiscard: function(data) {
- if (Enable_Logging) console.log("PYTHIA: card discarded - I got", data);
-
- // Input check
- if (!data || !data.args || !data.args.card_id || !!data.channelorig) {
- return;
- }
-
- var player = data.channelorig.substring(9);
- delete this.players[player].hand[data.args.card_id];
- },
-
- // Record when a wonder stage was played
- recordWonderStage: function(data) {
- if (Enable_Logging) console.log("PYTHIA: wonder built - I got", data);
-
- // Input check
- if (!data || !data.args || !data.args.step || !data.args.player_id) {
- return;
- }
-
- const playerId = data.args.player_id;
- const stage = data.args.step;
- var wonderId = this.players[playerId].wonder;
-
- // We might have corrupted data, refresh it from the game HTML
- if (wonderId == 0) {
- const board = this.dojo.byId("player_board_wonder_" + playerId);
- switch (board.style.backgroundPositionY) {
- case "0%":
- // Giza A
- wonderId = 1;
- break;
-
- case "7.69231%":
- // Baby A
- wonderId = 2;
- break;
-
- case "15.3846%":
- // Oly A
- wonderId = 3;
- break;
-
- case "23.0769%":
- // Rho A
- wonderId = 4;
- break;
-
- case "30.7692%":
- // Eph A
- wonderId = 5;
- break;
-
- case "38.4615%":
- // Alex A
- wonderId = 6;
- break;
-
- case "46.1538%":
- // Hali A
- wonderId = 7;
- break;
-
- case "53.8462%":
- // Giza B
- wonderId = 8;
- break;
-
- case "61.5385%":
- // Baby B
- wonderId = 9;
- break;
-
- case "69.2308%":
- // Oly B
- wonderId = 10;
- break;
-
- case "76.9231%":
- // Rho B
- wonderId = 11;
- break;
-
- case "84.6154%":
- // Eph B
- wonderId = 12;
- break;
-
- case "92.3077%":
- // Alex B
- wonderId = 13;
- break;
-
- case "100%":
- // Hali B
- wonderId = 14;
- break;
- }
-
- this.players[playerId].wonder = wonderId;
- }
-
- this.players[playerId].wonderStages += 1; // increase a counter of built wonder stages
-
- // Game correctness check
- if (!this.game.wonders[wonderId] || !this.game.wonders[wonderId].stages ||
- !this.game.wonders[wonderId].stages[stage]) {
- return;
- }
-
- // If Rhodos built a stage - it could have shields
- if (this.game.wonders[wonderId].stages[stage].shield) {
- this.players[playerId].shields += this.game.wonders[wonderId].stages[stage].shield;
- this.calculateWarScores();
- this.renderMilitaryPower(playerId);
- }
-
- // If Babylon built a stage - it could have science
- if (this.game.wonders[wonderId].stages[stage].science) {
- this.increaseScienceCounter(playerId, this.game.wonders[wonderId].stages[stage].science);
- }
-
- // If Hali built a stage - it could have discard play
- if (this.game.wonders[wonderId].stages[stage].pickDiscarded) {
- this.calculateDiscardWorth(this);
- }
- },
-
- // Update internal scores as well
- recordScoreUpdate: function(data) {
- if (Enable_Logging) console.log("PYTHIA: scores updated - I got", data);
-
- // Input check
- if (!data || !data.args || !data.args.scores) {
- return;
- }
-
- const scores = Object.keys(data.args.scores);
- for (const playerId of scores) {
- this.players[playerId].bgaScore = data.args.scores[playerId];
- this.renderPlayerScore(playerId);
- }
-
- // Update leader & runnerup positions
- this.renderLeaderRunnerup();
- },
-
- // Process war results
- recordWarResults: function(data) {
- if (Enable_Logging) console.log("PYTHIA: war battle happened - I got", data);
-
- // Input check
- if (!data || !data.args || !data.args.points || !data.args.neighbour_id) {
- return;
- }
-
- // Save defeat tokens
- if (data.args.points > 0) {
- this.players[data.args.neighbour_id].defeats += 1;
- }
-
- // If this is the last war - do cleanup
- if (this.currentAge == 3) {
- this.finishGame();
- }
- },
-
- // Calculate additional score from shields
- calculateWarScores: function() {
- var currentPlayerId = this.mainPlayer;
- var i = 0;
- while (i < this.playersCount) {
- var thisPlayer = this.players[currentPlayerId];
- thisPlayer.warScore = 0;
-
- // Check battles with right neighbour
- var rightPlayer = this.players[thisPlayer.right];
- if (thisPlayer.shields > rightPlayer.shields) {
- this.increaseWarScore(currentPlayerId, this.currentAge);
- } else if (thisPlayer.shields < rightPlayer.shields) {
- this.decreaseWarScore(currentPlayerId, this.currentAge);
- }
-
- // Check battles with left neighbour
- var leftPlayer = this.players[thisPlayer.left];
- if (thisPlayer.shields > leftPlayer.shields) {
- this.increaseWarScore(currentPlayerId, this.currentAge);
- } else if (thisPlayer.shields < leftPlayer.shields) {
- this.decreaseWarScore(currentPlayerId, this.currentAge);
- }
-
- currentPlayerId = thisPlayer.right;
- i++;
- }
- },
-
- calculateDiscardWorth: function(that, counter = 1) {
- const discardWrapper = that.dojo.byId('discarded_wrap');
-
- // Check that we can see discard div, else wait
- if (discardWrapper.style.display == "block") {
- const discarded = that.dojo.query("#discarded div");
- for (var i in discarded) {
- const card = discarded[i];
- if (!card.style) {
- continue;
- }
-
- // Calculate card position - the only way to find which card is actually in discard
- var posX, posY;
- if (that.isNewEdition) {
- posX = -255 * parseInt(card.style.backgroundPositionX) / 100;
- posY = -393 * parseInt(card.style.backgroundPositionY) / 100;
- } else {
- posX = -parseInt(card.style.width) * parseInt(card.style.backgroundPositionX) / 100;
- posY = -parseInt(card.style.height) * parseInt(card.style.backgroundPositionY) / 100;
- }
-
- var cardType = null;
- for (var j in that.game.card_types) {
- const originalCard = that.game.card_types[j];
- if (originalCard.backx == posX && originalCard.backy == posY) {
- cardType = j;
- break;
- }
- }
-
- if (cardType) {
- const cardWorth = that.calculateCardWorth(that.mainPlayer, cardType);
- that.renderCardPoints(card.id.substr(15), true, cardWorth.points, cardWorth.coins);
- }
- }
- } else {
- if (counter > 10) {
- clearTimeout();
- return;
- }
-
- setTimeout(that.calculateDiscardWorth, 2000, that, counter + 1);
- }
- },
-
- // Get how many coins and victory points this card will bring to this player
- calculateCardWorth: function(playerId, cardType) {
- const leftPlayerId = this.players[playerId].left;
- const rightPlayerId = this.players[playerId].right;
-
- var worth = {
- points: null,
- coins: null,
- };
-
- switch (parseInt(cardType)) {
- // Raw materials
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- case 28:
- case 28:
- case 30:
- case 31:
- if (this.players[playerId].playedCards.haven) {
- worth.points += 1;
- }
- if (this.players[playerId].playedCards.shipownersGuild) {
- worth.points += 1;
- }
- break;
-
-
- // Manufactured goods
- case 11:
- case 12:
- case 13:
- case 32:
- case 33:
- case 34:
- case 39:
- case 40:
- if (this.players[playerId].playedCards.shipownersGuild) {
- worth.points += 1;
- }
- if (this.players[playerId].playedCards.chamberOfCommerce) {
- worth.points += 2;
- }
- break;
-
- // Commercial cards
- case 18:
- case 19:
- case 20:
- case 21:
- if (this.players[playerId].playedCards.lighthouse) {
- worth.points += 1;
- }
- break;
-
- // Military cards
- case 22:
- case 23:
- case 24:
- case 43:
- case 44:
- case 45:
- case 46:
- case 70:
- case 71:
- case 72:
- case 73:
- case 80:
- if (!this.game.card_types[cardType] || !this.game.card_types[cardType].shield) {
- break;
- }
- worth.points = this.calculateMilitaryCardWorth(playerId, parseInt(this.game.card_types[cardType].shield));
- if (this.players[playerId].playedCards.ludus) {
- worth.points += 1;
- }
- break;
-
- // Scientific symbols
- case 25:
- case 26:
- case 27:
- case 47:
- case 48:
- case 49:
- case 50:
- case 58:
- case 74:
- case 75:
- case 76:
- case 77:
- case 78:
- if (!this.game.card_types[cardType] || !this.game.card_types[cardType].science) {
- break;
- }
- worth.points = this.calculateScienceCardWorth(playerId, this.game.card_types[cardType].science);
- break;
-
- // Age 2 commerce
- case 41: // Vineyard - coins for brown cards
- worth.coins = this.players[leftPlayerId].playedTypes["raw"] + this.players[rightPlayerId].playedTypes["raw"] +
- this.players[playerId].playedTypes["raw"];
- if (this.players[playerId].playedCards.lighthouse) {
- worth.points += 1;
- }
- break;
-
- case 42: // Bazaar - coins for grey cards
- worth.coins = (this.players[leftPlayerId].playedTypes["man"] + this.players[rightPlayerId].playedTypes["man"] +
- this.players[playerId].playedTypes["man"]) * 2;
- if (this.players[playerId].playedCards.lighthouse) {
- worth.points += 1;
- }
- break;
-
- // Age 3 guilds
- case 51: // Workers guild - brown cards
- worth.points = this.players[leftPlayerId].playedTypes["raw"] + this.players[rightPlayerId].playedTypes["raw"];
- if (this.players[playerId].playedCards.shipownersGuild) {
- worth.points += 1;
- }
- break;
- case 52: // Craftsmens guild - grey cards
- worth.points = 2 * (this.players[leftPlayerId].playedTypes["man"] + this.players[rightPlayerId].playedTypes["man"]);
- if (this.players[playerId].playedCards.shipownersGuild) {
- worth.points += 1;
- }
- break;
- case 53: // Traders guild - yellow cards
- worth.points = this.players[leftPlayerId].playedTypes["com"] + this.players[rightPlayerId].playedTypes["com"];
- if (this.players[playerId].playedCards.shipownersGuild) {
- worth.points += 1;
- }
- break;
- case 54: // Philosopehrs guild - yellow cards
- worth.points = this.players[leftPlayerId].playedTypes["sci"] + this.players[rightPlayerId].playedTypes["sci"];
- if (this.players[playerId].playedCards.shipownersGuild) {
- worth.points += 1;
- }
- break;
- case 55: // Spies guild - red cards
- worth.points = this.players[leftPlayerId].playedTypes["mil"] + this.players[rightPlayerId].playedTypes["mil"];
- if (this.players[playerId].playedCards.shipownersGuild) {
- worth.points += 1;
- }
- break;
- case 56:
- if (this.isNewEdition) {
- // Decorators guild - if all stages are built then 7 points
- worth.points = this.players[playerId].wonderStages == this.players[playerId].maxWonderStages ? 7 : 0;
- } else {
- // Strategist guild - defeat tokens
- worth.points = this.players[leftPlayerId].defeats + this.players[rightPlayerId].defeats;
- }
- if (this.players[playerId].playedCards.shipownersGuild) {
- worth.points += 1;
- }
- break;
- case 57: // Shipowners guild - own brown grey purple cards
- worth.points = this.players[playerId].playedTypes["raw"] + this.players[playerId].playedTypes["man"] +
- this.players[playerId].playedTypes["gui"] + 1;
- break;
- case 59: // Magistrates guild - blue cards
- worth.points = this.players[leftPlayerId].playedTypes["civ"] + this.players[rightPlayerId].playedTypes["civ"];
- if (this.players[playerId].playedCards.shipownersGuild) {
- worth.points += 1;
- }
- break;
- case 60: // Builders guild - wonder stages]
- worth.points = this.players[playerId].wonderStages + this.players[leftPlayerId].wonderStages +
- this.players[rightPlayerId].wonderStages;
- if (this.players[playerId].playedCards.shipownersGuild) {
- worth.points += 1;
- }
- break;
-
- // Age 3 commerce
- case 66: // Haven - coins and points for own brown cards
- worth.coins = this.players[playerId].playedTypes["raw"];
- worth.points = this.players[playerId].playedTypes["raw"];
- if (this.players[playerId].playedCards.lighthouse) {
- worth.points += 1;
- }
- break;
- case 67: // Lighthouse - coins and points for own yellow cards
- worth.coins = this.players[playerId].playedTypes["com"] + 1;
- worth.points = this.players[playerId].playedTypes["com"] + 1;
- break;
- case 68: // Chamber of commerce - coins and points for own grey cards
- worth.coins = this.players[playerId].playedTypes["man"] * 2;
- worth.points = this.players[playerId].playedTypes["man"] * 2;
- if (this.players[playerId].playedCards.lighthouse) {
- worth.points += 1;
- }
- break;
- case 69: // Arena - coins and points for own wonder stages
- worth.coins = this.players[playerId].wonderStages * 3;
- worth.points = this.players[playerId].wonderStages;
- if (this.players[playerId].playedCards.lighthouse) {
- worth.points += 1;
- }
- break
- case 79: // Ludus - coins and points for own military stages
- worth.coins = this.players[playerId].playedTypes["mil"] * 3;
- worth.points = this.players[playerId].playedTypes["mil"];
- if (this.players[playerId].playedCards.lighthouse) {
- worth.points += 1;
- }
- break;
- }
-
- return worth;
- },
-
- // How will war score change if a player gets extra shields
- calculateMilitaryCardWorth: function(playerId, extraShields) {
- // Input check
- if (!playerId || !this.players[playerId]) {
- return 0;
- }
-
- var thisPlayer = this.players[playerId];
- var newWarScore = 0;
-
- // Check battles with right neighbour
- var rightPlayer = this.players[thisPlayer.right];
- if ((thisPlayer.shields + extraShields) > rightPlayer.shields) {
- newWarScore += War_Points_Per_Age[this.currentAge];
- } else if ((thisPlayer.shields + extraShields) < rightPlayer.shields) {
- newWarScore -= 1;
- }
-
- // Check battles with left neighbour
- var leftPlayer = this.players[thisPlayer.left];
- if ((thisPlayer.shields + extraShields) > leftPlayer.shields) {
- newWarScore += War_Points_Per_Age[this.currentAge];
- } else if ((thisPlayer.shields + extraShields) < leftPlayer.shields) {
- newWarScore -= 1;
- }
-
- return newWarScore - thisPlayer.warScore;
- },
-
- // How many points will this science card bring to a player?
- calculateScienceCardWorth: function(playerId, newSymbol) {
- // Input check
- if (!playerId || !this.players[playerId] || !this.players[playerId].science) {
- return;
- }
-
- const playerScience = this.players[playerId].science;
- const sciencePointsNow = this.calculateSciencePoints(playerScience.gears, playerScience.tablets,
- playerScience.compasses, playerScience.jokers);
- var sciencePointsAfter = null;
-
- switch (newSymbol) {
- case 1:
- sciencePointsAfter = this.calculateSciencePoints(playerScience.gears + 1,
- playerScience.tablets, playerScience.compasses, playerScience.jokers);
- break;
-
- case 2:
- sciencePointsAfter = this.calculateSciencePoints(playerScience.gears,
- playerScience.tablets + 1, playerScience.compasses, playerScience.jokers);
- break;
-
- case 3:
- sciencePointsAfter = this.calculateSciencePoints(playerScience.gears,
- playerScience.tablets, playerScience.compasses + 1, playerScience.jokers);
- break;
-
- case "?":
- sciencePointsAfter = this.calculateSciencePoints(playerScience.gears,
- playerScience.tablets, playerScience.compasses, playerScience.jokers + 1);
- break;
-
- default:
- break;
- }
-
- return sciencePointsAfter - sciencePointsNow;
- },
-
- // How many points will a science set bring?
- calculateSciencePoints: function(gears, tablets, compasses, jokers) {
- // Joker can be any symbol, calculate each option with recursion if we have them
- if (jokers > 0) {
- const pointsWithJokerGear = this.calculateSciencePoints(gears + 1, tablets, compasses, jokers - 1);
- const pointsWithJokerTablet = this.calculateSciencePoints(gears, tablets + 1, compasses, jokers - 1);
- const pointsWithJokerCompass = this.calculateSciencePoints(gears, tablets, compasses + 1, jokers - 1);
-
- return Math.max(pointsWithJokerGear, pointsWithJokerTablet, pointsWithJokerCompass);
- } else {
- // No jokers - calculate according to the rules
- var points = gears * gears + tablets * tablets + compasses * compasses; // individual symbols
- points += 7 * Math.min(gears, tablets, compasses); // set of 3
-
- return points;
- }
- },
-
- // Cleanup things between ages
- changeAge: function(data) {
- if (Enable_Logging) console.log("PYTHIA: new age - I got", data);
-
- this.currentAge += 1;
-
- // Recalculate war scores for the new age
- this.calculateWarScores();
-
- const keys = Object.keys(this.players);
- for (const playerId of keys) {
- // Clean player hands and update total scores
- this.players[playerId].hand = {};
- this.renderPlayerScore(playerId);
- this.renderLeaderRunnerup();
- }
-
- // Clean rendered cards from previous age
- this.dojo.query("." + Player_Cards_Div_Class).forEach(this.dojo.empty);
- },
-
- // Cleanup Pythia when the game is done
- finishGame: function() {
- this.isFinished = true;
- this.togglePythiaSettingRichBoardsDisplay(false);
- this.togglePythiaSettingWarScoresDisplay(false);
- this.togglePythiaSettingPlayerCardsDisplay(false);
- },
-
- // Add war scores based on the age
- increaseWarScore: function(playerId, age) {
- this.players[playerId].warScore += War_Points_Per_Age[age];
- },
- // Decrase war scores
- decreaseWarScore: function(playerId, age) {
- this.players[playerId].warScore -= 1;
- },
-
- // Add a counter to played science symbols
- increaseScienceCounter: function(player, symbol) {
- switch (symbol) {
- case 1:
- this.players[player].science.gears += 1;
- break;
- case 2:
- this.players[player].science.tablets += 1;
- break;
- case 3:
- this.players[player].science.compasses += 1;
- break;
- case "?":
- this.players[player].science.jokers += 1;
- break;
- default:
- break;
- }
- },
-
- // Track if certain card was player by hte player, needed for Card Worth function
- increaseCardCounter: function(playerId, cardType) {
- switch (parseInt(cardType)) {
- case 57: // Shipowners guild - own brown grey purple cards
- this.players[playerId].playedCards.shipownersGuild = true;
- break;
- case 66: // Haven - coins and points for own brown cards
- this.players[playerId].playedCards.haven = true;
- break;
- case 67: // Lighthouse - coins and points for own yellow cards
- this.players[playerId].playedCards.lighthouse = true;
- break;
- case 68: // Chamber of commerce - coins and points for own grey cards
- this.players[playerId].playedCards.chamberOfCommerce = true;
- break;
- case 79: // Ludus - coins and points for own military stages
- this.players[playerId].playedCards.ludus = true;
- break;
- }
- },
-
- // Move cards unplayed cards between players
- passCards: function() {
- // This should be counter to age direction, because
- // Pythia always passes starting from the last player
- var direction = this.currentAge == 2 ? "right" : "left";
- var currentPlayerId = this.mainPlayer;
- var i = 0;
- while (i < this.playersCount) {
- var neighborId = this.players[currentPlayerId][direction];
- this.players[neighborId].hand = this.players[this.players[neighborId][direction]].hand;
- currentPlayerId = neighborId;
- i++;
- }
- },
-
- // Render player containers
- renderPythiaContainers: function(playerId) {
- // Insert war score container in scores table
- if (!this.dojo.byId(Player_Score_Id_Prefix + playerId)) {
- this.dojo.place(
- "<span id='" + Player_Score_Id_Prefix + playerId + "'" +
- "class='player_score_value " + Player_Score_Span_Class + "'> (1)</span>",
- BGA_Player_Score_Id_Prefix + playerId,
- "after");
- }
-
- // Insert military power container on player board
- if (!this.dojo.byId(Player_Military_Power_Id_Prefix + playerId)) {
- const refNode = this.dojo.query("#" + BGA_Player_Board_Id_Prefix + playerId + " .sw_coins");
- if (refNode && refNode[0]) {
- this.dojo.place(
- "<div id='" + Player_Military_Power_Id_Prefix + playerId + "' class='pythia_player_military_power'>" +
- "<img src='" + Military_Power_Icon + "'/><span>0</span></div>",
- refNode[0],
- "last");
- }
- }
-
- // Insert war score container on player board
- if (!this.dojo.byId(Player_War_Score_Id_Prefix + playerId)) {
- const refNode = this.dojo.query("#" + BGA_Player_Board_Id_Prefix + playerId + " .sw_coins");
- if (refNode && refNode[0]) {
- this.dojo.place(
- "<div id='" + Player_War_Score_Id_Prefix + playerId + "' class='pythia_player_war_score'>" +
- "<i class='fa fa-star'></i><span>1 (1)</span></div>",
- refNode[0],
- "first");
- }
- }
-
- // Skip card container for main player and if already rendered
- if (playerId == this.mainPlayer || this.dojo.byId(Player_Cards_Id_Prefix + playerId)) {
- return;
- }
- // Insert card container on player board
- this.dojo.place("<div id='" + Player_Cards_Id_Prefix + playerId + "'" +
- " class='" + Player_Cards_Div_Class + "'></div>",
- BGA_Player_Board_Id_Prefix + playerId,
- "first");
- },
-
- // Render player hands
- renderPlayerCards: function() {
- const keys = Object.keys(this.players);
- for (const playerId of keys) {
- if (playerId == this.mainPlayer || isObjectEmpty(this.players[playerId].hand)) {
- continue;
- }
-
- var cardsHTML = "";
- var left = 1;
- for (var card in this.players[playerId].hand) {
- var playedCard = this.game.card_types[this.players[playerId].hand[card].type];
- var posX = -playedCard.backx;
- var posY = -playedCard.backy;
- const cardHtmlId = Player_Hand_Card_Id_Prefix + card;
-
- cardsHTML += "<div id='" + cardHtmlId + "' style='left: " + left + "px;'>"
- cardsHTML += "<div style='background-position: " + posX + "px " + posY + "px;'>";
- cardsHTML += "<span>" + playedCard.nametr + "</span></div></div>";
-
- left += 79;
- }
- this.dojo.place(cardsHTML, Player_Cards_Id_Prefix + playerId, "only");
- }
- },
-
-
- // Render tooltips for cards in player hands
- renderPlayerCardTooltips: function() {
- const keys = Object.keys(this.players);
- for (const playerId of keys) {
- if (playerId == this.mainPlayer || isObjectEmpty(this.players[playerId].hand)) {
- continue;
- }
- for (var card in this.players[playerId].hand) {
- const tooltipId = "player_hand_item_" + card;
-
- // Game correctness check
- if (!window.parent.gameui.addTooltipHtml || !window.parent.gameui.tooltips ||
- !window.parent.gameui.tooltips[tooltipId] || !window.parent.gameui.tooltips[tooltipId].label) {
- continue;
- }
-
- window.parent.gameui.addTooltipHtml(Player_Hand_Card_Id_Prefix + card, window.parent.gameui.tooltips[tooltipId].label);
- }
- }
- },
-
- // Update total player score
- renderPlayerScore: function(playerId, score = 0) {
- if (this.isFinished) {
- return;
- }
-
- var playerScore = this.dojo.byId(Player_Score_Id_Prefix + playerId);
- if (playerScore) {
- const totalScore = this.players[playerId].bgaScore + this.players[playerId].warScore;
- playerScore.innerHTML = " (" + totalScore + ")";
- this.dojo.query("#" + Player_War_Score_Id_Prefix + playerId + " span")[0]
- .innerHTML = this.players[playerId].bgaScore + " (" + totalScore + ")";
- }
- },
-
- // Add border and position of leader and runnerup players
- renderLeaderRunnerup: function() {
- if (!this.settings.enableRichBoards || this.isFinished) {
- return;
- }
-
- // Clean previous leader & runnerup
- this.dojo.query("." + Player_Leader_Class + ", ." + Player_Runnerup_Class)
- .removeClass([Player_Leader_Class, Player_Runnerup_Class]);
-
- // Find leader and runner ups
- var totalScores = [];
- const keys = Object.keys(this.players);
- for (const playerId of keys) {
- totalScores.push(
- [playerId,
- this.players[playerId].bgaScore + this.players[playerId].warScore,
- this.players[playerId].coins
- ]);
- }
-
- totalScores.sort(function(a, b) {
- return b[1] - a[1] || b[2] - a[2];;
- });
-
- // Mark new ones
- this.dojo.addClass(BGA_Player_Board_Id_Prefix + totalScores[0][0], Player_Leader_Class);
- this.dojo.addClass(BGA_Player_Board_Id_Prefix + totalScores[1][0], Player_Runnerup_Class);
- },
-
- // Add laurel wreath and coins icons on top of the card container
- renderCardPoints: function(cardId, isDiscard = false, pointsWorth = null, coinsWorth = null) {
- // Leave if card has no worth info
- if (pointsWorth === null && coinsWorth === null) {
- return;
- }
-
- // Clean up previous worth in case we saw this card already
- const containerId = isDiscard ? Discard_Card_Worth_Id_Prefix + cardId : Card_Worth_Id_Prefix + cardId;
- this.dojo.destroy(containerId);
-
- // Build HTML
- const extraClass = this.settings.enableCardPoints ? "" : "pythia_hidden";
- var html = "<span id='" + containerId + "' class='" + Card_Worth_Class + " " + extraClass + "'>";
- if (coinsWorth !== null) {
- html += "<img class='" + Card_Worth_Coins_Class + "' src='" + Coins_Image[coinsWorth] + "' />";
- }
- if (pointsWorth !== null) {
- html += "<img src='" + Victory_Points_Image[pointsWorth] + "' />";
- }
- html += "</span>";
-
- if (isDiscard) {
- this.dojo.place(html, "discarded_item_" + cardId, "only");
- } else {
- this.dojo.place(html, "cardmenu_" + cardId, "after");
- }
- },
-
- // Render shields icon next to player coins
- renderMilitaryPower: function(playerId) {
- if (!playerId || !this.players[playerId] || this.isFinished) {
- return;
- }
-
- var container = this.dojo.query("#" + Player_Military_Power_Id_Prefix + playerId + " span");
- if (container[0]) {
- container[0].innerHTML = this.players[playerId].shields;
- }
- },
-
- // Render Pythia menu
- renderPythiaMenu: function() {
- var menuHtml = "<div id='pythia_menu'>";
- menuHtml += "<div class='menu_header'>";
- menuHtml += "<h3>PYTHIA v" + GM_info.script.version + "</h3>";
-
- // Show or hide Pythia menu based on the setting
- if (this.settings.showMenu) {
- menuHtml += "<div id='pythia_menu_list_toggle' class='toggle_container'><a href='javascript:void(0)' class='collapser' data-target='#pythia_menu .menu_content'>(collapse menu)</a>";
- menuHtml += "<a href='javascript:void(0)' class='expander pythia_hidden' data-target='#pythia_menu .menu_content'>(expand menu)</a>";
- menuHtml += "</div></div>";
- menuHtml += "<div class='menu_content'>";
- } else {
- menuHtml += "<div id='pythia_menu_list_toggle' class='toggle_container'><a href='javascript:void(0)' class='collapser pythia_hidden' data-target='#pythia_menu .menu_content'>(collapse menu)</a>";
- menuHtml += "<a href='javascript:void(0)' class='expander' data-target='#pythia_menu .menu_content'>(expand menu)</a>";
- menuHtml += "</div></div>";
- menuHtml += "<div class='menu_content pythia_hidden'>";
- }
-
- // Card Points setting
- menuHtml += "<div id='pythia_menu_cardpoints' class='menu_item'><span class='title'>Cards Worth:</span>";
- menuHtml += "<span class='status'>Enabled</span><button type='button'>Disable</button></div>";
-
- // Rich Boards setting
- menuHtml += "<div id='pythia_menu_richboards' class='menu_item'><span class='title'>Rich Boards:</span>";
- menuHtml += "<span class='status'>Enabled</span><button type='button'>Disable</button></div>";
-
- // War scores setting
- menuHtml += "<div id='pythia_menu_warscores' class='menu_item'><span class='title'>War Scores:</span>";
- menuHtml += "<span class='status'>Enabled</span><button type='button'>Disable</button></div>";
-
- // HD images setting
- menuHtml += "<div id='pythia_menu_hd' class='menu_item'><span class='title'>HD Images:</span>";
- menuHtml += "<span class='status'>Enabled</span><button type='button'>Disable</button></div>";
-
- // Fullwidth setting
- menuHtml += "<div id='pythia_menu_fullwidth' class='menu_item'><span class='title'>Full Width:</span>";
- menuHtml += "<span class='status'>Enabled</span><button type='button'>Disable</button></div>";
-
- menuHtml += "</div>";
- menuHtml += "</div>";
- this.dojo.place(menuHtml, "logs_wrap", "before");
-
- // Set correct texts based on settings
- this.togglePythiaSettingText("pythia_menu_warscores", this.settings.enableWarScores);
- this.togglePythiaSettingText("pythia_menu_richboards", this.settings.enableRichBoards);
- this.togglePythiaSettingText("pythia_menu_cardpoints", this.settings.enableCardPoints);
- this.togglePythiaSettingText("pythia_menu_hd", this.settings.enableHD);
- this.togglePythiaSettingText("pythia_menu_fullwidth", this.settings.enableFullwidth);
-
- // Connect event handlers
- this.dojo.connect(this.dojo.query("button", "pythia_menu_warscores")[0], "onclick", this, "togglePythiaSettingWarScores");
- this.dojo.connect(this.dojo.query("button", "pythia_menu_richboards")[0], "onclick", this, "togglePythiaSettingRichBoards");
- this.dojo.connect(this.dojo.query("button", "pythia_menu_cardpoints")[0], "onclick", this, "togglePythiaSettingCardPoints");
- this.dojo.connect(this.dojo.query("button", "pythia_menu_hd")[0], "onclick", this, "togglePythiaSettingHD");
- this.dojo.connect(this.dojo.query("button", "pythia_menu_fullwidth")[0], "onclick", this, "togglePythiaSettingFullwidth");
-
- // Expand & collapse menu handlers
- this.dojo.connect(this.dojo.query(".menu_header .collapser")[0], "onclick", this, "togglePythiaSettingMenu");
- this.dojo.connect(this.dojo.query(".menu_header .expander")[0], "onclick", this, "togglePythiaSettingMenu");
- this.dojo.connect(this.dojo.query(".menu_header .collapser")[0], "onclick", this, "toggleCollapserExpander");
- this.dojo.connect(this.dojo.query(".menu_header .expander")[0], "onclick", this, "toggleCollapserExpander");
- },
-
- // Enable or disable display of cards in player hands
- togglePythiaSettingPlayerCardsDisplay: function(pleaseShow) {
- if (pleaseShow) {
- this.dojo.query("." + Player_Cards_Div_Class).removeClass("pythia_hidden");
- this.dojo.query(".sw_coins", "boardspaces").addClass("pythia_player_cards_enabled");
- } else {
- this.dojo.query("." + Player_Cards_Div_Class).addClass("pythia_hidden");
- this.dojo.query(".sw_coins", "boardspaces").removeClass("pythia_player_cards_enabled");
- }
- },
-
- // Enable or disable display of war scores
- togglePythiaSettingWarScores: function(event) {
- this.settings.enableWarScores = !this.settings.enableWarScores;
- localStorage.setItem("pythia-seetings-warscores", this.settings.enableWarScores);
- this.togglePythiaSettingWarScoresDisplay(this.settings.enableWarScores);
- this.togglePythiaSettingText(event.target.parentNode.id, this.settings.enableWarScores);
- },
- togglePythiaSettingWarScoresDisplay: function(pleaseShow) {
- if (pleaseShow) {
- this.dojo.query("." + Player_Score_Span_Class).removeClass("pythia_hidden");
- } else {
- this.dojo.query("." + Player_Score_Span_Class).addClass("pythia_hidden");
- }
- },
-
- // Enable or disable display of leader and runnerup positions
- togglePythiaSettingRichBoards: function(event) {
- this.settings.enableRichBoards = !this.settings.enableRichBoards;
- localStorage.setItem("pythia-seetings-richboards", this.settings.enableRichBoards);
- this.togglePythiaSettingRichBoardsDisplay(this.settings.enableRichBoards);
- this.togglePythiaSettingText(event.target.parentNode.id, this.settings.enableRichBoards);
- },
- togglePythiaSettingRichBoardsDisplay: function(pleaseShow) {
- if (pleaseShow) {
- this.renderLeaderRunnerup();
- this.dojo.query(".pythia_player_war_score").removeClass("pythia_hidden");
- this.dojo.query(".pythia_player_military_power").removeClass("pythia_hidden");
- } else {
- this.dojo.query("." + Player_Leader_Class + ", ." + Player_Runnerup_Class)
- .removeClass([Player_Leader_Class, Player_Runnerup_Class]);
-
- this.dojo.query(".pythia_player_war_score").addClass("pythia_hidden");
- this.dojo.query(".pythia_player_military_power").addClass("pythia_hidden");
- }
- },
-
- // Enable or disable display of cards points worth
- togglePythiaSettingCardPoints: function(event) {
- this.settings.enableCardPoints = !this.settings.enableCardPoints;
- localStorage.setItem("pythia-seetings-cardpoints", this.settings.enableCardPoints);
- this.togglePythiaSettingCardPointsDisplay(this.settings.enableCardPoints);
- this.togglePythiaSettingText(event.target.parentNode.id, this.settings.enableCardPoints);
- },
- togglePythiaSettingCardPointsDisplay: function(pleaseShow) {
- if (pleaseShow) {
- this.dojo.query("." + Card_Worth_Class).removeClass("pythia_hidden");
- } else {
- this.dojo.query("." + Card_Worth_Class).addClass("pythia_hidden");
- }
- },
-
- // Enable or disable HD graphics
- togglePythiaSettingHD: function(event) {
- this.settings.enableHD = !this.settings.enableHD;
- localStorage.setItem("pythia-seetings-hd", this.settings.enableHD);
- this.togglePythiaSettingHDDisplay(this.settings.enableHD);
- this.togglePythiaSettingText(event.target.parentNode.id, this.settings.enableHD);
- },
- togglePythiaSettingHDDisplay: function(pleaseShow) {
- this.dojo.query("body").toggleClass("pythia_hd", pleaseShow);
- },
-
- // Hide or show elements for fullwidth mode
- togglePythiaSettingFullwidth: function(event) {
- this.settings.enableFullwidth = !this.settings.enableFullwidth;
- localStorage.setItem("pythia-seetings-fullwidth", this.settings.enableFullwidth);
- this.togglePythiaSettingFullwidthDisplay(this.settings.enableFullwidth);
- this.togglePythiaSettingText(event.target.parentNode.id, this.settings.enableFullwidth);
- },
- togglePythiaSettingFullwidthDisplay: function(pleaseShow) {
- this.dojo.query("body").toggleClass("pythia_fullwidth", pleaseShow);
- this.dojo.toggleClass("right-side-first-part", "pythia_hidden", pleaseShow);
- this.dojo.toggleClass("logs_wrap", "pythia_hidden", pleaseShow);
- },
-
- togglePythiaSettingMenu: function(event) {
- this.settings.showMenu = event.target.className == "expander";
- localStorage.setItem("pythia-seetings-showmenu", this.settings.showMenu);
- },
-
- // Switch enable/disable text in Pythia settings
- togglePythiaSettingText: function(parentId, isEnabled) {
- if (isEnabled) {
- this.dojo.query(".status", parentId)
- .addClass("enabled")
- .removeClass("disabled")[0]
- .innerHTML = "Enabled";
- this.dojo.query("button", parentId)[0].innerHTML = "Disable";
- } else {
- this.dojo.query(".status", parentId)
- .addClass("disabled")
- .removeClass("enabled")[0]
- .innerHTML = "Disabled";
- this.dojo.query("button", parentId)[0].innerHTML = "Enable";
- }
- },
-
- // Toggle hide / show of any visual element given data-target
- toggleCollapserExpander: function(event) {
- this.dojo.query(".collapser, .expander", event.target.parentNode).toggleClass("pythia_hidden");
- this.dojo.query(event.target.getAttribute('data-target')).toggleClass("pythia_hidden");
- },
-
- // Is this the first turn of the age?
- isFirstTurn: function() {
- return isObjectEmpty(this.players[this.mainPlayer].hand);
- },
-
- // Set Pythia CSS styles
- setStyles: function() {
- this.dojo.query("body").addClass("pythia_enabled");
- this.dojo.place(
- "<style type='text/css' id='Pythia_Styles'>" +
- // Generic settings
- ".pythia_player_cards_enabled.sw_coins { top: 50px; } " +
- ".pythia_enabled.arena_mode .player_elo_wrap { visibility: visible; }" +
- ".pythia_enabled #player_board_wrap_" + this.mainPlayer + " .sw_coins { top: 0px; } " +
- ".pythia_enabled #player_hand_wrap { padding-top: 58px; } " +
- ".pythia_enabled #discarded_wrap h3 { padding-bottom: 60px; } " +
- ".pythia_enabled #howto_tutorial { display: none; } " +
- ".pythia_enabled .pythia_hidden { display: none; } " +
- ".pythia_enabled .toggle_container { display: inline; } " +
-
- // Pythia menu
- "#pythia_menu { font-size: 14px; padding: 10px; position: relative; background-color: #e9d6bf; border: 1px solid black; border-radius: 5px; } " +
- "#pythia_menu .menu_header h3 { display: inline; } " +
- "#pythia_menu .menu_header a { margin-left: 5px; } " +
- "#pythia_menu .menu_content { margin-top: 10px; } " +
- "#pythia_menu .menu_item { height: 26px; } " +
- "#pythia_menu .menu_item span.title { width: 90px; display: inline-block;} " +
- "#pythia_menu .menu_item span.status { text-align: center; width: 55px; display: inline-block; } " +
- "#pythia_menu .menu_item span.status.enabled { color: green; } " +
- "#pythia_menu .menu_item span.status.disabled { color: red; } " +
- "#pythia_menu .menu_item button { width: 60px; padding: 3px; border-radius: 5px; margin-left: 10px; } " +
-
- // Player cards
- "." + Player_Cards_Div_Class + " { display: block; height: 50px; } " +
- "." + Player_Cards_Div_Class + " div { position: absolute; top: 11px; } " +
- "." + Player_Cards_Div_Class + " div div { background-image: url(" + Cards_Image + "); width: 128px; height: 45px; zoom: 0.6; } " +
- "." + Player_Cards_Div_Class + " div div span { width: 100%; text-align: center; position: absolute; left: 0; top: -25px; font-size: 18px; color: black; cursor: default; } " +
-
- // Rich boards
- "." + Player_Leader_Class + ", ." + Player_Runnerup_Class + " { border: 5px solid; } " +
- "." + Player_Leader_Class + " { border-color: green; } " +
- "." + Player_Runnerup_Class + " { border-color: red; border-style: inset; } " +
- "." + Player_Leader_Class + " h3::before, ." + Player_Runnerup_Class + " h3::before { float: left; margin-top: -4px; white-space: pre; }" +
- "." + Player_Leader_Class + " h3::before { content: '(Leader) '; color: green; }" +
- "." + Player_Runnerup_Class + " h3::before { content: '(Runner up) '; color: red; }" +
- ".pythia_player_military_power { display: inline; position: relative; top: 3px; }" +
- ".pythia_player_military_power img { width: 30px; padding: 0 4px; }" +
- ".pythia_player_military_power span { position: relative; top: -7px; }" +
- ".pythia_player_war_score { display: inline; padding-right: 4px; position: relative; top: -1px; }" +
- ".pythia_player_war_score i { font-size: 32px; }" +
- ".pythia_player_war_score span { padding-left: 4px; position: relative; top: -3px; }" +
-
- // Cards worth
- "." + Card_Worth_Class + " { position: absolute; top: -53px; left: 6px; width: 128px; text-align: center; }" +
- "." + Card_Worth_Class + " img { width: 48px; }" +
- "." + Card_Worth_Class + " img." + Card_Worth_Coins_Class + " { position: relative; top: -3px; }" +
-
- // War scores
- "." + Player_Score_Span_Class + " { display: inline; }" +
-
- // Fullwidth view
- ".pythia_fullwidth #left-side { margin-right: 0px; } " +
-
- // New edition styles
- ".new_edition ." + Player_Cards_Div_Class + " div div { background-image: url(" + Cards_Image_V2 + "); width: 255px; height: 110px; zoom: 0.3; text-align: center;} " +
- ".new_edition ." + Player_Cards_Div_Class + " div div span { font-size: 18px; top: 7px; } " +
- ".new_edition .last_board_item { padding-right: 2px; } " +
- ".new_edition .last_board_item .board_item { border-width: 4px; margin: -2px 0 0 -2px; border-color: greenyellow; border-style: outset; } " +
- ".new_edition .last_step_item { border-width: 4px; margin: -4px 0 0 -4px; border-color: greenyellow; border-style: outset; } " +
-
- // New edition HD boards
- "#pythia_menu_hd { display: none; } " +
- ".new_edition #pythia_menu_hd { display: block; } " +
- ".new_edition.pythia_hd .wonder_face, .new_edition.pythia_hd .player_board_wonder { background-size: 450px 3122px; background-image: url(" + HD_Boards + "); }" +
-
- "</style>", "sevenwonder_wrap", "last");
- }
- };
-
- function sleep(ms) {
- return new Promise(resolve => setTimeout(resolve, ms));
- }
-
- function isObjectEmpty(object) {
- return typeof(object) == "undefined" ||
- (Object.keys(object).length === 0 && object.constructor === Object);
- }
-
- // Everything starts here
-
- // Everything starts here
- var onload = async function() {
- if (Is_Inside_Game) {
- await sleep(3000); // Wait for BGA to load dojo and 7W scripts
- if (!window.parent || !window.parent.gameui || !window.parent.gameui.game_name ||
- window.parent.gameui.game_name != "sevenwonders") {
- return;
- }
-
- // Prevent multiple launches
- if (window.parent.isPythiaStarted) {
- return;
- } else {
- if (Enable_Logging) console.log("PYTHIA: I have come to serve you");
- window.parent.isPythiaStarted = true;
- window.parent.pythia = pythia.init();
- }
- }
- };
-
- if (document.readyState === "complete") {
- onload();
- } else {
- (addEventListener || attachEvent).call(window, addEventListener ? "load" : "onload", onload);
- }