About the Heritage Calculator Script

So I’ve been working on and off on this little web app for my friends over at Dying Kingdoms. They have some mildly confusing rules about how to buy certain abilities in the game, which sounded like the perfect opportunity to practice some scripting.

The goal of the project was to make a webpage that people could go to and have a visual structure that illuminated when abilities were available to purchase and when they stopped being available to purchase as the user went through and bought more abilities. In addition to that I wanted there to be a readout for how many points the user had spent to get the abilities, and for the user to be able to click on the names of the abilities to get more information about them.

THIS is just a demo, with a Generic format and two of the game’s bloodlines enabled.

Because the process of finding out about the game’s abilities during play is important I’ve password locked all of the abilities that don’t show up in the players handbook. Raven Kin is a fully secret bloodline so it defaults to the Test bloodline when the password is incorrect. However, Bloodline of Fire has some of it’s abilities in the players handbook, so I’ve made both a fully unlocked and a “preview” version of it;  even if you don’t have the password for the Bloodline of Fire you can still see all the info about it that you would if you had flipped the player’s handbook to that heritage’s page.

Code:

jQuery(document).ready( function($) {

//function to initialize the ui to accept the core data from the

//bloodline object and set all purchases to 0

function reset() {

$(“#t1aDesc”).hide();
$(“#t1jDesc”).hide();
$(“#t1eDesc”).hide();

$(“#t2aDesc”).hide();
$(“#t2jDesc”).hide();
$(“#t2eDesc”).hide();

$(“#t3aDesc”).hide();
$(“#t3jDesc”).hide();
$(“#t3eDesc”).hide();

$(“#mDesc”).hide();

cpSpent=0;
lastPurchase = [];

t1aBought = 0;
t1jBought = 0;
t1eBought = 0;

t2aBought = 0;
t2jBought = 0;
t2eBought = 0;

t3aBought = 0;
t3jBought = 0;
t3eBought = 0;

mBought = false;

lastPower=[];

$(“#row0”).empty();

$(“#t1aDesc”).empty();
$(“#t1jDesc”).empty();
$(“#t1eDesc”).empty();

$(“#t2aDesc”).empty();
$(“#t2jDesc”).empty();
$(“#t2eDesc”).empty();

$(“#t3aDesc”).empty();
$(“#t3jDesc”).empty();
$(“#t3eDesc”).empty();

$(“#mDesc”).empty();

$(“#row0”).append(“<h1>”+blood.name+”:</h1>”+”<h3>”+blood.desc+”</h3>”);

$(“#t1aDesc”).append(“<p><strong>”+blood.t1a+”</strong>: “+blood.t1aDesc+”</p>”);
$(“#t1jDesc”).append(“<p><strong>”+blood.t1j+”</strong>: “+blood.t1jDesc+”</p>”);
$(“#t1eDesc”).append(“<p><strong>”+blood.t1e+”</strong>: “+blood.t1eDesc+”</p>”);

$(“#t2aDesc”).append(“<p><strong>”+blood.t2a+”</strong>: “+blood.t2aDesc+”</p>”);
$(“#t2jDesc”).append(“<p><strong>”+blood.t2j+”</strong>: “+blood.t2jDesc+”</p>”);
$(“#t2eDesc”).append(“<p><strong>”+blood.t2e+”</strong>: “+blood.t2eDesc+”</p>”);

$(“#t3aDesc”).append(“<p><strong>”+blood.t3a+”</strong>: “+blood.t3aDesc+”</p>”);
$(“#t3jDesc”).append(“<p><strong>”+blood.t3j+”</strong>: “+blood.t3jDesc+”</p>”);
$(“#t3eDesc”).append(“<p><strong>”+blood.t3e+”</strong>: “+blood.t3eDesc+”</p>”);

$(“#mDesc”).append(“<p><strong>”+blood.m+”</strong>: “+blood.mDesc+”</p>”);

}

//tiny function to update the read-out of the ui, it gets called a LOT

function readOut() {

$(“#readout”).empty();
$(“#readout”).append(“<h2> CP spent:”+cpSpent+”</h2>”);

}

// function to undo the last power purchase, and reset the readout accordingly

function Undo() {

if(lastPurchase.length > 0) {

cpSpent= (cpSpent – lastPurchase.pop());

}

if(lastPower.length > 0) {

switch (lastPower[lastPower.length – 1]) {

case “#t1a”:

t1aBought= t1aBought-1;
break;

case “#t2a”:

t2aBought= t2aBought-1;
break;

case “#t3a”:

t3aBought = t3aBought-1;
break;

case “#t1j”:

t1jBought= t1jBought-1;
break;

case “#t2j”:

t2jBought= t2jBought-1;
break;

case “#t3j”:

t3jBought = t3jBought-1;
break;

case “#t1e”:

t1eBought= t1eBought-1;
break;

case “#t2e”:

t2eBought= t2eBought-1;
break;

case “#t3e”:

t3eBought = t3eBought-1;
break;

case”#m”:

mBought = false;
break;

}

lastPower.pop();

}

}

//sets up the constructor for bloodline objects

function Bloodline (name, t1a, t1j, t1e, t2a, t2j, t2e, t3a, t3j, t3e, m) {

this.name = name;
this.t1a = t1a;
this.t1j = t1j;
this.t1e = t1e;
this.t2a = t2a;
this.t2j = t2j;
this.t2e = t2e;
this.t3a = t3a;
this.t3j = t3j;
this.t3e = t3e;
this.m= m;

}

//initialize the generic bloodline “Test”

var Test = new Bloodline (“Test”, “Apprentice1”, “Journeyman1”, “Expert1”, “Apprentice2”, “Journeyman2”, “Expert2”, “Apprentice3”, “Journeyman3”, “Expert3″,”Mastery”);
Test.desc=”This is what the bloodline’s marks, themes and prereqs are.”;
Test.t1aDesc = “Describe apprentice ability of tier 1.”;
Test.t1jDesc = “Describe journeyman ability of tier 1.”;
Test.t1eDesc = “Describe expert ability of tier 1.”;

Test.t2aDesc = “Describe apprentice ability of tier 2.”;
Test.t2jDesc = “Describe journeyman ability of tier 2.”;
Test.t2eDesc = “Describe expert ability of tier 2.”;

Test.t3aDesc = “Describe apprentice ability of tier 3.”;
Test.t3jDesc = “Describe journeyman ability of tier 3.”;
Test.t3eDesc = “Describe expert ability of tier 3.”;

Test.mDesc=”Describe mastery ability here”;

Test.t1color =”#009933″;

Test.t2color=”#3399FF”;

Test.t3color=”#FF6600″;

Test.mcolor=”#9933FF”;

Test.textcolor=”black”;

// Bloodline of Fire would be here and follow the format of Test, cut for length

//add preview mode for bloodline of fire

var firePreview = new Bloodline (“Bloodline of Fire (Preview)”, “Fire Shield (D)”, “Journeyman1”, “Expert1”, “Light”, “Journeyman2”, “Expert2”, “Heat”, “Journeyman3”, “Expert3″,”Mastery”);
firePreview.desc=”You have a strong tie to the spirits of fire.<br></br>
Mark: If marked, you have a red-and-yellow streak along the temples
running from the edge of the eye to the top of the ear.”;
firePreview.t1aDesc = “You can manifest a Fire Shield on yourself, as the
Fire Invocation spell. This takes one minute of concentration to
manifest.”;
firePreview.t1jDesc = “Describe journeyman ability of tier 1.”;
firePreview.t1eDesc = “Describe expert ability of tier 1.”;

firePreview.t2aDesc = “By touch you can manifest Light, as the Fire Invocation
spell. This is an instantaneous effect that requires no preparation.”;
firePreview.t2jDesc = “Describe journeyman ability of tier 2.”;
firePreview.t2eDesc = “Describe expert ability of tier 2.”;

firePreview.t3aDesc = “By pointing you can manifest Heat, as the Fire Invocation
spell. This is an instantaneous effect that requires no preparation.”;
firePreview.t3jDesc = “Describe journeyman ability of tier 3.”;
firePreview.t3eDesc = “Describe expert ability of tier 3.”;

firePreview.mDesc=”Describe mastery ability here”;

firePreview.t1color =”#FFCE63″;

firePreview.t2color=”#FCB021″;

firePreview.t3color=”#FF6A00″;

firePreview.mcolor=”black”;

firePreview.textcolor=”#FF5F33″;

//raven kin bloodline, cut from this example for length

//validBloodlines is an array of the bloodline objects in the program

var validBloodlines = [Test, Raven, Fire];

//function colorize applies custom ui color schemes based on which bloodline the user

//selects

function colorize(blood){

//colorize row 1

$(“#t1a”).css(“background-color”, blood.t1color);
$(“#t1j”).css(“background-color”, blood.t1color);
$(“#t1e”).css(“background-color”, blood.t1color);

//colorize row 2

$(“#t2a”).css(“background-color”, blood.t2color);
$(“#t2j”).css(“background-color”, blood.t2color);
$(“#t2e”).css(“background-color”, blood.t2color);

//colorize row 3

$(“#t3a”).css(“background-color”, blood.t3color);
$(“#t3j”).css(“background-color”, blood.t3color);
$(“#t3e”).css(“background-color”, blood.t3color);

//colorize row 4

$(“#m”).css(“background-color”, blood.mcolor);
$(“#m”).css(“color”, blood.textcolor);

}

//unLock applies .lock, .unlock, and .unlocked to the appropriate divs based on the

//rules of prequisites for bloodline abilities.

function unLock() {

//check for journeyman locks and unlocks

if ((t1aBought>(t1jBought+1))& t2aBought>0 & t3aBought>0) {

$(“#t1j”).removeClass(“locked”);
$(“#t1jcost”).removeClass(“locked”);
$(“#t1j”).addClass(“unlocked”);
$(“#t1jcost”).addClass(“unlock”);

} else {

$(“#t1j”).removeClass(“unlocked”);
$(“#t1jcost”).removeClass(“unlock”);
$(“#t1j”).addClass(“locked”);
$(“#t1jcost”).addClass(“locked”);

}

if (t2aBought>(t2jBought+1) & t1aBought>0 & t3aBought>0) {

$(“#t2j”).removeClass(“locked”);
$(“#t2jcost”).removeClass(“locked”);
$(“#t2j”).addClass(“unlocked”);
$(“#t2jcost”).addClass(“unlock”);

} else {

$(“#t2j”).removeClass(“unlocked”);
$(“#t2jcost”).removeClass(“unlock”);
$(“#t2j”).addClass(“locked”);
$(“#t2jcost”).addClass(“locked”);

}

if (t3aBought>(t3jBought+1) & t1aBought>0 & t2aBought>0) {

$(“#t3j”).removeClass(“locked”);
$(“#t3jcost”).removeClass(“locked”);
$(“#t3j”).addClass(“unlocked”);
$(“#t3jcost”).addClass(“unlock”);

} else {

$(“#t3j”).removeClass(“unlocked”);
$(“#t3jcost”).removeClass(“unlock”);
$(“#t3j”).addClass(“locked”);
$(“#t3jcost”).addClass(“locked”);

}

//check for expert unlocks and locks

if (t1jBought>(t1eBought+1)) {

$(“#t1e”).removeClass(“locked”);
$(“#t1ecost”).removeClass(“locked”);
$(“#t1e”).addClass(“unlocked”);
$(“#t1ecost”).addClass(“unlock”);

} else {

$(“#t1e”).removeClass(“unlocked”);
$(“#t1ecost”).removeClass(“unlock”);
$(“#t1e”).addClass(“locked”);
$(“#t1ecost”).addClass(“locked”);

}

if (t2jBought>(t2eBought+1)) {

$(“#t2e”).removeClass(“locked”);
$(“#t2ecost”).removeClass(“locked”);
$(“#t2e”).addClass(“unlocked”);
$(“#t2ecost”).addClass(“unlock”);

} else {

$(“#t2e”).removeClass(“unlocked”);
$(“#t2ecost”).removeClass(“unlock”);
$(“#t2e”).addClass(“locked”);
$(“#t2ecost”).addClass(“locked”);

}

if (t3jBought>(t3eBought+1)) {

$(“#t3e”).removeClass(“locked”);
$(“#t3ecost”).removeClass(“locked”);
$(“#t3e”).addClass(“unlocked”);
$(“#t3ecost”).addClass(“unlock”);

} else {

$(“#t3e”).removeClass(“unlocked”);
$(“#t3ecost”).removeClass(“unlock”);
$(“#t3e”).addClass(“locked”);
$(“#t3ecost”).addClass(“locked”);

}

//check for mastery power unlock and lock

if (t1jBought>0 & t2jBought>0 & t3jBought>0 & !mBought) {

$(“#m”).removeClass(“locked”);
$(“#mcost”).removeClass(“locked”);
$(“#m”).addClass(“unlocked”);
$(“#mcost”).addClass(“unlock”);

} else {

$(“#m”).removeClass(“unlocked”);
$(“#mcost”).removeClass(“unlock”);
$(“#m”).addClass(“locked”);
$(“#mcost”).addClass(“locked”);

}

//has locked divs fade to half opacity but unlocked ones be fully opaque

$(“.locked”).fadeTo(“fast”, 0.5);

$(“.unlocked”).fadeTo(“fast”,1);

$(“.unlock”).fadeTo(“fast”,1);

}

// takes the passed object and then repopulates the ui with the bloodline-object’s

//specific values

function populate(blood){

$(“#t1a”).empty();

if (t1aBought <= 0){

$(“#t1a”).append(“<h3>”+blood.t1a+”</h3>”);

} else if (t1aBought===1){

$(“#t1a”).append(“<h3>”+t1aBought +” Use of “+blood.t1a+”</h3>”);

} else {

$(“#t1a”).append(“<h3>”+t1aBought+” Uses of “+blood.t1a+”</h3>”);

}

$(“#t1j”).empty();

if(t1jBought<=0){

$(“#t1j”).append(“<h3>”+blood.t1j+”</h3>”);

} else if (t1jBought===1){

$(“#t1j”).append(“<h3>”+t1jBought +” Use of “+blood.t1j+”</h3>”);

} else {

$(“#t1j”).append(“<h3>”+t1jBought+” Uses of “+blood.t1j+”</h3>”);

}

$(“#t1e”).empty();

if(t1eBought<=0){

$(“#t1e”).append(“<h3>”+blood.t1e+”</h3>”);

} else if (t1eBought===1){

$(“#t1e”).append(“<h3>”+t1eBought +” Use of “+blood.t1e+”</h3>”);

} else {

$(“#t1e”).append(“<h3>”+t1eBought+” Uses of “+blood.t1e+”</h3>”);

}

$(“#t2a”).empty();

if (t2aBought <= 0){

$(“#t2a”).append(“<h3>”+blood.t2a+”</h3>”);

} else if (t2aBought===1){

$(“#t2a”).append(“<h3>”+t2aBought +” Use of “+blood.t2a+”</h3>”);

} else {

$(“#t2a”).append(“<h3>”+t2aBought+” Uses of “+blood.t2a+”</h3>”);

}

$(“#t2j”).empty();

if(t2jBought<=0){

$(“#t2j”).append(“<h3>”+blood.t2j+”</h3>”);

} else if (t2jBought===1){

$(“#t2j”).append(“<h3>”+t2jBought +” Use of “+blood.t2j+”</h3>”);

} else {

$(“#t2j”).append(“<h3>”+t2jBought+” Uses of “+blood.t2j+”</h3>”);

}

$(“#t2e”).empty();

if(t2eBought<=0){

$(“#t2e”).append(“<h3>”+blood.t2e+”</h3>”);

} else if (t2eBought===1){

$(“#t2e”).append(“<h3>”+t2eBought +” Use of “+blood.t2e+”</h3>”);

} else {

$(“#t2e”).append(“<h3>”+t2eBought+” Uses of “+blood.t2e+”</h3>”);

}

$(“#t3a”).empty();

if (t3aBought <= 0){

$(“#t3a”).append(“<h3>”+blood.t3a+”</h3>”);

} else if (t3aBought===1){

$(“#t3a”).append(“<h3>”+t3aBought +” Use of “+blood.t3a+”</h3>”);

} else {

$(“#t3a”).append(“<h3>”+t3aBought+” Uses of “+blood.t3a+”</h3>”);

}

$(“#t3j”).empty();

if(t3jBought<=0){

$(“#t3j”).append(“<h3>”+blood.t3j+”</h3>”);

} else if (t3jBought===1){

$(“#t3j”).append(“<h3>”+t3jBought +” Use of “+blood.t3j+”</h3>”);

} else {

$(“#t3j”).append(“<h3>”+t3jBought+” Uses of “+blood.t3j+”</h3>”);

}

$(“#t3e”).empty();

if(t3eBought<=0){

$(“#t3e”).append(“<h3>”+blood.t3e+”</h3>”);

} else if (t3eBought===1){

$(“#t3e”).append(“<h3>”+t3eBought +” Use of “+blood.t3e+”</h3>”);

} else {

$(“#t3e”).append(“<h3>”+t3eBought+” Uses of “+blood.t3e+”</h3>”);

}

$(“#m”).empty();

$(“#m”).append(“<h3>”+blood.m+”</h3>”);

}

//triggers repopulation when a new selection is made from drop-down, by passing the

//corresponding bloodline-object to the populate function, and also calls the reset

//function to start the buying process fresh with the new selection

$( “select” ) .change(function () {

var str = “”;

$( “select option:selected” ).each(function() {

str += $( this ).text();

});

for (var each in validBloodlines) {

if (validBloodlines[each].name === str) {

blood= validBloodlines[each];

}

}

if(blood!=Test){

pass =prompt(“That bloodline is locked, please enter the password”);

switch (blood) {

case Raven:

if (pass ===”Raven”){

blood = Raven;

}else {

confirm(“Sorry your password was incorrect, loading the generic structure, select from the dropdown to try again.”);
blood = Test;

}
break;

case Fire:

if (pass === “Fire”){

blood = Fire;

}else{

confirm(“Sorry your password was incorrect, loading the generic structure, select from the dropdown to try again.”);
blood = firePreview;

}
break;

}

}

//intialize purchases to 0 and repops the menus

reset();
colorize(blood);
populate(blood);
readOut();
unLock();

}).change();

//toggles description of row 1 apprentice ability

$(“#t1a”).click(function(){

$(“#t1aDesc”).toggle();

});

//toggles description of row 1 journeyman ability

$(“#t1j”).click(function(){

if(($(“#t1j”).hasClass(“unlocked”))|t1jBought>0){

$(“#t1jDesc”).toggle();

}

});

//toggles description of row 1 expert ability

$(“#t1e”).click(function(){

if(($(“#t1e”).hasClass(“unlocked”))|t1eBought>0){

$(“#t1eDesc”).toggle();

}

});

//toggles description of row 2 apprentice ability

$(“#t2a”).click(function(){

$(“#t2aDesc”).toggle();

});

//toggles description of row 2 journeyman ability

$(“#t2j”).click(function(){

if(($(“#t2j”).hasClass(“unlocked”))|t2jBought>0){

$(“#t2jDesc”).toggle();

}

});

//toggles description of row 2 expert ability

$(“#t2e”).click(function(){

if(($(“#t2e”).hasClass(“unlocked”))|t2eBought>0){

$(“#t2eDesc”).toggle();

}

});

//toggles description of row 3 apprentice ability

$(“#t3a”).click(function(){

$(“#t3aDesc”).toggle();

});

//toggles description of row 3 journeyman ability

$(“#t3j”).click(function(){

if(($(“#t3j”).hasClass(“unlocked”))|t3jBought>0){

$(“#t3jDesc”).toggle();

}

});

//toggles description of row 3 expert ability

$(“#t3e”).click(function(){

if(($(“#t3e”).hasClass(“unlocked”))|t3eBought>0){

$(“#t3eDesc”).toggle();

}

});

//toggles description of mastery ability

$(“#m”).click(function(){

if(($(“#m”).hasClass(“unlocked”))|mBought===true){

$(“#mDesc”).toggle();

}

});

//performs the purchase of t1a power, and checks for unlocks

$(“#t1acost”).click(function(){

t1aBought +=1;
cpSpent+=1;
lastPurchase.push(1);
lastPower.push(“#t1a”);

populate(blood);
readOut();
unLock();

});

//performs the purchase of t2a power, and checks for unlocks

$(“#t2acost”).click(function(){

t2aBought +=1;
cpSpent+=2;
lastPurchase.push(2);
lastPower.push(“#t2a”);

populate(blood);

readOut();
unLock();

});

//performs the purchase of t3a power, and checks for unlocks

$(“#t3acost”).click(function(){

t3aBought +=1;
cpSpent+=3;
lastPurchase.push(3);
lastPower.push(“#t3a”);

populate(blood);
readOut();
unLock();

});

//performs the purchase of t1j power, and checks for unlocks

$(“#t1jcost”).click(function(){

if ($(“#t1jcost”).hasClass(“unlock”)){

t1jBought +=1;
cpSpent+=2;
lastPurchase.push(2);
lastPower.push(“#t1j”);

populate(blood);
readOut();
unLock();

}

});

//performs the purchase of t2j power, and checks for unlocks

$(“#t2jcost”).click(function(){

if ($(“#t2jcost”).hasClass(“unlock”)){

t2jBought +=1;
cpSpent+=3;
lastPurchase.push(3);
lastPower.push(“#t2j”);
populate(blood);
readOut();
unLock();

}

});

//performs the purchase of t3j power, and checks for unlocks

$(“#t3jcost”).click(function(){

if ($(“#t3jcost”).hasClass(“unlock”)){

t3jBought +=1;
cpSpent+=4;
lastPurchase.push(4);
lastPower.push(“#t3j”);

populate(blood);
readOut();
unLock();

}

});

//performs the purchase of t1e power, and checks for unlocks

$(“#t1ecost”).click(function(){

if ($(“#t1ecost”).hasClass(“unlock”)){

t1eBought +=1;
cpSpent+=3;
lastPurchase.push(3);
lastPower.push(“#t1e”);

populate(blood);
readOut();
unLock();

}

});

//performs the purchase of t2e power, and checks for unlocks

$(“#t2ecost”).click(function(){

if ($(“#t2ecost”).hasClass(“unlock”)){

t2eBought +=1;
cpSpent+=4;
lastPurchase.push(4);
lastPower.push(“#t2e”);
populate(blood);
readOut();
unLock();

}

});

//performs the purchase of t3e power, and checks for unlocks

$(“#t3ecost”).click(function(){

if ($(“#t3ecost”).hasClass(“unlock”)){

t3eBought +=1;
cpSpent+=5;
lastPurchase.push(5);
lastPower.push(“#t3e”);

populate(blood);
readOut();
unLock();

}

});

//performs the purchase of mastery power, and checks for unlocks

$(“#mcost”).click(function(){

if ($(“#mcost”).hasClass(“unlock”)){

mBought =true;
cpSpent+=7;
lastPurchase.push(7);
lastPower.push(“#m”);

populate(blood);
readOut();
unLock();

}

});

//cause the “undo” button to undo the last stored purchase

$(“#undo”).click(function(){

Undo();

populate(blood);
readOut();
unLock();

});

// on clicking the “reset” button reset all values to their starting point

$(“#reset”).click(function(){

reset();
populate(blood);
readOut();
unLock();

});

//causes the “start from this point” button to set cp spends to 0 but otherwise

//remember the purchases, to allow the user to plug in an existing character’s stats

//and see what purchase and buyback costs would be for that character

$(“#start”).click(function() {

cpSpent=0;
readOut();

});

});

Thanks for reading! Please, take a second to support The Crooked Thimble on Patreon!

About Brianalana

is the webadmin here at The Crooked Thimble. She and Trick are keeping the Crooked Thimble name alive over on Patreon. Their projects range from bi-weekly art livestreams, to small unity games. "Spreadsheets and SQL are Magic and when I use them I feel like a damn wizard!"
Bookmark the permalink.

Comments are closed