Traveller RPG Cargo Calculator

by ledlogic

HTML

<h1>Traveller RPG Cargo Calculator</h1>

<div class="if">
<label for="uwp1">UWP1</label>
<input type="text" size="10" id="uwp1" value="A944786-C" />
<select id="zone1">
<option value="">None</option>
<option value="a">Amber</option>
<option value="r">Red</option>
</select>
</div>

<div class="if">
<label for="uwp2">UWP2</label>
<input type="text" size="10" id="uwp2" value="C548786-8" />
<select id="zone2">
<option value="">None</option>
<option value="a">Amber</option>
<option value="r">Red</option>
</select>
</div>

<div class="">

<div class="if3">
<label for="dist">DISTANCE [parsecs]</label>
<input type="number" size="2" id="dist" value="1" />
</div>

<div class="if3">
<label for="broker">BROKER or STREETWISE [effect]</label>
<input type="number" size="2" id="broker" value="0" />
</div>

<div class="if3">
<label for="cargo">CARGO SPACE [dT]</label>
<input type="number" size="4" id="cargo" value="40" />
</div>

</div>

<br class="clear"/>

<div class="">
<button id="calc" class="clear">
Calc
</button>
</div>

<hr class="clear"/>

<div id="output"></div>

CSS

* {
  font-family: Bahnschrift;
}

input {
  font-size: 20px;
  height: 24px;
  border: 1px solid #060;
  border-radius: 4px;
}

button {
  font-size: 20px;
}

select {
  font-size: 20px;
  height: 28px;
  border: 1px solid #060;
  border-radius: 4px;
}

select option[value='a'] {
  color: #FFBF00;
}

select option[value='r'] {
  color: #FF0000;
}

#dist,
#broker,
#space {
  width: 140px;
  text-align: right;
}

label {
  color: #060;
  font-weight: 800;
  width: 100%;
  display: inline-block;
}

textarea {
  width: 100%;
  height: 100px;
  font-size: 20px;
  border: 1px solid #060;
  border-radius: 4px;
}

.if {
  border: 1px solid #333333;
  padding: 10px;
  margin: 10px 0;
  clear: both;
}

.if3 {
  --border: 1px solid #030303;
  padding: 10px;
  margin: 10px 0;
  width: 31%;
  float: left;
}

.clear {
  clear: both;
}

.lots th,
.lots td {
  border: 1px solid #333333;
  padding: 4px;
}

.tonsExceeded {
  color: #ff0000;
}

JavaScript

function d6() { return Math.round(Math.random() * 5 + 1); }
function d66() { return d6() * 10 + d6(); }
function d100() { return Math.round(Math.random() * 99 + 1); }

function hex(s) {
	return parseInt(s, 16);
}

function cap(s) { return s[0].toUpperCase() + s.substring(1); }

function UWP(u, zone) {
  this.starport = u[0];
  this.size = hex(u[1]);
  this.atmo = hex(u[2]);
  this.hydro = hex(u[3]);
  this.pop = hex(u[4]);
  this.gov = hex(u[5]);
  this.law = hex(u[6]);
  // - ignored
  this.tech = hex(u[8]);
  //console.log(this);
}

function calcTons(c) {
  switch (c) {
  	case 0:
      return 10 * d6();
    case 1:
      return 5 * d6();
    case 2:
      return d6();
    default:
      alert("wth");
  }
}

var lots = [];
var lotLabels = ["major", "minor", "incidental"];

function calcCargo() {
	var v = [];
  var zone = [];
  var uwp = [];
  for (var i=0; i<2; i++) {
  	v[i] = $("#uwp" + (i+1)).val();
    zone[i] = $("#zone" + (i+1)).val();
    uwp[i] = new UWP(v[i], zone[i]); 
  }
  var broker = hex($("#broker").val());
  var dist = hex($("#dist").val());
  var cargo = parseInt($("#cargo").val(), 10);
  var fpt = [0, 1000, 1600, 2600, 4400, 8500, 32000];
  
  // lots
  lots = [];
  for (var c=0; c<3; c++) {
    var mods = broker;
    
    // major, minor, incidental
    if (c==0) {
      mods-=4;
    }
    if (c==2) {
      mods+=2;
    }
    
    // uwp
    for (var i=0; i<2; i++) {
      var ui = uwp[i];
      if (ui.pop < 2) {
        mods-=4;
      }
      if (ui.pop >= 6 && ui.pop <= 7) {
        mods+=2;
      }
      if (ui.pop >= 8) {
        mods+=4;
      }
      switch (ui.starport) {
      	case "A": mods+=2; break;
        case "B": mods+=1; break;
        case "E": mods-=1; break;
        case "X": mods-=3; break;
      }
      switch (true) {
      	case ui.tech<=6: mods-=1; break;
        case ui.tech>=9: mods+=2; break;
      }
      if (ui.zone == "a") {
      	mods-=2;
      }
      if (ui.zone == "r") {
      	mods-=6;
      }
      mods...