Script: Assault Odds - Version 2.0.6

The home of third-party tools and utilities that can enhance your Conquer Club experience.

Moderator: Tech Team

Forum rules
Please read the Community Guidelines before posting.
User avatar
dgz345
Posts: 1363
Joined: Thu Oct 07, 2010 10:53 am

Script: Assault Odds - Version 2.0.6

Post by dgz345 »

Assault Odds
by: [player]chipv[/player]
idea: [player]Foxglove[/player]

What does it do?

Assault odds is a tool that quickly calculates precise odds for attacking a sequence of territories on any map.
It has been deliberately designed to be faster than other similar calculators and it will also handle larger numbers of armies.
It consists of a Quick calculator and a Pathfinder
You can show/hide these windows on your games page by using the options in the left menu.
when uses the panel interface it adds this as a panel

Where do I get it?
Install the userscript from here: http://tools.conquerclub.com/assaultodds/
Should work on all browsers supporting Tampermonkey


User Guide
Assault Odds User Guide

Changes in version 2.0.6: by [player]dgz345[/player]
- Should work in Firefox for real. And also load your settings! I don't know who implemented the saving of the settings but he/she forgot to load them...

[spoiler=version history]Changes in version 2.0.5: by [player]dgz345[/player]
- Should work in Firefox with tampermonkey. (Might not work in greasemonkey anymore in this version)
Old version available at http://tools.conquerclub.com/assaultodds/versions/


Changes in version 2.0.4: by [player]dgz345[/player]
- hopefully made it work in firefox 30+ and still working in chrome...

Changes in version 2.0.3: by [player]dgz345[/player]
- changed host

Changes in version 2.0.2: by [player]dgz345[/player]
- changed the code so it doesn't occupy the 9th panel (for adding more panels)

Changes in version 2.0.1: by [player]dgz345[/player]
- no one never told me there was problems with FF and panels

Changes in version 2.0.0: by [player]dgz345[/player]
- Works with and without panels (added as a new panel)
- Menu width
- Changed script host
- Many Hours Spent[/spoiler]

[spoiler=Information]Quick Calculator

Type in attacking army number and a sequence of defending army numbers to get the odds of the attacker winning.
Separate defending army numbers with commas.
e.g. Attacking 10 and Defending 3,2 will calculate odds of a 10 army attacking first a 3 then a 2
The results are saved for future use on the page.
This means that if you have very large numbers to calculate and even Assault Odds can't handle it in one go,
then do a calc for roughly half all the armies. Assault Odds re-uses old calcs making subsequent calcs very fast
and allows for bigger numbers to be calculated.
Currently if you refresh the page this data is lost, but the calcs are very quick for most numbers anyway.
Click on the Add Calc button to add more quick calcs for different routes.
The total will show the product of all quick calcs (so the overall odds of succeeding in all attacks).

Multiple Attackers

You can add attacking territories with commas if you want to attack the first defending territory from more than one place.

Tips

  • Do the biggest calculation first. This saves the calcs and will make subsequent calcs practically instantaneous.
  • Do a big calc just before you take your turn. Then you can calc as you go at speed without waiting for calcs.

Pathfinder

This is a sequence of dropdowns allowing you to plot a path on the map and work out odds at each step.
The dropdowns only show valid bordering territories and bombard spots. (A player cannot attack themselves for example).
You can add deployed armies to the first attacking territory selected.
Enter the number of armies to deploy and click anywhere away from the deploy box.
The first territory number will change accordingly.
Note you can choose any player to work out odds for, not just yourself.

Pathfinder During A Turn
Use the refresh button to recalculate path odds during a turn.
If the path is now invalid, the path will be cleared.

Statistics

Further odds on each number of attacking armies surviving can be found by switching the Statistics option on.
In the above example,
There is a 12% chance that exactly 4 attacking armies will survive an 8v4 assault.
There is a 48.2% chance that at least 6 attackers survive.
There is always a 100% chance that at least 1 army survives (since one has to be reserved for advancing).

Statistics are displayed for multiple attackers also.

For multiple quick calcs, at present, only the last calc statistics is shown.

Display Options

You can choose format of odds - decimal or percentage
You can also choose which windows to show on the page.
Statistics enables the display and calculation of odds of surviving attackers.[/spoiler]
User avatar
tigerbob
Posts: 126
Joined: Fri Dec 13, 2013 8:11 pm
Gender: Male
Location: Arkansas

Re: GM Script: Assault Odds - Version 2.0.0

Post by tigerbob »

Excellent. I've just got around to using this. It is very nice having it intergrated with the interface panel. Thank you sir.

edit: i'm using chrome.
User avatar
dgz345
Posts: 1363
Joined: Thu Oct 07, 2010 10:53 am

Re: GM Script: Assault Odds - Version 2.0.0

Post by dgz345 »

everything i do is mostly tested on chrome only.
User avatar
ztodd
Posts: 116
Joined: Sat Sep 06, 2008 9:38 pm
Gender: Male
Location: Arizona, USA

Re: GM Script: Assault Odds - Version 2.0.0

Post by ztodd »

Just installed this- not working for me in Chrome when using the panels- game #s 14098707 and 14098709 for example. It shows the new Odds panel, but that panel is empty. Why is this? Can it be fixed?

Also, the images are broken in the user's guide. Did photobucket change their policy so that images are not available forever? Or has it always been that way? If so, did the user's guide writer not know about that? Or not care?

