-
[타운스타] Autosell 오토셀 스크립트 사용방법게임/타운스타 2022. 2. 3. 21:21728x90반응형
타운스타 오토셀 스크립트를 이용하면 재료가 모일때마다 자동으로 팔아줘서 게임하기가 수월해진다.
1. 필수 설치 파일
위 사이트에서 스크립트를 실행해주는 프로그램을 설치하면 된다.
반응형2. 스크립트 다운로드
https://gala-analytics.herokuapp.com/townstar
위 사이트에서 스크립트를 다운로드 받을 수 있다.
코드의 맨 윗부분 유저스크립트에서, 한줄을 바꿔줘야한다.
@match 부분에 // @match *://*.sandbox-games.com/* 라고 넣어줘야 타운스타 내에서 스크립트가 동작한다.
아래는 내가 사용중인 코드 전문이다.
더보기// ==UserScript== // @name Town Star Auto-Sell // @namespace http://tampermonkey.net/ // @version 2.3 // @description Automatically sell crafted items. // @author Groove // @match *://*.sandbox-games.com/* // @grant none // @run-at document-start // ==/UserScript== (function() { 'use strict'; // keepAmt is the amount that you do not want to sell // sellMin is the minimum amount needed before attempting to sell // setting a sellMin of 100 will ensure that the item is only sold in batches of 100 (e.g. via Freight Ship) const craftedItems = [ //농작물 {item: 'Pinot_Noir_Grapes', keepAmt: 3, sellMin: 0}, //{item: 'Wheat', keepAmt: 0, sellMin: 0}, {item: 'Gasoline', keepAmt: 3, sellMin: 0}, {item: 'Wood', keepAmt: 10, sellMin: 0}, {item: 'Oak_Wood', keepAmt: 3, sellMin: 0}, {item: 'Lumber', keepAmt: 3, sellMin: 0}, //공산품 {item: 'Wine_Bottle', keepAmt: 3, sellMin: 0}, {item: 'Energy', keepAmt: 3, sellMin: 0}, {item: 'Pinot_Noir', keepAmt: 0, sellMin: 0}, // 철광산 {item: 'Silica', keepAmt: 6, sellMin: 0}, {item: 'Limestone', keepAmt: 3, sellMin: 0}, {item: 'Chromium', keepAmt: 3, sellMin: 0}, {item: 'Iron', keepAmt: 3, sellMin: 0} ] new MutationObserver(function(mutations) { let airdropcollected = 0; if(document.getElementsByClassName('hud-jimmy-button')[0] && document.getElementsByClassName('hud-jimmy-button')[0].style.display != 'none'){ document.getElementsByClassName('hud-jimmy-button')[0].click(); document.getElementById('Deliver-Request').getElementsByClassName('yes')[0].click(); document.getElementById('Deliver-Request').getElementsByClassName('close-button')[0].click(); } if(document.getElementsByClassName('hud-airdrop-button')[0] && document.getElementsByClassName('hud-airdrop-button')[0].style.display != 'none'){ if(airdropcollected == 0){ airdropcollected = 1; document.getElementsByClassName('hud-airdrop-button')[0].click(); document.getElementsByClassName('air-drop')[0].getElementsByClassName('yes')[0].click(); } } if (document.getElementById("playnow-container") && document.getElementById("playnow-container").style.visibility !== "hidden") { if(typeof Game == 'undefined' || (Game && Game.gameData == null)) { window.location.reload(); } else { document.getElementById("playButton").click(); console.log(Date.now() + ' ---===ACTIVATING AUTO SELL===---'); ActivateAutoSell(); } } }).observe(document, {childList: true, subtree: true}); function GetAvailableTradeObject(capacity) { return Object.values(Game.town.objectDict).filter(tradeObj => tradeObj.logicType === 'Trade') .find(tradeObj => Game.unitsData[tradeObj.objData.UnitType].Capacity == capacity && !Game.town.tradesList.find(activeTrade => activeTrade.source.x == tradeObj.townX && activeTrade.source.z == tradeObj.townZ) ) } function CloseWindows(elements, checkParent) { for (let i=0, n=elements.length; i < n; i++) { let el = checkParent ? elements[i].closest('.container') : elements[i]; let elVis = el.currentStyle ? el.currentStyle.visibility : getComputedStyle(el, null).visibility; let elDis = el.currentStyle ? el.currentStyle.display : getComputedStyle(el, null).display; if (!(elVis === 'hidden' || elDis === 'none')) { el.querySelector('.close-button') && el.querySelector('.close-button').click(); } } } async function WaitForCompletion(selector) { while (document.querySelector(selector) !== null) { await new Promise( resolve => requestAnimationFrame(resolve) ) } return document.querySelector(selector); } async function WaitForTradeLoad(targetTradeObj) { return await new Promise(resolve => { const waitForUpdate = setInterval(() => { let tradeUiObj = Game.app.root.findByName('TradeUi').script.trade.townObject; if (tradeUiObj && tradeUiObj.townX == targetTradeObj.townX && tradeUiObj.townZ == targetTradeObj.townZ && Game.app.root.findByName('TradeUi').script.trade.cityPaths[0].gasCost) { resolve('Loaded'); clearInterval(waitForUpdate); }; }, 500); }); } async function WaitForElement(selector) { while (document.querySelector(selector) === null) { await new Promise( resolve => requestAnimationFrame(resolve) ) } await new Promise(resolve => setTimeout(resolve, 1000)); return document.querySelector(selector); } async function CheckCrafts() { let allTradeObjects = Object.values(Game.town.objectDict).filter(tradeObj => tradeObj.logicType === 'Trade'); for (let i=0, n=allTradeObjects.length; i < n; i++) { if (allTradeObjects[i].logicObject.tapToCollectEntity.enabled) { allTradeObjects[i].logicObject.OnTapped(); } } if (Game.town.GetStoredCrafts()['Gasoline'] >= 1) { for (let i=0, n=craftedItems.length; i < n; i++) { if (Game.town.GetStoredCrafts()[craftedItems[i].item] >= craftedItems[i].keepAmt + 10) { let targetTradeObj; if (Game.town.GetStoredCrafts()[craftedItems[i].item] >= 100 + craftedItems[i].keepAmt) { targetTradeObj = GetAvailableTradeObject(100); } if (!targetTradeObj && Game.town.GetStoredCrafts()[craftedItems[i].item] >= 50 + craftedItems[i].keepAmt && craftedItems[i].sellMin <= 50){ targetTradeObj = GetAvailableTradeObject(50); } if (!targetTradeObj && Game.town.GetStoredCrafts()[craftedItems[i].item] >= 10 + craftedItems[i].keepAmt && craftedItems[i].sellMin <= 10){ targetTradeObj = GetAvailableTradeObject(10); } if (targetTradeObj){ CloseWindows(document.querySelectorAll('body > .container > .player-confirm .dialog-cell'), false); CloseWindows(document.querySelectorAll('.container > div:not(.hud):not(.player-confirm)'), true); Game.town.selectObject(targetTradeObj); Game.app.fire('SellClicked', {x: targetTradeObj.townX, z: targetTradeObj.townZ}); await WaitForCompletion('.LoadingOrders'); document.querySelector('#trade-craft-target [data-name="' + craftedItems[i].item + '"]').click(); await WaitForTradeLoad(targetTradeObj); if (Game.town.GetStoredCrafts()['Gasoline'] >= Game.app.root.findByName('TradeUi').script.trade.cityPaths[0].gasCost) { document.querySelector('#destination-target .destination .sell-button').click(); let tradeTimeout = setTimeout(function(){ document.querySelector('.trade-connection .no').click(); },10000); await WaitForCompletion('.trade-connection .compass'); clearTimeout(tradeTimeout); } else { console.log('Whoops! You have run out of gas.'); document.querySelector('#autosell-status .bank').textContent = 'ALERT: Out of gas!' document.querySelector('.container > .trade .close-button').click(); } } } } } else { console.log('Whoops! You have run out of gas.'); document.querySelector('#autosell-status .bank').textContent = 'ALERT: Out of gas!' } setTimeout(CheckCrafts, 5000); } async function ActivateAutoSell() { let autoSellStatus = document.createElement('div'); autoSellStatus.id = 'autosell-status'; autoSellStatus.style.cssText = 'pointer-events: all; position: absolute; left: 50%; transform: translate(-50%, 0);'; autoSellStatus.addEventListener( 'click', function(){this.children[0].textContent = 'Auto-Sell Active';}) let autoSellContent = document.createElement('div'); autoSellContent.classList.add('bank'); autoSellContent.style.cssText = 'background-color: #fde7e3; padding-left: 10px; padding-right: 10px'; autoSellContent.textContent = 'Auto-Sell Active'; autoSellStatus.appendChild(autoSellContent); await WaitForElement('.hud'); document.querySelector('.hud').prepend(autoSellStatus); CheckCrafts(); } })();
17번 라인의 const craftedItems = [ 부분에서,
팔고싶은 아이템을 적으면 된다.
예시로, {item: 'Wheat', keepAmt: 3, sellMin: 0} 의 의미는
Wheat(밀)이 3개를 항상 유지하며, 팔수있을때 판다(sellMin:0) 라는 뜻이다.
즉, 밀이 13개가 모이면 판매를 한다.
3. 타운스타 실행
타운스타를 실행하면 가운데 윗부분에 Auto-Sell Active라고 표시가 된다.
혹은 크롬 브라우저 창에 아래 스크린샷과 같이 TamperMonkey의 빨간색 1을 발견할 수 있다.
4. 평가
매우 편하게 게임을 할 수 있다.
특히 마을 건설 초반에 가솔린 테크가 완성되기 전에 돈을 모아야하는 시기가 있다.
그때 지루하지않고 편하게 지나갈 수 있고
중반쯤, 고급인력으로 대체할 때 돈이 많이 필요하게 된다.
하룻밤 켜놓고 자면 다음날 돈이 많이 모여있어서 마을 완성을 바로 할 수 있게 된다.
728x90반응형