Skip to content

Commit

Permalink
Merge pull request #13508 from nashidau/master
Browse files Browse the repository at this point in the history
RolemasterUnified Official: Baselist improvements and Charactermancer cleanups
  • Loading branch information
kfroll20 authored Nov 14, 2024
2 parents 37411c0 + 5a711e4 commit ad0cd2a
Show file tree
Hide file tree
Showing 4 changed files with 237 additions and 16 deletions.
12 changes: 12 additions & 0 deletions RolemasterUnified_Official/rolemasterunified.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
display: block;
}

span.choice-showing {
display: inline;
}



@font-face {
Expand Down Expand Up @@ -109,6 +113,10 @@ h3 {
box-shadow: 3px 3px 2px 1px rgba(0,0,0,0.4);
}

.fancybutton.disabled {
background: linear-gradient(to top left, #c4c5c7 0%, #dcdddf 52%, #ebebeb 100%);
}

.fancybutton:hover {
box-shadow: rgba(0, 0, 0, .3) 2px 8px 8px -5px;
transform: translate3d(0, 2px, 0);
Expand Down Expand Up @@ -740,6 +748,10 @@ div.repcontrol {
border-radius: 255px 15px 225px 15px/15px 225px 15px 255px;
}

.cmbaselistcount:not([value="6"]) + button {
pointer-events: none;
background: grey;
}

/*
* Levelup DP box. Starts in the usual spot but sticks to the top so we can see costs all
Expand Down
228 changes: 213 additions & 15 deletions RolemasterUnified_Official/rolemasterunified.html
Original file line number Diff line number Diff line change
Expand Up @@ -390,10 +390,47 @@ <h2>Profession</h2>
</div>
</charmancer>

<charmancer class="select-charmancer-baselists">
<charmancer class="sheet-charmancer-baselists">
<div>
<h2>Base Lists</h2>





<div class='cmbaselistlists choice'>
<span class='cmbaselist0show choice'><span><input name='comp_cmbaselistselected0' id='cmbaselistselected0' type='checkbox' ></span><label for='cmbaselistselected0'><span class='cmbaselist0name'></span></label><input type='text' name='comp_cmbaselistname0'></span><hr><span class='cmbaselist1show choice'><span><input name='comp_cmbaselistselected1' id='cmbaselistselected1' type='checkbox' ></span><label for='cmbaselistselected1'><span class='cmbaselist1name'></span></label><input type='text' name='comp_cmbaselistname1'></span><hr><span class='cmbaselist2show choice'><span><input name='comp_cmbaselistselected2' id='cmbaselistselected2' type='checkbox' ></span><label for='cmbaselistselected2'><span class='cmbaselist2name'></span></label><input type='text' name='comp_cmbaselistname2'></span><hr><span class='cmbaselist3show choice'><span><input name='comp_cmbaselistselected3' id='cmbaselistselected3' type='checkbox' ></span><label for='cmbaselistselected3'><span class='cmbaselist3name'></span></label><input type='text' name='comp_cmbaselistname3'></span><hr><span class='cmbaselist4show choice'><span><input name='comp_cmbaselistselected4' id='cmbaselistselected4' type='checkbox' ></span><label for='cmbaselistselected4'><span class='cmbaselist4name'></span></label><input type='text' name='comp_cmbaselistname4'></span><hr><span class='cmbaselist5show choice'><span><input name='comp_cmbaselistselected5' id='cmbaselistselected5' type='checkbox' ></span><label for='cmbaselistselected5'><span class='cmbaselist5name'></span></label><input type='text' name='comp_cmbaselistname5'></span><hr><span class='cmbaselist6show choice'><span><input name='comp_cmbaselistselected6' id='cmbaselistselected6' type='checkbox' ></span><label for='cmbaselistselected6'><span class='cmbaselist6name'></span></label><input type='text' name='comp_cmbaselistname6'></span><hr><span class='cmbaselist7show choice'><span><input name='comp_cmbaselistselected7' id='cmbaselistselected7' type='checkbox' ></span><label for='cmbaselistselected7'><span class='cmbaselist7name'></span></label><input type='text' name='comp_cmbaselistname7'></span><hr><span class='cmbaselist8show choice'><span><input name='comp_cmbaselistselected8' id='cmbaselistselected8' type='checkbox' ></span><label for='cmbaselistselected8'><span class='cmbaselist8name'></span></label><input type='text' name='comp_cmbaselistname8'></span><hr><span class='cmbaselist9show choice'><span><input name='comp_cmbaselistselected9' id='cmbaselistselected9' type='checkbox' ></span><label for='cmbaselistselected9'><span class='cmbaselist9name'></span></label><input type='text' name='comp_cmbaselistname9'></span><hr><span class='cmbaselist10show choice'><span><input name='comp_cmbaselistselected10' id='cmbaselistselected10' type='checkbox' ></span><label for='cmbaselistselected10'><span class='cmbaselist10name'></span></label><input type='text' name='comp_cmbaselistname10'></span><hr><span class='cmbaselist11show choice'><span><input name='comp_cmbaselistselected11' id='cmbaselistselected11' type='checkbox' ></span><label for='cmbaselistselected11'><span class='cmbaselist11name'></span></label><input type='text' name='comp_cmbaselistname11'></span><hr><span class='cmbaselist12show choice'><span><input name='comp_cmbaselistselected12' id='cmbaselistselected12' type='checkbox' ></span><label for='cmbaselistselected12'><span class='cmbaselist12name'></span></label><input type='text' name='comp_cmbaselistname12'></span><hr><span class='cmbaselist13show choice'><span><input name='comp_cmbaselistselected13' id='cmbaselistselected13' type='checkbox' ></span><label for='cmbaselistselected13'><span class='cmbaselist13name'></span></label><input type='text' name='comp_cmbaselistname13'></span><hr><span class='cmbaselist14show choice'><span><input name='comp_cmbaselistselected14' id='cmbaselistselected14' type='checkbox' ></span><label for='cmbaselistselected14'><span class='cmbaselist14name'></span></label><input type='text' name='comp_cmbaselistname14'></span><hr><span class='cmbaselist15show choice'><span><input name='comp_cmbaselistselected15' id='cmbaselistselected15' type='checkbox' ></span><label for='cmbaselistselected15'><span class='cmbaselist15name'></span></label><input type='text' name='comp_cmbaselistname15'></span><hr><span class='cmbaselist16show choice'><span><input name='comp_cmbaselistselected16' id='cmbaselistselected16' type='checkbox' ></span><label for='cmbaselistselected16'><span class='cmbaselist16name'></span></label><input type='text' name='comp_cmbaselistname16'></span><hr><span class='cmbaselist17show choice'><span><input name='comp_cmbaselistselected17' id='cmbaselistselected17' type='checkbox' ></span><label for='cmbaselistselected17'><span class='cmbaselist17name'></span></label><input type='text' name='comp_cmbaselistname17'></span><hr><span class='cmbaselist18show choice'><span><input name='comp_cmbaselistselected18' id='cmbaselistselected18' type='checkbox' ></span><label for='cmbaselistselected18'><span class='cmbaselist18name'></span></label><input type='text' name='comp_cmbaselistname18'></span><hr><span class='cmbaselist19show choice'><span><input name='comp_cmbaselistselected19' id='cmbaselistselected19' type='checkbox' ></span><label for='cmbaselistselected19'><span class='cmbaselist19name'></span></label><input type='text' name='comp_cmbaselistname19'></span><hr><span class='cmbaselist20show choice'><span><input name='comp_cmbaselistselected20' id='cmbaselistselected20' type='checkbox' ></span><label for='cmbaselistselected20'><span class='cmbaselist20name'></span></label><input type='text' name='comp_cmbaselistname20'></span><hr>

Lists Selected <input type='number' name='comp_cmbaselistcount'> / 6

</div>

<div class='cmbaselistfixed choice'>
Your chosen profession has six base lists.<br>

<span class='cmbaselist0show choice'><span class='cmbaselist0name'>List Name</span><br></span><span class='cmbaselist1show choice'><span class='cmbaselist1name'>List Name</span><br></span><span class='cmbaselist2show choice'><span class='cmbaselist2name'>List Name</span><br></span><span class='cmbaselist3show choice'><span class='cmbaselist3name'>List Name</span><br></span><span class='cmbaselist4show choice'><span class='cmbaselist4name'>List Name</span><br></span><span class='cmbaselist5show choice'><span class='cmbaselist5name'>List Name</span><br></span>

</div>



<div class='cmbaselistsnolists choice'>
Your chosen profession has no base lists.
</div>



<button class="fancybutton" type="back" value="profession">Back (Profession)</button>
<button class="fancybutton" type="submit" value="stats">Next (Stats)</button>
<span class='choice baselistnosave'>
<button class="fancybutton disabled " type="action" value="noaction">Next (Stats)</button>
</span>
<span class='choice baselistsave'>
<button class="fancybutton " type="action" name="act_baselistsdone">Next (Stats)</button>
</span>
<span class='choice baselistsalwaysallow'>
<button class="fancybutton " type="submit" value="stats">Next (Stats)</button>
</span>
</div>
</charmancer>

<charmancer class="sheet-charmancer-stats">
Expand Down Expand Up @@ -5306,7 +5343,7 @@ <h3>Custom Spell List</h3>

<br>

Revision 163d394d6154b2284a7ac62c3e0f702660786091
Revision 232ac6239a389a9fff6ffa1fcb511c5f307cc398


<hr>
Expand Down Expand Up @@ -6921,7 +6958,6 @@ <h3>Custom Spell List</h3>
let trickerybonus = {};
addPendingFunction("Update Grace & Trickery", () => prepareGraceTrickery(gracebonus, trickerybonus));
addPendingFunction("Update Spells", () => {
console.log(gracebonus, trickerybonus);
updateSpells(gracebonus, trickerybonus)
});
addPendingFunction("Update favorites", RMUSkills.updateFavorites);
Expand Down Expand Up @@ -7033,12 +7069,14 @@ <h3>Custom Spell List</h3>
skill.specializations.forEach((spec) => {
let bestbonus = -100;
const aname = spec.aname;
getAttrs([aname + "_ranks_misc", aname + "_misc"], (attrs) => {
getAttrs([aname + "_ranks_misc", aname + "_misc", aname + "_ranks"], (attrs) => {
let [bonus, ranks, slog] = calculateSpecBonus(skill, attrs[aname + '_ranks_misc'],
attrs[aname + '_misc'], spec.stat, pbonus, catbonus, log);
let update = {[aname + "_bonus"]: bonus, [aname + "_info"]: slog};
if (ranks > 0) {
if (ranks != 0) {
update[aname + "_ranks"] = ranks;
} else if (attrs[aname + "_ranks"] && attrs[name + "_ranks"] != "") {
update[aname + "_ranks"] = " "; // So there is something there; so set space
}
if ((bonus - 25) > bestbonus) {
bestbonus = bonus - 25;
Expand Down Expand Up @@ -7074,8 +7112,10 @@ <h3>Custom Spell List</h3>
let toget = []
toget.push(basename + "_ranks_misc");
toget.push(basename + "_misc");
toget.push(basename + "_ranks");
getAttrsPending(toget,
(attrs) => {
const aname = skill.aname;
let [bonus, ranks, slog] = calculateSpecBonus(skill,
attrs[basename + '_ranks_misc'],
attrs[basename + '_misc'], false, pbonus, catbonus, log);
Expand All @@ -7085,9 +7125,11 @@ <h3>Custom Spell List</h3>
}

let update = {[basename + "_bonus"]: bonus, [basename + "_info"]: slog};
if (ranks > 0) {
update[basename + "_ranks"] = ranks;
}
if (ranks != 0) {
update[aname + "_ranks"] = ranks;
} else if (attrs[aname + "_ranks"] && attrs[name + "_ranks"] != "") {
update[aname + "_ranks"] = " "; // So there is something there; so set space
}
setAttrsPending(update);
});
}
Expand Down Expand Up @@ -7580,7 +7622,7 @@ <h3>Custom Spell List</h3>
});
}

// listranks is a dictinary of ranks indexed by the spell list name
// listranks is a dictionary of ranks indexed by the spell list name
function initSpellListsCM(savedlists, profession, realm, costs, listranks) {
const cmdata = getCharmancerData();
const lu = cmdata?.levelup;
Expand Down Expand Up @@ -7611,7 +7653,7 @@ <h3>Custom Spell List</h3>
if (realm.indexOf('/') > -1) {
// Hybrid: Two realms
realms = realm.split('/');
addPendingFunction("Hyrid realm 1 open lists",()=> {
addPendingFunction("Hybrid realm 1 open lists",()=> {
_spellDoQuery(previousranks, `ListType:*${realms[0]} Open*`, '', 'open', costs['Open'], listranks );
});
addPendingFunction("Hybrid realm 2 open lists",()=> {
Expand Down Expand Up @@ -7696,8 +7738,7 @@ <h3>Custom Spell List</h3>
function updateSpellCategory(spellgroup, bonus, gracebonus, trickerybonus) {

getAttrsPending(["customspelllists"], (ev) => {
let customlists = ev.customspelllists;
console.log("customlists", customlists);
let customlists = ev.customspelllists || {};


getSectionIDsPending(`repeating_spelllistspell${spellgroup}`, (ids) => {
Expand All @@ -7718,7 +7759,6 @@ <h3>Custom Spell List</h3>

let mastery = realmstat + realmstat + RMUSkills.getStat('me') +
RMUSkills.getSkillBonus(ranks);
console.log(gracebonus, trickerybonus);
setAttrsPending({
[`${basename}_ranks`]: ranks,
[`${basename}_scr`]: scrbonus + ranks + bonus,
Expand Down Expand Up @@ -10081,6 +10121,108 @@ <h3>Custom Spell List</h3>

});



onCheck("page:baselists", () => {
const cmdata = getCharmancerData();
const profession = cleanCompendiumName(cmdata?.profession?.values?.profession);
getCompendiumQuery(`Category:SpellList ListType:${profession} Base`, (lists) => {
if (!lists || lists[0].expansion == 0) {
// No spell lists
showChoices(['cmbaselistsnolists', 'baselistsalwaysallow'])
hideChoices(['cmbaselistlists', 'cmbaselistfixed', 'baselistsave', 'baselistnosave']);
return;
}

const textupdates = {};
const hideupdates = [];
const showupdates = [];
const attrupdates = {};
hideupdates.push('cmbaselistsnolists');
if (lists.length == 6) {
showupdates.push('cmbaselistfixed');
hideupdates.push('cmbaselistlists', 'baselistsalwaysallow', 'baselistsave', 'baselistnosave');
// Select the first 6 automatically and move on.
for (let i = 0 ; i < 6 ; i ++) {
attrupdates['cmbaselistselected' + i] = 'on';
}
} else {
showupdates.push('cmbaselistlists', 'baselistsave');
hideupdates.push('cmbaselistfixed', 'baselistnosave', 'baselistsalwaysallow');
}
let i = 0;
for (i = 0 ; i < lists.length ; i ++) {
let list = lists[i];
textupdates[`cmbaselist${i}name`] = list.name;
showupdates.push(`cmbaselist${i}show`);
attrupdates['cmbaselistname' + i] = list.name;
}
if (i > 20) {
rmuerror("Too many base lists for this profession", profession);
i = 20;
}
for ( ; i < 20 ; i ++) {
hideupdates.push(`cmbaselist${i}show`);
attrupdates['cmbaselistselected' + i] = 'off';
}
setCharmancerText(textupdates);
showChoices(showupdates);
console.log("hide", hideupdates, "show", showupdates);
hideChoices(hideupdates);
setAttrs(attrupdates);
});
});

function createBaseListsCount(cmdata) {
const values = cmdata.baselists.values;
let count = 0;
for (let i = 0 ; i < 21 ; i ++) {
const value = values['cmbaselistselected' + i];
count += (value == 'on') ? 1 : 0;
}
return count;
}

/* On the baselists selection page, someone selected or cleared a selector
* for a baselist. Update the count and show or hide the next button based
* on the the value (ie 6) */
onCheck(Array.from({length: 21}).map((_,i) => "mancerchange:cmbaselistselected" + i).join(' '), (_) => {
// Get them all and count
const cmdata = getCharmancerData();
const count = createBaseListsCount(cmdata);
const updates = {}
if (count == 6) {
showChoices(["baselistsave"]);
hideChoices(["baselistnosave"]);
} else {
hideChoices(["baselistsave"]);
showChoices(["baselistnosave"]);
}
updates.cmbaselistcount = count;
setAttrs(updates);
});

onCheck("clicked:baselistsdone", () => {
const count = createBaseListsCount(getCharmancerData());
if (count == 6) {
changeCharmancerPage("stats");
}
});

function createSaveBaseLists() {
const cmdata = getCharmancerData();
const values = cmdata.baselists.values;
const updates = {};
for (let i = 0 ; i < 21 ; i ++) {
const value = values['cmbaselistselected' + i];
if (value == 'on') {
const rowid = generateRowID();
updates[`repeating_spelllistspellownbase_${rowid}_name`] = values['cmbaselistname' + i];
}
}
setAttrs(updates);
}

onCheck("page:stats", () => {
const cmdata = getCharmancerData();
console.log("stats page");
Expand Down Expand Up @@ -10691,6 +10833,8 @@ <h3>Custom Spell List</h3>
}
});

addPendingFunction("CMFinish: Save base lists", createSaveBaseLists);

addPendingFunction("CMFinish: update all skills", RMUSkills.updateAllSkills);
addPendingFunction("CMFinish: Front page", updateFrontPage);

Expand Down Expand Up @@ -14712,10 +14856,15 @@ <h3>Custom Spell List</h3>
}

if (version == 5) {
addPendingFunction("Force skill update from missing update in 5", RMUSkills.updateAllSkills);
addPendingFunction("Upgrade to 6: Force skill update from missing update in 5", RMUSkills.updateAllSkills);
version = 6;
}

if (version == 6) {
addPendingFunction("Upgrade to 7: Save baselists on sheet", upgradeV6to7);
version = 7;
}

if (oldversion != version) {
addPendingFunction(`Version update to ${version}`, () => {
setAttrsPending({version: version});
Expand Down Expand Up @@ -14839,6 +14988,55 @@ <h3>Custom Spell List</h3>
});
}

// Since treasure law requires you to pick base lists, we are going to store them on
// the sheet itself going forward.
//
// We only need to apply this change if they have a profession. So newly created
// characters are skipped.
function upgradeV6to7() {
getAttrsPending(["profession"], (prof) => {
if (!prof.profession) {
//New character; done!
console.log("Character not created; skipping");
return;
}
console.log("get existing base lists");
getSectionIDsPending("repeating_spelllistspellownbase", (ids) => {
if (ids.length == 6) {
console.log("if 6... we are done");
// We have enough; stop.
return;
}
const toget = []
for (id of ids) {
toget.push(`repeating_spelllistspellownbase_${id}_name`);
}
getAttrsPending(toget, (listnames) => {
// FIXME: This is a set.
const names = {};
for (name in listnames) {
names[listnames[name]] = true;
}
getCompendiumQueryPending(`Category:SpellList ListType:*${prof.profession} Base*`, (lists) => {
const toupdate = {};
for (ind in lists) {
const list = lists[ind];
if (names[list.name]) {
continue;
}
const rowid = generateRowID();
toupdate[`repeating_spelllistspellownbase_${rowid}_name`] = list.name;
}

setAttrsPending(toupdate);
});
});
});
});


}




Expand Down
2 changes: 1 addition & 1 deletion RolemasterUnified_Official/sheet.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"legacy": false,
"printable": true,
"compendium": "RMU",
"version": "1730910133"
"version": "1731512507"
}
11 changes: 11 additions & 0 deletions RolemasterUnified_Official/updates.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
# 2024-11-14

- Add description to each step of the Charactermancer buttons
- Clear ranks on specialised skills if 0. Previously worked for non specilised skills, this fixes
specialised skills as well (@ixs)
- Add base lists selection in charactermancer. Useful for professions with base lists. Additionally
base lists are now stored on the sheet. So they persist.
- Add control to stop progression until you have entered all data on the sheet required.
- Bump sheet version 7
- Existing charaacters will have their base lists updated on the main sheet.

# 2024-11-7

- Sheet version to 6. Funny how lots happen at once.
Expand Down

0 comments on commit ad0cd2a

Please sign in to comment.