Lone Wolf Combat simulator. See https://www.projectaon.org/en/Main/Home
A Pen by Jason Livesay on CodePen.
<div><label for="lwcs">Lone Wolf Combat Skill:</label> | |
<input name="lwcs"> | |
<label for="lwep">Lone Wolf Endurance Points</label> | |
<input name="lwep"> | |
</div> | |
<div> | |
<label for="opcs">Opponent Combat Skill:</label> | |
<input name="opcs"> | |
<label for="opep">Opponent Endurance Points</label> | |
<input name="opep"> | |
</div> | |
<button id="Next" onclick="nextRound()">Next Combat Round</button> | |
<button onclick="reset()">Reset</button> | |
<div></div> | |
<div id="combatlw"></div> | |
<div id="combatop"></div> |
Lone Wolf Combat simulator. See https://www.projectaon.org/en/Main/Home
A Pen by Jason Livesay on CodePen.
// Lone Wolf Combat automater. See https://www.projectaon.org/en/Main/Home | |
function columnSplit(cols) { | |
return cols.split(' ').map(l => l.split('/')); | |
} | |
function makeTable({cols, data}) { | |
const rows = [1,2,3,4,5,6,7,8,9,0]; | |
cols = columnSplit(cols); | |
data = data.map(columnSplit); | |
return {rows, cols, data}; | |
} | |
function wr(...strs) { | |
strs.map(s => document.write(s+" ")); | |
document.write('<br>'); | |
} | |
function wrJSON(...objs) { | |
objs.map(o => wr(JSON.stringify(o))); | |
} | |
let randomNumberTable = | |
` | |
9312814772 | |
6388854931 | |
9566576367 | |
2504866872 | |
0595709441 | |
2825673256 | |
3480714840 | |
6204611420 | |
0566218416 | |
4656059015 | |
`.replace(/(?:\r\n|\r|\n)/g,''); | |
function getRandomNumber() { | |
return randomNumberTable[Math.floor(Math.random()*randomNumberTable.length)]*1; | |
} | |
function matchingColumn({cols, combatRatio}) { | |
for (let c = 0; c < cols.length; c++) { | |
const col = cols[c]; | |
if (col.indexOf(combatRatio+"")>=0) return c; | |
if (col.indexOf('l')>=0 && combatRatio <= col[0]*1 ) return c; | |
if (col.indexOf('g')>=0 && combatRatio >= col[0]*1 ) return c; | |
} | |
console.error('No matching column: ', combatRatio, cols); | |
} | |
function roundResult({table, combatRatio, randomNumber}) { | |
const row = table.rows.indexOf(randomNumber); | |
const col = matchingColumn({cols:table.cols, combatRatio}); | |
const [ opponent, loneWolf ] = table.data[row][col]; | |
return { loneWolf, opponent }; | |
} | |
// CS = Combat Skill, EP = Endurance Points | |
function battle({loneWolfCS, opponentCS, | |
loneWolfEP, opponentEP}) { | |
let victor = 'none', rounds = []; | |
const combatRatio = loneWolfCS - opponentCS; | |
let table = pos; | |
if (combatRatio < 0) table = neg; | |
do { | |
const randomNumber = getRandomNumber(); | |
const {loneWolf, opponent} = roundResult({table, combatRatio, randomNumber}); | |
loneWolfEP -= loneWolf*1; | |
opponentEP -= opponent*1; | |
if (loneWolf == 'K') loneWolfEP = 0; | |
if (opponent == 'K') opponentEP = 0; | |
if (opponentEP <= 0) victor = 'Lone Wolf'; | |
if (loneWolfEP <= 0) victor = 'opponent'; | |
rounds.push({randomNumber, combatRatio, loneWolf, opponent, | |
loneWolfEP, opponentEP, victor}); | |
} while(victor=='none'); | |
return { rounds, victor, loneWolfEP, opponentEP }; | |
} | |
let output = {}; | |
function wr_(category, ...strs) { | |
strs.map(s => output[category] += (s+" ")); | |
output[category] += '<br>'; | |
} | |
function printCombat(rounds, upTo) { | |
output = {lw:'',op:''}; | |
let n = 0; | |
for (let round of rounds) { | |
if (n > upTo) break; | |
const { loneWolf, opponent, loneWolfEP, opponentEP, victor } = round; | |
if (loneWolf == 'K') wr_('op','Opponent has struck a killing blow and Lone Wolf has perished.'); | |
if (opponent == 'K') wr_('lw','Lone Wolf has struck a killing blow and won the fight.'); | |
if (opponent >= 0) wr_('lw','Lone Wolf attacks for '+opponent+' damage leaving opponent with '+opponentEP +' endurance points.'); | |
if (loneWolf >= 0) wr_('op','Opponent attacks for '+loneWolf+' damage leaving Lone Wolf with '+loneWolfEP +' endurance points.'); | |
if (victor != 'none') { wr_('lw','The victor is '+victor+'.'); break;} | |
n++; | |
} | |
document.getElementById('combatlw').innerHTML = output.lw; | |
document.getElementById('combatop').innerHTML = output.op; | |
} | |
let neg = makeTable({cols:'-11/l -10/-9 -8/-7 -6/-5 -4/-3 -2/-1 0', | |
data: ['0/K 0/K 0/8 0/6 1/6 2/5 3/5', | |
'0/K 0/8 0/7 1/6 2/5 3/5 4/4', | |
'0/8 0/7 1/6 2/5 3/5 4/4 5/4', | |
'0/8 1/7 2/6 3/5 4/4 5/4 6/3', | |
'1/7 2/6 3/5 4/4 5/4 6/3 7/2', | |
'2/6 3/6 4/5 5/4 6/3 7/2 8/2', | |
'3/5 4/5 5/4 6/3 6/2 8/2 9/1', | |
'4/4 5/4 6/3 7/2 8/0 9/0 10/0 11/0', | |
'5/3 6/3 7/2 8/0 9/0 10/0 11/0', | |
'6/0 7/0 8/0 9/10 10/0 11/0 12/0'] }); | |
let pos = makeTable({cols:'0 1/2 3/4 5/6 7/8 9/10 11/g', | |
data: ['3/5 4/5 5/4 6/4 7/4 8/3 9/3', | |
'4/4 5/4 6/3 7/3 8/3 9/3 10/2', | |
'5/4 6/3 7/3 8/3 9/2 10/2 11/2', | |
'6/3 7/3 8/2 9/2 10/2 11/2 12/2', | |
'7/2 8/2 9/2 10/2 11/2 12/2 14/1', | |
'8/2 9/2 10/2 11/1 12/1 14/1 16/1', | |
'9/1 10/1 11/1 12/0 14/0 16/0 18/0', | |
'10/0 11/0 12/0 14/0 16/0 18/0 K/0', | |
'11/0 12/0 14/0 16/0 18/0 K/0 K/0', | |
'12/0 14/0 16/0 18/0 K/0 K/0 K/0'] }); | |
function readFields(fields) { | |
let data = {}; | |
for (let key in fields) { | |
data[key] = document.getElementsByName(fields[key])[0].value; | |
} | |
return data; | |
} | |
let roundNumber = 0; | |
let combatResult = null; | |
function nextRound() { | |
if (!combatResult) { | |
let fields = { loneWolfCS: 'lwcs',opponentCS:'opcs', | |
loneWolfEP: 'lwep', opponentEP:'opep'}; | |
let stats = readFields(fields); | |
combatResult = battle(stats); | |
} | |
printCombat(combatResult.rounds, roundNumber); | |
roundNumber++; | |
} | |
function reset() { | |
combatResult = null; | |
roundNumber = 0; | |
document.getElementById('combatlw').innerHTML=''; | |
document.getElementById('combatop').innerHTML=''; | |
} | |
div, body { | |
margin-bottom: 10px; | |
line-height: 20px; | |
} | |
label { | |
display:inline-block; | |
width:30%; | |
text-align: right; | |
} | |
input { | |
align: left; | |
width: 50px; | |
} | |
button { | |
border: 1 px solid black; | |
background: none; | |
box-shadow:none; | |
border-radius: 0px; | |
margin-left: 5%; | |
} | |
#combatlw, #combatop { | |
display: inline-block; | |
vertical-align: top; | |
margin-left: 1%; | |
} |