// ==UserScript==
// @name VGA Bot-Core
// @namespace daunting/bot
// @version 0.1
// @date 2018-04-01
// @author Daunting
// @description Library of functions for NU bot library
// @include http://planets.nu/*
// @include http://play.planets.nu/*
// @include http://test.planets.nu/*
// @include userscript
// @resource userscript https://greasyfork.org/en/scripts/35354-planets-nu-build-plan-plugin
// @homepage http://planets.nu
// ==/UserScript==
function wrapper () { // wrapper for injection
if (vgap.version < 3.0)
{
console.log("VGABot-Core plugin requires at least NU version 3.0. Plugin disabled." );
return;
}
var plugin_version = 0.1;
console.log("VGABot-Core plugin version: v" + plugin_version );
/**
* Specify your plugin
* You need to have all those methods defined or errors will be thrown.
* I inserted the print-outs in order to demonstrate when each method is
* being called. Just comment them out once you know your way around.
*
* For any access to plugin class variables and methods,
* "vgap.plugins["vgaBot"].my_variable" has to be used
* instead of "this.my_variable".
*/
var vgaBotCore =
{
/**
* processload: executed whenever a turn is loaded: either the current turn or
* an older turn through time machine
*/
processload: function()
{
console.log("ProcessLoad: plugin called.");
},
/**
* loaddashboard: executed to rebuild the dashboard content after a turn is loaded
*/
loaddashboard: function()
{
console.log("LoadDashboard: plugin called.");
},
/**
* showdashboard: executed when switching from starmap to dashboard
*/
showdashboard: function()
{
console.log("ShowDashboard: plugin called.");
},
/**
* showsummary: executed when returning to the main screen of the dashboard
*/
showsummary: function()
{
console.log("ShowSummary: plugin called.");
},
/**
* loadmap: executed after the first turn has been loaded to create the map
* as far as I can tell not executed again when using time machine
*/
loadmap: function()
{
console.log("LoadMap: plugin called.");
},
/**
* showmap: executed when switching from dashboard to starmap
*/
showmap: function()
{
console.log("ShowMap: plugin called.");
},
/**
* draw: executed on any click or drag on the starmap
*/
draw: function()
{
console.log("Draw: plugin called.");
},
/**
* loadplanet: executed a planet is selected on dashboard or starmap
*/
loadplanet: function()
{
console.log("LoadPlanet: plugin called.");
},
/**
* loadstarbase: executed a planet is selected on dashboard or starmap
*/
loadstarbase: function()
{
console.log("LoadStarbase: plugin called.");
},
/**
* loadship: executed a planet is selected on dashboard or starmap
*/
loadship: function()
{
console.log("LoadShip: plugin called.");
},
/***************************************************************************************
* Custom plugin variables
***************************************************************************************/
missionEnum: {
EXPLORATION: 0,
HISS: 8,
CLOAK: 9,
BEAMFUEL: 10,
BEAMDUR: 11,
BEAMTRIT: 12,
BEAMMOLY: 13,
BEAMSUP: 14
},
/*****************************
* Unload freighters
******************************/
unloadToPlanet: function(ship, planet)
{
vgap.plugins["vgaBotCore"].transferClans(ship, planet, ship.clans);
vgap.plugins["vgaBotCore"].transferSupplies(ship, planet, ship.supplies);
vgap.plugins["vgaBotCore"].transferDur(ship, planet, ship.duranium);
vgap.plugins["vgaBotCore"].transferTrit(ship, planet, ship.tritanium);
vgap.plugins["vgaBotCore"].transferMoly(ship, planet, ship.molybdenum);
vgap.plugins["vgaBotCore"].transferCredits(ship, planet, ship.megacredits);
},
transferClans: function(src, dest, nClans)
{
if (src.clans >= nClans)
{
if (dest.ownerid == src.ownerid)
{
dest.clans += nClans;
dest.changed = 1;
}
else
{
src.transferclans += nClans;
vgap.plugins["vgaBotCore"].setTransferTarget(src, dest);
}
src.clans -= nClans;
src.changed = 1;
}
},
transferSupplies: function(src, dest, nSupplies)
{
if (src.supplies >= nSupplies)
{
if (dest.ownerid == src.ownerid)
{
dest.supplies += nSupplies;
dest.changed = 1;
}
else
{
src.transfersupplies += nSupplies;
vgap.plugins["vgaBotCore"].setTransferTarget(src, dest);
}
src.supplies -= nSupplies;
src.changed = 1;
}
},
transferDur: function(src, dest, nDur)
{
if (src.duranium >= nDur)
{
if (dest.ownerid == src.ownerid)
{
dest.duranium += nDur;
dest.changed = 1;
}
else
{
src.transferduranium += nDur;
vgap.plugins["vgaBotCore"].setTransferTarget(src, dest);
}
src.duranium -= nDur;
src.changed = 1;
}
},
transferTrit: function(src, dest, nTrit)
{
if (src.tritanium >= nTrit)
{
if (dest.ownerid == src.ownerid)
{
dest.tritanium += nTrit;
dest.changed = 1;
}
else
{
src.transfertritanium += nTrit;
vgap.plugins["vgaBotCore"].setTransferTarget(src, dest);
}
src.tritanium -= nTrit;
src.changed = 1;
}
},
transferMoly: function(src, dest, nMoly)
{
if (src.molybdenum >= nMoly)
{
if (dest.ownerid == src.ownerid)
{
dest.molybdenum += nMoly;
dest.changed = 1;
}
else
{
src.transfermolybdenum += nMoly;
vgap.plugins["vgaBotCore"].setTransferTarget(src, dest);
}
src.molybdenum -= nMoly;
src.changed = 1;
}
},
transferCredits: function(src, dest, nCredits)
{
if (src.megacredits >= nCredits && dest.ownerid == src.ownerid)
{
dest.megacredits += nCredits;
src.megacredits -= nCredits;
src.changed = 1;
dest.changed = 1;
}
},
setTransferTarget: function(src, dest)
{
src.transfertargetid = dest.id;
if (dest.isPlanet)
src.transfertargettype = 1;
else if (dest.isShip)
src.transfertargettype = 0;
},
/*****************************
* Move Ships
******************************/
findNearestStarbase: function(target)
{
var min = 100000;
var ret = null;
for (var i=0; i<vgap.planets.length; i++)
{
var planet = vgap.planets[i];
if ( planet.ownerid == vgap.player.id && planet.isbase)
{
var distance = vgap.plugins["vgaBotCore"].calcDistance(planet, target);
if (distance < min)
{
min = distance;
ret = planet;
}
}
}
return ret;
},
orbittingPlanet: function(ship)
{
for (var i=0; i<vgap.planets.length; i++)
{
var planet = vgap.planets[i];
if ( (ship.x == planet.x && ship.y == planet.y) )
return planet;
}
return null;
},
/**
* TODO: Need to make sure ships don't go to the same planet.
*/
findNearestUnownedPlanet: function(thing)
{
var min = 100000;
var ret = null;
for (var i=0; i<vgap.planets.length; i++)
{
var planet = vgap.planets[i];
if ( (thing.x != planet.x || thing.y != planet.y) && planet.ownerid == 0)
{
var distance = vgap.plugins["vgaBotCore"].calcDistance(planet, thing);
if (distance < min)
{
min = distance;
ret = planet;
}
}
}
return ret;
},
findNearestEnemyPlanet: function(thing)
{
var min = 100000;
var ret = null;
for (var i=0; i<vgap.planets.length; i++)
{
var planet = vgap.planets[i];
if ( (thing.x != planet.x || thing.y != planet.y) && planet.ownerid != 0 && planet.ownerid != vgap.player.id)
{
var distance = vgap.plugins["vgaBotCore"].calcDistance(planet, thing);
if (distance < min)
{
min = distance;
ret = planet;
}
}
}
return ret;
},
calcDistance: function(a, b)
{
return Math.sqrt(Math.pow(a.x-b.x,2) + Math.pow(a.y-b.y,2));
},
createWaypoint: function(ship, dest)
{
var waypoint = {id:ship.id, x1:ship.x, y1:ship.y, x2:dest.x, y2:dest.y, color:"#009900", dasharray:null};
ship.lastwaypoint=waypoint;
//vgap.waypoints.push(waypoint);
ship.targetx = dest.x;
ship.targety = dest.y;
ship.target = dest;
ship.warp = ship.engineid;
ship.changed = 1;
},
clearWaypoint: function(ship)
{
ship.lastwaypoint=null;
ship.targetx = ship.x;
ship.targety = ship.y;
ship.target = null;
ship.changed = 1;
},
loadFuel: function(ship)
{
var fuelAvailable = vgap.plugins["vgaBotCore"].getFuelAvailable(ship);
var planet = vgap.plugins["vgaBotCore"].orbittingPlanet(ship);
var sbPlanet = vgap.plugins["vgaBotCore"].findNearestStarbase(ship.target);
var returnFuel = vgap.plugins["vgaBotCore"].calcFuelConsumption(ship, ship.target, sbPlanet, false);
var needed = vgap.plugins["vgaBotCore"].calcFuelConsumption(ship, ship, ship.target, true) + returnFuel;
var added = 0;
console.log("Ship " + ship.id + ": Needed: " + needed + " Ship: " + ship.neutronium + " Available: " + fuelAvailable + " Return: " + returnFuel);
while (needed > ship.neutronium && needed < fuelAvailable)
{
if (needed > ship.neutronium)
{
if (planet != null && planet.ownerid == vgap.player.id)
{
var adding = needed - ship.neutronium;
added += adding;
planet.neutronium -= adding;
ship.neutronium += adding;
}
}
needed = vgap.plugins["vgaBotCore"].calcFuelConsumption(ship, ship, ship.target, true) + returnFuel;
}
if (ship.neutronium < needed && added > 0)
{
ship.neutronium -= added;
planet.neutronium += added;
}
else if (planet != null && planet.neutronium > 0 && planet.ownerid == vgap.player.id)
{
planet.neutronium -= 1;
ship.neutronium += 1;
}
console.log("Added fuel: " + added);
return ship.neutronium >= needed;
},
calcFuelConsumption: function(ship, start, dest, includeCargo)
{
var fuelFactor = vgap.plugins["vgaBotCore"].getFuelFactor(ship);
var mass = vgap.plugins["vgaBotCore"].getMass(ship, includeCargo);
var distance = vgap.plugins["vgaBotCore"].calcDistance(start, dest);
var cloakFuel = 0;
if (ship.mission == vgap.plugins["vgaBotCore"].missionEnum.CLOAK)
{
var turns = Math.ceil(distance / Math.pow(ship.engineid,2));
var hull = vgap.getHull(ship.hullid);
cloakFuel = Math.ceil(hull.mass / 20) * turns;
}
console.log("mass: " + mass + " cloakFuel: " + cloakFuel + " distance: " + distance + " factor: " + fuelFactor);
return Math.truncate(fuelFactor * Math.truncate(mass / 10) * Math.truncate(distance / Math.pow(ship.engineid,2)) / 10000) + cloakFuel;
},
getFuelFactor: function(ship)
{
var engine = vgap.getEngine(ship.engineid);
return engine.warps[ship.engineid-1];
},
getMass: function(ship, includeCargo)
{
var mass = 0;
var hull = vgap.getHull(ship.hullid);
mass += hull.mass;
if (ship.torpedoid != 0)
{
var torps = vgap.getTorpedo(ship.torpedoid);
mass += torps.mass * ship.torps;
}
if (ship.beamid != 0)
{
var beam = vgap.getBeam(ship.beamid);
mass += beam.mass * ship.beams;
}
//Will still have ammo
mass += ship.ammo;
if (includeCargo)
{
mass += ship.duranium + ship.tritanium + ship.molybdenum + ship.supplies + ship.clans +
ship.neutronium;
}
return mass;
},
getFuelAvailable: function(ship)
{
var planet = vgap.plugins["vgaBotCore"].orbittingPlanet(ship);
var fuel = ship.neutronium;
if (planet != null && planet.ownerid == ship.ownerid)
fuel += planet.neutronium;
return fuel;
},
/****************************
* Intel
*****************************/
hasOrbitingShip: function(planet)
{
var ret = false;
for (var i=0; i<vgap.myships.length; i++)
{
var ship = vgap.myships[i];
if (ship.x == planet.x && ship.y == planet.y)
ret = true;
}
return ret;
},
shouldCloak: function(ship)
{
var cloak = true;
var hull = vgap.getHull(ship.hullid);
//Can it cloak?
if (!hull.cancloak)
cloak = false;
//Is it moving (currently only cloaking when moving ...)?
//TODO: Put in tactical decision to cloak on friendly planets or in space.
if (cloak)
{
if (ship.target == null)
cloak = false;
}
//Target a friendly planet?
if (cloak)
{
if (ship.target.isPlanet && ship.target.ownerid == ship.ownerid)
cloak = false;
}
return cloak;
},
/****************************
* Build Ships
*****************************/
calcShipCredits: function(shipAssembly, base)
{
console.log("Ship hull name: " + shipAssembly.hull.name);
var credits = shipAssembly.hull.cost +
shipAssembly.hull.engines * shipAssembly.engine.cost;
if (shipAssembly.hull.launchers != 0 && shipAssembly.torp != null)
credits += shipAssembly.hull.launchers * shipAssembly.torp.launchercost;
if (shipAssembly.hull.beams != 0 && shipAssembly.beam != null)
credits += shipAssembly.hull.beams * shipAssembly.beam.cost;
credits += vgap.plugins["vgaBotCore"].calcTechCost(base.hulltechlevel, shipAssembly.hull.techlevel);
credits += vgap.plugins["vgaBotCore"].calcTechCost(base.enginetechlevel, shipAssembly.engine.techlevel);
credits += vgap.plugins["vgaBotCore"].calcTechCost(base.torptechlevel, shipAssembly.torp.techlevel);
credits += vgap.plugins["vgaBotCore"].calcTechCost(base.beamtechlevel, shipAssembly.beam.techlevel);
return credits;
},
calcTechCost: function(baseTech, shipTech)
{
var cost = 0;
if (baseTech < shipTech)
{
for (i=baseTech; i<shipTech; i++)
cost += i*100;
}
//Have we upgraded to level 9 (i.e. 10)
if (shipTech == 9 && cost > 0)
cost += 900;
if (cost > 0)
{
console.log("Tech Cost: " + cost);
console.log("Upgrade from " + baseTech + " to " + shipTech);
}
return cost;
},
calcShipDur: function(shipAssembly)
{
var dur = shipAssembly.hull.duranium +
shipAssembly.hull.engines * shipAssembly.engine.duranium;
if (shipAssembly.hull.launchers != 0 && shipAssembly.torp != null)
dur += shipAssembly.hull.launchers * shipAssembly.torp.duranium;
if (shipAssembly.hull.beams != 0 && shipAssembly.beam != null)
dur += shipAssembly.hull.beams * shipAssembly.beam.duranium;
return dur;
},
calcShipTrit: function(shipAssembly)
{
var trit = shipAssembly.hull.tritanium +
shipAssembly.hull.engines * shipAssembly.engine.tritanium;
if (shipAssembly.hull.launchers != 0 && shipAssembly.torp != null)
trit += shipAssembly.hull.launchers * shipAssembly.torp.tritanium;
if (shipAssembly.hull.beams != 0 && shipAssembly.beam != null)
trit += shipAssembly.hull.beams * shipAssembly.beam.tritanium;
return trit;
},
calcShipMoly: function(shipAssembly)
{
var moly = shipAssembly.hull.molybdenum +
shipAssembly.hull.engines * shipAssembly.engine.molybdenum;
if (shipAssembly.hull.launchers != 0 && shipAssembly.torp != null)
moly += shipAssembly.hull.launchers * shipAssembly.torp.molybdenum;
if (shipAssembly.hull.beams != 0 && shipAssembly.beam != null)
moly += shipAssembly.hull.beams * shipAssembly.beam.molybdenum;
return moly;
},
findHullNamed: function(hullName)
{
var ret = null;
for (var i=0; i<vgap.hulls.length; i++)
{
if (vgap.hulls[i].name == hullName)
ret = vgap.hulls[i];
}
return ret;
},
assembleShip: function(base, shipAssembly)
{
var planet = vgap.getPlanet(base.planetid);
//Pay for the ship
var credits = vgap.plugins["vgaBotCore"].calcShipCredits(shipAssembly, base);
var dur = vgap.plugins["vgaBotCore"].calcShipDur(shipAssembly);
var trit = vgap.plugins["vgaBotCore"].calcShipTrit(shipAssembly);
var moly = vgap.plugins["vgaBotCore"].calcShipMoly(shipAssembly);
planet.duranium -= dur;
planet.tritanium -= trit;
planet.molybdenum -= moly;
vgap.plugins["vgaBotCore"].payForStructure(planet, 0, credits);
//Upgrade all tech needed
if (base.beamtechlevel < shipAssembly.beam.techlevel)
{
base.beamtechup = shipAssembly.beam.techlevel - base.beamtechlevel;
base.beamtechlevel = shipAssembly.beam.techlevel;
}
if (base.hulltechlevel < shipAssembly.hull.techlevel)
{
base.hulltechup = shipAssembly.hull.techlevel - base.hulltechlevel;
base.hulltechlevel = shipAssembly.hull.techlevel;
}
if (base.enginetechlevel < shipAssembly.engine.techlevel)
{
base.enginetechup = shipAssembly.engine.techlevel - base.enginetechlevel;
base.enginetechlevel = shipAssembly.engine.techlevel;
}
if (base.torptechlevel < shipAssembly.torp.techlevel)
{
base.torptechup = shipAssembly.torp.techlevel - base.torptechlevel;
base.torptechlevel = shipAssembly.torp.techlevel;
}
//Assemble the ship
base.buildbeamcount = shipAssembly.hull.beams;
base.buildbeamid = shipAssembly.beam.id;
var stockitem = vgap.getStock(base.id, 3, shipAssembly.beam.id);
stockitem.builtamount += shipAssembly.hull.beams;
stockitem.amount += shipAssembly.hull.beams;
stockitem.changed = 1;
base.buildengineid = shipAssembly.engine.id;
stockitem = vgap.getStock(base.id, 2, shipAssembly.engine.id);
stockitem.builtamount += shipAssembly.hull.engines;
stockitem.amount += shipAssembly.hull.engines;
stockitem.changed = 1;
base.buildhullid = shipAssembly.hull.id;
stockitem = vgap.getStock(base.id, 1, shipAssembly.hull.id);
stockitem.builtamount += 1;
stockitem.amount += 1;
stockitem.changed = 1;
base.buildtorpcount = shipAssembly.hull.launchers;
base.buildtorpedoid = shipAssembly.torp.id;
stockitem = vgap.getStock(base.id, 4, shipAssembly.torp.id);
stockitem.builtamount += shipAssembly.hull.launchers;
stockitem.amount += shipAssembly.hull.launchers;
stockitem.changed = 1;
base.isbuilding = true;
base.changed = 1;
planet.changed = 1;
},
/*****************************
* Build Structures
******************************/
calcMaxFactories: function(planet)
{
var nFactories;
if (planet.clans <= 100)
nFactories = planet.clans;
else
nFactories = Math.truncate(100 + Math.sqrt( planet.clans - 100));
return nFactories;
},
calcMaxMines: function(planet)
{
var nMines;
if (planet.clans <= 200)
nMines = planet.clans;
else
nMines = Math.truncate(200 + Math.sqrt( planet.clans - 200));
return nMines;
},
calcMaxDefense: function(planet)
{
var nDefense;
if (planet.clans <= 50)
nDefense = planet.clans;
else
nDefense = Math.truncate(50 + Math.sqrt( planet.clans - 50));
return nDefense;
},
calcDesiredDefense: function(planet)
{
return Math.min(20, vgap.plugins["vgaBotCore"].calcMaxDefense(planet));
},
buildFactories: function(planet, max)
{
while(planet.factories < max && vgap.plugins["vgaBotCore"].payForStructure(planet, 1, 3))
{
planet.factories += 1;
planet.builtfactories += 1;
}
return planet.factories >= max;
},
buildMines: function(planet, max)
{
while(planet.mines < max && vgap.plugins["vgaBotCore"].payForStructure(planet, 1, 4))
{
planet.mines += 1;
planet.builtmines += 1;
}
return planet.mines >= max;
},
buildDefense: function(planet, max)
{
while(planet.defense < max && vgap.plugins["vgaBotCore"].payForStructure(planet, 1, 10))
{
planet.defense += 1;
planet.builtdefense += 1;
}
return planet.defense >= max;
},
payForStructure: function(planet, nSupplies, nCredits)
{
var bought = false;
//Check if we can afford this
if (planet.supplies >= nSupplies && ((planet.supplies + planet.megacredits) > (nSupplies + nCredits)) )
{
bought = true;
planet.supplies -= nSupplies;
var nCreditsSpend = Math.min(planet.megacredits, nCredits);
planet.megacredits -= nCreditsSpend;
nCredits -= nCreditsSpend;
if (nCredits > 0)
{
vgap.plugins["vgaBotCore"].sellSupplies(planet, nCredits);
planet.megacredits -= nCredits;
}
}
return bought;
},
sellSupplies: function(planet, nSupplies)
{
planet.suppliessold += nSupplies;
planet.supplies -= nSupplies;
planet.megacredits += nSupplies;
},
/*****************************
* Tax
******************************/
}; //End plugin
// register your plugin with NU
vgap.registerPlugin(vgaBot, "vgaBotCore");
} //wrapper for injection
var script = document.createElement("script");
script.type = "application/javascript";
script.textContent = "(" + wrapper + ")();";
document.body.appendChild(script);
document.body.removeChild(script);