mingot
free agent
Inspired by this exchange, I decided that I would take a crack at converting X-Acts very useful Java Applet (IVs to PID) to JavaScript, and hopefully kick off a series of useful calculators that can be put on site. Sarenji did all of the user interface work, including input and validation to turn my rough1routines into something usable. So thank you X-Act and Sarenji!
To use, you may copy the information in the code block below into a file, and name it ivstopid.html, and open in a browser.
Currently the this has been tested in IE6, IE8, Firefox 3, and Chrome.
And here it is:
To use, you may copy the information in the code block below into a file, and name it ivstopid.html, and open in a browser.
Currently the this has been tested in IE6, IE8, Firefox 3, and Chrome.
And here it is:
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>IVs to PID</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<script type="text/javascript">
<!--
/////////////////////////////////////////////////////////////////
// RNG CODE BEGIN
/////////////////////////////////////////////////////////////////
// ctor to define our lcrngr class. Very simple, holds
// the current seed that the _get method will use to
// get the previous number.
function lcrngr(seed)
{
// Set the initial seed of the RNG
this.seed = seed;
}
// Get the previous value
function lcrngr_get()
{
this.seed = (((0xEEB90000 * this.seed | 0) + (0xEB65 * this.seed)) + 0x0A3561A1) & 0xFFFFFFFF;
return this.seed >>> 16;
}
lcrngr.prototype.lcrngr_get=lcrngr_get;
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
// CALCULATION CODE BEGIN
/////////////////////////////////////////////////////////////////
//
function calculate(hp, atk, def, spa, spd, spe, nature, id)
{
// Create our array that we are going to return which
// will contain all of the information that we are
// interested in.
var resultArray = [];
// We need to test the last IV with the high bit both
// cleared and set, as either can actually produce the
// same end IVs.
var lastIvClear = 0;
var lastIvSet = 0;
lastIvClear = spe + (spa << 5) + (spe << 10);
lastIvSet = lastIvClear ^ 0x8000;
var firstIvClear = 0;
var firstIvSet = 0;
firstIvClear = hp + (atk << 5) + (def << 10);
firstIvSet = firstIvClear ^ 0x8000;
for (var cnt = 0; cnt <= 0x1FFFE; cnt++)
{
// We need to test with the high bit cleared
// and set so we're just going to do them both
// in a single loop.
var lastivTest = 0;
if(cnt % 2 == 0)
{
lastivTest = lastIvClear;
}
else
{
lastivTest = lastIvSet;
}
// This is the seed for the string of RNG results
// that we want to test for a match to supplied
// IVs and nature.
var seedTest = (lastivTest << 16) + (cnt % 0xFFFF);
// We are going to check this one now, reversing
// through and seeing if we get a nature match.
var rng = new lcrngr(seedTest);
// Get the next two numbers, as we need them
// to create our IV comparison.
var rng1 = rng.lcrngr_get();
var rng2 = rng.lcrngr_get();
if(rng1 == firstIvSet || rng1 == firstIvClear)
{
var rng3 = rng.lcrngr_get();
var rng4 = rng.lcrngr_get();
// Keep track of our starting seed, which is what
// we can pass to a forward running RNG to recreate
// this sequence.
var method1Seed = rng.seed;
rng.lcrngr_get();
var method234Seed = rng.seed;
// This means we have at least a partial match
// for methods 1, 2, and 3. Lets go through
// each one of these and build a PID/Check the
// nature.
var method1pid = unsign((rng2 << 16) + rng3);
if(method1pid % 25 == nature)
{
var sid = rng2 ^ rng3 ^ id;
resultArray[resultArray.length]
= new seed("Method 1", unsign(method1Seed), method1pid, method1pid % 2, method1pid % 256, sid);
}
var method2pid = unsign((rng3 << 16) + rng4);
if(method2pid % 25 == nature)
{
var sid = rng3 ^ rng4 ^ id;
resultArray[resultArray.length]
= new seed("Method 2", unsign(method234Seed), method2pid, method2pid % 2, method2pid % 256, sid);
}
var method3pid = unsign((rng2 << 16) + rng4);
if(method3pid % 25 == nature)
{
var sid = rng2 ^ rng4 ^ id;
resultArray[resultArray.length]
= new seed("Method 3", unsign(method234Seed), method3pid, method3pid % 2, method3pid % 256, sid);
}
}
if(rng2 == firstIvSet || rng2 == firstIvClear)
{
var rng3 = rng.lcrngr_get();
var rng4 = rng.lcrngr_get();
// Get the next RNG call that we need to create our seed
rng.lcrngr_get();
var method234Seed = rng.seed;
var method4pid = unsign((rng3 << 16) + rng4);
if(method4pid % 25 == nature)
{
var sid = rng3 ^ rng4 ^ id;
resultArray[resultArray.length]
= new seed("Method 4", unsign(method234Seed), method4pid, method4pid % 2, method4pid % 256, sid);
}
}
}
return resultArray;
}
/////////////////////////////////////////////////////////////////
// SEED
/////////////////////////////////////////////////////////////////
function seed(method, seed, pid, ability, gender, sid)
{
this.method = method;
this.seed = seed;
this.pid = pid;
this.ability = ability;
this.gender = gender;
this.sid = sid;
}
function unsign(v)
{
return (v >>> 1) * 2 + (v & 1)
}
/////////////////////////////////////////////////////////////////
// DISPLAY / USER INTERFACE
/////////////////////////////////////////////////////////////////
//
function calculateAndDisplay()
{
// Pull all of our values that we are going to pass
// to the calculate function from our text boxes and
// validate the values.
var hp = parseInt(document.getElementById('TextHp').value);
var atk = parseInt(document.getElementById('TextAtk').value);
var def = parseInt(document.getElementById('TextDef').value);
var spa = parseInt(document.getElementById('TextSpA').value);
var spd = parseInt(document.getElementById('TextSpD').value);
var spe = parseInt(document.getElementById('TextSpe').value);
var nat = parseInt(document.getElementById('nature').value);
var idn = parseInt(document.getElementById('idnum').value);
//alert("Hp: " + hp + "; Atk: " + atk + "; Def: " + def + "; SpA: " + spa + "; SpD " + spd + "; Spe: " + spe + "; Nature: " + nat + "; id: " + idn);
var resultArray = calculate(hp, atk, def, spa, spd, spe, nat, idn);
displayResults(resultArray);
}
function fixField(field, minValue, maxValue)
{
if (field.value.search(/^[0-9]+$/) === -1)
field.value = minValue;
else if (field.value < minValue)
field.value = minValue;
else if (field.value > maxValue)
field.value = maxValue;
}
function displayResults(resultArray)
{
var tbl = document.getElementById('resultTable');
while(tbl.rows.length > 1)
tbl.deleteRow(tbl.rows.length - 1);
for(i=0;i<resultArray.length;i++)
{
var lastRow = tbl.rows.length;
var iteration = lastRow;
var row = tbl.insertRow(lastRow);
var cellMethod = row.insertCell(0);
var textNode = document.createTextNode(resultArray[i].method);
cellMethod.appendChild(textNode);
var cellSeed = row.insertCell(1);
var textNode = document.createTextNode(resultArray[i].seed.toString(16).toUpperCase());
cellSeed.appendChild(textNode);
var cellPID = row.insertCell(2);
var textNode = document.createTextNode(resultArray[i].pid.toString(16).toUpperCase());
cellPID.appendChild(textNode);
var cellAbility = row.insertCell(3);
var textNode = document.createTextNode(resultArray[i].ability.toString(16).toUpperCase());
cellAbility.appendChild(textNode);
var cellGender = row.insertCell(4);
var textNode = document.createTextNode(resultArray[i].gender.toString());
cellGender.appendChild(textNode);
var cellSID = row.insertCell(5);
var textNode = document.createTextNode(resultArray[i].sid.toString());
cellSID.appendChild(textNode);
}
}
function hideError() {
document.getElementById('jserror').style.display = 'none';
}
// -->
</script>
<style type="text/css">
body {
font-family: Verdana, serif;
color: #444;
}
table {
padding: 10px;
border: 1px solid black;
margin: 10px;
}
table#resultTable {
border-collapse:collapse;
border: none;
}
table#resultTable th, table#resultTable td {
border: 1px solid black;
padding: 5px 10px;
}
label {
font-weight: bold;
font-style: italic;
float: right;
}
input#FindPID {
margin: 5px 0;
width: 80%;
padding: 10px;
}
h1 {
font-size: 1.5em;
font-weight: normal;
margin-bottom: 0;
border-bottom: 1px solid #ccc;
}
h2 {
font-family: Helvetica,Arial,sans-serif;
font-style: italic;
font-size: 1em;
font-weight: normal;
margin: 0;
}
#jserror {
background: #FFDDDD;
border-top: 1px solid #FFAAAA;
border-bottom: 1px solid #FFAAAA;
padding: 10px;
margin: 10px 0;
}
</style>
</head>
<body onload="hideError();">
<h1>IVs to PID</h1>
<h2>—by X-Act, mingot, and Sarenji</h2>
<div id="jserror">
<strong>Warning:</strong> JavaScript is disabled! Please enable
JavaScript to use this.
</div>
<table id="form">
<tr>
<td><label for="TextHp">HP:</label ></td>
<td><input id="TextHp" type="text" size="2" maxlength="2" value="31" onblur="fixField(this, 0, 31);"/></td>
<td><label for="TextAtk">Atk:</label></td>
<td><input id="TextAtk" type="text" size="2" maxlength="2" value="31" onblur="fixField(this, 0, 31);"/></td>
<td><label for="TextDef">Def:</label></td>
<td><input id="TextDef" type="text" size="2" maxlength="2" value="31" onblur="fixField(this, 0, 31);"/></td>
</tr>
<tr>
<td><label for="TextSpA">SpA:</label></td>
<td><input id="TextSpA" type="text" size="2" maxlength="2" value="31" onblur="fixField(this, 0, 31);"/></td>
<td><label for="TextSpD">SpD:</label></td>
<td><input id="TextSpD" type="text" size="2" maxlength="2" value="31" onblur="fixField(this, 0, 31);"/></td>
<td><label for="TextSpe">Spe:</label></td>
<td><input id="TextSpe" type="text" size="2" maxlength="2" value="31" onblur="fixField(this, 0, 31);"/></td>
</tr>
<tr>
<td><label for="nature">Nature:</label></td>
<td><select id="nature">
<option value="0">Hardy</option>
<option value="1">Lonely</option>
<option value="2">Brave</option>
<option value="3">Adamant</option>
<option value="4">Naughty</option>
<option value="5">Bold</option>
<option value="6">Docile</option>
<option value="7">Relaxed</option>
<option value="8">Impish</option>
<option value="9">Lax</option>
<option value="10">Timid</option>
<option value="11">Hasty</option>
<option value="12">Serious</option>
<option value="13">Jolly</option>
<option value="14">Naive</option>
<option value="15">Modest</option>
<option value="16">Mild</option>
<option value="17">Quiet</option>
<option value="18">Bashful</option>
<option value="19">Rash</option>
<option value="20">Calm</option>
<option value="21">Gentle</option>
<option value="22">Sassy</option>
<option value="23">Careful</option>
<option value="24">Quirky</option>
</select></td>
<td><label for="idnum">ID:</label></td>
<td><input id="idnum" type="text" size="5" maxlength="5" value="0" onblur="fixField(this, 0, 65535);"/></td>
</tr>
<tr>
<th colspan="16"><input id="FindPID" type="button" value="Find PID" onclick="calculateAndDisplay();"/></th>
</tr>
</table>
<table id="resultTable">
<tr>
<th>Method</th>
<th>Seed</th>
<th>PID</th>
<th>Ability</th>
<th>Gender</th>
<th>SID</th>
</tr>
</table>
</body>
</html>