Last active
May 20, 2024 18:16
-
-
Save Silvyre/7e73756f108dc987a0d12d609e615371 to your computer and use it in GitHub Desktop.
π§π AutoControl for Colonist.io (ACCio): play Colonist.io using your keyboard! Setup instructions in comments below.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"customEntities":{"script":[["1",{"name":"wall.js","value":{"mdTime":1641400238352,"srcCode":"await ACCio(_ => {\n socketGameSend.buildCityWall();\n selectNextAfterDelay();\n});"}}],["2",{"name":"setup.js","value":{"mdTime":1656815986599,"srcCode":" try {\n return ACCio(_ => console.log(\"ACCio is already enabled! Try refreshing if you're having trouble.\"));\n }\n catch (e) { console.error(e) }\n\n try {\n await ACtl.runInPageCtx('https://cdn.jsdelivr.net/gh/CoeJoder/waitForKeyElements.js@v1.2/waitForKeyElements.js');\n }\n catch {\n return ACtl.runInPageCtx(_ => console.error('ACCio failed to load all required libraries.'));\n }\n\n ACCio = new Proxy(ACtl.runInPageCtx, {\n apply: (target, thisArg, argumentsList) => {\n if (['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)) {\n return;\n }\n\n try { return target(...argumentsList); }\n catch (e) { console.error(e) }\n }\n });\n\n await ACtl.runInPageCtx(_ => waitForKeyElements('canvas[style*=\"touch-action: none\"]', async _ => {\n if (window.accioEnabled) {\n return;\n }\n\n await new Promise(r => setTimeout(r, 500));\n\n if (!uiGameTradeInfoController) {\n console.error('ACCio could not find the required Window attribute - try refreshing the page.');\n return;\n }\n\n canvas = document.querySelector('canvas');\n gameManager = uiGameTradeInfoController.uiGameManager;\n socketGameSend = gameManager.socketGameSend;\n eventController = gameManager.eventController;\n mechanics = eventController.uiGameMechanics;\n tradeController = gameManager.tradeController;\n bankController = gameManager.bankController;\n mapController = gameManager.mapController;\n mapView = mapController.mapView;\n highlightController = mapController.highlightController;\n highlightDiceController = mechanics.find(o => o.highlightDiceNumbers);\n cardController = mechanics.find(o => o.getCardFromHand);\n popupController = mechanics.find(o => o.popupW);\n selectPlayerToStealController = mechanics.find(o => o.updateCheckmark);\n robberController = mechanics.find(o => o.lastRobberTile);\n stateController = mechanics.find(o => o.displayActionState);\n expandableButtons = gameManager?.actionsController?.buttonViews?.filter(o => o.expandedButtons?.length >= 0) || [];\n turnButtonView = gameManager.actionsController.buttonViews.find(o => o.action.toString().includes('TurnButton'));\n CardCountView = mechanics.find(o => o.initResourceCardCountViews).cardCountViewContainer.children.at(-1).constructor;\n gameState = gameManager.gameState;\n mapState = gameState.mapState;\n myColor = gameState.myColor;\n hideBankCards = gameState.gameSettings.hideBankCards;\n tileCorners = mapState.tileState.tileCorners;\n tileEdges = mapState.tileState.tileEdges;\n tileFaces = mapState.tileState.tiles;\n hexH = mapView.hexagonHeight;\n hexW = mapView.hexagonWidth;\n\n a_ = ['None', 'GameSetupPlaceSettlement', 'GameSetupPlaceCity', 'GameSetupRoadPlacement', 'PlaceRoad', 'PlaceRoadForFree', 'PlaceSettlement', 'PlaceCity', 'PlaceCityWithDiscount', 'PlaceShip', 'PlaceShipForFree', 'SelectShipToMove', 'MoveShip', 'PlaceCityWall', 'PlaceCityWallForFree', 'PlaceKnight', 'PlaceKnightForFree', 'UpgradeKnight', 'UpgradeKnightForFree', 'ActivateKnight', 'SelectKnightToTakeAction', 'SelectKnightAction', 'MoveKnightOffTurn', 'SelectKnightToRemove', 'PlaceRobberOrPirate', 'PlaceRobberOnly', 'PlacePirateOnly', 'SelectWhoToRob', 'SelectCardsToDiscard', 'SelectProgressCardsToDiscard', 'Place2MoreRoadBuilding', 'Place1MoreRoadBuilding', 'Select2ResourcesForYearOfPlenty', 'Select1ResourceForMonopoly', 'SelectCardsForPendingDistributions', 'PlaceMetropolis', 'SelectProgressCard', 'SelectCityToPillage', 'PlaceMerchant', 'SelectDiceForAlchemist', 'SelectTileProductionNumbersToSwap', 'SelectPlayerForDeserter', 'SelectRoadToRemove', 'DiplomatSelectWhetherToPlaceNewEdgePiece', 'IntrigueSelectKnightToMove', 'SpySelectPlayer', 'SpySelectProgressCard', 'SelectCardsForWedding', 'CommercialHarborSelectPlayerAndResource', 'CommercialHarborOpponentSelectsCard', 'MasterMerchantSelectPlayer', 'MasterMerchantSelectCards', 'MerchantFleetSelectResource', 'ResourceMonopolySelectResource', 'CommodityMonopolySelectResource'].reduce((obj, e, idx) => ({ [e]: idx, ...obj }), {});\n b_ = ['Empty', 'Settlement', 'City', 'DestroyedCity', 'KnightActiveLevel1', 'KnightActiveLevel2', 'KnightActiveLevel3', 'KnightInactiveLevel1', 'KnightInactiveLevel2', 'KnightInactiveLevel3'].reduce((obj, e, idx) => ({ [e]: idx, ...obj }), {});\n c_ = ['ResourceBack', 'Lumber', 'Brick', 'Wool', 'Grain', 'Ore', 'DevelopmentBack', 'Knight', 'VictoryPoint', 'Monopoly', 'RoadBuilding', 'YearOfPlenty', 'CommodityBack', 'Cloth', 'Coin', 'Paper', 'ProgressCardTradeBack', 'ProgressCardTradeCommercialHarbor', 'ProgressCardTradeMasterMerchant', 'ProgressCardTradeMerchant', 'ProgressCardTradeMerchantFleet', 'ProgressCardTradeResourceMonopoly', 'ProgressCardTradeCommodityMonopoly', 'ProgressCardPoliticsBack', 'ProgressCardPoliticsBishop', 'ProgressCardPoliticsConstitution', 'ProgressCardPoliticsDeserter', 'ProgressCardPoliticsDiplomat', 'ProgressCardPoliticsIntrigue', 'ProgressCardPoliticsSaboteur', 'ProgressCardPoliticsSpy', 'ProgressCardPoliticsWarlord', 'ProgressCardPoliticsWedding', 'ProgressCardScienceBack', 'ProgressCardScienceAlchemist', 'ProgressCardScienceCrane', 'ProgressCardScienceEngineer', 'ProgressCardScienceInventor', 'ProgressCardScienceIrrigation', 'ProgressCardScienceMedicine', 'ProgressCardScienceMining', 'ProgressCardSciencePrinter', 'ProgressCardScienceRoadBuilding', 'ProgressCardScienceSmith'].reduce((obj, e, idx) => ({ [e]: idx, [idx]: e, ...obj }), {});\n e_ = ['ContinueGame', 'GameStateUpdated', 'PlayerControllerStateUpdated', 'DiceStateUpdated', 'BankStateUpdated', 'MapStateUpdated', 'GameSettingsUpdated', 'AmountOfCardsToDiscardUpdated', 'AmountOfCardsToSelect', 'SelectCardsToDiscard', 'SelectCardsFromBankUsingDevelopmentCard', 'SelectCardsForPendingDistribution', 'SelectCardToGiveToAnotherPlayer', 'ConfirmUseDevelopmentCard', 'PlayersTakingAction', 'PlayersDoneTakingAction', 'StealDevelopmentCardFromPlayer', 'StealResourceCardFromPlayer', 'SelectPlayer', 'SelectPlayerForDevelopmentCard', 'SelectPlayerAndCard', 'SelectDice', 'GivePlayerCardFromTile', 'ExchangeCards', 'CloseTradeUI', 'ShowTradeUI', 'EmbargoStatusUpdated', 'RemoveTradeOffer', 'TradeOfferRejected', 'TradeOfferAccepted', 'NewTradeOfferReceived', 'BoldTextInTradeWindow', 'CloseDiscardCardUI', 'ShowDiscardCardUI', 'ClosePopupUI', 'CancelSpecialBuildPhase', 'SetRoadEdgeHighlight', 'SetShipEdgeHighlight', 'SetCornerHighlight', 'SetTileHighlight', 'HighlightDiceNumbersForInventor', 'VoteReceived', 'PlayerReceivedAchievement', 'CavasResized', 'ClickedMultiButton', 'SpectatorCountUpdated', 'KnightStateReceived', 'KnightStateUpdated', 'BarbarianInvasionStateUpdated', 'CityImprovementStateReceived', 'CityImprovementStateUpdated', 'ForceShowCityImprovementButtons', 'UnlockedCityImprovments', 'PlayerReceivedMetropolis', 'MerchantStateReceived', 'MerchantStateUpdated', 'GameEnd', 'GameEndRematchTextUpdated', 'GameEndShowMap', 'GameEndHideMap', 'ActivateRedDice', 'HoveredOverPlayerInformationArrow', 'PointerOutPlayerInformationView', 'RobberMoved', 'MerchantBankTradeRatioActive'].reduce((obj, e, idx) => ({ [e]: idx, ...obj }), {});\n n_ = ['ChatSubmit', 'UpdateNickName', 'ClickedLobbyGameListButton', 'RequestLobbyRoomList', 'ClickedStartTutorial', 'ClickedBotGame', 'ClickedCreateRoom', 'ClickedJoinRoom', 'AccessGameLink', 'ClickedSpectateGame', 'ClickedReconnectGame', 'ClickedChangeIcon', 'EnteredMatchmaking', 'ClickedDice', 'SelectedTile', 'SelectedTiles', 'SelectedPlayer', 'PassedTurn', 'SelectedCards', 'BuyDevelopmentCard', 'WantToBuildRoad', 'ConfirmBuildRoad', 'ConfirmRemoveRoad', 'WantToBuildSettlement', 'ConfirmBuildSettlement', 'WantToBuildCity', 'ConfirmBuildCity', 'WantToBuildShip', 'ConfirmBuildShip', 'WantToMoveShip', 'SelectedShipToMove', 'ConfirmMoveShip', 'WantToBuildCityWall', 'ConfirmBuildCityWall', 'WantToPlaceKnight', 'ConfirmPlaceKnight', 'WantToUpgradeKnight', 'ConfirmUpgradeKnight', 'WantToActivateKnight', 'ConfirmActivateKnight', 'WantToTakeKnightAction', 'SelectKnightToTakeAction', 'ConfirmMoveKnight', 'ConfirmMoveKnightOffTurn', 'ConfirmRemoveKnight', 'ConfirmCityUpgrade', 'ConfirmBuildMetropolis', 'ConfirmPillageCity', 'ConfirmDicePair', 'CancelAction', 'ClickedDevelpomentCard', 'CreatedPlayerOffer', 'AcceptedOffer', 'TakeAcceptedOffer', 'RejectedOffer', 'CreatedCounterOffer', 'ClickedEmbargo', 'RequestActionSwap', 'RequestSpecialBuildPhase', 'CancelSpecialBuildPhase', 'RoomReadyToStart', 'RoomSelectColor', 'RoomStartGame', 'RoomKickPlayer', 'RoomAddBot', 'RoomSettingChangePrivateGame', 'RoomSettingUpdateGameModeSetting', 'RoomSettingUpdateMapSetting', 'RoomSettingUpdateDiceSetting', 'RoomSettingChangeVictoryPointsToWin', 'RoomSettingChangeKarmaActive', 'RoomSettingChangeCardDiscardLimit', 'RoomSettingChangeFriendlyRobber', 'RoomSettingChangeMaxPlayers', 'RoomSettingChangeHideBankCards', 'RoomSettingChangeGameSpeed', 'RoomSettingChangeBotSpeed', 'ClickedRematch', 'Vote', 'ClickedFindGame', 'ClickedCancelFindGame', 'DisconnectedFromSocketServer', 'RequestToJoinMatchmakingMatch', 'ExitedMatchmaking'].reduce((obj, e, idx) => ({ [e]: idx, ...obj }), {});\n t_ = ['GameSetup', 'Dice', 'Turn', 'GameEnd', 'SpecialBuildPhase'].reduce((obj, e, idx) => ({ [e]: idx, ...obj }), {});\n p_ = ['None', 'Robber', 'Pirate'].reduce((obj, e, idx) => ({ [e]: idx, ...obj }), {});\n et_ = ['Empty', 'Road', 'Ship'].reduce((obj, e, idx) => ({ [e]: idx, ...obj }), {});\n\n cType = { North: 0, South: 1 };\n eType = { NorthWest: 0, West: 1, SouthWest: 2 };\n\n selectedHL = null;\n selectedDiceHL = null;\n selectedDiceView = null;\n selectedInventorTile = null;\n hoveredOverPlayerInformationArrow = false;\n lastPlayer = null;\n lastTurnState = null;\n lastActionState = null;\n lastEvent = null;\n passTurnTexture = null;\n\n const gameMode = gameState.gameSettings?.settingTexts()?.at(4)?.at(1);\n isSF = gameMode?.includes('Seafarers');\n isCK = gameMode?.includes('Cities & Knights');\n\n const moveInArray = (arr, fromIdx, toIdx) => {\n const elem = arr.at(fromIdx);\n arr.splice(fromIdx, 1);\n arr.splice(toIdx, 0, elem);\n };\n\n const highlightBg = (view, color) => {\n if (!view.hasHighlightedBg) {\n view.hasHighlightedBg = true;\n }\n else {\n view.children.splice(0, 1);\n }\n\n view.drawBg();\n moveInArray(view.children, -1, 0);\n\n view.bg.geometry.graphicsData.at(0).fillStyle.color = color || 0xffffff;\n view.bg.geometry.graphicsData.at(0).fillStyle.alpha = color ? 0.3 : 0;\n };\n\n const _activateEndTurn = turnButtonView.activateEndTurn.bind(turnButtonView);\n const _deactivateEndTurn = turnButtonView.deactivateEndTurn.bind(turnButtonView);\n const _sendEvent = eventController.sendEvent.bind(eventController);\n\n eventController.sendEvent = async (v, e) => {\n _sendEvent(v, e);\n \n await new Promise(r => setTimeout(r, 100));\n \n const takingTurn = gameState.currentTurnPlayerColor == myColor;\n const takingOffTurnAction = gameState.playersTakingOffTurnAction.includes(myColor);\n\n if (takingTurn && gameState.currentTurnState == t_.Dice && !getPopupView()) {\n const canUseAlchemist = getCardViews().flatMap(cv => cv.cardData.allowableTurnStates).includes(t_.Dice) && gameState.currentActionState == a_.None;\n \n if (canUseAlchemist) {\n selectNextCardAfterDelay(25);\n return; \n }\n }\n\n canvas.style.border = `2px solid ${takingTurn || takingOffTurnAction ? 'orange' : 'transparent'}`; \n };\n\n tradeController.rightExchangeController.updateBankRatios = () => {\n const that = tradeController.rightExchangeController;\n const e = gameState.myBankTradeRatios.getAllBankTradeRatios()\n , t = that.bankRatioContainer.width / e.length;\n e.sort((e,t)=>e.resource > t.resource ? 1 : -1);\n for (const [a,i] of e.entries()) {\n const e = new CardCountView(t * a,0,t,that.bankRatioContainer.height,that.bankRatioContainer,i.resource);\n e.updateText(i.tradeRatio + \":1\");\n e.view.setClickAction(() => that.exchangeView.cardContainer.addNewCardOfType(i.resource));\n that.cardViews.push(e);\n that.cardViewsWithBoldedText.includes(e.cardData.cardEnum) && e.boldText();\n if (i.tradeRatio < 4) {\n highlightBg(e, i.tradeRatio == 2 ? 0x00ff00 : 0xffff00);\n }\n }\n };\n\n const getEnhancedPopupInfoForDistribution = (e, forAqueduct = true) => {\n const t = e.selectCardFormat.amountOfCardsToSelect;\n const warnings = [];\n const reminders = [];\n\n for (let resource = c_.Lumber; resource <= c_.Ore; resource++) {\n let amt = getQuestionMarkAmountForCard(gameState.bank.totalResourceCardOfType(resource), hideBankCards);\n\n const myProduction = getNonGoldProductionForNumber(\n [myColor],\n gameState.lastDice1 + gameState.lastDice2,\n resource\n );\n\n const otherProduction = getNonGoldProductionForNumber(\n gameState.getOtherActivePlayerColors(),\n gameState.lastDice1 + gameState.lastDice2,\n resource\n );\n\n const totalProduction = t + otherProduction + (forAqueduct ? 0 : myProduction);\n\n if (amt == 0) {\n warnings.push(`β οΈ The bank has no ${c_[resource]} left!`);\n }\n else if (hideBankCards ? amt == '?' : amt <= 7) {\n if (totalProduction > 1 && totalProduction <= 7) {\n warnings.push(`β οΈ The bank is low on ${c_[resource]}.`);\n }\n else if (totalProduction > 8) {\n warnings.push(`β οΈ The bank will not have enough ${c_[resource]} for everyone!`);\n }\n }\n\n if (!forAqueduct && myProduction > 0 && amt != 0) {\n reminders.push(`β You will also produce ${myProduction} ${c_[resource]}.`);\n }\n }\n\n if (warnings.length) {\n warnings.unshift('\\n');\n }\n\n if (reminders.length) {\n reminders.unshift('\\n');\n }\n\n return {\n imageTextureName: forAqueduct ? \"icon_aqueduct\" : \"tile_gold\",\n title: `${warnings.length ? 'β οΈ ' : ''}${forAqueduct ? \"Aqueduct\" : \"Gold Tile\"}`,\n body: \"Take \" + (1 == t ? t + \" resource\" : t + \" resources\") + \" from the bank\" + warnings.join('\\n') + reminders.join('\\n')\n }\n };\n\n if (isCK) {\n const _setNewView = popupController.setNewView.bind(popupController);\n\n popupController.setNewView = (e, t) => {\n if (e?.popupImageAndDescription?.constructor?.getPopupInformationForAqueductDistribution) {\n e.popupImageAndDescription.constructor.getPopupInformationForAqueductDistribution = e => getEnhancedPopupInfoForDistribution(e);\n e.popupImageAndDescription.constructor.getPopupInformationForGoldTileDistribution = e => getEnhancedPopupInfoForDistribution(e, false);\n }\n _setNewView(e, t);\n }\n }\n\n const _displayActionState = stateController.displayActionState.bind(stateController);\n\n stateController.displayActionState = e => {\n _displayActionState(e);\n\n const takingOffTurnAction = gameState.playersTakingOffTurnAction.includes(myColor);\n\n if (\n !takingOffTurnAction &&\n gameState.currentTurnPlayerColor == lastPlayer &&\n gameState.currentTurnState == lastTurnState &&\n gameState.currentActionState == lastActionState &&\n gameState.currentActionState != a_.SelectCityToPillage\n ) {\n return;\n }\n\n if ([\n a_.SelectCityToPillage,\n a_.Place1MoreRoadBuilding,\n a_.PlaceRobberOnly,\n a_.PlaceRobberOrPirate,\n a_.PlacePirateOnly,\n a_.MoveKnightOffTurn\n ].includes(gameState.currentActionState) && lastActionState) {\n selectNextAfterDelay();\n }\n\n if ([\n a_.SelectProgressCard,\n a_.SelectProgressCardsToDiscard,\n a_.SpySelectProgressCard\n ].includes(gameState.currentActionState) && lastActionState) {\n selectNextCardAfterDelay(25);\n }\n\n lastPlayer = gameState.currentTurnPlayerColor;\n lastTurnState = gameState.currentTurnState;\n lastActionState = gameState.currentActionState;\n };\n\n getQuestionMarkAmountForCard = (e, t) => t ? 0 == e ? \"0\" : e <= 7 ? \"?\" : e <= 13 ? \"??\" : \"???\" : String(e);\n\n bankController.update =_=> {\n const e = gameState.bank\n , t = gameState.gameSettings.hideBankCards\n , a = e.totalDevelopmentCards()\n , i = (0,\n getQuestionMarkAmountForCard)(a, t);\n bankController.developmentCardCountView.updateText(i);\n let shouldExpandBank = false;\n for (const a of bankController.resourceCardCountViews) {\n const i = e.totalResourceCardOfType(a.cardData.cardEnum);\n a.updateText((0,\n getQuestionMarkAmountForCard)(i, t))\n if (i <= 7) {\n highlightBg(a, i == 0 ? 1 : 0xff0000);\n if (i == 0 || a.cardData.cardEnum >= c_.Cloth) {\n shouldExpandBank = true;\n }\n }\n else {\n highlightBg(a);\n }\n }\n if (shouldExpandBank && !bankController.isBankInterfaceExpanded()) {\n bankController.expandBankInterface();\n }\n else {\n bankController.contractBankInterface();\n }\n };\n\n getMyCorners =_=> tileCorners.reduce((acc, tc, idx) => {\n if (tc.owner == myColor) {\n acc.push(idx);\n }\n return acc;\n }, []);\n\n getMyEdges =_=> tileEdges.reduce((acc, te, idx) => {\n if (te.owner == myColor) {\n acc.push(idx);\n }\n return acc;\n }, []);\n\n getNonGoldProductionForNumber = (players, n, resource) => {\n const myCorners = tileCorners.filter(tc => (!players || players.includes(tc.owner)) && tc.buildingType >= b_.Settlement && tc.buildingType <= b_.DestroyedCity);\n\n const commMap = { [c_.Wool]: c_.Cloth, [c_.Ore]: c_.Coin, [c_.Lumber]: c_.Paper };\n\n const production = tileFaces.reduce((cardEnums, t) => {\n if (t.diceNumber == n && t.tileType >= c_.Lumber && t.tileType <= c_.Ore && !robberController.lastRobberTile.sameTileHex(t)) {\n\n t.hexFace.corners().forEach(c => {\n const building = myCorners.find(({ hexCorner: hc }) => hc.sameCorner(c));\n\n if (!building) {\n return;\n }\n\n cardEnums.push(t.tileType);\n\n if (building.buildingType == b_.City) {\n cardEnums.push(isCK ? commMap[t.tileType] || t.tileType : t.tileType);\n }\n });\n }\n return cardEnums;\n }, []);\n\n return resource ? production.filter(res => res == resource).length : production;\n };\n\n openTrade = (withCommodities = false) => {\n const controller = mechanics.find(o => o.getTradeOffer);\n\n for (let c = c_.Lumber; c <= (withCommodities ? c_.Paper : c_.Ore); c++) {\n if (c == c_.Ore + 1) {\n c = c_.Cloth;\n }\n\n const offer = controller.getTradeOffer();\n const wanted = offer.wantedResources.cards;\n\n if (!wanted.includes(c) && tradeController.leftExchangeController.canAddResource(c)) {\n offer.offeredResources.addCards([c]);\n\n const offerToCounter = getLastCounterableOffer();\n\n if (offerToCounter) {\n socketGameSend.createdCounterOffer(offerToCounter.id, offer);\n }\n else {\n socketGameSend.createdPlayerOffer(offer);\n }\n }\n }\n };\n\n getLastCounterableOffer =_=> uiGameTradeInfoController.offers.find(({ offer, idx }) => (\n !offer.isCounterOffer &&\n offer.creator != myColor &&\n (!offerWasAcceptedByMe(offer) || remainingOffersAreUncounterable(idx))\n ))?.offer;\n\n counterOffer =_=> {\n const offer = getLastCounterableOffer();\n if (offer) {\n tradeController.editOffer(offer);\n }\n };\n\n clickCardInInventory = (card, cardViews) => {\n cardViews.some(cv => {\n if (cv.cardData.cardEnum == card) {\n return cv.view._events.click.fn() || true;\n }\n });\n };\n\n selectProgressCard = (reverse = false) => {\n const a = [...new Set((getPopupView()?.selectCardContainer?.cardsToSelectFrom || getPopupView().playerCardContainer).cardInventory.getAllCardEnums().filter(e => e > c_.Paper))];\n\n const b = [...a];\n b.unshift(b.pop());\n\n const nextCardMap = Object.assign(...b.map((k, i) => ({ [k]: a[i] })));\n const prevCardMap = Object.assign(...a.map((k, i) => ({ [k]: b[i] })));\n\n const selectFromInv = (getPopupView()?.selectCardContainer?.cardsToSelectFrom || getPopupView().playerCardContainer).cardInventory.cardViews.filter(({ cardData: c }) => c.cardEnum > c_.Paper);\n const selectedInv = (getPopupView()?.selectCardContainer?.cardsSelected || getPopupView().selectedCardContainer).cardInventory;\n\n let [selected] = selectedInv.getAllCardEnums();\n\n clickCardInInventory(selected ? (reverse ? prevCardMap[selected] : nextCardMap[selected]) : a.at(0 - reverse), selectFromInv);\n };\n\n getPopupView =_=> popupController?.currentView;\n\n getSelectedCard = getAlchemist => getCardViews().find(({ cardData: c }) =>\n c.cardEnum == (getAlchemist ? c_.ProgressCardScienceAlchemist : getPopupView()?.cardEnum));\n\n selectCardFromHand = resource => {\n try { tradeController.clickedTrade(); }\n catch (e) { console.error(e) }\n\n try { !tradeController.editingOffer && counterOffer(); }\n catch (e) { console.error(e) }\n\n try { getPopupView().playerCardContainer.cardClickAction(resource); }\n catch (e) { console.error(e) }\n\n try { getPopupView().selectCardView.clickedCardToSelectFrom(resource); }\n catch (e) { console.error(e) }\n\n tradeController.leftExchangeController.clickedResourceCard(resource);\n };\n\n selectCardsFromHand = (resource, max = false) => {\n try { tradeController.clickedTrade(); }\n catch (e) { console.error(e) }\n\n const numResources = tradeController.leftExchangeController.getAllActiveCards().filter(r => r == resource).length;\n const { tradeRatio } = gameState.myBankTradeRatios.bankTradeRatios.find(r => r.resource == resource);\n const numToAdd = Math.floor(numResources / tradeRatio) ** max * tradeRatio * (numResources >= tradeRatio);\n\n [...Array(numToAdd)].forEach(_ => {\n try { getPopupView().playerCardContainer.cardClickAction(resource); }\n catch (e) { console.error(e) }\n\n try { getPopupView().selectCardView.clickedCardToSelectFrom(resource); }\n catch (e) { console.error(e) }\n\n try { tradeController.leftExchangeController.clickedResourceCard(resource); }\n catch (e) { console.error(e) }\n });\n };\n\n selectCardFromElsewhere = resource => {\n try {\n if (getPopupView()?.clickedTopResource) {\n try { getPopupView()?.clickedTopResource(resource); }\n catch (e) { console.error(e) }\n }\n else {\n try { tradeController.clickedTrade(); }\n catch (e) { console.error(e) }\n\n try { if (!tradeController.editingOffer) { counterOffer(); } }\n catch (e) { console.error(e) }\n\n try { clickCardInInventory(resource, getPopupView().selectedCardContainer.cardInventory.cardViews); }\n catch (e) { console.error(e) }\n }\n }\n catch (e) { console.error(e) }\n\n tradeController.rightExchangeController.exchangeView.cardContainer.addNewCardOfType(resource);\n };\n\n offerWasAcceptedByMe = offer => {\n return uiGameTradeInfoController.tradeInfoContainer?.children?.some(c => {\n const playerIcon = c?.leftProposal?.children[2];\n const acceptedOfferFound = playerIcon?.children[1]?._texture?.textureCacheIds?.includes('icon_check');\n\n return acceptedOfferFound && offer.id == c?.offer?.id && playerIcon?.playerState?.color == myColor;\n });\n };\n\n remainingOffersAreUncounterable = idx => {\n const remainingOffers = uiGameTradeInfoController.offers.slice(idx + 1);\n return !remainingOffers.some(offer => !offer.isCounterOffer);\n };\n\n setSelectedHighlight = hl => selectedHL = hl || getHighlightViews().at(0);\n\n getSelectedHighlight =_=> {\n if (!getHighlightViews().includes(selectedHL)) {\n setSelectedHighlight();\n }\n\n return selectedHL;\n };\n\n getHighlightedPart =_=> {\n const cornersHighlighted = highlightController.corners.length;\n const edgesHighlighted = highlightController.roadEdges.length || highlightController.shipEdges.length;\n const tilesHighlighted = highlightController.tiles.length;\n\n const multiplePartTypesHighlighted = [ cornersHighlighted, edgesHighlighted, tilesHighlighted ].filter(Boolean).length > 1;\n\n if (multiplePartTypesHighlighted) {\n return 'Multiple';\n }\n else if (cornersHighlighted) {\n return 'Corner';\n }\n else if (edgesHighlighted) {\n return 'Edge';\n }\n else if (tilesHighlighted) {\n return 'Face';\n }\n };\n\n multiplePartTypesHighlighted =_=> {\n return getHighlightedPart() == 'Multiple';\n };\n\n xyzToHexPart = (x, y, z, part) => {\n return this[`tile${part}s`].find(({ [`hex${part}`]: p }) =>\n p.x == x && p.y == y && (part == 'Face' || p.z == z)\n )[`hex${part}`];\n };\n\n hexPartToPixels = ({ x, y, z }, p) => {\n try {\n const part = p || getHighlightedPart();\n const toPixel = part == 'Edge' ? 'centerPointToPixel' : 'toPixel';\n\n return xyzToHexPart(x, y, z, part)[toPixel](mapView.mapCenter, hexH / 2);\n }\n catch (e) { console.error(e) }\n };\n\n pixelsToHexPart = ({ x, y }, p) => {\n const part = p || getHighlightedPart();\n const toPixel = part == 'Edge' ? 'centerPointToPixel' : 'toPixel';\n const tolerance = part == 'Face' ? hexH / 3 : 10;\n\n return this[`tile${part}s`].find(({ [`hex${part}`]: hexPart }) => {\n const p = hexPart[toPixel](mapView.mapCenter, hexH / 2);\n return Math.abs(p.x - x) < tolerance && Math.abs(p.y - y) < tolerance;\n })[`hex${part}`];\n };\n\n getNextHighlightInArray = (direction = 'up') => {\n const hl = getSelectedHighlight();\n const reverse = ['down', 'left'].includes(direction);\n\n if (reverse) {\n return getHighlightViews().at(\n (getHighlightViews().indexOf(hl) + 1) % getHighlightViews().length\n );\n }\n else {\n const nextIdx = getHighlightViews().indexOf(hl) - 1;\n return getHighlightViews().at(nextIdx >= 0 ? nextIdx : getHighlightViews().length - 1);\n }\n };\n\n findHighlight = (coords, part) => {\n if (!coords) {\n return;\n }\n\n try {\n const { x, y } = coords;\n const tolerance = (part || getHighlightedPart()) == 'Face' ? hexH / 3 : 10;\n return getHighlightViews().find(({ center: c }) => Math.abs(c.x - x) < tolerance && Math.abs(c.y - y) < tolerance);\n }\n catch (e) { console.error(e) }\n };\n\n getHighlightInDirection = dir => {\n if (multiplePartTypesHighlighted()) {\n return getNextHighlightInArray(dir);\n }\n\n const hl = getSelectedHighlight();\n const hlPart = getHighlightedPart();\n const current = pixelsToHexPart(hl.center);\n\n const { x: currX, y: currY, z: currZ } = current;\n\n if (hlPart == 'Corner') {\n if (gameState.currentActionState == a_.PlaceKnight || getHighlightViews().length < tileCorners.filter(c => !c.restrictedStartingPlacement).length / 4) {\n return getNextHighlightInArray(dir);\n }\n\n this.upCorner = d => ({ x: currX + Math.floor((d + !currZ) / 2), y: currY - Math.floor((d + !currZ) / 2) * 2, z: (d + currZ) % 2 });\n this.downCorner = d => ({ x: currX - Math.floor((d + currZ) / 2), y: currY + Math.floor((d + currZ) / 2) * 2, z: (d + currZ) % 2 });\n this.rightCorner = d => ({ x: currX + Math.floor((d + !currZ) / 2), y: currY - (d % 2) * (1 - currZ * 2), z: (d + currZ) % 2 });\n this.leftCorner = d => ({ x: currX - Math.floor((d + currZ) / 2), y: currY - (d % 2) * (1 - currZ * 2), z: (d + currZ) % 2 });\n\n const maxDistance = Math.ceil(Math.sqrt(tileCorners.length) + 2);\n\n for (let distance = 1; distance <= maxDistance; distance++) {\n const nextHex = this[`${dir}Corner`](distance);\n\n const nextHL = findHighlight(hexPartToPixels(nextHex));\n if (nextHL) {\n return nextHL;\n }\n }\n\n return hl;\n }\n else if (hlPart == 'Edge') {\n return getNextHighlightInArray(dir);\n }\n else if (hlPart == 'Face') {\n if (getHighlightViews().length < tileFaces.length / 5) {\n return getNextHighlightInArray(dir);\n }\n\n this.upFace = d => ({ x: currX + d, y: currY - d });\n this.downFace = d => ({ x: currX - d, y: currY + d });\n this.rightFace = d => ({ x: currX + d, y: currY + 0 });\n this.leftFace = d => ({ x: currX - d, y: currY + 0 });\n\n const maxDistance = Math.ceil(Math.sqrt(tileFaces.length) + 2);\n\n for (let distance = 1; distance <= maxDistance; distance++) {\n const nextHex = this[`${dir}Face`](distance);\n\n const nextHL = findHighlight(hexPartToPixels(nextHex));\n if (nextHL) {\n return nextHL;\n }\n }\n\n const someDirectionWorks = [upFace, downFace, rightFace, leftFace].filter(f => f != this[`${dir}Face`]).some(face => {\n return Array.from(Array(maxDistance).keys()).some(distance => {\n return findHighlight(hexPartToPixels(face(distance + 1)));\n });\n });\n\n return someDirectionWorks ? hl : getNextHighlightInArray(dir);\n }\n };\n\n getHighlightViews =_=> highlightController.highlightViews;\n\n selectHighlight = hl => {\n if (!highlightController.highlightViews.length) {\n return;\n }\n\n const\n roadAndShipEdges = highlightController.shipEdges.filter(e => highlightController.roadEdges.includes(e)),\n allEdges = [...new Set([...highlightController.roadEdges, ...highlightController.shipEdges])],\n idx = getHighlightViews().indexOf(hl);\n\n let tileCornerWillBeHighlighted = false;\n let tileFaceWillBeHighlighted = false;\n\n try { tileCornerWillBeHighlighted = findHighlight(hexPartToPixels(pixelsToHexPart(hl.center, 'Corner'), 'Corner'), 'Corner') } catch (e) { console.error(e) }\n try { tileFaceWillBeHighlighted = findHighlight(hexPartToPixels(pixelsToHexPart(hl.center, 'Face'), 'Face'), 'Face') } catch (e) { console.error(e) }\n\n if (gameState.currentTurnState == t_.GameSetup || roadAndShipEdges.includes(allEdges[idx])) {\n hl._events.click.fn();\n }\n else if (multiplePartTypesHighlighted() ? tileFaceWillBeHighlighted : highlightController.tiles.length) {\n const\n face = pixelsToHexPart(hl.center, 'Face'),\n a = mapController.mapView.getTileLeftCenterCircle(face),\n i = 2.5 * a.radius,\n e = .7 * i * highlightController.buttonScaleForMobile,\n o = a.x - e / 2,\n n = a.y + i / 2;\n\n gameState.currentActionState == a_.SelectKnightAction\n ? highlightController.confirmActionController.showConfirmation(a.x - i / 2, a.y - i / 2, i, o, n, e, _ => hl._events.click.fn())\n : hl._events.click.fn();\n }\n else if (multiplePartTypesHighlighted() ? false : allEdges.length) {\n const\n edge = tileEdges.at(allEdges[idx]).hexEdge,\n a = edge.endPoints()[0].toPixel(mapView.mapCenter, hexH / 2),\n i = edge.endPoints()[1].toPixel(mapView.mapCenter, hexH / 2),\n n = Math.sqrt((a.x - i.x) ** 2 + (a.y - i.y) ** 2) / 2,\n o = (a.x + i.x) / 2 - n / 2,\n s = (a.y + i.y) / 2 - n / 2,\n e = 1.1 * n,\n r = (a.x + i.x) / 2 - e / 2,\n l = (a.y + i.y) / 2 + n / 2;\n\n highlightController.confirmActionController.showConfirmation(o, s, n, r, l, e, _ => {\n highlightController.confirmedEdgeSelection(allEdges[idx]);\n });\n\n const edgeIdx = tileEdges.findIndex(({ hexEdge }) => hexEdge == edge);\n const { roadEdges, shipEdges } = highlightController;\n const roadOnlyEdges = roadEdges.filter(e => !shipEdges.includes(e));\n const shipOnlyEdges = shipEdges.filter(e => !roadEdges.includes(e));\n\n if (roadOnlyEdges.includes(edgeIdx) && isSF) {\n highlightController.confirmActionController.whiteHighlightView._tintRGB += 5e2;\n }\n else if (shipOnlyEdges.includes(edgeIdx)) {\n highlightController.confirmActionController.whiteHighlightView._tintRGB -= 2e3;\n }\n }\n else if (multiplePartTypesHighlighted() ? tileCornerWillBeHighlighted : highlightController.corners.length) {\n const\n corner = tileCorners.at(highlightController.corners[idx]).hexCorner,\n a = corner.toPixel(mapView.mapCenter, hexH / 2),\n i = 1.2 * mapView.cornerCircleR,\n e = 1.1 * i * highlightController.buttonScaleForMobile,\n n = a.x - e / 2,\n o = a.y + i / 2;\n\n highlightController.confirmActionController.showConfirmation(a.x - i / 2, a.y - i / 2, i, n, o, e, ()=>{\n highlightController.confirmedCornerSelection(highlightController.corners[idx])\n });\n }\n\n setSelectedHighlight(hl);\n highlightController.highlightViews.pop();\n };\n\n deselectHighlight =_=> selectedHL = null;\n\n selectNextPlayer = (reverse = false) => {\n try {\n let playerAvatars, selectPlayer, firstPlayer, selectedPlayerIdx = 0 - reverse;\n\n const pv = getPopupView() || selectPlayerToStealController;\n\n if (selectPlayerToStealController?.isWrongState() == false) {\n selectPlayer = player => pv.selectPlayerAction(player);\n playerAvatars = pv.ui.playerAvatarContainer.playerAvatars;\n }\n else if (pv.selectPlayerAction) {\n selectPlayer = player => pv.selectPlayerAction(player);\n playerAvatars = (pv.selectPlayerView || pv).playerSelectorContainer.playerAvatars;\n }\n else {\n selectPlayer = player => pv.playerClickPlayerAvatar(player);\n playerAvatars = (pv.selectPlayerView || pv).playerSelectorContainer.playerAvatars;\n }\n\n selectedPlayer = playerAvatars.find((avatar, idx) => {\n if (idx == 0) {\n firstPlayer = avatar.playerState.color;\n }\n if (avatar.alpha == 1) {\n selectedPlayerIdx = idx;\n return true;\n }\n })?.playerState?.color;\n\n selectPlayer(\n playerAvatars.at((selectedPlayerIdx + 1 * (selectedPlayer && (reverse ? -1 : 1))) % playerAvatars.length).playerState.color\n );\n }\n catch (e) { console.error(e) }\n };\n\n selectNext = (direction = 'up') => {\n try {\n selectNextPlayer(['down', 'left'].includes(direction));\n }\n catch (e) { console.error(e) }\n\n try {\n if (gameState.currentActionState == a_.SelectTileProductionNumbersToSwap) {\n selectNextInventorTile(direction);\n return;\n }\n }\n catch (e) { console.error(e) }\n\n try {\n let currHL = getSelectedHighlight();\n let nextHL;\n\n if (currHL && !getHighlightViews().length) {\n return;\n }\n\n if (currHL) {\n nextHL = getHighlightInDirection(direction);\n }\n\n selectHighlight(nextHL || currHL || getHighlightViews()[0]);\n }\n catch (e) { console.error(e) }\n };\n\n confirmSelection =_=> {\n if (!selectPlayerToStealController.isWrongState()) {\n selectPlayerToStealController.checkAction();\n return;\n }\n\n const hl = getSelectedHighlight();\n\n if (hl) {\n try { \n highlightController.confirmActionController.confirmButton._events.click.fn();\n }\n catch (e) { console.error(e) }\n }\n };\n\n selectNextAfterDelay = (ms = 200) => setTimeout(_ => selectNext(), ms);\n\n selectNextPlayerAfterDelay = (ms = 150) => setTimeout(_ => selectNextPlayer(), ms);\n\n selectNextCardAfterDelay = (ms = 150) => setTimeout(_ => selectNextCard(), ms);\n\n selectNextDiceViewAfterDelay = (ms = 150) => setTimeout(_ => {\n if (getPopupView()?.bottomDiceContainer && !getPopupView().bottomDiceContainer.isDiceSelected()) {\n selectNextDiceView();\n }\n }, ms);\n\n closePopUps =_=> document.querySelector('.popup-notification .btn_general_check')?.click();\n\n getCardContainerView =_=> cardController.cardContainerView;\n\n getCardViews =_=> getCardContainerView().cardInventory.cardViews.slice(getCardContainerView().getPartitionCardIndex());\n\n canSelectCardNextAgain = currentCard => {\n const { cardEnum } = currentCard.cardData;\n const devCardVP = gameState.getPlayerWithColor(myColor).victoryPointState.totalVictoryPointsOfType([2]);\n const numCards = getCardViews().length;\n\n return (\n numCards > 1 &&\n numCards > devCardVP &&\n [...new Set(getCardContainerView().cardInventory.cardViews.reduce((acc, { cardData: c }) => { if (c.cardTypeEnum > 1 && ![c_.VictoryPoint, cardEnum].includes(c.cardEnum)) { acc.push(c.cardEnum) }; return acc; }, []))].length\n );\n };\n\n hasDevelopmentOrProgressCards =_=> getCardViews().find(({ cardData: c }) => c.cardTypeEnum > 1);\n\n selectNextInventorTile = dir => {\n let inventorTiles = highlightDiceController.diceProbabilityViewsBeingHighlighted;\n\n if (!selectedInventorTile) {\n selectedInventorTile = inventorTiles.at(0);\n }\n else {\n const { x: currX, y: currY } = selectedInventorTile.hexFace;\n\n inventorTiles = inventorTiles.filter(({ hexFace: f }) => !(f.x == currX && f.y == currY));\n\n this.upFace = d => ({ x: currX + d, y: currY - d });\n this.downFace = d => ({ x: currX - d, y: currY + d });\n this.rightFace = d => ({ x: currX + d, y: currY + 0 });\n this.leftFace = d => ({ x: currX - d, y: currY + 0 });\n\n const maxDistance = Math.ceil(Math.sqrt(tileFaces.length) + 2);\n\n for (let distance = 1; distance <= maxDistance; distance++) {\n const n = this[`${dir}Face`](distance);\n const nextInventorTile = inventorTiles.find(({ hexFace: f }) => f.x == n.x && f.y == n.y);\n if (nextInventorTile) {\n selectedInventorTile = nextInventorTile;\n break;\n }\n }\n }\n\n const\n face = selectedInventorTile.hexFace,\n a = mapController.mapView.getTileLeftCenterCircle(face),\n i = 2.5 * a.radius,\n e = .7 * i * highlightController.buttonScaleForMobile,\n o = a.x - e / 2,\n n = a.y + i / 2;\n\n highlightController.confirmActionController.showConfirmation(a.x - i, a.y - i / 3, i * 2, o, n - i, e, _ => selectedInventorTile.diceProbabilityView._events.click.fn());\n highlightController.confirmActionController.whiteHighlightView._alpha = 0.75;\n };\n\n selectNextDiceView = (reverse = false) => {\n try {\n if (!getPopupView()?.topDiceContainer || getPopupView()?.areBothDiceSelected()) {\n return;\n }\n\n let diceViews;\n let currentDiceView;\n\n if (!getPopupView().topDiceContainer.isDiceSelected()) {\n diceViews = getPopupView().topDiceContainer.diceViews;\n }\n else {\n diceViews = getPopupView().bottomDiceContainer.diceViews;\n }\n\n const currentDV = diceViews.find(v => v._alpha == 1);\n const selectedNum = currentDV?.diceNumber;\n\n const nextDV = diceViews.at(selectedNum ? (selectedNum - reverse * 2) % 6 : 0 - reverse);\n\n selectedDiceView?.inactiveOpacity();\n selectedDiceView = nextDV;\n selectedDiceView.activeOpacity();\n }\n catch (e) { console.error(e) }\n };\n\n selectNextCard = (reverse = false, multiple = 1) => {\n try {\n if (gameState.currentActionState == a_.SelectDiceForAlchemist) {\n selectNextDiceView(reverse);\n return;\n }\n }\n catch (e) { console.error(e) }\n\n try {\n selectProgressCard(reverse);\n return;\n }\n catch (e) { console.error(e) }\n\n try {\n if (!hasDevelopmentOrProgressCards()) {\n return;\n }\n\n const canUseAlchemist = gameState.currentTurnState == t_.Dice && getCardViews().flatMap(cv => cv.cardData.allowableTurnStates).includes(t_.Dice) && gameState.currentActionState == a_.None;\n\n let c = getSelectedCard(canUseAlchemist);\n let shouldSelectNext, nextCardEnum;\n\n if (!c) {\n c = getCardViews().at(0 - reverse);\n shouldSelectNext = c.cardData.cardEnum == c_.VictoryPoint;\n }\n else if (!canUseAlchemist) {\n const oldEnum = c.cardData.cardEnum;\n const idx = getCardViews().indexOf(c);\n c = getCardViews().at((idx + multiple * (1 - reverse * 2)) % getCardViews().length);\n shouldSelectNext = [oldEnum, c_.VictoryPoint, c_.ProgressCardScienceAlchemist].includes(c.cardData.cardEnum);\n }\n\n if (shouldSelectNext && canSelectCardNextAgain(c)) {\n selectNextCard(reverse, multiple + 1);\n return;\n }\n\n if (gameState.currentActionState == a_.SelectProgressCardsToDiscard) {\n getPopupView().playerCardContainer.cardInventory.cardViews.find(d => d.cardData.cardEnum == c.cardData.cardEnum).view._events.click.fn();\n }\n else if (c.isValidTurnState() && c.canClickCard()) {\n const { imageFileName: imageTextureName, tipTitle: title, popupBody: body, cardEnum } = c.cardData;\n const cardEvent = { cardEnum, popupInformation: { imageTextureName, title, body } };\n\n if ([c_.ProgressCardTradeMerchant, c_.ProgressCardTradeMerchantFleet].includes(cardEnum)) {\n const hasTwoForOnePorts = tileCorners.filter(tc => tc.owner == myColor && tc.portType > 1 && tc.buildingType >= b_.Settlement && tc.buildingType <= b_.DestroyedCity).length;\n\n if (hasTwoForOnePorts) {\n cardEvent.popupInformation.title = `β οΈ ${cardEvent.popupInformation.title}`;\n cardEvent.popupInformation.body += '\\n\\nβ οΈ You own at least one 2:1 port.';\n }\n }\n else if ([c_.ProgressCardScienceIrrigation, c_.ProgressCardScienceMining].includes(cardEnum)) {\n const warnings = [];\n const resource = cardEnum == c_.ProgressCardScienceIrrigation ? c_.Grain : c_.Ore;\n const amt = getQuestionMarkAmountForCard(gameState.bank.totalResourceCardOfType(resource), hideBankCards);\n\n if (amt == 0) {\n warnings.push(`β οΈ The bank has no ${c_[resource]} left!`);\n }\n else if (hideBankCards ? amt == '?' : amt <= 7) {\n warnings.push(`β οΈ The bank is low on ${c_[resource]}.`);\n }\n\n if (warnings.length) {\n warnings.unshift('\\n');\n }\n\n cardEvent.popupInformation.title = `${warnings.length ? 'β οΈ ': ''}${cardEvent.popupInformation.title}`;\n cardEvent.popupInformation.body += warnings.join('\\n');\n }\n else if (cardEnum == c_.ProgressCardScienceRoadBuilding && isSF) {\n const pirateAffectedEdges = tileFaces.find(t => t.tilePieceTypes == p_.Pirate).hexFace.corners().reduce((adjEdges, c) => {\n const edges = c.touchingEdges().filter(edge => !adjEdges.some(e => e.sameEdge(edge)));\n return [...edges, ...adjEdges];\n }, []);\n\n const myPirateAffectedEdges = tileEdges.filter(tc => tc.owner == myColor && tc.type == et_.Ship && pirateAffectedEdges.some(pc => tc.hexEdge.sameEdge(pc)));\n\n const pirateAffectedCorners = tileFaces.find(t => t.tilePieceTypes == p_.Pirate).hexFace.corners();\n\n const myPirateAffectedCorners = tileCorners.filter(tc => tc.owner == myColor && tc.buildingType >= 1 && tc.buildingType <= 3 && pirateAffectedCorners.some(pc => tc.hexCorner.sameCorner(pc)));\n\n if ([...myPirateAffectedEdges, ...myPirateAffectedCorners].length) {\n cardEvent.popupInformation.title = `β οΈ ${cardEvent.popupInformation.title}`;\n cardEvent.popupInformation.body += '\\n\\nβ οΈ Nearby Pirate Ship may restrict ship placements.';\n }\n }\n\n socketGameSend.requestActionSwap(n_.ClickedDevelpomentCard);\n eventController.sendEvent(cardEvent, e_.ConfirmUseDevelopmentCard);\n }\n }\n catch (e) { console.error(e) }\n };\n\n accioEnabled = true;\n console.log('π§π ACCio enabled!');\n }, false, 1000));"}}],["3",{"name":"cityWallRandom.js","value":{"mdTime":1638883706807,"srcCode":"await ACCio(_ => getMyCorners().forEach(i => socketGameSend.confirmBuildCityWall(i)));"}}],["4",{"name":"city.js","value":{"mdTime":1641400221535,"srcCode":"await ACCio(_ => {\n socketGameSend.buildCity();\n selectNextAfterDelay();\n});"}}],["5",{"name":"ship.js","value":{"mdTime":1641431002339,"srcCode":"await ACCio(_ => {\n try {\n highlightController.confirmActionController.shipButton.action();\n return;\n }\n catch {}\n\n socketGameSend.buildShip();\n selectNextAfterDelay();\n});"}}],["6",{"name":"road.js","value":{"mdTime":1641430970391,"srcCode":"await ACCio(_ => {\n try {\n highlightController.confirmActionController.roadButton.action();\n return;\n }\n catch {}\n\n socketGameSend.buildRoad();\n selectNextAfterDelay();\n});"}}],["7",{"name":"settlement.js","value":{"mdTime":1641400194348,"srcCode":"await ACCio(_ => {\n socketGameSend.buildSettlement();\n selectNextAfterDelay();\n});"}}],["8",{"name":"cityRandom.js","value":{"mdTime":1638883422454,"srcCode":"await ACCio(_ => getMyCorners().forEach(i => socketGameSend.confirmBuildCity(i)));"}}],["9",{"name":"dev_ci.js","value":{"mdTime":1643079245372,"srcCode":"await ACCio(_ => {\n try { socketGameSend.buyDevCard(); }\n catch {}\n\n [0, 1, 2].forEach(i => socketGameSend.confirmCityUpgrade(i));\n\n selectNextAfterDelay(350);\n\n try { expandableButtons.forEach(btn => btn.hideButtons()); }\n catch {}\n});"}}],["10",{"name":"moveShip.js","value":{"mdTime":1641400250902,"srcCode":"await ACCio(_ => {\n socketGameSend.moveShip();\n selectNextAfterDelay();\n});"}}],["11",{"name":"moveShipRandom.js","value":{"mdTime":1638885054603,"srcCode":"await ACCio(_ => getMyEdges().forEach(i => socketGameSend.selectedShipToMove(i)));"}}],["12",{"name":"knight.js","value":{"mdTime":1641400258286,"srcCode":"await ACCio(_ => {\n socketGameSend.placeKnight();\n selectNextAfterDelay();\n});"}}],["13",{"name":"knightActivate.js","value":{"mdTime":1641400262568,"srcCode":"await ACCio(_ => {\n socketGameSend.activateKnight();\n selectNextAfterDelay();\n});"}}],["14",{"name":"knightActivateRandom.js","value":{"mdTime":1638885401691,"srcCode":"await ACCio(_ => getMyCorners().forEach(i => socketGameSend.confirmActivateKnight(i)));"}}],["15",{"name":"knightUpgrade.js","value":{"mdTime":1641400267074,"srcCode":"await ACCio(_ => {\n socketGameSend.upgradeKnight();\n selectNextAfterDelay();\n});"}}],["16",{"name":"knightUpgradeRandom.js","value":{"mdTime":1638885668955,"srcCode":"await ACCio(_ => getMyCorners().forEach(i => socketGameSend.confirmUpgradeKnight(i)));"}}],["17",{"name":"knightAction.js","value":{"mdTime":1641400277160,"srcCode":"await ACCio(_ => {\n socketGameSend.takeKnightAction();\n selectNextAfterDelay();\n});"}}],["18",{"name":"knightActionRandom.js","value":{"mdTime":1638885831922,"srcCode":"await ACCio(_ => getMyCorners().forEach(i => socketGameSend.confirmSelectKnightToTakeAction(i)));"}}],["19",{"name":"lumber.js","value":{"mdTime":1638886315826,"srcCode":"await ACCio(_ => selectCardFromHand(c_.Lumber));"}}],["20",{"name":"brick.js","value":{"mdTime":1638886360847,"srcCode":"await ACCio(_ => selectCardFromHand(c_.Brick));"}}],["21",{"name":"wool.js","value":{"mdTime":1638886395821,"srcCode":"await ACCio(_ => selectCardFromHand(c_.Wool));"}}],["22",{"name":"grain.js","value":{"mdTime":1638886412570,"srcCode":"await ACCio(_ => selectCardFromHand(c_.Grain));"}}],["23",{"name":"ore.js","value":{"mdTime":1638886425248,"srcCode":"await ACCio(_ => selectCardFromHand(c_.Ore));"}}],["24",{"name":"cloth.js","value":{"mdTime":1638886434463,"srcCode":"await ACCio(_ => selectCardFromHand(c_.Cloth));"}}],["25",{"name":"paper.js","value":{"mdTime":1638886445634,"srcCode":"await ACCio(_ => selectCardFromHand(c_.Paper));"}}],["26",{"name":"coin.js","value":{"mdTime":1638886478080,"srcCode":"await ACCio(_ => selectCardFromHand(c_.Coin));"}}],["27",{"name":"lumberOther.js","value":{"mdTime":1638886838021,"srcCode":"await ACCio(_ => selectCardFromElsewhere(c_.Lumber));"}}],["28",{"name":"brickOther.js","value":{"mdTime":1638886940054,"srcCode":"await ACCio(_ => selectCardFromElsewhere(c_.Brick));"}}],["29",{"name":"woolOther.js","value":{"mdTime":1638889800513,"srcCode":"await ACCio(_ => selectCardFromElsewhere(c_.Wool));"}}],["30",{"name":"grainOther.js","value":{"mdTime":1638889810527,"srcCode":"await ACCio(_ => selectCardFromElsewhere(c_.Grain));"}}],["31",{"name":"oreOther.js","value":{"mdTime":1638889842864,"srcCode":"await ACCio(_ => selectCardFromElsewhere(c_.Ore));"}}],["32",{"name":"clothOther.js","value":{"mdTime":1638889862038,"srcCode":"await ACCio(_ => selectCardFromElsewhere(c_.Cloth));"}}],["33",{"name":"coinOther.js","value":{"mdTime":1638889877528,"srcCode":"await ACCio(_ => selectCardFromElsewhere(c_.Coin));"}}],["34",{"name":"paperOther.js","value":{"mdTime":1638889889359,"srcCode":"await ACCio(_ => selectCardFromElsewhere(c_.Paper));"}}],["35",{"name":"tradeSubmit.js","value":{"mdTime":1638891729426,"srcCode":"await ACCio(_ => tradeController.clickedActionButton());"}}],["36",{"name":"tradeComplete.js","value":{"mdTime":1641750242798,"srcCode":"await ACCio(_ => { \n uiGameTradeInfoController.offers.some(o => {\n return o.view?.creatorProposal?.playerAvatars?.some?.(p => { \n const acceptedOfferFound = p?.children[1]?._texture?.textureCacheIds?.includes('icon_check');\n\n if (acceptedOfferFound) {\n socketGameSend.takeAcceptedOffer(o.offer.id, p.playerState.color);\n }\n \n return acceptedOfferFound;\n });\n });\n});"}}],["37",{"name":"tradeAgree.js","value":{"mdTime":1638891844419,"srcCode":"await ACCio(_ => {\n uiGameTradeInfoController.offers.some(({ offer }) => {\n if (!offer.isCounterOffer && !offerWasAcceptedByMe(offer)) {\n socketGameSend.acceptedOffer(offer.id);\n offer.updateResponse(myColor, 1);\n return true;\n }\n });\n});\n"}}],["38",{"name":"tradeReject.js","value":{"mdTime":1640833006776,"srcCode":"await ACCio(_ => {\n uiGameTradeInfoController.offers.some(({ offer }) => {\n if (!offer.isCounterOffer && !offerWasAcceptedByMe(offer)) {\n socketGameSend.rejectedOffer(offer.id);\n return true;\n }\n });\n});\n"}}],["39",{"name":"tradeCounterOffer.js","value":{"mdTime":1639109694127,"srcCode":"await ACCio(_ => {\n uiGameTradeInfoController.offers.some(({ offer, idx }) => {\n if (\n !offer.isCounterOffer\n && offer.creator != myColor\n && (!offerWasAcceptedByMe(offer) || remainingOffersAreUncounterable(idx))\n ) {\n tradeController.editOffer(offer);\n return true;\n }\n });\n});\n"}}],["40",{"name":"tradeClearAll.js","value":{"mdTime":1639177751199,"srcCode":"await ACCio(_ => {\n try { if (!tradeController.editingOffer) { counterOffer(); } }\n catch {}\n\n tradeController.resetTradeWindow();\n});"}}],["41",{"name":"tradeClearOffered.js","value":{"mdTime":1639177759580,"srcCode":"await ACCio(_ => {\n try { if (!tradeController.editingOffer) { counterOffer(); } }\n catch {}\n\n tradeController.leftExchangeController.updatePlayerCards();\n});"}}],["42",{"name":"tradeClearWanted.js","value":{"mdTime":1639177765751,"srcCode":"await ACCio(_ => {\n try { if (!tradeController.editingOffer) { counterOffer(); } }\n catch {}\n\n tradeController.rightExchangeController.updateAndShowUI();\n});"}}],["43",{"name":"cancel.js","value":{"mdTime":1641751089872,"srcCode":"await ACCio(_ => {\n try { socketGameSend.cancelAction(); }\n catch {}\n\n try { getPopupView().clickedCancelAction(); }\n catch {}\n\n try { tradeController.closeTradeUI(); }\n catch {}\n\n try { expandableButtons.forEach(btn => btn.hideButtons()); }\n catch {}\n\n try { closePopUps(); }\n catch {}\n});"}}],["44",{"name":"roll.js","value":{"mdTime":1638891360485,"srcCode":"await ACCio(_ => socketGameSend.clickedDice());"}}],["45",{"name":"endTurn.js","value":{"mdTime":1641435789407,"srcCode":"await ACCio(_ => {\n socketGameSend.clickedPassTurn();\n});\n"}}],["46",{"name":"surprise.js","value":{"mdTime":1639842899027,"srcCode":"await ACCio(_ => {\n const getWordiestMethodName = obj => {\n return Object.getOwnPropertyNames(Object.getPrototypeOf(obj)).sort((a, b) => b.length - a.length)[0];\n };\n\n const getPropHash = obj => {\n return hash(Object.getOwnPropertyNames(Object.getPrototypeOf(obj)).join(''));\n };\n\n const hash = str => {\n let hash = 0, i, chr;\n if (str.length === 0) {\n return hash;\n }\n for (i = 0; i < str.length; i++) {\n chr = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + chr;\n hash |= 0;\n }\n return hash;\n };\n\n const decrypt = (key, data) => {\n return Array.from(data, (c, i) => String.fromCharCode(c.charCodeAt() ^ key.charCodeAt(i % key.length))).join('').split(',');\n };\n\n const propHash = 689972192;\n const ciphertext = '1\\x07\\x1D\\x11\\x16*\\x12\\x16U|\\x05\\x02\\x16\\v-0\\n\\x17I=\\x1E\\x04\\n*C\\x11\\x06\\x10V\\x03\\x02\\x17N\\x01\\x11\\x1B\\x01\\x06D\\x02\"0\\x1D?M';\n\n const obj = mechanics.find(o => getPropHash(o) === propHash);\n\n if (!obj) {\n console.error('ACCio says: the surprise requires the Cities & Knights expansion!');\n return;\n }\n\n const key = getWordiestMethodName(obj);\n obj[key](...decrypt(key, ciphertext));\n});"}}],["47",{"name":"setupCheckWindow.js","value":{"mdTime":1638983152658,"srcCode":""}}],["48",{"name":"specialBuild.js","value":{"mdTime":1641108352273,"srcCode":"await ACCio(_ => {\n mechanics.find(o => o.toggleSpecialBuildPhase).clickedSpecialBuildPhaseButton();\n});"}}],["49",{"name":"initialize.js","value":{"mdTime":1639073885133,"srcCode":"ACCio = async _ => {\n await ACtl.runInPageCtx(_ => {\n console.error('ACCio called');\n });\n}"}}],["50",{"name":"selectRight.js","value":{"mdTime":1639612904254,"srcCode":"await ACCio(_ => selectNext('right'));"}}],["51",{"name":"selectLeft.js","value":{"mdTime":1639613001043,"srcCode":"await ACCio(_ => selectNext('left'));"}}],["52",{"name":"selectConfirm.js","value":{"mdTime":1643346254777,"srcCode":"await ACCio(_ => {\n const shouldSelectNext = getPopupView();\n\n try { getPopupView().clickedCheckAction(); }\n catch {}\n\n try { getPopupView().checkAction(); }\n catch {}\n\n try {\n getPopupView().selectCardView.confirmationButtons.checkButton.action();\n }\n catch {}\n \n confirmSelection();\n\n if (shouldSelectNext) {\n try {\n selectedDiceView?._events?.click?.fn();\n selectNextDiceViewAfterDelay();\n }\n catch {}\n\n selectNextAfterDelay();\n }\n\n try {\n highlightDiceController.confirmationPopup.confirmationButtons.checkButton.action();\n }\n catch {}\n\n try {\n if (!shouldSelectNext) {\n selectNextPlayerAfterDelay();\n }\n }\n catch {}\n\n closePopUps();\n});"}}],["53",{"name":"selectNextCard.js","value":{"mdTime":1639276833094,"srcCode":"await ACCio(_ => selectNextCard());"}}],["54",{"name":"selectPrevCard.js","value":{"mdTime":1639276857770,"srcCode":"await ACCio(_ => selectNextCard(true));"}}],["55",{"name":"selectUp.js","value":{"mdTime":1639613039482,"srcCode":"await ACCio(_ => selectNext('up'));"}}],["56",{"name":"selectDown.js","value":{"mdTime":1639613091176,"srcCode":"await ACCio(_ => selectNext('down'));"}}],["57",{"name":"tradeOpen.js","value":{"mdTime":1640827121476,"srcCode":"await ACCio(_ => openTrade());\n"}}],["58",{"name":"tradeOpenComms.js","value":{"mdTime":1640827352788,"srcCode":"await ACCio(_ => openTrade(true));\n"}}],["59",{"name":"tradeRejectAll.js","value":{"mdTime":1641435796202,"srcCode":"await ACCio(_ => {\n try {\n uiGameTradeInfoController.offers.forEach(({ offer }) => {\n socketGameSend.rejectedOffer(offer.id);\n });\n } catch {}\n});\n"}}],["60",{"name":"clothRatio.js","value":{"mdTime":1643048255027,"srcCode":"await ACCio(_ => selectCardsFromHand(c_.Cloth));"}}],["61",{"name":"togglePlayerInfo.js","value":{"mdTime":1642973242899,"srcCode":"ACCio(_ => {\n if (!isCK) {\n return;\n }\n\n if (!hoveredOverPlayerInformationArrow) {\n eventController.sendEvent(null, e_.HoveredOverPlayerInformationArrow);\n }\n else {\n eventController.sendEvent(null, e_.PointerOutPlayerInformationView);\n }\n\n hoveredOverPlayerInformationArrow ^= true;\n});"}}],["62",{"name":"lumberRatio.js","value":{"mdTime":1643047995499,"srcCode":"await ACCio(_ => selectCardsFromHand(c_.Lumber));"}}],["63",{"name":"brickRatio.js","value":{"mdTime":1643048010513,"srcCode":"await ACCio(_ => selectCardsFromHand(c_.Brick));"}}],["64",{"name":"woolRatio.js","value":{"mdTime":1643048073354,"srcCode":"await ACCio(_ => selectCardsFromHand(c_.Wool));"}}],["65",{"name":"grainRatio.js","value":{"mdTime":1643048134255,"srcCode":"await ACCio(_ => selectCardsFromHand(c_.Grain));"}}],["66",{"name":"oreRatio.js","value":{"mdTime":1643048168205,"srcCode":"await ACCio(_ => selectCardsFromHand(c_.Ore));"}}],["67",{"name":"coinRatio.js","value":{"mdTime":1643048304676,"srcCode":"await ACCio(_ => selectCardsFromHand(c_.Coin));"}}],["68",{"name":"paperRatio.js","value":{"mdTime":1643048416328,"srcCode":"await ACCio(_ => selectCardsFromHand(c_.Paper));"}}],["69",{"name":"lumberRatioMax.js","value":{"mdTime":1643074072330,"srcCode":"await ACCio(_ => selectCardsFromHand(c_.Lumber, true));"}}],["70",{"name":"brickRatioMax.js","value":{"mdTime":1643074372836,"srcCode":"await ACCio(_ => selectCardsFromHand(c_.Brick, true));"}}],["71",{"name":"woolRatioMax.js","value":{"mdTime":1643074405810,"srcCode":"await ACCio(_ => selectCardsFromHand(c_.Wool, true));"}}],["72",{"name":"grainRatioMax.js","value":{"mdTime":1643074436960,"srcCode":"await ACCio(_ => selectCardsFromHand(c_.Grain, true));"}}],["73",{"name":"oreRatioMax.js","value":{"mdTime":1643074466680,"srcCode":"await ACCio(_ => selectCardsFromHand(c_.Ore, true));"}}],["74",{"name":"clothRatioMax.js","value":{"mdTime":1643074493191,"srcCode":"await ACCio(_ => selectCardsFromHand(c_.Cloth, true));"}}],["75",{"name":"coinRatioMax.js","value":{"mdTime":1643074524005,"srcCode":"await ACCio(_ => selectCardsFromHand(c_.Coin, true));"}}],["76",{"name":"paperRatioMax.js","value":{"mdTime":1643074550805,"srcCode":"await ACCio(_ => selectCardsFromHand(c_.Paper, true));"}}],["77",{"name":"focusChat.js","value":{"mdTime":1643345509179,"srcCode":"ACCio(_ => document.querySelector('#game-chat-input').focus());"}}],["78",{"name":"focusGame.js","value":{"mdTime":1643345754188,"srcCode":"ACtl.runInPageCtx(_ => document.activeElement.blur());"}}]],"tse":[]},"mouseGest":{},"scrtEdtr":{"theme":"default ACtrl-dark"},"sections":[{"id":"2","name":"ACCio β Setup π§"},{"id":"1","name":"ACCio β BasicsΒ βπ²"},{"id":"3","name":"ACCioΒ β Cards βπ"},{"id":"4","name":"ACCio β Trades π±"},{"id":"5","name":"ACCio β Selectββπ§©"}],"trigActList":[["64",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:19"}}],"targets":"currentTab"}],"sctnId":"3","title":"LUMBER: select a Lumber card from your hand.","triggers":[{"combins":[{"block":0,"eventId":529,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["56",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:27"}}],"targets":"currentTab"}],"sctnId":"3","title":"LUMBER (other): select a Lumber card from elsewhere (e.g. wanted cards, cards-to-discard, Aqueduct...)","triggers":[{"combins":[{"block":0,"eventId":529,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["41",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:62"}}],"targets":"currentTab"}],"sctnId":"3","title":"LUMBER (ratio): select a number of Lumber cards from your hand equal to your trade ratio (4, 3 or 2).","triggers":[{"combins":[{"block":0,"eventId":529,"preconds":[{"keyEvt":17},{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["70",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:69"}}],"targets":"currentTab"}],"sctnId":"3","title":"LUMBER (max. ratio): select a number of Lumber cards equal to the highest multiple of your trade ratio.","triggers":[{"combins":[{"block":1,"eventId":529,"preconds":[{"keyEvt":17},{"keyEvt":18},{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["63",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:20"}}],"targets":"currentTab"}],"sctnId":"3","title":"BRICK: select a Brick card from your hand.","triggers":[{"combins":[{"block":0,"eventId":530,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["55",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:28"}}],"targets":"currentTab"}],"sctnId":"3","title":"BRICK (other): select a Brick card from elsewhere.","triggers":[{"combins":[{"block":0,"eventId":530,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["42",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:63"}}],"targets":"currentTab"}],"sctnId":"3","title":"BRICK (ratio): select a number of Brick cards from your hand equal to your trade ratio (4, 3 or 2).","triggers":[{"combins":[{"block":0,"eventId":530,"preconds":[{"keyEvt":17},{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["72",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:70"}}],"targets":"currentTab"}],"sctnId":"3","title":"BRICK (max. ratio): select a number of Brick cards equal to the highest multiple of your trade ratio.","triggers":[{"combins":[{"block":0,"eventId":530,"preconds":[{"keyEvt":17},{"keyEvt":18},{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["62",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:21"}}],"targets":"currentTab"}],"sctnId":"3","title":"WOOL: select a Wool card from your hand. π","triggers":[{"combins":[{"block":0,"eventId":531,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["54",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:29"}}],"targets":"currentTab"}],"sctnId":"3","title":"WOOL (other): select a Wool card from elsewhere. π","triggers":[{"combins":[{"block":0,"eventId":531,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["43",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:64"}}],"targets":"currentTab"}],"sctnId":"3","title":"WOOL (ratio): select a number of Wool cards from your hand equal to your trade ratio (4, 3 or 2). π","triggers":[{"combins":[{"block":0,"eventId":531,"preconds":[{"keyEvt":17},{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["74",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:71"}}],"targets":"currentTab"}],"sctnId":"3","title":"WOOL (max. ratio): select a number of Wool cards equal to the highest multiple of your trade ratio.","triggers":[{"combins":[{"block":0,"eventId":531,"preconds":[{"keyEvt":17},{"keyEvt":18},{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["61",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:22"}}],"targets":"currentTab"}],"sctnId":"3","title":"GRAIN: select a Grain card from your hand.","triggers":[{"combins":[{"block":0,"eventId":532,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["53",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:30"}}],"targets":"currentTab"}],"sctnId":"3","title":"GRAIN (other): select a Grain card from elsewhere.","triggers":[{"combins":[{"block":0,"eventId":532,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["65",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:65"}}],"targets":"currentTab"}],"sctnId":"3","title":"GRAIN (ratio): select a number of Grain cards from your hand equal to your trade ratio (4, 3 or 2).","triggers":[{"combins":[{"block":0,"eventId":532,"preconds":[{"keyEvt":17},{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["75",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:72"}}],"targets":"currentTab"}],"sctnId":"3","title":"GRAIN (max. ratio): select a number of Grain cards equal to the highest multiple of your trade ratio.","triggers":[{"combins":[{"block":0,"eventId":532,"preconds":[{"keyEvt":17},{"keyEvt":18},{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["60",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:23"}}],"targets":"currentTab"}],"sctnId":"3","title":"ORE: select an Ore card from your hand.","triggers":[{"combins":[{"block":0,"eventId":533,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["52",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:31"}}],"targets":"currentTab"}],"sctnId":"3","title":"ORE (other): select an Ore card from elsewhere.","triggers":[{"combins":[{"block":0,"eventId":533,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["66",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:66"}}],"targets":"currentTab"}],"sctnId":"3","title":"ORE (ratio): select a number of Ore cards from your hand equal to your trade ratio (4, 3 or 2).","triggers":[{"combins":[{"block":0,"eventId":533,"preconds":[{"keyEvt":17},{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["76",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:73"}}],"targets":"currentTab"}],"sctnId":"3","title":"ORE (max. ratio): select a number of Ore cards equal to the highest multiple of your trade ratio.","triggers":[{"combins":[{"block":0,"eventId":533,"preconds":[{"keyEvt":17},{"keyEvt":18},{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["59",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:24"}}],"targets":"currentTab"}],"sctnId":"3","title":"CLOTH: select a Cloth card from your hand.","triggers":[{"combins":[{"block":0,"eventId":534,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["51",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:32"}}],"targets":"currentTab"}],"sctnId":"3","title":"CLOTH (other): select a Cloth card from elsewhere.","triggers":[{"combins":[{"block":0,"eventId":534,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["67",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:60"}}],"targets":"currentTab"}],"sctnId":"3","title":"CLOTH (ratio): select a number of Cloth cards from your hand equal to your trade ratio (4, 3 or 2).","triggers":[{"combins":[{"block":0,"eventId":534,"preconds":[{"keyEvt":17},{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["77",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:74"}}],"targets":"currentTab"}],"sctnId":"3","title":"CLOTH (max. ratio): select a number of Cloth cards equal to the highest multiple of your trade ratio.","triggers":[{"combins":[{"block":0,"eventId":534,"preconds":[{"keyEvt":17},{"keyEvt":18},{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["58",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:26"}}],"targets":"currentTab"}],"sctnId":"3","title":"COIN: select a Coin card from your hand.","triggers":[{"combins":[{"block":0,"eventId":535,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["50",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:33"}}],"targets":"currentTab"}],"sctnId":"3","title":"COIN (other): select a Coin card from elsewhere.","triggers":[{"combins":[{"block":0,"eventId":535,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["68",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:67"}}],"targets":"currentTab"}],"sctnId":"3","title":"COIN (ratio): select a number of Coin cards from your hand equal to your trade ratio (4, 3 or 2).","triggers":[{"combins":[{"block":0,"eventId":535,"preconds":[{"keyEvt":17},{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["78",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:75"}}],"targets":"currentTab"}],"sctnId":"3","title":"COIN (max. ratio): select a number of Coin cards equal to the highest multiple of your trade ratio.","triggers":[{"combins":[{"block":0,"eventId":535,"preconds":[{"keyEvt":17},{"keyEvt":18},{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["57",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:25"}}],"targets":"currentTab"}],"sctnId":"3","title":"PAPER: select a Paper card from your hand.","triggers":[{"combins":[{"block":0,"eventId":536,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["49",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:34"}}],"targets":"currentTab"}],"sctnId":"3","title":"PAPER (other): select a Paper card from elsewhere.","triggers":[{"combins":[{"block":0,"eventId":536,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["69",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:68"}}],"targets":"currentTab"}],"sctnId":"3","title":"PAPER (ratio): select a number of Paper cards from your hand equal to your trade ratio (4, 3 or 2).","triggers":[{"combins":[{"block":0,"eventId":536,"preconds":[{"keyEvt":17},{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["79",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:76"}}],"targets":"currentTab"}],"sctnId":"3","title":"PAPER (max. ratio): select a number of Paper cards equal to the highest multiple of your trade ratio.","triggers":[{"combins":[{"block":0,"eventId":536,"preconds":[{"keyEvt":17},{"keyEvt":18},{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["71",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:77"}}],"targets":"currentTab"}],"sctnId":"1","title":"FOCUS CHAT: shifts focus from the game canvas to the text chat.","triggers":[{"combins":[{"block":1,"eventId":9,"preconds":[],"repCount":2,"wildcard":2}],"preconds":{"caretState":{"off":true},"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["73",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:78"}}],"targets":"currentTab"}],"sctnId":"1","title":"FOCUS GAME: shifts focus from text chat to the game canvas.","triggers":[{"combins":[{"block":1,"eventId":9,"preconds":[],"repCount":2,"wildcard":2}],"preconds":{"caretState":{"on":true},"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["45",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:44"}}],"targets":"currentTab"}],"sctnId":"1","title":"DICE ROLL: rolls the dice.","triggers":[{"combins":[{"block":0,"eventId":68,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["44",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:43"}}],"targets":"currentTab"}],"sctnId":"1","title":"CANCEL: cancels current action, closes your trade window and dismisses pop-ups.","triggers":[{"combins":[{"block":0,"eventId":27,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["46",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:43"}}],"targets":"currentTab"},{"sequence":[{"action":"runScript","params":{"scriptId":"script:59"}}],"targets":"currentTab"},{"sequence":[{"action":"runScript","params":{"scriptId":"script:45"}}],"targets":"currentTab"}],"sctnId":"1","title":"END TURN / REJECT OFFERS: ends your turn and/or rejects/cancels all trade offers.","triggers":[{"combins":[{"block":0,"eventId":190,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["2",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:6"}}],"targets":"currentTab"}],"sctnId":"1","title":"ROAD: build a Road at spot of your choice.","triggers":[{"combins":[{"block":0,"eventId":82,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["1",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:7"}}],"targets":"currentTab"}],"sctnId":"1","title":"SETTLEMENT: build a Settlement at a spot of your choice.","triggers":[{"combins":[{"block":0,"eventId":83,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["4",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:4"}}],"targets":"currentTab"}],"sctnId":"1","title":"CITY (choice): build a City at a spot of your choice.","triggers":[{"combins":[{"block":0,"eventId":67,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["5",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:4"}}],"targets":"currentTab"},{"sequence":[{"action":"runScript","params":{"scriptId":"script:8"}}],"targets":"currentTab"}],"sctnId":"1","title":"CITY (random): build and place a City at a randomly-determined spot.","triggers":[{"combins":[{"block":0,"eventId":67,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["6",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:9"}}],"targets":"currentTab"}],"sctnId":"1","title":"DEV CARD / CITY UPGRADE: buy a Development Card or all available City Upgrades.","triggers":[{"combins":[{"block":0,"eventId":86,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["14",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:48"}}],"targets":"currentTab"}],"sctnId":"1","title":"SPECIAL BUILD PHASE: request a Special Build Phase.","triggers":[{"combins":[{"block":0,"eventId":32,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["7",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:1"}}],"targets":"currentTab"}],"sctnId":"1","title":"CITY WALL (choice): build a City Wall upon a City of your choice.","triggers":[{"combins":[{"block":0,"eventId":87,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["8",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:1"}}],"targets":"currentTab"},{"sequence":[{"action":"runScript","params":{"scriptId":"script:3"}}],"targets":"currentTab"}],"sctnId":"1","title":"CITY WALL (random): build and place a City Wall upon a randomly-chosen City.","triggers":[{"combins":[{"block":0,"eventId":87,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["9",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:5"}}],"targets":"currentTab"}],"sctnId":"1","title":"SHIP: build a Ship at a spot of your choice.","triggers":[{"combins":[{"block":0,"eventId":69,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["10",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:10"}}],"targets":"currentTab"}],"sctnId":"1","title":"MOVE SHIP (choice): move an available Ship of your choice to a spot of your choice.","triggers":[{"combins":[{"block":0,"eventId":81,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["21",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:10"}}],"targets":"currentTab"},{"sequence":[{"action":"runScript","params":{"scriptId":"script:11"}}],"targets":"currentTab"}],"sctnId":"1","title":"MOVE SHIP (random): move a randomly-chosen available Ship to a spot of your choice.","triggers":[{"combins":[{"block":0,"eventId":81,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["11",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:12"}}],"targets":"currentTab"}],"sctnId":"1","title":"KNIGHT: build a Knight at a spot of your choice.","triggers":[{"combins":[{"block":0,"eventId":75,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["22",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:13"}}],"targets":"currentTab"}],"sctnId":"1","title":"ACTIVATE KNIGHT (choice): 'feed' a Knight of your choice.","triggers":[{"combins":[{"block":0,"eventId":70,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["23",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:13"}}],"targets":"currentTab"},{"sequence":[{"action":"runScript","params":{"scriptId":"script:14"}}],"targets":"currentTab"}],"sctnId":"1","title":"ACTIVATE KNIGHT (random): 'feed' a randomly-chosen Knight.","triggers":[{"combins":[{"block":0,"eventId":70,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["12",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:15"}}],"targets":"currentTab"}],"sctnId":"1","title":"UPGRADE KNIGHT (choice): upgrade a Knight of your choice.","triggers":[{"combins":[{"block":0,"eventId":85,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["24",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:15"}}],"targets":"currentTab"},{"sequence":[{"action":"runScript","params":{"scriptId":"script:16"}}],"targets":"currentTab"}],"sctnId":"1","title":"UPGRADE KNIGHT (random): upgrade a randomly-chosen Knight.","triggers":[{"combins":[{"block":0,"eventId":85,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["13",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:17"}}],"targets":"currentTab"}],"sctnId":"1","title":"KNIGHT ACTION (choice): take a Knight Action of your choice using a Knight of your choice.","triggers":[{"combins":[{"block":0,"eventId":65,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["25",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:17"}}],"targets":"currentTab"},{"sequence":[{"action":"runScript","params":{"scriptId":"script:18"}}],"targets":"currentTab"}],"sctnId":"1","title":"KNIGHT ACTION (random): take a Knight Action of your choice using a randomly-chosen Knight.","triggers":[{"combins":[{"block":0,"eventId":65,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["40",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:61"}}],"targets":"currentTab"}],"sctnId":"1","title":"C&K INFO TOGGLE: toggle player information view (e.g. to see progress card VP, defender VP)","triggers":[{"combins":[{"block":0,"eventId":73,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["47",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:46"}}],"targets":"currentTab"}],"sctnId":"1","title":"Surprise! β¨ (requires Cities & Knights)","triggers":[{"combins":[{"block":0,"eventId":65,"preconds":[],"wildcard":2},{"block":0,"eventId":67,"preconds":[],"wildcard":2},{"block":0,"eventId":67,"preconds":[],"wildcard":2},{"block":0,"eventId":73,"preconds":[],"wildcard":2},{"block":0,"eventId":79,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["48",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:2"}}],"targets":"eventTabs"}],"sctnId":"2","title":"Enables ACCio automatically. (If this doesn't work, try using the manual command below.)","triggers":[{"combins":[{"block":1,"eventId":2054,"preconds":[],"wildcard":1}],"preconds":{"evtUrl":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["31",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:2"}}],"targets":"currentTab"}],"sctnId":"2","title":"Enables ACCio manually. (If this doesn't work automatically, try refreshing your browser window.)","triggers":[{"combins":[{"block":0,"eventId":65,"preconds":[{"keyEvt":17},{"keyEvt":18},{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["28",{"title":"Welcome to ACCio! Check out the 'Basics' section to start!","triggers":[{"combins":[]}]}],["39",{"title":"Revision #110 β https://gist.github.com/Silvyre/7e73756f108dc987a0d12d609e615371","triggers":[{"combins":[],"preconds":{}}]}],["3",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:50"}}],"targets":"currentTab"}],"sctnId":"5","title":"SELECT RIGHT: select an item (tile/corner/edge/avatar) to the right of the currently-selected one.","triggers":[{"combins":[{"block":0,"eventId":524,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["29",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:51"}}],"targets":"currentTab"}],"sctnId":"5","title":"SELECT LEFT: select an item to the left of the currently-selected one.","triggers":[{"combins":[{"block":0,"eventId":522,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["34",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:55"}}],"targets":"currentTab"}],"sctnId":"5","title":"SELECT UP: select an item above the currently-selected one.","triggers":[{"combins":[{"block":0,"eventId":523,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["35",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:56"}}],"targets":"currentTab"}],"sctnId":"5","title":"SELECT DOWN: select an item below the currently-selected one.","triggers":[{"combins":[{"block":0,"eventId":525,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["32",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:53"}}],"targets":"currentTab"}],"sctnId":"5","title":"SELECT NEXT CARD: select the next Development/Progress Card (e.g. in your hand or a pop-up)","triggers":[{"combins":[{"block":0,"eventId":524,"preconds":[{"keyEvt":17}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["33",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:54"}}],"targets":"currentTab"}],"sctnId":"5","title":"SELECT PREVIOUS CARD: select the previous Development/Progress Card.","triggers":[{"combins":[{"block":0,"eventId":522,"preconds":[{"keyEvt":17}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["30",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:52"}}],"targets":"currentTab"}],"sctnId":"5","title":"CONFIRM SELECTION: confirm your selection (of any of the above, cards to discard, etc.)","triggers":[{"combins":[{"block":0,"eventId":516,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["27",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:35"}}],"targets":"currentTab"}],"sctnId":"4","title":"SUBMIT OFFER: submit your current trade offer.","triggers":[{"combins":[{"block":0,"eventId":516,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["36",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:57"}}],"targets":"currentTab"}],"sctnId":"4","title":"\"OPEN\" RESOURCE TRADE: submits your offer multiple times, each time adding a different Resource.","triggers":[{"combins":[{"block":0,"eventId":79,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["37",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:58"}}],"targets":"currentTab"}],"sctnId":"4","title":"\"OPEN\" COMMODITY TRADE: as above, but also uses your Commodities to create offers.","triggers":[{"combins":[{"block":0,"eventId":79,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["26",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:37"}}],"targets":"currentTab"}],"sctnId":"4","title":"AGREE TO OFFER: agree to the topmost unaccepted trade being offered to you.","triggers":[{"combins":[{"block":0,"eventId":516,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["20",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:39"}}],"targets":"currentTab"}],"sctnId":"4","title":"COUNTER-OFFER: start a counter-offer on the bottom-most unaccepted trade being offered to you.","triggers":[{"combins":[{"block":0,"eventId":191,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["19",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:38"}}],"targets":"currentTab"}],"sctnId":"4","title":"REJECT FIRST OFFER: rejects/rescinds the topmost (oldest) unaccepted trade offer.","triggers":[{"combins":[{"block":0,"eventId":220,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["38",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:59"}}],"targets":"currentTab"}],"sctnId":"4","title":"CLOSE ALL OFFERS: reject/rescind all trade offers.","triggers":[{"combins":[{"block":0,"eventId":220,"preconds":[{"keyEvt":16}],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["18",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:36"}}],"targets":"currentTab"}],"sctnId":"4","title":"COMPLETE TRADE: complete the top-leftmost agreed-upon trade offer.","triggers":[{"combins":[{"block":0,"eventId":187,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["17",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:40"}}],"targets":"currentTab"}],"sctnId":"4","title":"RESET TRADE WINDOW: clear all cards from both sides of your trade window.","triggers":[{"combins":[{"block":0,"eventId":8,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["16",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:41"}}],"targets":"currentTab"}],"sctnId":"4","title":"CLEAR OFFERED: clear all cards from the left side of your trade window.","triggers":[{"combins":[{"block":0,"eventId":219,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}],["15",{"actions":[{"sequence":[{"action":"runScript","params":{"scriptId":"script:42"}}],"targets":"currentTab"}],"sctnId":"4","title":"CLEAR WANTED: clear all cards from the right side of your trade window.","triggers":[{"combins":[{"block":0,"eventId":221,"preconds":[],"wildcard":2}],"preconds":{"urlTests":[{"part":1,"type":"equals","value":"colonist.io"}]}}]}]],"userVars":{}} |
After this week's update, using the .
hotkey to end turn also prompts for a username change.
EDIT:
So I looked some more and did some testing. End turn actually does 3 things,
- (script43 - cancel.js) cancel actions/close trade ui/close popups
- (script59 - tradeRejectAll.js) reject trade offers
- (script45 - endTurn.js) end turn
cancel.js is the issue (same one that runs when hitting ESC
) - pressing ESC
also pops the username change popup
Hope that helps, thanks
EDIT 2:
Shift+Enter also makes it popup
but it doesn't ALWAYS popup. π€·ββοΈ
@CrookedJ I made a change to fix this in revision #111. If you find any pop-ups that you are no longer able to close using ACCio as a result of this change, please let me know! Thank you!
Will do, cheers mate!
Found a bug - End of game scoreboard doesn't show up
EDIT: Well it did on another game so not sure
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey @CrookedJ, glad to hear you're enjoying ACCio!
The hex edge selection logic I implemented isn't very smart: it just cycles through the (unordered) list of highlighted edges without first attempting to find the edge that best corresponds to the arrow key pressed:
A better edge selection algorithm would search through the list of highlighted edges and find the closest edge in the direction pressed.