Skip to content

Commit

Permalink
Feat - Custom Monster stat blocks using journals
Browse files Browse the repository at this point in the history
  • Loading branch information
Azmoria committed Jul 27, 2023
1 parent 3c32c1a commit 2f74f43
Show file tree
Hide file tree
Showing 7 changed files with 661 additions and 14 deletions.
13 changes: 9 additions & 4 deletions CombatTracker.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,8 @@ function init_combat_tracker(){
next=$("#combat_area tr").first()
}
next.attr('data-current','1');
if($("#resizeDragMon:not(.hideMon)").length>0) {
$("[data-current][data-monster] button.openSheetCombatButton").click();
if($("#resizeDragMon:not(.hideMon)").length>0 && $("[data-current] button.openSheetCombatButton").css('visibility') == 'visible') {
$("[data-current] button.openSheetCombatButton").click();
}
let newTarget=$("#combat_area tr[data-current=1]").attr('data-target');
if(window.TOKEN_OBJECTS[currentTarget] != undefined){
Expand Down Expand Up @@ -651,12 +651,17 @@ function ct_add_token(token,persist=true,disablerolling=false){
if(!token.isPlayer()){
stat=$('<button class="openSheetCombatButton" style="font-size:10px;"><svg class="statSVG" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/><g><path d="M19,5v14H5V5H19 M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3L19,3z"/></g><path d="M14,17H7v-2h7V17z M17,13H7v-2h10V13z M17,9H7V7h10V9z"/></g></svg></button>');

stat.click(function(){
stat.click(function(){
if(token.options.statBlock){
let customStatBlock = window.JOURNAL.notes[token.options.statBlock].text;
load_monster_stat(undefined, undefined, customStatBlock);
return;
}
load_monster_stat(token.options.monster, token.options.id);
});
if(window.DM){
buttons.append(stat);
if(!token.isMonster()){
if(!token.isMonster() && !token.options.statBlock){
stat.css("visibility", "hidden");
}

Expand Down
4 changes: 2 additions & 2 deletions Journal.js
Original file line number Diff line number Diff line change
Expand Up @@ -657,15 +657,15 @@ class JournalManager{
// matches "1d10", " 1d10 ", "1d10+1", " 1d10+1 ", "1d10 + 1" " 1d10 + 1 "
const damageRollRegex = /(([0-9]+d[0-9]+)\s?([+-]\s?[0-9]+)?)/g
// matches " +1 " or " + 1 "
const hitRollRegex = /\s([+-]\s?[0-9]+)\s|\(([+-]\s?[0-9]+)\)/g
const hitRollRegex = /(\s)([+-]\s?[0-9]+)(\s)|\(([+-]\s?[0-9]+)\)|(\;)([+-]\s?[0-9]+)(\&)/g
const htmlNoSpaceHitRollRegex = />([+-]\s?[0-9]+)</g
const dRollRegex = /\s(\s?d[0-9]+)\s/g
const tableNoSpaceRollRegex = />(\s?d[0-9]+\s?)</g
const actionType = "roll"
const rollType = "AboveVTT"
const updated = currentElement.html()
.replaceAll(damageRollRegex, ` <button data-exp='$2' data-mod='$3' data-rolltype='${rollType}' data-actiontype='${actionType}' class='avtt-roll-button' title='${actionType}'> $1</button> `)
.replaceAll(hitRollRegex, ` <button data-exp='1d20' data-mod='$2' data-rolltype='rollType' data-actiontype=${actionType} class='avtt-roll-button' title='${actionType}'> $2</button> `)
.replaceAll(hitRollRegex, `$5$1<button data-exp='1d20' data-mod='$2$4$6' data-rolltype='rollType' data-actiontype=${actionType} class='avtt-roll-button' title='${actionType}'> $2$4$6</button>$3$7`)
.replaceAll(htmlNoSpaceHitRollRegex, `><button data-exp='1d20' data-mod='$1' data-rolltype='rollType' data-actiontype=${actionType} class='avtt-roll-button' title='${actionType}'> $1</button><`)
.replaceAll(dRollRegex, ` <button data-exp='1$1' data-mod='0' data-rolltype='to hit' data-actiontype=${actionType} class='avtt-roll-button' title='${actionType}'> $1</button> `)
.replaceAll(tableNoSpaceRollRegex, `><button data-exp='1$1' data-mod='0' data-rolltype='to hit' data-actiontype=${actionType} class='avtt-roll-button' title='${actionType}'> $1</button><`)
Expand Down
8 changes: 7 additions & 1 deletion Main.js
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,13 @@ function should_use_iframes_for_monsters() {
* @param {Number} monsterId given monster ID
* @param {UUID} tokenId selected token ID
*/
function load_monster_stat(monsterId, tokenId) {
function load_monster_stat(monsterId, tokenId, customStatBlock=undefined) {
if(customStatBlock){
let container = build_draggable_monster_window();
display_stat_block_in_container(customStatBlock, container, tokenId, customStatBlock);
$(".sidebar-panel-loading-indicator").hide();
return;
}
if(window.TOKEN_OBJECTS[tokenId].options.monster == 'open5e'){
let container = build_draggable_monster_window();
build_and_display_stat_block_with_id(window.TOKEN_OBJECTS[tokenId].options.stat, container, tokenId, function () {
Expand Down
14 changes: 10 additions & 4 deletions MonsterStatBlock.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,15 @@ function build_and_display_stat_block_with_data(monsterData, container, tokenId,
}
}

function display_stat_block_in_container(statBlock, container, tokenId) {
const html = build_monster_stat_block(statBlock);
function display_stat_block_in_container(statBlock, container, tokenId, customStatBlock = undefined) {
const html = (customStatBlock) ? $(`
<div class="container avtt-stat-block-container custom-stat-block">${customStatBlock}</div>`) : build_monster_stat_block(statBlock);
container.find("#noAccessToContent").remove(); // in case we're re-rendering with better data
container.find(".avtt-stat-block-container").remove(); // in case we're re-rendering with better data
container.append(html);
if(customStatBlock){
window.JOURNAL.add_journal_roll_buttons(html);
}
container.find("#monster-image-to-gamelog-link").on("click", function (e) {
e.stopPropagation();
e.preventDefault();
Expand All @@ -58,9 +62,11 @@ function display_stat_block_in_container(statBlock, container, tokenId) {
imgContainer.find("img").addClass("magnify");
send_html_to_gamelog(imgContainer[0].outerHTML);
});
container.find("div.image").append(statBlock.imageHtml());
if(!customStatBlock)
container.find("div.image").append(statBlock.imageHtml());
container.find("a").attr("target", "_blank"); // make sure we only open links in new tabs
scan_monster(container, statBlock, tokenId);
if(!customStatBlock)
scan_monster(container, statBlock, tokenId);
// scan_creature_pane(container, statBlock.name, statBlock.image);
add_stat_block_hover(container);
$("span.hideme").parent().parent().hide();
Expand Down
27 changes: 25 additions & 2 deletions TokenMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,20 @@ function token_context_menu_expanded(tokenIds, e) {
close_token_context_menu();
});
body.append(button);
} else if (token.isMonster()) {
}
else if(token.options.statBlock){
let button =$('<button>Open Monster Stat Block<span class="material-icons icon-view"></span></button>');

button.click(function(){
let customStatBlock = window.JOURNAL.notes[token.options.statBlock].text;
load_monster_stat(undefined, undefined, customStatBlock)
close_token_context_menu();
});
if(token.options.player_owned || window.DM){
body.append(button);
}
}
else if (token.isMonster()) {
let button = $(`<button>Open Monster Stat Block<span class="material-icons icon-view"></span></button>`);
button.on("click", function() {
load_monster_stat(token.options.monster, token.options.id);
Expand Down Expand Up @@ -2319,7 +2332,17 @@ function add_to_quick_roll_menu(token){
);
qrm_entry_buttons.append(remove_from_list);

if(token.isMonster() == true){
if(token.options.statBlock){
stat_block=$('<button title="Open Monster Stat Block" class="qrm_buttons_bar" style="display:inline-block;"><svg class="statSVG" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/><g><path d="M19,5v14H5V5H19 M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3L19,3z"/></g><path d="M14,17H7v-2h7V17z M17,13H7v-2h10V13z M17,9H7V7h10V9z"/></g></svg></button>');

stat_block.click(function(){
window.JOURNAL.display_note(token.options.statBlock);
});
if(!token.isMonster()){
stat_block.css("visibility", "hidden");
}
}
else if(token.isMonster() == true){
stat_block=$('<button title="Open Monster Stat Block" class="qrm_buttons_bar" style="display:inline-block;"><svg class="statSVG" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/><g><path d="M19,5v14H5V5H19 M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3L19,3z"/></g><path d="M14,17H7v-2h7V17z M17,13H7v-2h10V13z M17,9H7V7h10V9z"/></g></svg></button>');

stat_block.click(function(){
Expand Down
47 changes: 47 additions & 0 deletions TokensPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -1634,6 +1634,50 @@ function display_token_configuration_modal(listItem, placedToken = undefined) {
let imageUrlInput = sidebarPanel.build_image_url_input(determineLabelText(), addImageUrl);
inputWrapper.append(imageUrlInput);

let has_note = customization.tokenOptions.statBlock;
let editNoteButton = $(`<button class="custom-stat-buttons icon-note material-icons">
<span style='font-family:Roboto,Open Sans,Helvetica,sans-serif;'>
Create Custom Statblock
</span>
</button>`)
if(has_note){
let viewNoteButton = $(`<button class="custom-stat-buttons icon-view-note material-icons"><span style='font-family:Roboto,Open Sans,Helvetica,sans-serif;'>View Custom Statblock</span></button>`)
let deleteNoteButton = $(`<button class="custom-stat-buttons icon-note-delete material-icons"><span style='font-family:Roboto,Open Sans,Helvetica,sans-serif;'>Delete Custom Statblock</span></button>`)
editNoteButton = $(`<button class="custom-stat-buttons icon-note material-icons"><span style='font-family:Roboto,Open Sans,Helvetica,sans-serif;'>Edit Custom Statblock</span></button>`)
inputWrapper.append(viewNoteButton);
inputWrapper.append(editNoteButton);
inputWrapper.append(deleteNoteButton);
viewNoteButton.off().on("click", function(){
window.JOURNAL.display_note(customization.id);
});
deleteNoteButton.off().on("click", function(){
if(customization.id in window.JOURNAL.notes){
delete window.JOURNAL.notes[customization.id];
window.JOURNAL.persist();
}
delete customization.tokenOptions.statBlock;
persist_token_customization(customization);
display_token_configuration_modal(listItem, placedToken)
});
}
else {
inputWrapper.append(editNoteButton);
}

editNoteButton.off().on("click", function(){
if (!(customization.id in window.JOURNAL.notes)) {
window.JOURNAL.notes[customization.id] = {
title: customization.tokenOptions.name,
text: '',
plain: '',
player: true
}
customization.tokenOptions.statBlock = customization.id;
persist_token_customization(customization);
display_token_configuration_modal(listItem, placedToken);
}
window.JOURNAL.edit_note(customization.id);
});
if (listItem.isTypeMyToken()) {

// MyToken name
Expand Down Expand Up @@ -1681,6 +1725,7 @@ function display_token_configuration_modal(listItem, placedToken = undefined) {
});
inputWrapper.append(imageScaleWrapper);


// border color
if(listItem.isTypePC()){
customization.tokenOptions.color = color_from_pc_object(find_pc_by_player_id(listItem.id));
Expand All @@ -1704,6 +1749,8 @@ function display_token_configuration_modal(listItem, placedToken = undefined) {
};




const specificBorderColorValue = (typeof customization.tokenOptions.color === "string" && customization.tokenOptions.color.length > 0);

const borderColorToggle = build_toggle_input(specificBorderColorSetting, specificBorderColorValue, function (useSpecificColorKey, useSpecificColorValue) {
Expand Down
Loading

0 comments on commit 2f74f43

Please sign in to comment.