So many questions... but very few will be answered probably, because people don't know or don't care. ;) (Sorry for my negative attitude- but most of the time it's true. But I really do appreciate the site programmers and script developers.)
D4 Damager
Posts: 142
Joined: Thu Feb 02, 2012 4:48 pm

Re: GM Script: Assault Odds - Version 2.0.0

Post by D4 Damager »

I also get a blank Odds tab. Can provide outputs if you want to try debugging, just let me know...
User avatar
dgz345
Posts: 1363
Joined: Thu Oct 07, 2010 10:53 am

Re: GM Script: Assault Odds - Version 2.0.0

Post by dgz345 »

hmm im using chrome without problem. i think i noticed that it didnt work in FF.

ill take a shower.then read what you guys have writen
User avatar
dgz345
Posts: 1363
Joined: Thu Oct 07, 2010 10:53 am

Re: GM Script: Assault Odds - Version 2.0.0

Post by dgz345 »

ztodd wrote:Just installed this- not working for me in Chrome when using the panels- Game 14098707 and Game 14098709 for example. It shows the new Odds panel, but that panel is empty. Why is this? Can it be fixed?

is it just these games? or all games? did you install it directly to chrome or are you using tampermonkey
im using tampermonkey https://chrome.google.com/webstore/deta ... fkfo?hl=en

ztodd wrote:Also, the images are broken in the user's guide. Did photobucket change their policy so that images are not available forever? Or has it always been that way? If so, did the user's guide writer not know about that? Or not care?

what userguide. i dont find anybroken links when i check the userguide for assault odds?
link please.

ztodd wrote:So many questions... but very few will be answered probably, because people don't know or don't care. ;) (Sorry for my negative attitude- but most of the time it's true. But I really do appreciate the site programmers and script developers.)

sorry to prove you wrong. i lurk on the tools and bug forum. i always answer if there is anything i can help with.
User avatar
dgz345
Posts: 1363
Joined: Thu Oct 07, 2010 10:53 am

Re: GM Script: Assault Odds - Version 2.0.0

Post by dgz345 »

as soon as userscripts is up. ill upload this

Code: Select all

//
// ==UserScript==
// @name          Conquer Club Assault Odds
// @namespace     http://userscripts.org/
// @version       2.0.0
// @description   Calculates available attack routes and odds
// @include       http*://*.conquerclub.com*/game.php*
// ==/UserScript==
// Copyright 2009-2012 chipv.freehostia.com
// All rights reserved

var is_FF = /firefox/.test( navigator.userAgent.toLowerCase() );
var is_panel = document.getElementById('console_bottom')!=null?true:false;
var forumUrl = "http://www.conquerclub.com/forum/viewtopic.php?f=527&t=202003";
var scriptUrl = "http://userscripts.org/scripts/source/350060.user.js";
var cMode = "attached";



var version = "2.0.0";
var cast = 1;
var display = 7;
var features=[];
var mapName = document.getElementById('outer-map').style.backgroundImage;
if(mapName.match(/conquerclub.com\/(.+?)\./)) {
mapName = RegExp.$1;
}
var logDiv = document.getElementById('log');
var dashboard = document.getElementById('dashboard');
var armiesarray = new Array();
var owners = new Array();
var path = new Array();
var conq = new Array();
var steps = new Array();
var bds = new Array();
var bmb = new Array();
var terr = new Array();
var copy = new Array();
var qcalcs = new Array();
var owner;
var proto;
var deploy = 0;
var qcalc = 1;
var cols = new Array('#000','#f00','#009a04','#00f','#cc0','#f0f','#0cc','#f92','#7f7f7f');
var attacking = {'11' : 15/36,'12' : 55/216, '21' : 125/216,'22' : 295/1296,'31' : 855/1296,'32' : 2890/7776};
var defending = {'11' : 21/36,'12' : 161/216,'21' : 91/216, '22' : 581/1296,'31' : 441/1296,'32' : 2275/7776};
var splitting = {'11' : 0,    '12' : 0,      '21' : 0,      '22' : 420/1296,'31' : 0,       '32' : 2611/7776};
var displays = new Array("Quick Calc", "Pathfinder", "Statistics");
var bombard = 0;
var Stack = [];
var Stats = [];
var compiled;
var qcomps = new Array();
var sref;
var map;

function Survived(size,blanks,duds) {
this._min = new Array(size);
for(var m=0; m<(size); m++) {
 this._min[m] = 0;
}
this._odds = 0;
this._blanks = blanks;
this._duds = duds;
}

function cleanup() {
Stack = null;
Stats = null;
}

function defence(des,deduct) {
    var newDefs = new Array();
    if(deduct > 0) newDefs[0] = des[0] - deduct;
     for(var i=1; i<des.length; i++) {
     newDefs.push(des[i]);
   }
   return newDefs;   
}

function formatOdds(odds) {
var prob = odds;
if(!cast) prob = (100 * prob).toFixed(1) + "%";
return prob;
}

   
function bubble(parent,ab,dbs,dc,rm) {
var sv = checkStackStats(ab,dbs,dc,rm);   
parent._odds += sv._odds * dc;
for(var y=0; y<sv._min.length;y++) {
 parent._min[y] += dc * sv._min[y];
}
}

function bubbled(parent,abs,dbs,dc,rm) {
var sv = checkStackedStats(abs,dbs,dc,rm);   
parent._odds += sv._odds * dc;
for(var y=0; y<sv._min.length;y++) {
 parent._min[y] += dc * sv._min[y];
}
}

function checkStack(f,c,d) {
 if(Stack[f] && Stack[f][c.toString()]) return (d * Stack[f][c.toString()]);
 else return (d * conquest(f,c));
}

function checkStacked(f,c,d) {
 if(Stack[f.toString()] && Stack[f.toString()][c.toString()]) return (d * Stack[f.toString()][c.toString()]);
 else return (d * overwhelm(f,c));
}

function checkStackStats(f,c,d,r) {
 if(Stats[f] && Stats[f][c.toString()]) return (Stats[f][c.toString()]);
 else return (conquestStats(f,c,r));
}

function checkStackedStats(f,c,d,r) {
 if(Stats[f.toString()] && Stats[f.toString()][c.toString()]) return (Stats[f.toString()][c.toString()]);
 else return (overwhelmStats(f,c,r));
}

function conquest(a,ds) {
if(!Stack[a]) Stack[a] = new Array();
var d = ds[0];
var ad = (a>4)? 3:a-1;
var dd = (d>1)?2:d;
var dice = ad + '' + dd;
var loss = (ad<dd)? ad:dd;
var a1 = 0;
if(loss){
 if(a - loss > ds.length) a1 += checkStack(a-loss,ds,defending[dice]);
 if(d == loss) {
  if(ds.length == 1) a1 += attacking[dice];
  else a1 += checkStack(a-1,defence(ds,0),attacking[dice]);
 }
 else a1 += checkStack(a,defence(ds,loss),attacking[dice]);
 if(splitting[dice] && (a-1 > ds.length)) a1 += checkStack(a-1,defence(ds,1),splitting[dice]);
}
Stack[a][ds.toString()] = a1;
return a1;
}

function overwhelm(as,ds) {
if(!Stack[as.toString()]) Stack[as.toString()] = new Array();
var a = as[0];
var d = ds[0];
var ad = (a>4)? 3:a-1;
var dd = (d>1)?2:d;
var dice = ad + '' + dd;
var loss = (ad<dd)? ad:dd;
var a1 = 0;
if(loss) {
   if(a -1 == loss) {
      if(as.length == 2) a1 += checkStack(as[1],ds,defending[dice])
      else a1 += checkStacked(defence(as,0),ds,defending[dice]);
   }
   else a1 += checkStacked(defence(as,loss),ds,defending[dice]);
   if(d == loss) {
    if(ds.length == 1) a1 += attacking[dice];
    else a1 += checkStack(a - 1,defence(ds,0),attacking[dice]);
   }
   else a1 += checkStacked(as,defence(ds,loss),attacking[dice]);
  if(splitting[dice]) {
   if(a>2) a1 += checkStacked(defence(as,1),defence(ds,1),splitting[dice]);
   else {
      if(as.length == 2) a1 += checkStack(as[1],defence(ds,1),splitting[dice]);
      else a1 += checkStacked(defence(as,0),defence(ds,1),splitting[dice]);
   }
   }
}
Stack[as.toString()][ds.toString()] = a1;
return a1;      
}

function conquestStats(a,ds,rem) {
if(!Stats[a]) Stats[a] = new Array();
if(!Stats[a][ds.toString()]) Stats[a][ds.toString()] = new Survived(a+rem,ds.length,1);
var d = ds[0];
var ad = (a>4)? 3:a-1;
var dd = (d>1)?2:d;
var dice = ad + '' + dd;
var loss = (ad<dd)? ad:dd;
if(loss){
 if(a - loss > ds.length) bubble(Stats[a][ds.toString()],a-loss,ds,defending[dice],rem);
 if(d == loss) {
  if(ds.length == 1) {
   Stats[a][ds.toString()]._odds += attacking[dice];
   for(var y=0;y<a+rem; y++) {
    Stats[a][ds.toString()]._min[y] += attacking[dice];
   }   
  }
  else bubble(Stats[a][ds.toString()],a-1,defence(ds,0),attacking[dice],rem+1);
 }
 else bubble(Stats[a][ds.toString()],a,defence(ds,loss),attacking[dice],rem);
 if(splitting[dice] && (a-1 > ds.length)) bubble(Stats[a][ds.toString()],a-1,defence(ds,1),splitting[dice],rem);
}
return Stats[a][ds.toString()];
}

function overwhelmStats(as,ds,rem) {
if(!Stats[as.toString()]) Stats[as.toString()] = new Array();
var atot=0;
for(var cb=0; cb<as.length; cb++) {
 atot += as[cb];
}
if(!Stats[as.toString()][ds.toString()]) Stats[as.toString()][ds.toString()] = new Survived(atot + rem,ds.length,as.length);
var a = as[0];
var d = ds[0];
var ad = (a>4)? 3:a-1;
var dd = (d>1)?2:d;
var dice = ad + '' + dd;
var loss = (ad<dd)? ad:dd;
if(loss) {
   if(a -1 == loss) {
      if(as.length == 2) bubble(Stats[as.toString()][ds.toString()],as[1],ds,defending[dice],rem+1);
      else bubbled(Stats[as.toString()][ds.toString()],defence(as,0),ds,defending[dice],rem+1);
   }
   else bubbled(Stats[as.toString()][ds.toString()],defence(as,loss),ds,defending[dice],rem);
   if(d == loss) {
    if(ds.length == 1) {
      Stats[as.toString()][ds.toString()]._odds += attacking[dice];
      for(var y=0;y<atot+rem; y++) {
       Stats[as.toString()][ds.toString()]._min[y] += attacking[dice];
     }   
    }
    else bubble(Stats[as.toString()][ds.toString()],a-1,defence(ds,0),attacking[dice],rem +1 + atot - a);
   }
   else bubbled(Stats[as.toString()][ds.toString()],as,defence(ds,loss),attacking[dice],rem);
    if(splitting[dice]) {
     if(a>2) bubbled(Stats[as.toString()][ds.toString()],defence(as,1),defence(ds,1),splitting[dice],rem);
     else {
     if(as.length == 2) bubble(Stats[as.toString()][ds.toString()],as[1],defence(ds,1),splitting[dice],rem+1);
     else bubbled(Stats[as.toString()][ds.toString()],defence(as,0),defence(ds,1),splitting[dice],rem+1);
     }
   }
}
return Stats[as.toString()][ds.toString()];      
}


function addSelect(tid,eid) {
if(tid) {   
 var pid = parseInt(eid.split('i')[1]);
 path = path.splice(0,pid);
 path.push(terr[tid]);
 setTable();
}
}

function addPath(ind) {
if(ind) {
 var opp = new Array();
 for(var s=1; s<steps.length; s++) {
  opp.push(armiesarray[steps[s]]);
 }
 var prob;
 if(display & (1 << 2)) {
    compiled = checkStackStats(armiesarray[path[0]] + deploy, opp,1,0);
    prob = formatOdds(compiled._odds);
 }
 else prob = formatOdds(checkStack(armiesarray[path[0]] + deploy, opp,1));
 html = "<td><span class=\"player" + owners[path[ind]] + "\">" + path[ind] + " (" + armiesarray[path[ind]] + ")</span></td><td>" + prob + "</td></tr>";
}
else   
html = "<td><span class=\"player" + owners[path[0]] + "\">" + path[0] + " (" + (armiesarray[path[0]] + deploy) + ")</span></td><td>&nbsp;</td></tr>";
if(bombard) {
html += "<tr><td>&nbsp;</td><td>No More Attacks</td>";
return html;
}
var uihtml = "<tr><td>&nbsp;</td><td><select id=\"ui" + (ind + 1) + "\"><option value=\"\">To</option>";
var valid = 0;
bds[path[ind]].sort();
for(var d=0; d<bds[path[ind]].length; d++) {
 if(steps.indexOf(bds[path[ind]][d]) == -1 && owners[bds[path[ind]][d]] != owner) {
  var sel = (path.length > ind && bds[path[ind]][d] == path[ind+1]) ? ' selected' : '';
  uihtml += "<option" + sel + " style=\"font-weight:bold;color:" +  cols[owners[bds[path[ind]][d]]] + "\" value=\"" + terr.indexOf(bds[path[ind]][d]) + "\">" + bds[path[ind]][d] + " (" + armiesarray[bds[path[ind]][d]] + ")</option>";
  valid++;
 } 
}
bmb[path[ind]].sort();
for(var d=0; d<bmb[path[ind]].length; d++) {
 if(steps.indexOf(bmb[path[ind]][d]) == -1 && owners[bmb[path[ind]][d]] != owner) {
  var sel = (path.length > ind && bmb[path[ind]][d] == path[ind+1]) ? ' selected' : '';
  uihtml += "<option" + sel + " style=\"font-weight:bold;color:" +  cols[owners[bmb[path[ind]][d]]] + "\" value=\"" + terr.indexOf(bmb[path[ind]][d]) + "\">" + bmb[path[ind]][d] + " (" + armiesarray[bmb[path[ind]][d]] + ")</option>";
  valid++;
  if(sel != '') bombard = 1;
 } 
}
if(valid)html += uihtml + "</select></td>";
else html += "<tr><td>&nbsp;</td><td>No More Attacks</td>";
return html;
}

function showHide() {
for(var t=0; t<displays.length; t++) {
document.getElementById('dispdiv' + t).style.display = ((display & (1<<t)) ? "" : "none");
}
}

function getArmies() {
owners = new Array();
armiesarray = new Array();
var armies;
var spread = document.getElementById('armies').innerHTML;
if(spread) {
   armies = eval("(" + spread + ")");
   for(var a=0; a<armies.length;a++) {
      owners[terr[a]] = parseInt(armies[a]["player"]);
      var q = parseInt(armies[a]["quantity"]);
      armiesarray[terr[a]] = (q==-1)? 0: q;
   }   
}
else{
var s = document.getElementsByTagName('script');
for(var sx=0; sx<s.length; sx++) {
   if(s[sx].innerHTML.match(/armies = (.+?);/)) {
      armies = eval("(" + RegExp.$1 + ")");
      for(var a=0; a<armies.length;a++) {
         owners[terr[a]] = parseInt(armies[a]["player"]);
         var q = parseInt(armies[a]["quantity"]);
         armiesarray[terr[a]] = (q==-1)? 0: q;
      }   
   }
}   
}
}

function setStats() {
var shtml = "<table class=\"listing\" border=\"1\" rules=\"all\"><thead><tr><th colspan=\"3\">Statistics</th></tr></thead><tbody><tr><td># Surviving Attackers</td><td>Exactly This # Survive</td><td>Minimum This # Survive</td></tr>";
var exact,rc;
if(compiled) {
for(var s=(compiled._blanks + compiled._duds - 1); s<compiled._min.length - 1; s++) {
exact = compiled._min[s] - compiled._min[s+1];   
rc = (s & 1) ? "<tr class=\"odd\">" : "<tr class=\"even\">";
shtml += rc + "<td>" + (s+1) + "</td><td>" + formatOdds(exact) + "</td><td>" + formatOdds(compiled._min[s]) + "</td></tr>";
}
rc = ((compiled._min.length-1) & 1) ? "<tr class=\"odd\">" : "<tr class=\"even\">";
shtml += rc + "<td>" + (compiled._min.length) + "</td><td>" + formatOdds(compiled._min[compiled._min.length-1]) + "</td><td>" + formatOdds(compiled._min[compiled._min.length-1]) + "</td></tr>";
shtml += "</tbody></table>";
}
document.getElementById('dispdiv2').innerHTML = shtml;
}

function validateQcalc(name,id,min) {
   var qc = document.getElementById(id);
  var dstring = qc.value.split(',');
   var pint = new Array();
   for(var g=0; g<dstring.length;g++) {
      pint[g] = parseInt(dstring[g]);
       if(isNaN(pint[g]) || pint[g] < min) {
         pint = new Array();
         break;
      }
   }
   if(!pint.length) {   
      qc.value = '';
     alert(name + " armies must be one or more numbers > " + (min - 1) + " separated by commas");
   }
   return pint;
}

function setTable() {
var thtml="";
if (is_panel) {
    thtml = "<div id=\"panelheader_odds\" class=\"panelheader\">Assault Odds</div>";
    thtml += "<div title=\"Move\" id=\"paneltogglewrapper_odds\" onclick=\"togglePanels()\" class=\"settingslinks\" style=\"position:absolute;z-index:999;right:10px;top:-8px;\"><a id=\"paneltoggle_odds\"><img width=\"18\" src=\"/static/icons/button-move2.png\"></a></div>"
}
thtml += "<div id=\"dispdiv0\"><table class=\"listing\" border=\"1\" rules=\"rows\"><thead><tr><th colspan=\"4\">Quick Calc</th></tr></thead><tbody>";
var valt = '&nbsp;';
if(document.getElementById('qtotal')) valt = document.getElementById('qtotal').innerHTML;
for(var q=0; q<qcalc; q++) {
var vala = '';   
var vald = '';
var valq = '&nbsp;';   
if(document.getElementById('qatt' + q) && document.getElementById('qatt' + q).value) vala = " value=\"" + document.getElementById('qatt' + q).value + "\" ";
if(document.getElementById('qdef' + q) && document.getElementById('qdef' + q).value) vald = " value=\"" + document.getElementById('qdef' + q).value + "\" ";
if(document.getElementById('quick' + q)) valq = document.getElementById('quick' + q).innerHTML;
thtml += "<tr><td>Attackers&nbsp;<input size=\"5\" id=\"qatt" + q + "\" width=\"100px\" type=\"text\" " + vala + "/></td><td>Defenders&nbsp;<input id=\"qdef" + q + "\" type=\"text\" size=10 " + vald + "/></td>";
thtml += "<td><input id=\"calc" + q + "\" type=\"button\" value=\"Odds\"/></td><td width=\"150px\" id=\"quick" + q + "\">" + valq + "</td></tr>";
}
thtml += "<tr><td><input type=\"button\" value=\"Add Calc\" id=\"qadd\" /></td><td><b style=\"font-size:10px\">Separate attacker/defender numbers with commas</b></td><td>Total: </td><td id=\"qtotal\">" + valt + "</td></tr></tbody></table></div>";
thtml += "<div id=\"dispdiv1\"><table class=\"listing\" border=\"1\" rules=\"all\"><thead><tr><th colspan=\"5\">Pathfinder</th></tr></thead><tbody><tr><td>Deploy</td><td>Territory</td><td style=\"width:200px;\">Attack Path</td><td style=\"width:100px;\">Odds</td><td>&nbsp;</td></tr>";
thtml +=  "<tr><td><input size=\"5\" id=\"deploy\" type=text value=\"" + deploy + "\" /></td><td><select style=\"width:200px;\" id=\"ui0\"><option value=\"\">From</option>";
for(var d=0; d<copy.length; d++) {
 if(owners[copy[d]] > 0) {   
  var sel = (path.length && copy[d] == path[0]) ? ' selected' : '';
  thtml += "<option" + sel + " style=\"font-weight:bold;color:" +  cols[owners[copy[d]]] + "\" value=\"" + terr.indexOf(copy[d]) + "\">" + copy[d] + " (" + armiesarray[copy[d]] + ")</option>";
 }
}         
thtml += "</select></td>";
if(path.length) owner = owners[path[0]];
steps = new Array();
bombard = 0;
for(var p=0; p<path.length; p++) {
 steps.push(path[p]);   
 thtml +=addPath(p);
}
thtml += "<td>&nbsp;</td><td>&nbsp;</td><td><input type=\"button\" id=\"pref\" value=\"Refresh\" /></td></tr></tbody></table></div>";
thtml += "<div id=\"dispdiv2\"></div>";
if (!is_panel) {
    thtml = "<H3>Assault Odds</H3>" + thtml;
}
document.getElementById('console_odds').innerHTML = thtml;

setStats();
document.getElementById('ui0').addEventListener('change', function() {
 addSelect(this.options[this.selectedIndex].value, this.id); 
}
, true);
document.getElementById('pref').addEventListener('click', function() {
getArmies();
if(owners[path[0]] == owner) {
   var valid = 1;
   var last = 0;
   for(var f=1; f<path.length; f++) {
     if(owners[path[f]] == owner && owners[path[f-1]] != owner) {
        valid = 0;
        break;
     }
     if(owners[path[f]] == owner) last = f;
   }
   if(valid) {
      if(last > 0) {
        for(var r=0; r<last; r++) {
          path.shift();
         }
      }
   }
   else path = new Array();
}
else path = new Array();
setTable();
}
, true);
document.getElementById('deploy').addEventListener('change', function() {
  if(isNaN(this.value)) this.value = 0;
  deploy = parseInt(this.value);
  getArmies();
  setTable();
}
, true);
document.getElementById('qadd').addEventListener('click', function() {
  qcalc++;
   setTable();
}
, true);
for(q=0; q<qcalc; q++) {
document.getElementById('qatt' + q).addEventListener('keypress', function(event) {
  event.stopPropagation();
}
, false);
document.getElementById('qatt' + q).addEventListener('keyup', function(event) {
  event.stopPropagation();
}
, false);   
document.getElementById('qdef' + q).addEventListener('keypress', function(event) {
  event.stopPropagation();
}
, false);
document.getElementById('qdef' + q).addEventListener('keyup', function(event) {
  event.stopPropagation();
}
, false);   
document.getElementById('calc' + q).addEventListener('click', function() {
  var ind = this.id.split('alc')[1];
   var aint = validateQcalc("Attacking", 'qatt' + ind,2);
   var dint = validateQcalc("Defending", 'qdef' + ind,1);
   if(aint.length && dint.length){
    var total = 1;
   if(aint.length == 1) {
       if(display & (1<<2)) {
          compiled = checkStackStats(aint[0],dint,1,0)
       qcalcs[ind] = compiled._odds;
       }
       else qcalcs[ind] = (checkStack(aint[0],dint,1));
    }
    else {
       if(display & (1<<2)) {
          compiled = checkStackedStats(aint,dint,1,0)
       qcalcs[ind] = compiled._odds;
       }      
       else qcalcs[ind] = (checkStacked(aint,dint,1));
    }
    for(var qr=0; qr<qcalc; qr++) {
     total *= qcalcs[qr];
    }    
    document.getElementById('quick' + ind).innerHTML = formatOdds(qcalcs[ind]);
    document.getElementById('qtotal').innerHTML = formatOdds(total);
    setStats();
  }
   else document.getElementById('quick' + ind).innerHTML = '';   
}
, true);
}

for(p=1;p<path.length+1;p++) {
 if(document.getElementById('ui' + p)) {
 document.getElementById('ui' + p).addEventListener('change', function() {
  addSelect(this.options[this.selectedIndex].value, this.id); 
 }
, true);
}
}
showHide();
}

function showMenu() {
var gmMenu = document.createElement('div');
gmMenu.id="ass";
var html = "<h3><b>Assault Odds <span style='font-size:7pt;' ><a href='" +forumUrl+"'>" + version + "</a></span></b></h3>";
gmMenu.innerHTML = html;
ul[0].parentNode.appendChild(gmMenu);
ul = document.createElement ('ul');
ul.style.borderWidth = "1px 1px 0px 1px";
var inner = "<li><a href=\"javascript:void(0);\" onclick=\"document.getElementById('castopt').style.display=(document.getElementById('castopt').style.display == ''? 'none':'');\"><span>Options</span></a></li>";
inner += "<div id=\"castopt\" style=\"display:none\">";
inner+= "<b>Format</b><br />";
inner += "<input id=\"casting1\" type=\"radio\" name=\"casting\"" + ((cast)? " checked":"") + ">Decimal<br />";
inner += "<input id=\"casting2\" type=\"radio\" name=\"casting\"" + ((cast)? "":" checked") + ">Percentage<br />";
inner += "<li></li><b>Display</b><br />";
for(var t=0; t<displays.length; t++) {
inner += "<input id=\"disp" + t + "\" type=\"checkbox\" value=\"" + t + "\"" + ((display & (1<<t)) ? " checked":"") + " />" + displays[t] + "<br />";
}
inner += "<li></li></div>";
ul.innerHTML = inner;
gmMenu.appendChild(ul);
document.getElementById('casting1').addEventListener("click" , function () {
cast = (this.checked == true)? 1:0;
GM_setValue('cast',cast);
}, true);
document.getElementById('casting2').addEventListener("click" , function () {
cast = (this.checked == true)? 0:1;
GM_setValue('cast',cast);
}, true);
for(var t=0; t<displays.length; t++) {
document.getElementById('disp' + t).addEventListener("click" , function () {
for (var u=0; u< displays.length; u++){
if (document.getElementById('disp' + u).checked==true)
display |= 1 << document.getElementById('disp' + u).value;
else
display &= ~( 1 << document.getElementById('disp' + u).value);
}
GM_setValue('display',display);
showHide();
}, true);
}
checkForUpdate();
}
function checkForUpdate() {
    var lastversion = GM_getValue('lastupdate', 0);
    if (lastversion < new Date().getTime() - 60*60*1000) {
        GM_setValue('lastupdate', new Date().getTime() + "");
        GM_xmlhttpRequest({
            method: 'GET',
            url: forumUrl,
            onload: updateServerNumber
        });
    }
    else {
        updateOptionsMenu();
    }
}

function updateServerNumber(response) {
    try {
     var serverVersion = /version\s+(\d+.\d+.\d+)/.exec(response.responseText)[1];
     GM_setValue('updateavailable', serverVersion);
     updateOptionsMenu();
    }catch(e){}
}

function isNewVersion() {
    var serverVersion = GM_getValue('updateavailable', false);
    if (serverVersion) {
        var newVersion = serverVersion.split('.').map(function(string) {
                return parseInt(string,10);
         });
         var thisVersion = version.split('.').map(function(string) {
                return parseInt(string,10);
         });
         return (newVersion[0]>thisVersion[0] || (newVersion[0]==thisVersion[0] && (newVersion[1]>thisVersion[1] || (newVersion[1]==thisVersion[1] && newVersion[2]>thisVersion[2]))));
    }
    return false;
}

function updateOptionsMenu() {
    var cgMenu = document.getElementById("ass");
    var ul = document.createElement('ul');
    ul.style.borderWidth = "0px 1px 0px 1px";
    var source = scriptUrl;
    if(isNewVersion()) {
        ul.innerHTML = "<li><a id=\"assVersionInfo\" href=" + source + "><span class=\"attention\">New Update Available</span></a></li>";
        cgMenu.appendChild(ul);
    }
    else {
        ul.innerHTML = "<li><a id=\"assVersionInfo\" href=" + source + "><span>Latest Version Installed</span></a></li>";
        cgMenu.appendChild(ul);
    }
    /*var ftext = features.join("\n");
    document.getElementById('cgVersionInfo').addEventListener("click" , function () {
         alert('New version features\n' + ftext);
        },true);*/
}

var leftBar = document.getElementById("leftColumn");
if(leftBar) {
var ul = leftBar.getElementsByTagName("ul");
if (ul[0]) {
proto = window.location.protocol;
   showMenu();
}
}

GM_addStyle("#console_odds {padding: 5px;} #console_odds table {background-color:#eee} #console_odds table {font-weight:bold;text-align:center}");

window.addEventListener("unload" , cleanup, false);

if(document.getElementById('action-form')) {   
var s = document.getElementsByTagName('script');
   
    for(var sx=0; sx<s.length; sx++) {
   if(s[sx].innerHTML.match(/map = (.+?);/)) {
   map = eval("(" + RegExp.$1 + ")");
   for(var a=0; a<map["countries"].length;a++) {
      terr.push(map["countries"][a]["name"]);
   }   
   for(var a=0; a<map["countries"].length;a++) {
      var name = map["countries"][a]["name"];
      bds[name] = new Array();
      bmb[name] = new Array();
      for(var j=0; j<map["countries"][a]["borders"].length; j++) {
         bds[name].push(terr[map["countries"][a]["borders"][j]]);         
      }
      for(var j=0; j<map["countries"][a]["bombardments"].length; j++) {
         bmb[name].push(terr[map["countries"][a]["bombardments"][j]]);
      }
   }
   copy = terr.slice();
  copy.sort();
  getArmies();
       
  var div = document.createElement('div');
  div.id = "console_odds";
  var panelLocation = document.getElementById('console_container');
  if (is_panel) {
      div.style.position = "relative";
      div.style.width = "auto";
      div.style.display="none";
      div.className="attachedpanel";
      div.paddingBottom="10px";
      var panelnav = "<li id=\"panel_nav_odds\" class=\"\"><a href=\"javascript:void 0;\" onclick=\"toggle_console('odds');\"><span id=\"panel_nav_text_odds\">Odds</span></a></li>"
      document.getElementById('invertedtabs').childNodes[1].innerHTML += panelnav;
      GM_addStyle("#dispdiv0 table,#dispdiv1 table,#dispdiv2 table {height:50px;} #console_odds select {width:200px} #dispdiv1 input {valign:middle}");
      panelLocation.insertBefore(div, panelLocation.lastChild);
      unsafeWindow.panels = ['action','basic','game','map','stats','snapshots','chat','log','settings','odds'];
      unsafeWindow.panelnames = ['Action','Overview','Game','Map','Stats','Snapshots','Chat','Log','Settings','Assault Odds'];
      var loadValue = GM_getValue("oddsLoc");
      if(typeof(loadValue) != "undefined") {
          cMode=loadValue;
      }
      unsafeWindow.myOptions.panels[9]=["odds",cMode];
  }
  else {
      div.innerHTML = "<H3>Assault Odds</H3>";
      GM_addStyle("#dispdiv0 table,#dispdiv1 table,#dispdiv2 table {height:50px;width:650px} #console_odds select {width:200px} #dispdiv1 input {valign:middle}");
      dashboard.parentNode.insertBefore(div, document.getElementById('action-form').nextSibling);
  }
 
  setTable();
  if (is_panel) {
      if (is_FF) {
          var oldVersion=unsafeWindow.updatePanels;
          unsafeWindow.updatePanels = function() {
              var cMode = unsafeWindow.myOptions.panels[9][1];
              setTimeout(function() {
                  GM_setValue("oddsLoc",cMode);},0);
              return oldVersion();
          };
      }
      else{
      (function() {
          var oldVersion = this.updatePanels;
          this.updatePanels = function() {
              var result = oldVersion.apply(this, arguments);
              GM_setValue("oddsLoc",unsafeWindow.myOptions.panels[9][1]);
          };
      })();
      }
      if (unsafeWindow.myOptions.panelSelected=="odds") unsafeWindow.toggle_console('odds');
      unsafeWindow.togglePanels();
  }
       
  break;
   }
}
}
tunafizzle
Posts: 3
Joined: Tue May 13, 2008 4:13 am

Re: Script: Assault Odds - Version 2.0.3

Post by tunafizzle »

I appreciate the work on the plugin, but maybe the tool/exstension builders here could use another site besides userscripts? I know i've wanted to try out other plugins and update assault odds for a while but userscripts.org has been down for what seems to be months. Any reason these plugins can't be on github, sourceforge, etc? or at least have them mirrored on another site?
User avatar
dgz345
Posts: 1363
Joined: Thu Oct 07, 2010 10:53 am

Re: Script: Assault Odds - Version 2.0.3

Post by dgz345 »

User avatar
EASTOFEDEN
Posts: 10
Joined: Wed Dec 08, 2010 8:04 pm
Location: Iowa

Re: Script: Assault Odds - Version 2.0.3

Post by EASTOFEDEN »

Can't upgrade to new version. Using firefox. Anyway to get it updated?
User avatar
Woltato
Posts: 192
Joined: Sat Jan 17, 2009 8:09 pm
Gender: Male
Location: Bingley, UK

Re: Script: Assault Odds - Version 2.0.3

Post by Woltato »

Slight bug with the latest version of assault odds. When changing the Display options tab, hiding pathfinder and statistics which I don't use, it doesn't remember the settings. refresh the page and they just re-appear again. This is on firefox.
User avatar
dgz345
Posts: 1363
Joined: Thu Oct 07, 2010 10:53 am

Re: Script: Assault Odds - Version 2.0.3

Post by dgz345 »

Will look at it next month when I get home to a computer
User avatar
ztodd
Posts: 116
Joined: Sat Sep 06, 2008 9:38 pm
Gender: Male
Location: Arizona, USA

Re: Script: Assault Odds - Version 2.0.3

Post by ztodd »

I finally installed it with Tampermonkey- working good. You're awesome dgz. For some reason it doesn't show stats for # surviving attackers less than 8 here - is that by design? Why would it not show for less than 8?

Not too big a deal though. Seems to work real good.

[bigimg]http://s18.postimg.org/xkiuejq2x/Capture.png[/bigimg]
User avatar
ztodd
Posts: 116
Joined: Sat Sep 06, 2008 9:38 pm
Gender: Male
Location: Arizona, USA

Re: Script: Assault Odds - Version 2.0.3

Post by ztodd »

If you feel like adding new features, maybe add an option on each line for "Stay behind"- that would mean we want all the armies to stay behind instead of moving on for that attack, to attack from that same spot again to a different neighboring country. Does that make sense? I know it may not be as easy to program as I might think at first, but if you're up for the challenge...
User avatar
dgz345
Posts: 1363
Joined: Thu Oct 07, 2010 10:53 am

Re: Script: Assault Odds - Version 2.0.3

Post by dgz345 »

I know I have thought about that problem. But I haven't had a computer for a month. Can check next month.
User avatar
ztodd
Posts: 116
Joined: Sat Sep 06, 2008 9:38 pm
Gender: Male
Location: Arizona, USA

Re: Script: Assault Odds - Version 2.0.3

Post by ztodd »

I've got all kinds of suggestions for ya... of course you can pick and choose what ya wanna do. Included my suggestion from previous post also so they're all in one place.

For quick calc:
- Add a note field for each quick calc
- Add an "include" checkbox on each quick calc (checked by default). The total % will only include those that have the checkbox checked.

For path-finder:
- Add a checkbox on each line in the path-finder for "Stay behind"- that would mean we want all the armies to stay behind instead of moving on for that attack, to attack from that same spot again to a different neighboring country.
- Add an "Add to quick calc" button in the path-finder which will add a line to quick-calc and automatically fill in the numbers from the pathfinder into it, and will automatically enter a note "From (start country) to (end country)"
* Add a button or hyperlink on the rows in quick-calc that came from path-finder, which when click on, would populate the data back into path-finder again. (This might be a bit more work since you'd have to also store all the territories attacking from and to, for each line- could be stored in hidden fields or in cookie / local storage in some kind of 2-d array.)

Let me know if my suggestions aren't clear. You're awesome.
User avatar
dgz345
Posts: 1363
Joined: Thu Oct 07, 2010 10:53 am

Re: Script: Assault Odds - Version 2.0.3

Post by dgz345 »

I'll look at it when I get home to my computer.

I haven't created my own script so I'm not as good as the creators of the scripts but I'll see what i can do :-)
User avatar
EBConquer
Posts: 973
Joined: Sun Dec 05, 2010 1:11 am
Gender: Male
Location: San Diego
Contact:

Re: Script: Assault Odds - Version 2.0.3

Post by EBConquer »

This addon is making the chat and log start from the top vs the bottom. Figured i'd let you know dgz.

Thanks for all your work too, dgz! I think i can speak for everybody in that all your contributions don't go unnoticed. :)

Edit: That's w/ the new panel interface activated btw.
Image
User avatar
RobbieDub
Posts: 433
Joined: Fri Aug 21, 2009 1:12 am
Gender: Male
Location: Salt Spring Island

Re: Script: Assault Odds - Version 2.0.4

Post by RobbieDub »

I just tried using this in chrome on my mac with panels activated and it doesn't work.
I really like panels I just wish some of my other favourite plugins worked with them as well.
Hope you can have a chance to tidy them up soon.
Highest Rank Colonel with 2932
Image
User avatar
Robespierre__
Posts: 515
Joined: Sat Jun 28, 2008 2:23 pm
Gender: Male
Location: New Jersey

Re: Script: Assault Odds - Version 2.0.4

Post by Robespierre__ »

Anyone able to get the assault odds to work (using Tampermonkey or whatever)? It has been a long time since I have been able to ... the newest versions of Chrome and Firefox seems to have extensions/scripts on lock down which may be causing the problem.
Image
User avatar
dgz345
Posts: 1363
Joined: Thu Oct 07, 2010 10:53 am

Re: Script: Assault Odds - Version 2.0.4

Post by dgz345 »

Robespierre__ wrote:Anyone able to get the assault odds to work (using Tampermonkey or whatever)? It has been a long time since I have been able to ... the newest versions of Chrome and Firefox seems to have extensions/scripts on lock down which may be causing the problem.


it works for me on chrome using panel interface. ill check the old interface and see if it works.

EDIT: works for me in old interface aswell.

Im using latest chrome, latest tamper and latest script version

if u are using chrome press ctrl+shift+ j to open console.
refresh the gamepage.
send me a pm with the text in the console if its not loading.
tomasmk
Posts: 1
Joined: Sun Jun 03, 2018 7:05 am

Re: Script: Assault Odds - Version 2.0.4

Post by tomasmk »

I just installed it on Firefox with Greasemonkey. I can't see any difference or new interface, besides the "AssaultOdds Options" bar on the left side menu.

Is there any known fix to this?

Thanks
User avatar
Dukasaur
Community Team
Community Team
Posts: 28213
Joined: Sat Nov 20, 2010 4:49 pm
Location: Beautiful Niagara

Re: Script: Assault Odds - Version 2.0.4

Post by Dukasaur »

tomasmk wrote:I just installed it on Firefox with Greasemonkey. I can't see any difference or new interface, besides the "AssaultOdds Options" bar on the left side menu.

Is there any known fix to this?

Thanks


Firefox doesn't play nice with others. 90% of these scripts now only work with Chrome and Tampermonkey.
“‎Life is a shipwreck, but we must not forget to sing in the lifeboats.”
― Voltaire
User avatar
anonymus
Posts: 1579
Joined: Tue Apr 28, 2009 10:09 am
Location: Former DDR

Re: Script: Assault Odds - Version 2.0.4

Post by anonymus »

added tampermonkey and the assult-odds shows up in lefthand menu-section but no window in the actual game, am i doing something wrong here? Mainly interested in the pathfinder..

/ :?:
[bigimg]https://u.cubeupload.com/SoNic11111/eb7ezgifcomgifmaker2023.gif[/bigimg]
[spoiler=BoganGod speaks the truth][/spoiler]
Post Reply

Return to “Third-Party Tools & Enhancements”