BACK WITH A HUGE SUCCESS! I have a proof-of-concept version working. My code really needs to be cleaned up, functions renamed, and certain others streamlined. And, I still want to explore some other functionality. But here's the rough structure. I have a wordpress page with a pro subscription to allow me to use plugs. I'm using the scripts n styles plugin to allow me to directly inject javascript onto the page I'm using the formidable forms plugin to organize my database and to display the character sheet and its data. The wordpress javascript is: function randbetween(min, max) { // min and max included
var val = Math.floor(Math.random() * (max - min + 1) + min);
return val;
}
function roll(rolltype){
var abilityval = getAbility(rolltype);
var skillval = getSkill(rolltype);
var bonusval = 0;
var penaltyval = 0;
//var x = ability+skill+bonus+penalty+randbetween(1,10);
console.log("rolltype: " + rolltype);
console.log("ability val: " + abilityval);
console.log("ability val: " + skillval);
var randval = randbetween(1,10);
var rollval = abilityval + skillval + bonusval + penaltyval + randval;
console.log("Rand Val: " + randval);
var msg = "Final Roll Value: " + rollval;
alert("Final Roll Value: " + rollval);
window.parent.postMessage(msg,"*");
}
function getAbility(rolltype){
switch(rolltype){
case "Finesse":
return parseInt(document.getElementById("Finesse").innerHTML);
case "Intelligence":
return parseInt(document.getElementById("Intelligence").innerHTML);
case "Spirit":
return parseInt(document.getElementById("Spirit").innerHTML);
case "Power":
return parseInt(document.getElementById("Power").innerHTML);
case "Charms":
return parseInt(document.getElementById("Power").innerHTML);
case "Transfiguration":
return parseInt(document.getElementById("Power").innerHTML);
case "Defense":
return parseInt(document.getElementById("Power").innerHTML);
case "DarkArts":
return parseInt(document.getElementById("Power").innerHTML);
case "Arithmancy":
return parseInt(document.getElementById("Intelligence").innerHTML);
case "History":
return parseInt(document.getElementById("Intelligence").innerHTML);
case "Muggles":
return parseInt(document.getElementById("Intelligence").innerHTML);
case "Runes":
return parseInt(document.getElementById("Intelligence").innerHTML);
case "Herbology":
return parseInt(document.getElementById("Finesse").innerHTML);
case "Flying":
return parseInt(document.getElementById("Finesse").innerHTML);
case "Artificing":
return parseInt(document.getElementById("Finesse").innerHTML);
case "Potions":
return parseInt(document.getElementById("Finesse").innerHTML);
case "Alchemy":
return parseInt(document.getElementById("Finesse").innerHTML);
case "SocialSkills":
return parseInt(document.getElementById("Spirit").innerHTML);
case "Perception":
return parseInt(document.getElementById("Spirit").innerHTML);
case "Creatures":
return parseInt(document.getElementById("Spirit").innerHTML);
case "Divination":
return parseInt(document.getElementById("Spirit").innerHTML);
case "Astronomy":
return parseInt(document.getElementById("Spirit").innerHTML);
default:
return 0;
}
}
function getSkill(rolltype){
switch(rolltype){
case "Charms":
return parseInt(document.getElementById("Charms").innerHTML);
case "Transfiguration":
return parseInt(document.getElementById("Transfiguration").innerHTML);
case "Defense":
return parseInt(document.getElementById("Defense").innerHTML);
case "DarkArts":
return parseInt(document.getElementById("DarkArts").innerHTML);
case "Arithmancy":
return parseInt(document.getElementById("Arithmancy").innerHTML);
case "History":
return parseInt(document.getElementById("History").innerHTML);
case "Muggles":
return parseInt(document.getElementById("Muggles").innerHTML);
case "Runes":
return parseInt(document.getElementById("Runes").innerHTML);
case "Herbology":
return parseInt(document.getElementById("Herbology").innerHTML);
case "Flying":
return parseInt(document.getElementById("Flying").innerHTML);
case "Artificing":
return parseInt(document.getElementById("Artificing").innerHTML);
case "Potions":
return parseInt(document.getElementById("Potions").innerHTML);
case "Alchemy":
return parseInt(document.getElementById("Alchemy").innerHTML);
case "SocialSkills":
return parseInt(document.getElementById("SocialSkills").innerHTML);
case "Perception":
return parseInt(document.getElementById("Perception").innerHTML);
case "Creatures":
return parseInt(document.getElementById("Creatures").innerHTML);
case "Divination":
return parseInt(document.getElementById("Divination").innerHTML);
case "Astronomy":
return parseInt(document.getElementById("Astronomy").innerHTML);
default:
return 0;
}
}
function getBonus(){ //should include equipment
}
function getPenalty(){
}
function parseLinesToArray() {
var elements = document.getElementById('traitlist').innerHTML;
var split = elements.split(', ');
for (var i =0; i<split.length; i++) {
console.log(split[i].toString());
}
} On the browser extension I'm using the following files: manifest.json {
"name": "Charms Check Roll20 Extension",
"version": "0.0.1",
"description": "A pre-alpha attempt to create a roll20 plugin for Charms Check",
"content_scripts": [
{
"css": ["fullscreen.css"],
"matches": ["<a href="https://app.roll20.net/editor/" rel="nofollow">https://app.roll20.net/editor/</a>"],
"html": ["index.html"],
"js": ["script.js"],
"run_at": "document_end"
}
],
"manifest_version": 3,
"author": "MrLiioadin",
"action":{
"default_popup": "index.html",
"default_title": "Charms Check Character Roller"
}
} script.js window.setTimeout(test, 5000); //ensures page is fully loaded before executing functions
function test (){
addiframe();
getElement();
postToChat("Charms Check Extension is ready");
}
const addiframe = function(){
const myiframe = document.createElement('iframe');
myiframe.setAttribute("id", "dynamiciframe");
myiframe.setAttribute("class", "ui-dialog ui-widget ui-widget-content ui-corner-all initiativedialog ui-draggable ui-resizable ui-dialog-buttons");
myiframe.setAttribute("src","<a href="https://charmscheck.com/character-sheet/entry/865/" rel="nofollow">https://charmscheck.com/character-sheet/entry/865/</a>");
document.body.appendChild(myiframe);
postToChat("iframecreated");
}
const postToChat = (msg) => {
const chatInputElement = document.querySelector('#textchat-input textarea'),
chatButtonElement = document.querySelector('#textchat-input .btn');
if (chatInputElement && chatButtonElement) {
const activeText = chatInputElement.value;
chatInputElement.value = msg;
chatButtonElement.click();
if (activeText) setTimeout(() => chatInputElement.value = activeText, 10);
}
}
function getElement(){
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
// Listen to message from child window
eventer(messageEvent,function(e) {
var key = e.message ? "message" : "data";
var data = e[key];
postToChat(data);
},false);
} fullscreen.css (misnomer, it's not a fullscreen script) #dynamiciframe{
overflow:hidden;
overflow-x:hidden;
overflow-y:hidden;
height:30%;
width:15%;
position:absolute;
left:60px;
top:5px;
border-style: solid;
border-width: 3px;
position:absolute;
z-index:1;
} Explanation: On the wordpress side, each button has its own id and I'm using the id to grab the innerHTML to get the value held for that particular attribute. When the button is pressed, all rolling is handled on the wordpress side to allow me greater control such as eventually having specialized rolls and allowing me to build out a compendium in formidable forms. The iframe lives inside the roll20 body. The result of the roll is passed to the iframe's parent window (the roll20 body). The result is posted to an alert (I know, it's annoying. I'll remove it later) and then run through Oosh's code to postToChat. And, scene.