Last active
December 17, 2019 23:28
-
-
Save dragonfax/ff4d7f4ee226348d99b9 to your computer and use it in GitHub Desktop.
auto clicker for steam summer game (wchill version)
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
// ==UserScript== | |
// @name Monster Minigame Auto-script | |
// @namespace https://github.com/wchill/steamSummerMinigame | |
// @description A script that runs the Steam Monster Minigame for you. Modified from mouseas's original version to include autoclick. | |
// @version 1.0 | |
// @match http://steamcommunity.com/minigame/towerattack* | |
// @updateURL https://raw.githubusercontent.com/wchill/steamSummerMinigame/master/autoPlay.js | |
// @downloadURL https://raw.githubusercontent.com/wchill/steamSummerMinigame/master/autoPlay.js | |
// ==/UserScript== | |
// IMPORTANT: Update the @version property above to a higher number such as 1.1 and 1.2 when you update the script! Otherwise, Tamper / Greasemonkey users will not update automatically. | |
var clickRate = 15; // change to number of desired clicks per second | |
var isAlreadyRunning = false; | |
if (thingTimer !== undefined) { | |
window.clearTimeout(thingTimer); | |
} | |
function doTheThing() { | |
if (isAlreadyRunning || g_Minigame === undefined || !g_Minigame.CurrentScene().m_bRunning || !g_Minigame.CurrentScene().m_rgPlayerTechTree) { | |
return; | |
} | |
isAlreadyRunning = true; | |
goToLaneWithBestTarget(); | |
useGoodLuckCharmIfRelevant(); | |
useMedicsIfRelevant(); | |
// TODO use abilities if available and a suitable target exists | |
// - Tactical Nuke on a Spawner if below 50% and above 25% of its health | |
// - Cluster Bomb and Napalm if the current lane has a spawner and 2+ creeps | |
// - Metal Detector if a boss, miniboss, or spawner death is imminent (predicted in > 2 and < 7 seconds) | |
// - Morale Booster if available and lane has > 2 live enemies | |
// - Decrease Cooldowns if another player used a long-cooldown ability < 10 seconds ago (any ability but Medics or a consumable) | |
// TODO purchase abilities and upgrades intelligently | |
attemptRespawn(); | |
isAlreadyRunning = false; | |
} | |
function goToLaneWithBestTarget() { | |
// We can overlook spawners if all spawners are 40% hp or higher and a creep is under 10% hp | |
var spawnerOKThreshold = 0.4; | |
var creepSnagThreshold = 0.1; | |
var targetFound = false; | |
var lowHP = 0; | |
var lowLane = 0; | |
var lowTarget = 0; | |
var lowPercentageHP = 0; | |
var ENEMY_TYPE = { | |
"SPAWNER":0, | |
"CREEP":1, | |
"BOSS":2, | |
"MINIBOSS":3, | |
"TREASURE":4 | |
} | |
// determine which lane and enemy is the optimal target | |
var enemyTypePriority = [ | |
ENEMY_TYPE.TREASURE, | |
ENEMY_TYPE.BOSS, | |
ENEMY_TYPE.MINIBOSS, | |
ENEMY_TYPE.SPAWNER, | |
ENEMY_TYPE.CREEP | |
]; | |
var skippingSpawner = false; | |
var skippedSpawnerLane = 0; | |
var skippedSpawnerTarget = 0; | |
for (var k = 0; !targetFound && k < enemyTypePriority.length; k++) { | |
var enemies = []; | |
// gather all the enemies of the specified type. | |
for (var i = 0; i < 3; i++) { | |
for (var j = 0; j < 4; j++) { | |
var enemy = g_Minigame.CurrentScene().GetEnemy(i, j); | |
if (enemy && enemy.m_data.type == enemyTypePriority[k]) { | |
enemies[enemies.length] = enemy; | |
} | |
} | |
} | |
// target the enemy of the specified type with the lowest hp | |
for (var i = 0; i < enemies.length; i++) { | |
if (enemies[i] && !enemies[i].m_bIsDestroyed) { | |
if(lowHP < 1 || enemies[i].m_flDisplayedHP < lowHP) { | |
targetFound = true; | |
lowHP = enemies[i].m_flDisplayedHP; | |
lowLane = enemies[i].m_nLane; | |
lowTarget = enemies[i].m_nID; | |
} | |
var percentageHP = enemies[i].m_flDisplayedHP / enemies[i].m_data.max_hp; | |
if(lowPercentageHP == 0 || percentageHP < lowPercentageHP) { | |
lowPercentageHP = percentageHP; | |
} | |
} | |
} | |
// If we just finished looking at spawners, | |
// AND none of them were below our threshold, | |
// remember them and look for low creeps (so don't quit now) | |
if (enemyTypePriority[k] == ENEMY_TYPE.SPAWNER && lowPercentageHP > spawnerOKThreshold) { | |
skippedSpawnerLane = lowLane; | |
skippedSpawnerTarget = lowTarget; | |
skippingSpawner = true; | |
targetFound = false; | |
} | |
// If we skipped a spawner and just finished looking at creeps, | |
// AND the lowest was above our snag threshold, | |
// just go back to the spawner! | |
if (skippingSpawner && enemyTypePriority[k] == ENEMY_TYPE.CREEP && lowPercentageHP > creepSnagThreshold ) { | |
lowLane = skippedSpawnerLane; | |
lowTarget = skippedSpawnerTarget; | |
} | |
} | |
// go to the chosen lane | |
if (targetFound) { | |
if (g_Minigame.CurrentScene().m_nExpectedLane != lowLane) { | |
//console.log('switching langes'); | |
g_Minigame.CurrentScene().TryChangeLane(lowLane); | |
} | |
// target the chosen enemy | |
if (g_Minigame.CurrentScene().m_nTarget != lowTarget) { | |
//console.log('switching targets'); | |
g_Minigame.CurrentScene().TryChangeTarget(lowTarget); | |
} | |
} | |
} | |
function useMedicsIfRelevant() { | |
var myMaxHealth = g_Minigame.CurrentScene().m_rgPlayerTechTree.max_hp; | |
// check if health is below 50% | |
var hpPercent = g_Minigame.CurrentScene().m_rgPlayerData.hp / myMaxHealth; | |
if (hpPercent > 0.5 || g_Minigame.CurrentScene().m_rgPlayerData.hp < 1) { | |
return; // no need to heal - HP is above 50% or already dead | |
} | |
// check if Medics is purchased and cooled down | |
if (hasPurchasedAbility(7)) { | |
if (isAbilityCoolingDown(7)) { | |
return; | |
} | |
// Medics is purchased, cooled down, and needed. Trigger it. | |
console.log('Medics is purchased, cooled down, and needed. Trigger it.'); | |
triggerAbility(7); | |
} | |
} | |
// Use Good Luck Charm if doable | |
function useGoodLuckCharmIfRelevant() { | |
// check if Good Luck Charms is purchased and cooled down | |
if (hasPurchasedAbility(6)) { | |
if (isAbilityCoolingDown(6)) { | |
return; | |
} | |
// Good Luck Charms is purchased, cooled down, and needed. Trigger it. | |
console.log('Good Luck Charms is purchased, cooled down, and needed. Trigger it.'); | |
triggerAbility(6); | |
} | |
} | |
//If player is dead, call respawn method | |
function attemptRespawn() { | |
if ((g_Minigame.CurrentScene().m_bIsDead) && | |
((g_Minigame.CurrentScene().m_rgPlayerData.time_died * 1000) + 5000) < (new Date().getTime())) { | |
RespawnPlayer(); | |
} | |
} | |
function isAbilityCoolingDown(abilityId) { | |
return g_Minigame.CurrentScene().GetCooldownForAbility(abilityId) > 0; | |
} | |
function hasPurchasedAbility(abilityId) { | |
// each bit in unlocked_abilities_bitfield corresponds to an ability. | |
// the above condition checks if the ability's bit is set or cleared. I.e. it checks if | |
// the player has purchased the specified ability. | |
return (1 << abilityId) & g_Minigame.CurrentScene().m_rgPlayerTechTree.unlocked_abilities_bitfield; | |
} | |
function triggerAbility(abilityId) { | |
var elem = document.getElementById('ability_' + abilityId); | |
if (elem && elem.childElements() && elem.childElements().length >= 1) { | |
g_Minigame.CurrentScene().TryAbility(document.getElementById('ability_' + abilityId).childElements()[0]); | |
} | |
} | |
var thingTimer = window.setInterval(doTheThing, 1000); | |
function clickTheThing() { | |
g_Minigame.m_CurrentScene.DoClick( | |
{ | |
data: { | |
getLocalPosition: function() { | |
var enemy = g_Minigame.m_CurrentScene.GetEnemy( | |
g_Minigame.m_CurrentScene.m_rgPlayerData.current_lane, | |
g_Minigame.m_CurrentScene.m_rgPlayerData.target), | |
laneOffset = enemy.m_nLane * 440; | |
return { | |
x: enemy.m_Sprite.position.x - laneOffset, | |
y: enemy.m_Sprite.position.y - 52 | |
} | |
} | |
} | |
} | |
); | |
} | |
var clickTimer = window.setInterval(clickTheThing, 1000/clickRate); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You can rename autoclick.js to autoclick.user.js for Auto-install in Tampermonkey when clicking on RAW button.