randomizeFCs

randomize names and FCs for planets.nu and replaces the builtin random generator

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name          randomizeFCs
//
// @description   randomize names and FCs for planets.nu and replaces the builtin random generator
// 				  to eliminate command codes it only replaces FCs in the format 0a0.
// 				  ship names get changed only if they contain capital letters.
//
// @include       http://play.planets.nu/*
// @include 	  http://test.planets.nu/*
// @include 	  http://planets.nu/*
// @version       3.0.0
// @homepage      https://greasyfork.org/en/users/32642-stephen-piper
// @namespace https://greasyfork.org/en/users/32642-stephen-piper
// ==/UserScript==

function wrapper() {
  var defaultplanet = new dataObject();
  var execplanets = [];
  var builtfact = [];
  var builtmine = [];
  var ready = [];
  var taxrate = [];

  function setRandom() {
  }
  setRandom.prototype = {

    loadControls : function() {
      // debugger;
      this.clearData();

      if (vgapMap.prototype.spMenuItem != undefined) {
	vgapMap.prototype.spMenuItem("Random FCs", "setRandom", function() {
	  setRandom.prototype.setRandomFC();
	});

	vgapMap.prototype.spMenuItem("Random Ship Names", "setRandom", function() {
	  setRandom.prototype.setRandomShipNames();
	});

	vgapMap.prototype.spMenuItem("Exec Notes", "setRandom", function() {
	  setRandom.prototype.parsenotes();
	});
	
	vgapMap.prototype.spMenuItem("Clear", "_massClear", function() {
	  setRandom.prototype.clearData();
	});
      }

    },

    clearData : function() {
      execplanets = [];
      builtfact = [];
      builtmine = [];
      builtdef = [];
      ready = [];
      taxrate = [];
      defaultplanet = new dataObject();
    },

    setRandomFC : function() {
      for (var i = 0; i < vgap.myplanets.length; ++i) {
	var planet = vgap.myplanets[i];
	if (vgap.player.id == planet.ownerid && planet.readystatus == 0) {
	  if (planet.friendlycode == /[0-9][a-zA-Z][0-9]/) {
	    planet.friendlycode = vgap.randomFC();
	    planet.changed = true;
	  }
	}
      }
      
      for (var i = 0; i < vgap.myships.length; ++i) {
	var ship = vgap.myships[i];
	if (vgap.player.id == ship.ownerid && ship.readystatus == 0) {
	  if (ship.friendlycode == /[0-9][a-zA-Z][0-9]/) {
	    ship.friendlycode = vgap.randomFC();
	    ship.changed = true;
	  }
	}
      }

      vgap.indicator.text("done");
      vgap.indicateOn();
    },

    setRandomShipNames : function() {
      var url = "http://api.wordnik.com:80/v4/words.json/randomWord";
      var data = {
	"hasDictionaryDef" : "true",
	"includePartOfSpeech" : "verb-intransitive",
	"minLength" : "5",
	"maxLength" : "16",
	"limit" : "1",
	"api_key" : "a2a73e7b926c924fad7001ca3111acd55af2ffabf50eb4ae5",
      };
      var pat = /.*?[A-Z]/;

      for (var i = 0; i < vgap.myships.length; ++i) {
	var ship = vgap.myships[i];
	if (vgap.player.id == ship.ownerid && pat.test(ship.name)) {
	  $.ajax({
	    async : false,
	    type : 'GET',
	    url : url,
	    data : data,
	    success : function(data) {
	      ship.name = data.word;
	      ship.changed = 1;
	    }
	  });
	}
      }

      vgap.indicator.text("done");
      vgap.indicateOn();
    },

    // **** commands are executed in the following order ****
    // { ["defaultplanet":{] // used for all planets that don't have notes
    // "checkready":"", // don't execute if planet.readystatus > 0
    // "buildfact":"xxx", // phaze 1, can skip any build in any phaze
    // "builddef":"xxx",
    // "fcdef":"aaa", // once planet.defenses >= builddef
    // "fc":["random","aaa"], // set random or a fixed value if !fcdef
    // "buildmines":"xxx",
    
    // "buildfact2":"xxx", // phaze 2, after all phaze 1 builds
    // "builddef2":"xxx",
    // "minerate2":"xxx", // miningrate/turn
    // "resground2":"xxxx", // minerals in ground
    // "buildmines2":"xxx", // dependant on native type, miningrate && resground

    // "minbuildtax3:"xxx",	// native supported tax < minbuildtax
    // "buildfact3":"xxx", // dependant on native type
    // "minerate3":"xxx",
    // "resground3":"xxxx",
    // "buildmines3":"xxx",
    
//    "natmaxtax":"xxx",
//    "nathappy":"xxx",
//    "natmaxhappych":"xxx",
//    "natmintaxamt":"xxx",

    // "ready":"1" // set planet.readystatus
    // [}] } // close default

    
    // **** "minerate3[neu,dur,tri,mol]":"xxx" // minimum miningrate/turn
    // **** "resground3[neu,dur,tri,mol]":"xxxx" // minimum minerals in ground


    nativetaxrate : function(l, c) {
      tax =
	  Math.floor((-c * 100 + 1000 - Math.sqrt(l.nativeclans) - (l.factories + l.mines) / 2 - 50 * (10 - l.nativegovernment)) / 85);
      return tax;
    },

    nativesupport : function(c) {
      ns = c.clans;
      ns *= c.race == 1 ? 2 : 1; // feds == 1
      ns *= c.nativetype == 6 ? 2 : 1; // insect == 6
      return ns;
    },

    nativeTaxAmount : function(c, ntr) {
      var nt = 0;
      if (c.nativeclans > 0) {
	if (c.race == 6 && ntr > 20) { // borg == 6
	  ntr = 20;
	}

	nt = (c.nativeclans / 100) * (ntr / 10) * (c.nativegovernment / 5);

	nt = c.nativetype == 5 ? 0 : nt; // amorphous == 5
	nt = c.nativetype == 6 ? 2 * nt : nt; // insect == 6
	nt = c.race == 1 ? 2 * nt : nt; // feds == 1

	nt = Math.round(nt);
	// nt = Math.min(this.nativesupport(c), nt);
      }
      
      return nt;
    },
    
    nativesupportedtax : function (l, ntr) {
      nt = this.nativeTaxAmount(l, ntr);
      ns = this.nativesupport(l);
      nt = Math.min( nt , ns);
      return nt;
    },

    parsenotes : function() {
      for (var f = 0; f < vgap.myplanets.length; f++) {
	var l = vgap.myplanets[f];
	if (l.note != undefined && l.note.body != "") {
	  try {
	    var jn = JSON.parse(l.note.body
		// , function(h, k) {console.log(h+" "+k)}
	    );
	  } catch (e) {
	    console.log("parse error " + l.id + " " + l.note.body);
	    continue;
	  }
	  
	  if (jn.defaultplanet != undefined) {
	    defaultplanet = jn.defaultplanet;
	    // console.log("found default");
	  } else {
	    l.execute = jn;
	    // console.log("found explicit " + l.id)
	  }
	}
      }

      this.execute();
      for (var f = 0; f < vgap.myplanets.length; f++) {
	var l = vgap.myplanets[f];
	if (l.note != undefined && l.note.body != "") {

	  vgap.indicator.text("done");
	  vgap.indicateOn();
	}
      }
    },

    execute : function() {
      for (var f = 0; f < vgap.myplanets.length; f++) {
	var l = vgap.myplanets[f];
	if (l.execute != undefined) {
	  // console.log(l.id + " single");
	  this.executesingle(l, l.execute);

	} else if (defaultplanet != null) {
	  // console.log(l.id + " default");
	  this.executesingle(l, defaultplanet);
	}
      }
      vgap.map.draw();
    },

    executesingle : function(l, jn) {

      // this has to be first
      if (jn.readonly != undefined) {
	vgap.readOnly = true;
	vgap.indicator.text("Read Only");
	vgap.indicateOn();
      }

      // this has to be first
      if (jn.checkready != undefined && l.readystatus > 0) {
	// console.log(l.id + " checkReady");
	ready.push(l.id);
	return;
      }

      if (jn.buildfact != undefined) { // 1st phaze
	this.buildFactories(l, jn.buildfact);
      }

      fcdef = false;
      if (jn.builddef != undefined) { // 1st phaze
	this.buildDefense(l, jn.builddef);
	if (l.defense >= jn.builddef && jn.fcdef != undefined) {
	  fcdef = true;
	  if (l.friendlycode != jn.fcdef) {
	    l.friendlycode = jn.fcdef;
	    l.changed = true;
	    // console.log(l.id + " deffc " + l.friendlycode);
	  }
	}
      }
      
      if (jn.fc != undefined && !fcdef) {
	if (jn.fc == "random") {
	  l.friendlycode = vgap.randomFC();
	  l.changed = true;
	  // console.log(l.id + " rndfc " + l.friendlycode);
	} else if (jn.fc != l.friendlycode) {
	  l.friendlycode = jn.fc;
	  l.changed = true;
	  // console.log(l.id + " fc " + l.friendlycode);
	}
      }

      if (jn.builddef2 != undefined) { // 2nd phaze
	this.buildDefense(l, jn.builddef2);
      }

	var minbuildtax = 0;
	if (jn.minbuildtax2 != undefined)
	  minbuildtax = jn.minbuildtax2
	
     if (jn.buildfact2 != undefined) {
	if (this.nativesupportedtax(l, 10) < minbuildtax) {
          if (l.nativeclans == 0 || l.nativetype == 5 || l.nativetype == 4) {
	  this.buildFactories(l, jn.buildfact2);
	}
	}
      }
	
      if (jn.buildmines2 != undefined) { // 2nd phaze

	if (this.nativesupportedtax(l, 10) < minbuildtax) {
	  if (l.nativeclans == 0 || l.nativetype == 3 || l.nativetype == 5 || l.nativetype == 4) {
          this.buildMines(l, jn.buildmines2);
        } else {
          var q = 0;
          var m = 0;
          var r = 0;
          var s = 0;
          
          if (jn.minerate2 != undefined) {
            m += jn.minerate2;
            
            q += l.densityneutronium > m ? 1 : 0;
            q += l.densityduranium > m ? 1 : 0;
            q += l.densitytritanium > m ? 1 : 0;
            q += l.densitymolybdenum > m ? 1 : 0;
          }
          
          if (jn.resground2 != undefined) {
            r += jn.resground2;
            
            s += l.groundneutronium > r ? 1 : 0;
            s += l.groundduranium > r ? 1 : 0;
            s += l.groundtritanium > r ? 1 : 0;
            s += l.groundmolybdenum > r ? 1 : 0;
          }
          
          if ((q > 0 || m == 0) && (s > 0 || r == 0))
            this.buildMines(l, jn.buildmines2);
        }
	}
      }

	var minbuildtax = 0;
	if (jn.minbuildtax3 != undefined)
	  minbuildtax = jn.minbuildtax3
	
     if (jn.buildfact3 != undefined) { // 3nd phaze
	if (this.nativesupportedtax(l, 10) < minbuildtax) {
          if (l.nativeclans == 0 || l.nativetype == 5 || l.nativetype == 4) {
	  this.buildFactories(l, jn.buildfact3);
	}
	}
      }

    // 1 Humanoid - Any starbase that is built around a humanoid planet will
    // have tech 10 hull technology automatically.
    // 7 Amphibian - Any starbase that is built around a amphibian planet will
    // have tech 10 beam technology automatically.
    // 8 Ghipsoldal - Any starbase that is built around a ghipsoldal planet will
    // have tech 10 engine technology automatically.
    // 9 Siliconoid - Any starbase that is built around a siliconoid planet will
    // have tech 10 torpedo technology automatically.

    // 2 Bovinoid - Bovinoids are very valuable. Every 10000 Bovinoids will
    // produce 1 supply unit per turn.
    // 3 Reptilian - If there Reptilians living on a planet then your mining
    // rate will be doubled.
    // 4 Avian - Are quick to forgive you for overtaxing them. They will allow
    // you to slightly overtax them without growing unhappy.
    // 5 Amorphous - The only bad natives. The Amorphous lifeforms eat 500
    // colonists (5 clans) per turn.
    // 6 Insectoid - Insectoids produce twice the normal amount of credits per
    // turn per percentage as other native races.
      
      if (jn.buildmines3 != undefined) { // 3nd phaze
	if (this.nativesupportedtax(l, 10) < minbuildtax) {
	  if (l.nativeclans == 0 || l.nativetype == 3 || l.nativetype == 5 || l.nativetype == 4) {
          this.buildMines(l, jn.buildmines3);
        } else {
	  
          q = 0;
          m = 0;
          r = 0;
          s = 0;
          
          if (jn.minerate3 != undefined) {
            m += jn.minerate3;
            
            q += l.densityneutronium > m ? 1 : 0;
            q += l.densityduranium > m ? 1 : 0;
            q += l.densitytritanium > m ? 1 : 0;
            q += l.densitymolybdenum > m ? 1 : 0;
          }
          
          if (jn.resground3 != undefined) {
            r += jn.resground3;
            
            s += l.groundneutronium > r ? 1 : 0;
            s += l.groundduranium > r ? 1 : 0;
            s += l.groundtritanium > r ? 1 : 0;
            s += l.groundmolybdenum > r ? 1 : 0;
          }
          
          if ((q > 0 || m == 0) && (s > 0 || r == 0))
            this.buildMines(l, jn.buildmines3);
        }
      }
      }
      
//    "nathappy":"xxx",
//    "natmaxhappych":"xxx",
//    "natmintaxamt":"xxx",
      var nativetaxrate = l.nativetaxrate;

      if (jn.nathappy != undefined) {
	var nathappych = jn.nathappy - l.nativehappypoints;
	if (nathappych != 0) {
	  var maxhappych = nathappych;
	  if (jn.natmaxhappych != undefined) {
	    maxhappych = jn.natmaxhappych;
	    if (nathappych > maxhappych) {
	      nathappych = maxhappych;
	    } else if (nathappych < -maxhappych) {
	      nathappych = -maxhappych;
	    }
	  }
	  
	  l.nativetaxrate = this.nativetaxrate(l, nathappych);
	  
	  if (l.nativetaxrate < 0) {
	    l.nativetaxrate = 0;
	  }
	}
      }
      
      
//    "natmintaxamt":"xxx",
      
      if (jn.natmintaxamt != undefined) {
	var taxamt = this.nativesupportedtax(l, l.nativetaxrate);
	if (taxamt < jn.natmintaxamt) {
	  l.nativetaxrate = 0;
	}
      }
      
//    "natmaxtax":"xxx",

      if (jn.natmaxtax != undefined) {
	if (l.nativetaxrate > jn.natmaxtax) {
	  l.nativetaxrate = parseInt(jn.natmaxtax);
	}
      }

      if (l.nativetaxrate != nativetaxrate) {
	var nativetaxamt = this.nativesupportedtax(l, l.nativetaxrate);
	l.nativehappychange = vgap.nativeTaxChange(l);
	taxrate.push({id:l.id, tax:l.nativetaxrate, happy:l.nativehappychange, taxamt:nativetaxamt});
	l.changed = true;
      }
      
      if (l.changed) {
	execplanets.push(l.id);
// console.log(l.id + " changed");
      }

      // has to be last
      if (jn.ready != undefined) {
	l.readystatus = jn.ready;
	l.changed = true;
	ready.push(l.id);
	// console.log("ready " + l.id);
      }

    },

    buildFactories : function(d, a) {
      var c = this.maxBuilding(d, 100);

      a = Math.min(a - d.factories, d.supplies, Math.floor((d.supplies + d.megacredits) / 4), c - d.factories);

      if (a > 0) {
	this.spendSuppliesMC(d, a, a * 3)  

	d.builtfactories += a;
	d.factories += a;
	d.changed = true;
	// console.log(d.id + " factories " + a + " = " + d.factories);
        builtfact.push({id:d.id, qty:a});
     }

      return a;
    },

    spendSuppliesMC : function(d, c, a) {
      if (c + a <= d.supplies + d.megacredits && c <= d.supplies) {
	if (d.megacredits < a) {
	  var b = a - d.megacredits;
	  d.megacredits += b;
	  d.supplies -= b;
	  d.suppliessold += b;
	  // console.log(d.id + " supplies "+d.suppliessold +" mc " +
	  // d.megacredits);
	}
	d.megacredits -= a;
	d.supplies -= c;
	d.changed = true;
      }
    },

    miningRate (p, ground, density) {
      m = vgap.miningRate(p, density);
      m = m > ground ? ground : Math.round(m);
	
      return m;
    },

    buildMines : function(d, a) {
      var c = this.maxBuilding(d, 200);

      a = Math.min(a - d.mines, d.supplies, Math.floor((d.supplies + d.megacredits) / 5), c - d.mines);

      if (a > 0) {
	this.spendSuppliesMC(d, a, a * 4);

	d.builtmines += a;
	d.mines += a;
	d.changed = true;
	// console.log(d.id + " mines " + a + " = " + d.mines);
// builtmine.push(d.id);
        builtmine.push({id:d.id, qty:a});
      }

      return a;
    },

    buildDefense : function(d, a) {
      var c = this.maxBuilding(d, 50);

      a = Math.min(a - d.defense, d.supplies, Math.floor((d.supplies + d.megacredits) / 11), c - d.defense);

      if (a > 0) {
	this.spendSuppliesMC(d, a, a * 10);

	d.builtdefense += a;
	d.defense += a;
	d.changed = true;
	// console.log(d.id + " defense " + a + " = " + d.defense);
	
        builtdef.push({id:d.id, qty:a});
     }
      return a;
    },

    maxBuilding : function(d, a) {
      if (d.clans <= a) {
	return d.clans
      } else {
	return Math.floor(a + Math.sqrt(d.clans - a))
      }
    },

  };

  var oldDrawPlanet = vgapMap.prototype.drawPlanet;
  vgapMap.prototype.drawPlanet = function(planet, ctx, fullrender) {

    var note = planet.note;
    planet.note = "";

    oldDrawPlanet.apply(this, arguments);

    planet.note = note;

    var x = this.screenX(planet.x);
    var y = this.screenY(planet.y);

    // planets with script executed
    for (i = 0; i < ready.length; ++i) {
      if (ready[i] == planet.id) {
	this.drawCircle(ctx, x, y, 8 * this.zoom, "lightgreen", 2);
      }
    }

//    for (i = 0; i < execplanets.length; ++i) {
//      if (execplanets[i] == planet.id) {
//	this.drawCircle(ctx, x, y, 7 * this.zoom, "green", 2);
//      }
//    }

    x2 = this.screenX(planet.x + 11 * 1.5);
    
    q = 0;
    for (i = 0; i < builtfact.length; ++i) {
      if (builtfact[i].id == planet.id) {
	q += builtfact[i].qty;
	// this.drawCircle(ctx, x, y, 12 * this.zoom, "yellow", 2);
      }
    }

    if (q != 0) {
      ctx.fillStyle = "orange";
      y2 = this.screenY(planet.y - (2 - 2) * 6 * 1.5);
      ctx.fillText("F+"+q, x2, y2);
    }

    q = 0;
    for (i = 0; i < builtmine.length; ++i) {
      if (builtmine[i].id == planet.id) {
	q += builtmine[i].qty;
	// this.drawCircle(ctx, x, y, 9 * this.zoom, "orange", 2);
      }
    }
    
    if (q != 0) {
      ctx.fillStyle = "orange";
      y2 = this.screenY(planet.y - (3 - 2) * 6 * 1.5);
      ctx.fillText("M+"+q, x2, y2);
    }

    q = 0;
    for (i = 0; i < builtdef.length; ++i) {
      if (builtdef[i].id == planet.id) {
	q += builtdef[i].qty;
	// this.drawCircle(ctx, x, y, 9 * this.zoom, "orange", 2);
      }
    }
    
    if (q != 0) {
      ctx.fillStyle = "orange";
      y2 = this.screenY(planet.y - (4 - 2) * 6 * 1.5);
      ctx.fillText("D+"+q, x2, y2);
    }

      ctx.fillStyle = "lightgreen";
      y2 = this.screenY(planet.y - (5 - 2) * 6 * 1.5);
      for (i = 0; i < taxrate.length; ++i) {
	if (taxrate[i].id == planet.id) {
//	  taxrate.push({id:l.id, tax:l.nativetaxrate, happy:l.nativehappychange, taxamt:nativetaxamount});
	  ctx.fillText("t%"+taxrate[i].tax+" hc" + taxrate[i].happy + " $" + taxrate[i].taxamt, x2, y2);
	  break;
	}
      }
    
    if (planet.note && planet.note.body.length > 0) {
      this.drawCircle(ctx, x, y, 3.5 * this.zoom, "blue", 1);
    }
  };

  // vgaPlanets.prototype.randomFC() can generate commands
  var oldRandomFC = vgaPlanets.prototype.randomFC;
  vgaPlanets.prototype.randomFC = function() {
    // replace function, old function is broken
    // randomFC.apply(this, arguments);

    c = "";
    c += Math.floor(Math.random() * 10);
    var b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    c += b.charAt(Math.floor(Math.random() * b.length))
    c += Math.floor(Math.random() * 10);

    return c
  };

  var oldLoadControls = vgapMap.prototype.loadControls;
  vgapMap.prototype.loadControls = function() {
    oldLoadControls.apply(this, arguments);

    setRandom.prototype.loadControls();
  };
};

var script = document.createElement("script");
script.type = "application/javascript";
script.textContent = "(" + wrapper + ")();";

document.body.appendChild(script);