505 lines
14 KiB
JavaScript
505 lines
14 KiB
JavaScript
var DiceRoller = {};
|
|
(function (self) {
|
|
|
|
var VERSION = "2.1.0";
|
|
|
|
self.view;
|
|
|
|
self.dice = [];
|
|
|
|
self.diceTypes = {
|
|
simpleDie: {
|
|
id: "simpleDie",
|
|
},
|
|
starwarsFFG: {
|
|
id: "starwarsFFG",
|
|
symbols: {
|
|
success: "Q",
|
|
failure: "R",
|
|
|
|
triumph: "E",
|
|
advantage: "W",
|
|
threat: "T",
|
|
despair: "Y",
|
|
|
|
dark: "I",
|
|
light: "U",
|
|
light_dark: "O",
|
|
}
|
|
}
|
|
};
|
|
|
|
var starwarsSymbols = self.diceTypes.starwarsFFG.symbols
|
|
|
|
self.init = function () {
|
|
var that = this;
|
|
|
|
var simpleDice = [2, 4, 6, 8, 10, 12, 20, 100];
|
|
for (var x = 0; x < simpleDice.length; x++) {
|
|
var simpleDieId = "d" + simpleDice[x];
|
|
self.dice.push({
|
|
id: simpleDieId,
|
|
dieType: self.diceTypes.simpleDie.id,
|
|
label: simpleDieId,
|
|
sides: simpleDice[x],
|
|
min: 1,
|
|
max: simpleDice[x]
|
|
});
|
|
}
|
|
var starwarsFFGDiceLabels = ["boost", "setback", "ability", "difficulty", "proficiency", "challenge", "force"];
|
|
var starwarsFFGDice = [
|
|
{
|
|
id: "boost",
|
|
sideCount: 6,
|
|
sideFaces: [
|
|
"", "",
|
|
starwarsSymbols.advantage + starwarsSymbols.advantage, starwarsSymbols.advantage,
|
|
starwarsSymbols.success + starwarsSymbols.advantage, starwarsSymbols.success
|
|
]
|
|
},
|
|
{
|
|
id: "setback",
|
|
sideCount: 6,
|
|
sideFaces: [
|
|
"", "",
|
|
starwarsSymbols.failure, starwarsSymbols.failure,
|
|
starwarsSymbols.threat, starwarsSymbols.threat
|
|
]
|
|
},
|
|
{
|
|
id: "ability",
|
|
sideCount: 8,
|
|
sideFaces: [
|
|
"", starwarsSymbols.success,
|
|
starwarsSymbols.success, starwarsSymbols.success + starwarsSymbols.success,
|
|
starwarsSymbols.advantage, starwarsSymbols.advantage,
|
|
starwarsSymbols.success + starwarsSymbols.advantage, starwarsSymbols.advantage + starwarsSymbols.advantage
|
|
]
|
|
},
|
|
{
|
|
id: "difficulty",
|
|
sideCount: 8,
|
|
sideFaces: [
|
|
"", starwarsSymbols.failure,
|
|
starwarsSymbols.failure + starwarsSymbols.failure, starwarsSymbols.threat,
|
|
starwarsSymbols.threat, starwarsSymbols.threat,
|
|
starwarsSymbols.threat + starwarsSymbols.threat, starwarsSymbols.failure + starwarsSymbols.threat
|
|
]
|
|
},
|
|
{
|
|
id: "proficiency",
|
|
sideCount: 12,
|
|
sideFaces: [
|
|
"", starwarsSymbols.success,
|
|
starwarsSymbols.success, starwarsSymbols.success + starwarsSymbols.success,
|
|
starwarsSymbols.success + starwarsSymbols.success, starwarsSymbols.advantage,
|
|
starwarsSymbols.success + starwarsSymbols.advantage, starwarsSymbols.success + starwarsSymbols.advantage,
|
|
starwarsSymbols.success + starwarsSymbols.advantage, starwarsSymbols.advantage + starwarsSymbols.advantage,
|
|
starwarsSymbols.advantage + starwarsSymbols.advantage, starwarsSymbols.triumph
|
|
]
|
|
},
|
|
{
|
|
id: "challenge",
|
|
sideCount: 12,
|
|
sideFaces: [
|
|
"", starwarsSymbols.failure,
|
|
starwarsSymbols.failure, starwarsSymbols.failure + starwarsSymbols.failure,
|
|
starwarsSymbols.failure + starwarsSymbols.failure, starwarsSymbols.threat,
|
|
starwarsSymbols.threat, starwarsSymbols.failure + starwarsSymbols.threat,
|
|
starwarsSymbols.failure + starwarsSymbols.threat, starwarsSymbols.threat + starwarsSymbols.threat,
|
|
starwarsSymbols.threat + starwarsSymbols.threat, starwarsSymbols.despair
|
|
]
|
|
},
|
|
{
|
|
id: "force",
|
|
sideCount: 12,
|
|
sideFaces: [
|
|
starwarsSymbols.dark, starwarsSymbols.dark,
|
|
starwarsSymbols.dark, starwarsSymbols.dark,
|
|
starwarsSymbols.dark, starwarsSymbols.dark,
|
|
starwarsSymbols.dark + starwarsSymbols.dark, starwarsSymbols.light,
|
|
starwarsSymbols.light, starwarsSymbols.light + starwarsSymbols.light,
|
|
starwarsSymbols.light + starwarsSymbols.light, starwarsSymbols.light + starwarsSymbols.light
|
|
]
|
|
},
|
|
|
|
];
|
|
for (var x = 0; x < starwarsFFGDice.length; x++) {
|
|
self.dice.push({
|
|
id: starwarsFFGDice[x].id,
|
|
dieType: self.diceTypes.starwarsFFG.id,
|
|
label: starwarsFFGDice[x].id.capitalize(),
|
|
sides: starwarsFFGDice[x].sideCount,
|
|
min: 0,
|
|
max: starwarsFFGDice[x].sideCount - 1,
|
|
sideFaces: starwarsFFGDice[x].sideFaces
|
|
});
|
|
}
|
|
|
|
self.view = new Ractive({
|
|
el: "#site-content",
|
|
append: true,
|
|
template: "#dice-roller-template",
|
|
decorators: {
|
|
},
|
|
data: {
|
|
VERSION: VERSION,
|
|
dicePool: [],
|
|
dice: [],
|
|
results: [],
|
|
getDieDisplayData: function (dieId, result) {
|
|
if (dieId == null)
|
|
return;
|
|
|
|
var dieData = _.find(self.dice, function (e) {
|
|
return e.id == dieId;
|
|
});
|
|
|
|
var style = "";
|
|
var label = dieData.label;
|
|
|
|
if (dieData.dieType == self.diceTypes.simpleDie.id) {
|
|
if (result != null) {
|
|
style += " simple";
|
|
if (result <= dieData.min)
|
|
style += " negative";
|
|
if (result >= dieData.max)
|
|
style += " positive";
|
|
|
|
label = dieData.label + ": <br />" + result;
|
|
}
|
|
}
|
|
if (dieData.dieType == self.diceTypes.starwarsFFG.id) {
|
|
style += self.diceTypes.starwarsFFG.id;
|
|
if (result != null) {
|
|
style += " no-select " + dieData.id
|
|
label = dieData.sideFaces[result];
|
|
if ((dieData.id == "boost" || dieData.id == "ability" || dieData.id == "difficulty") && label.length == 2)
|
|
style += " duo";
|
|
}
|
|
}
|
|
return {
|
|
id: dieData.id,
|
|
style: style,
|
|
label: label
|
|
};
|
|
},
|
|
getCompoundResult: function (result) {
|
|
var simpleDieResult;
|
|
var starwarsFFGDieResults;
|
|
var starwarsFFGDieFinalResult;
|
|
|
|
_.each(result.keys, function (dieId) {
|
|
var dieData = _.find(self.dice, function (e) {
|
|
return e.id == dieId;
|
|
});
|
|
|
|
if (dieData == null)
|
|
return;
|
|
|
|
if (dieData.dieType == self.diceTypes.simpleDie.id) {
|
|
if (simpleDieResult == null)
|
|
simpleDieResult = 0;
|
|
var dieResults = result[dieId];
|
|
if (dieResults != null) {
|
|
for (var x = 0; x < dieResults.length; x++) {
|
|
simpleDieResult += dieResults[x];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (dieData.dieType == self.diceTypes.starwarsFFG.id) {
|
|
if (starwarsFFGDieResults == null)
|
|
starwarsFFGDieResults = {};
|
|
var resultValues = [];
|
|
var dieResults = result[dieId];
|
|
for (var x = 0; x < dieResults.length; x++) {
|
|
resultValues += dieData.sideFaces[dieResults[x]].split();
|
|
}
|
|
for (var x = 0; x < resultValues.length; x++) {
|
|
var resultValue = resultValues[x];
|
|
if (starwarsFFGDieResults[resultValue] == null)
|
|
starwarsFFGDieResults[resultValue] = 0;
|
|
starwarsFFGDieResults[resultValue]++;
|
|
}
|
|
}
|
|
});
|
|
|
|
if (starwarsFFGDieResults != null) {
|
|
starwarsFFGDieFinalResult = "";
|
|
|
|
//Success/Triumph vs Failure/Despair
|
|
var successResult = starwarsFFGDieResults[starwarsSymbols.success] || 0;
|
|
var triumphResult = starwarsFFGDieResults[starwarsSymbols.triumph] || 0;
|
|
successResult += triumphResult;
|
|
|
|
var failureResult = starwarsFFGDieResults[starwarsSymbols.failure] || 0;
|
|
var despairResult = starwarsFFGDieResults[starwarsSymbols.despair] || 0;
|
|
failureResult += despairResult;
|
|
|
|
var vsResult = successResult - failureResult;
|
|
if (vsResult != 0) {
|
|
var absResult = Math.abs(vsResult);
|
|
starwarsFFGDieFinalResult += absResult.toString() + " ";
|
|
if (vsResult > 0)
|
|
starwarsFFGDieFinalResult += "Success" + (triumphResult > 0 ? " (with Triumph); " : "; ");
|
|
if (vsResult < 0)
|
|
starwarsFFGDieFinalResult += "Failure" + (despairResult > 0 ? " (with Despair); " : "; ");
|
|
}
|
|
|
|
// Triumph and Despair
|
|
if (triumphResult > 0)
|
|
starwarsFFGDieFinalResult += triumphResult + " Triumph; ";
|
|
if (despairResult > 0)
|
|
starwarsFFGDieFinalResult += despairResult + " Despair; ";
|
|
|
|
//Advantage Vs Threat
|
|
var advantageResult = starwarsFFGDieResults[starwarsSymbols.advantage] || 0;
|
|
var threatResult = starwarsFFGDieResults[starwarsSymbols.threat] || 0;
|
|
|
|
var vsResult = advantageResult - threatResult;
|
|
if (vsResult != 0) {
|
|
var absResult = Math.abs(vsResult);
|
|
starwarsFFGDieFinalResult += absResult.toString() + " ";
|
|
if (vsResult > 0)
|
|
starwarsFFGDieFinalResult += " Advantage; ";
|
|
if (vsResult < 0)
|
|
starwarsFFGDieFinalResult += " Threat; ";
|
|
}
|
|
|
|
var darkResult = starwarsFFGDieResults[starwarsSymbols.dark] || 0;
|
|
if (darkResult)
|
|
starwarsFFGDieFinalResult += darkResult + " Dark Side; ";
|
|
|
|
var lightResult = starwarsFFGDieResults[starwarsSymbols.light] || 0;
|
|
if (lightResult)
|
|
starwarsFFGDieFinalResult += lightResult + " Light Side; ";
|
|
|
|
if (starwarsFFGDieFinalResult.length == 0)
|
|
starwarsFFGDieFinalResult = "Nil ";
|
|
}
|
|
|
|
return (starwarsFFGDieFinalResult == null ? "" : starwarsFFGDieFinalResult) + (simpleDieResult == null ? "" : simpleDieResult);
|
|
}
|
|
},
|
|
oninit: function () {
|
|
var view = this;
|
|
|
|
ga("send", {
|
|
hitType: "event",
|
|
eventCategory: "dice-roller",
|
|
eventAction: "version",
|
|
eventLabel: VERSION
|
|
});
|
|
|
|
view.set("dice", self.dice);
|
|
|
|
this.on({
|
|
addToDicePool: function (event, dieId) {
|
|
var dicePool = view.get("dicePool");
|
|
var currentDiceData = _.find(dicePool, function (e) {
|
|
return e.id == dieId;
|
|
});
|
|
|
|
if (!!currentDiceData) {
|
|
currentDiceData.amount++;
|
|
} else {
|
|
var diceData = _.find(self.dice, function (e) {
|
|
return e.id == dieId;
|
|
});
|
|
dicePool.push($.extend(diceData, {
|
|
amount: 1
|
|
}));
|
|
}
|
|
|
|
view.update();
|
|
},
|
|
removeFromDicePool: function (event, dieId) {
|
|
var dicePool = view.get("dicePool");
|
|
|
|
var currentDiceData = _.find(dicePool, function (e) {
|
|
return e.id == dieId;
|
|
});
|
|
|
|
if (!!currentDiceData) {
|
|
currentDiceData.amount--;
|
|
}
|
|
|
|
if (currentDiceData.amount <= 0) {
|
|
dicePool.remove(currentDiceData);
|
|
}
|
|
|
|
view.update();
|
|
},
|
|
rollPool: function (event) {
|
|
var dicePool = view.get("dicePool").slice();
|
|
|
|
if (dicePool.length == 0)
|
|
return;
|
|
|
|
var result = {
|
|
keys: [],
|
|
timestamp: (new Date()).toLocaleTimeString()
|
|
};
|
|
var dieTypesUsed = [];
|
|
for (var x = 0; x < dicePool.length; x++) {
|
|
(function (result) {
|
|
var dieData = dicePool[x];
|
|
|
|
if (!_.has(dieTypesUsed, dieData.dieType))
|
|
dieTypesUsed.push(dieData.dieType);
|
|
|
|
result.keys.push(dieData.id);
|
|
RandomChad.rollDice(dieData.sides, dieData.amount, function (resultArray) {
|
|
result[dieData.id] = [];
|
|
for (var x = 0; x < resultArray.length; x++) {
|
|
result[dieData.id].push(resultArray[x] + (dieData.min - 1));
|
|
}
|
|
view.update();
|
|
});
|
|
})(result);
|
|
}
|
|
|
|
view.unshift("results", result);
|
|
for (var x = 0; x < dieTypesUsed.length; x++) {
|
|
ga("send", {
|
|
hitType: "event",
|
|
eventCategory: "dice-roller",
|
|
eventAction: "dieTypeUsed",
|
|
eventLabel: dieTypesUsed[x]
|
|
});
|
|
}
|
|
},
|
|
resetPool: function (event) {
|
|
view.set("dicePool", []);
|
|
ga("send", {
|
|
hitType: "event",
|
|
eventCategory: "dice-roller",
|
|
eventAction: "resetPool"
|
|
});
|
|
},
|
|
clearResults: function (event) {
|
|
view.set("results", []);
|
|
ga("send", {
|
|
hitType: "event",
|
|
eventCategory: "dice-roller",
|
|
eventAction: "clearResults"
|
|
});
|
|
},
|
|
copyResult: function (event) {
|
|
|
|
ga("send", {
|
|
hitType: "event",
|
|
eventCategory: "dice-roller",
|
|
eventAction: "reset"
|
|
});
|
|
}
|
|
});
|
|
},
|
|
onrender: function () {
|
|
var view = this;
|
|
}
|
|
});
|
|
};
|
|
})(DiceRoller);
|
|
RollAdvantage.InitRegister.push(DiceRoller.init);
|
|
var RandomChad = {};
|
|
(function (self) {
|
|
//https://api.random.org/json-rpc/1/basic
|
|
//https://api.random.org/json-rpc/1/invoke
|
|
|
|
var diceCache = {};
|
|
|
|
function dieResultHandler(resultArray, die, amount, callback) {
|
|
if (diceCache[die]) {
|
|
diceCache[die] = diceCache[die].concat(resultArray);
|
|
} else {
|
|
diceCache[die] = resultArray;
|
|
}
|
|
if (callback) {
|
|
var returnResult = diceCache[die].slice(0, amount);
|
|
diceCache[die] = diceCache[die].slice(amount, diceCache.length);
|
|
callback(returnResult);
|
|
}
|
|
}
|
|
|
|
self.rollDice = function (die, amount, callback) {
|
|
die = die ? die : 20;
|
|
amount = amount ? amount : 1;
|
|
|
|
if (!diceCache[die] || diceCache[die].length < amount) {
|
|
var options = {
|
|
"jsonrpc": "2.0",
|
|
"method": "generateIntegers",
|
|
"params": {
|
|
"apiKey": "8272a582-c84c-494d-82c5-a8bb6aa62059",
|
|
"n": amount + 10,
|
|
"min": 1,
|
|
"max": die,
|
|
"replacement": true
|
|
},
|
|
"id": die
|
|
};
|
|
|
|
$.post("https://api.random.org/json-rpc/2/invoke", JSON.stringify(options), function (response) {
|
|
dieResultHandler(response.result.random.data, die, amount, callback);
|
|
}, "json")
|
|
.fail(function (jqXHR, textStatus, error) {
|
|
console.log("Post error: " + error);
|
|
console.log("Random.Org could not be reached.");
|
|
var results = [];
|
|
for (var x = 0; x < amount; x++) {
|
|
results.push(generateInt(1, die));
|
|
}
|
|
dieResultHandler(results, die, amount, callback);
|
|
});
|
|
|
|
} else {
|
|
var returnResult = diceCache[die].slice(0, amount);
|
|
diceCache[die] = diceCache[die].slice(amount, diceCache.length);
|
|
callback(returnResult);
|
|
}
|
|
};
|
|
|
|
function generateInt(min, max) {
|
|
min = Math.ceil(min);
|
|
max = Math.floor(max);
|
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
}
|
|
|
|
self.rollD2 = function (amount, callback) {
|
|
self.rollDice(2, amount, callback);
|
|
};
|
|
|
|
self.rollD4 = function (amount, callback) {
|
|
self.rollDice(4, amount, callback);
|
|
};
|
|
|
|
self.rollD6 = function (amount, callback) {
|
|
self.rollDice(6, amount, callback);
|
|
};
|
|
|
|
self.rollD8 = function (amount, callback) {
|
|
self.rollDice(8, amount, callback);
|
|
};
|
|
|
|
self.rollD10 = function (amount, callback) {
|
|
self.rollDice(10, amount, callback);
|
|
};
|
|
|
|
self.rollD12 = function (amount, callback) {
|
|
self.rollDice(12, amount, callback);
|
|
};
|
|
|
|
self.rollD20 = function (amount, callback) {
|
|
self.rollDice(20, amount, callback);
|
|
};
|
|
|
|
self.rollD100 = function (amount, callback) {
|
|
self.rollDice(100, amount, callback);
|
|
};
|
|
|
|
})(RandomChad);
|
|
|
|
|