DasSauerkraut / calendar-weather

A module for FoundryVTT that adds a calendar widget with weather, moons cycles, and a customizable calendar.
Apache License 2.0
19 stars 26 forks source link

Additional functions accessible for macro's #155

Open Stendarpaval opened 4 years ago

Stendarpaval commented 4 years ago

While I was busy making a macro for tracking spell durations, I noticed that I was unable to access DateTime.js, DTCalc.js and DTMod.js directly through macro's in Foundry.

This was rather unfortunate, since that meant I'd have to duplicate the lengthy DateTime.normalize() function in my macro, which felt rather inefficient. That's why I decided to add this simple function to ElapsedTime.js starting at line 35:

    static toolCreateFromSeconds(seconds) {
        return DateTime.create(DTMod.fromSeconds(seconds));
    }

This function is useful for macro users, because it can use a time value in seconds as an argument. This is great because the events stored in the queue accessible through game.Gametime.ElapsedTime._eventQueue.array store the event time _time in seconds, whereas most functions in ElapsedTime.js make use of DTMod dictionaries.

Another benefit of adding that function is that you can directly add and subtract seconds from the seconds variable before converting it to a DateTime dictionary, which in turn has built-in functions for formatting the result using .shortDate() or .longDate() functions.

I also want to add that there are a significant number of typing errors in the Readme.md file, specifically where the programmatic interface examples are listed. These are errors like missing a closing bracket, or using parentheses instead of brackets/accolades.

(Please note that I've only started dabbling with javascript since I bought Foundry two weeks ago, so I may have missed some kind of obvious way to access the functions from these classes. (maybe game.Gametime.DTM() and such, but it's unclear to me right now))

Finally, thanks for making this module. Tracking time in my megadungeon crawl was a nightmare, this should help a ton.

Edit: I should add that I'm running Foundry v0.7.4 and About Time v0.1.58

Motara7 commented 4 years ago

Hi Stendarpaval,

I've been using Turn Alert to track rounds/level spells. I would love to use the calendar to track longer duration spells. If you have macros that are working, would you please share them with me?

Stendarpaval commented 3 years ago

@Motara7 Yeah, not a problem. Here’s the macro I use for spell tracking:

//
// This macro requires the About Time module to work.
//

const durationLengths = ["1 minute", "10 minutes", "1 hour", "8 hours","24 hours"];
const durationNum = [1, 10, 60, 480, 1440];
const text = '<div style="width:100%; text-align:center;">' + "Select spell duration:" + '</div>';

if (!actor) {
    ui.notifications.warn('You need to select a token before using this macro!');
} else {

  let buttons = {}, dialog, content = text;

  durationLengths.forEach((str)=> {
      buttons[str] = {
        label : str,
        callback : () => {
          const targetTime = game.Gametime.DTNow();
          targetTime.minutes += durationNum[durationLengths.indexOf(str)];
          sendChatMsg("In " + str + ", this spell will end!", str);
          const endedMsg = msgFormat(actor.getActiveTokens()[0].name + "'s spell ended", "The spell that was cast " + str + " ago has ended by now.", str);
          const spellDurationId = game.Gametime.reminderAt(targetTime, endedMsg);
          actor.setFlag("dnd5e","spellDurationId",spellDurationId);
          console.log("Spell Tracker: added spell id", spellDurationId, "at", game.Gametime.getTimeString(),"(in-game time)");
          dialog.render(true);
        }
      }
    });

  dialog = new Dialog({title : 'Set spell duration', content, buttons}).render(true);
};

function msgFormat(isActiveMsg, msgContent, durationText) {
  const htmlMsg = '<div><div class="dnd5e chat-card item-card">\
                  <header class="card-header flexrow red-header">\
                    <img src="icons/tools/navigation/hourglass-yellow.webp" title="Spell Tracker" width="36" height="36">\
                    <h3 class="item-name">' + isActiveMsg + '</h3>\
                  </header>\
                  <div class="card-content br-text" style="display: block;">\
                    <p>' + msgContent + '</p></div>\
                    <footer class="card-footer">\
                      <span>Spell Duration Tracker</span>\
                      <span>' + durationText + '</span>\
                      <span>' + actor.name + '\
                    </footer>\
                  </div>';
  return htmlMsg;
}

function sendChatMsg(msgContent, durationText) {
  const chatData = {
    user:  game.user.id,
    speaker: game.user,
    content: msgFormat(actor.getActiveTokens()[0].name + " is casting a Spell", msgContent, durationText),
  };
  ChatMessage.create(chatData,{});
};

If you add the toolCreateFromSeconds function I outlined in my original comment, then you can use this following macro to see an overview of tracked spells (with the date and time at which they end, plus the name of the token that was selected when you started tracking it):

var names = [];
var spellQueue = [];
var trackerIDs = [];

for (let i = 0; i < game.Gametime.ElapsedTime._eventQueue.size; i++) {
    const message = game.Gametime.ElapsedTime._eventQueue.array[i]._args[0];
    // var names = [];
    if (message != undefined) {
        const nameStart = message.lastIndexOf("</span>                      <span>") + 35;
        const nameEnd = message.lastIndexOf("                    </footer>                  </div>");
        const name = message.slice(nameStart,nameEnd);
        names[i] = name;
        // console.log(name);
        //console.log(message);
        var spellSeconds = game.Gametime.ElapsedTime._eventQueue.array[i]._time;
        var spellDate = game.Gametime.ElapsedTime.toolCreateFromSeconds(spellSeconds);
        // console.log(spellDate.shortDate());
        spellQueue[i] = spellDate.shortDate().date + " " + spellDate.shortDate().time + ": " + name;
        trackerIDs[i] = game.Gametime.ElapsedTime._eventQueue.array[i]._uid;
    };
};
// console.log(spellQueue);
// console.log(trackerIDs);

let buttons = {}, dialog, content = `<div sytle="width:100%; text-align:left;></div>`;

spellQueue.forEach((str)=> {
    buttons[str] = {
      label : str,
      callback : () => {
        var i = spellQueue.indexOf(str);
        game.Gametime.clearTimeout(trackerIDs[i]);
        sendChatMsg(names[i] + "'s spell ended early.")
        delete buttons[str];
        dialog.render(true);
      }
    }
  });

dialog = new Dialog({title : 'Spelltracker Queue', content, buttons}).render(true);
// const info = dialog.appId;
// console.log(info);
//console.log(spellQueue);
//game.Gametime.clearTimeout(1603284372311);
//console.log(game.Gametime.queue());

function sendChatMsg(msgContent) {
    const chatData = {
        user: game.user.id,
        speaker: speaker,
        content: msgContent
    };
    ChatMessage.create(chatData,{});
} 

There’s a small bug when a tracked spell ends after you shut down and restart the server, which causes the “Spell Ended“ chat message to appear multiple times, but I haven’t found a way or the time to solve it yet. Edit: code block formatting

Motara7 commented 3 years ago

Thank you so much for your reply. I am having problems. I suspect my ignorance is getting in the way. If I understand correctly, I need to make a script macro out of the first part:

`// // This macro requires the About Time module to work. //

const durationLengths = ["1 minute", "10 minutes", "1 hour", "8 hours","24 hours"]; const durationNum = [1, 10, 60, 480, 1440]; const text = ' ' + "Select spell duration:" + ' ';

if (!actor) { ui.notifications.warn('You need to select a token before using this macro!'); } else {

let buttons = {}, dialog, content = text;

durationLengths.forEach((str)=> { buttons[str] = { label : str, callback : () => { const targetTime = game.Gametime.DTNow(); targetTime.minutes += durationNum[durationLengths.indexOf(str)]; sendChatMsg("In " + str + ", this spell will end!", str); const endedMsg = msgFormat(actor.getActiveTokens()[0].name + "'s spell ended", "The spell that was cast " + str + " ago has ended by now.", str); const spellDurationId = game.Gametime.reminderAt(targetTime, endedMsg); actor.setFlag("dnd5e","spellDurationId",spellDurationId); console.log("Spell Tracker: added spell id", spellDurationId, "at", game.Gametime.getTimeString(),"(in-game time)"); dialog.render(true); } } });

dialog = new Dialog({title : 'Set spell duration', content, buttons}).render(true); };

function msgFormat(isActiveMsg, msgContent, durationText) { const htmlMsg = '

http://icons/tools/navigation/hourglass-yellow.webp ' + isActiveMsg + '

' + msgContent + '

Spell Duration Tracker ' + durationText + ' ' + actor.name + '

'; return htmlMsg; }

function sendChatMsg(msgContent, durationText) { const chatData = { user: game.user.id, speaker: game.user, content: msgFormat(actor.getActiveTokens()[0].name + " is casting a Spell", msgContent, durationText), }; ChatMessage.create(chatData,{}); };` I have created the macro and selected an actor, however, when I execute the macro nothing happens. By which I mean nothing. I get no error message on screen or in the console. There are two things I see which may or may not be causing a problem:

  1. There is a line that says " actor.setFlag("dnd5e","spellDurationId",spellDurationId); " but I am using Pathfinder 1e. Does this matter? If so, what is the correct way for me to change this?
  2. There is a line that says " " and I have no idea what it is supposed to be. It comes up blank in the macro (just a big empty space). Is that correct?

On Wed, Nov 25, 2020 at 1:22 AM Stendarpaval notifications@github.com wrote:

@Motara7 https://github.com/Motara7 Yeah, not a problem. Here’s the macro I use for spell tracking:

`// // This macro requires the About Time module to work. //

const durationLengths = ["1 minute", "10 minutes", "1 hour", "8 hours","24 hours"]; const durationNum = [1, 10, 60, 480, 1440]; const text = ' ' + "Select spell duration:" + ' ';

if (!actor) { ui.notifications.warn('You need to select a token before using this macro!'); } else {

let buttons = {}, dialog, content = text;

durationLengths.forEach((str)=> { buttons[str] = { label : str, callback : () => { const targetTime = game.Gametime.DTNow(); targetTime.minutes += durationNum[durationLengths.indexOf(str)]; sendChatMsg("In " + str + ", this spell will end!", str); const endedMsg = msgFormat(actor.getActiveTokens()[0].name + "'s spell ended", "The spell that was cast " + str + " ago has ended by now.", str); const spellDurationId = game.Gametime.reminderAt(targetTime, endedMsg); actor.setFlag("dnd5e","spellDurationId",spellDurationId); console.log("Spell Tracker: added spell id", spellDurationId, "at", game.Gametime.getTimeString(),"(in-game time)"); dialog.render(true); } } });

dialog = new Dialog({title : 'Set spell duration', content, buttons}).render(true); };

function msgFormat(isActiveMsg, msgContent, durationText) { const htmlMsg = '

http://icons/tools/navigation/hourglass-yellow.webp ' + isActiveMsg + '

' + msgContent + '

Spell Duration Tracker ' + durationText + ' ' + actor.name + '

'; return htmlMsg; }

function sendChatMsg(msgContent, durationText) { const chatData = { user: game.user.id, speaker: game.user, content: msgFormat(actor.getActiveTokens()[0].name + " is casting a Spell", msgContent, durationText), }; ChatMessage.create(chatData,{}); };`

If you add the toolCreateFromSeconds function I outlined in my original comment, then you can use this following macro to see an overview of tracked spells (with the date and time at which they end, plus the name of the token that was selected when you started tracking it):

`var names = []; var spellQueue = []; var trackerIDs = [];

for (let i = 0; i < game.Gametime.ElapsedTime._eventQueue.size; i++) { const message = game.Gametime.ElapsedTime._eventQueue.array[i]._args[0]; // var names = []; if (message != undefined) { const nameStart = message.lastIndexOf(" ") + 35; const nameEnd = message.lastIndexOf(" "); const name = message.slice(nameStart,nameEnd); names[i] = name; // console.log(name); //console.log(message); var spellSeconds = game.Gametime.ElapsedTime._eventQueue.array[i]._time; var spellDate = game.Gametime.ElapsedTime.toolCreateFromSeconds(spellSeconds); // console.log(spellDate.shortDate()); spellQueue[i] = spellDate.shortDate().date + " " + spellDate.shortDate().time + ": " + name; trackerIDs[i] = game.Gametime.ElapsedTime._eventQueue.array[i]._uid; }; }; // console.log(spellQueue); // console.log(trackerIDs);

let buttons = {}, dialog, content = <div sytle="width:100%; text-align:left;>

;

spellQueue.forEach((str)=> { buttons[str] = { label : str, callback : () => { var i = spellQueue.indexOf(str); game.Gametime.clearTimeout(trackerIDs[i]); sendChatMsg(names[i] + "'s spell ended early.") delete buttons[str]; dialog.render(true); } } });

dialog = new Dialog({title : 'Spelltracker Queue', content, buttons}).render(true); // const info = dialog.appId; // console.log(info); //console.log(spellQueue); //game.Gametime.clearTimeout(1603284372311); //console.log(game.Gametime.queue());

function sendChatMsg(msgContent) { const chatData = { user: game.user.id, speaker: speaker, content: msgContent }; ChatMessage.create(chatData,{}); }`

There’s a small bug when a tracked spell ends after you shut down and restart the server, which causes the “Spell Ended“ chat message to appear multiple times, but I haven’t found a way or the time to solve it yet.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/DasSauerkraut/calendar-weather/issues/155#issuecomment-733578390, or unsubscribe https://github.com/notifications/unsubscribe-auth/ARX2HTHVJCM7WSP6L7ZTMOLSRTEDXANCNFSM4S2E6MWQ .

Stendarpaval commented 3 years ago

@Motara7 Sorry for the late reply, I don't check github very often. I'm also sorry to hear that it's not working for you. The way you pasted my code makes it seem like you weren't able to copy it with the same formatting as it was presented originally. In other words, perhaps some lines ended up being broken off too soon, which might cause some issues.

Thus I've attached two files with the code, which you should be able to open in any text editor and copy it from there without any risk of losing its formatting.

spellEndedNotification.txt spelltracker_queue.txt

As for your numbered questions:

  1. That line of code isn't necessary for the macro to work. It's actually part of some functionality I had in mind for storing and later on retrieving which actors were concentrating on what spells. I'm not sure if it would work in a Pathfinder 1e game, since that dnd5e flag is indeed intended for actor characteristics of 5e. It shouldn't stop the macro from functioning, though.
  2. Not sure what you mean here, though in both macro's the use of empty spaces inside quotation marks is actually quite important, as it either formats strings for text to be displayed, or uses it to find parts of a string to extract the name of the character that originally cast the spell from.

One reason why the second macro may not have worked for you is because you didn't add the function I outlined in my original post to ElapsedTime.js (which I realized some time ago is actually part of the About Time module, not really the calendar module). Without the toolCreateFromSeconds() function, the second macro shouldn't be able to display dates and time.

I hope that helps.

Motara7 commented 3 years ago

Thank you again for your response. spellEndedNotification is working as expected. You are correct. I must have copied the code poorly and I didn't realize it was 2 macros!

I am going to tinker with it to see if I can get it to multiply the selected spell duration (for minutes, tens-of-minutes, and hours) by the caster level of the selected token and I'm going to try to add a dialog box to add in the name of the spell/effect. If you like, I will send you the script if I get it to work.

What does spelltracker_queue do? I can't make heads or tails of the code and when I run the macro I get the following error:

Macros.js:224 TypeError: game.Gametime.ElapsedTime.toolCreateFromSeconds is not a function at Macro.eval (eval at callScriptMacroFunction (Macros.js:176),

:18:45) at Macro.callScriptMacroFunction [as callScriptFunction] (Macros.js:179) at Macro.renderMacro [as renderContent] (Macros.js:197) at Macro.executeMacro (Macros.js:221) at Hotbar._onClickMacro (foundry.js:20520) at HTMLLIElement.dispatch (jquery.min.js:2) at HTMLLIElement.v.handle ( jquery.min.js:2) executeMacro @ Macros.js:224 On Mon, Dec 14, 2020 at 12:06 PM Stendarpaval wrote: > @Motara7 Sorry for the late reply, I don't > check github very often. I'm also sorry to hear that it's not working for > you. > The way you pasted my code makes it seem like you weren't able to copy it > with the same formatting as it was presented originally. In other words, > perhaps some lines ended up being broken off too soon, which might cause > some issues. > > Thus I've attached two files with the code, which you should be able to > open in any text editor and copy it from there without any risk of losing > its formatting. > > spellEndedNotification.txt > > spelltracker_queue.txt > > > As for your numbered questions: > > 1. That line of code isn't necessary for the macro to work. It's > actually part of some functionality I had in mind for storing and later on > retrieving which actors were concentrating on what spells. I'm not sure if > it would work in a Pathfinder 1e game, since that dnd5e flag is indeed > intended for actor characteristics of 5e. It shouldn't stop the macro from > functioning, though. > 2. Not sure what you mean here, though in both macro's the use of > empty spaces inside quotation marks is actually quite important, as it > either formats strings for text to be displayed, or uses it to find parts > of a string to extract the name of the character that originally cast the > spell from. > > One reason why the second macro may not have worked for you is because you > didn't add the function I outlined in my original post to ElapsedTime.js > (which I realized some time ago is actually part of the About Time module, > not really the calendar module). Without the toolCreateFromSeconds() > function, the second macro should be able to display dates and time. > > I hope that helps. > > — > You are receiving this because you were mentioned. > Reply to this email directly, view it on GitHub > , > or unsubscribe > > . >
Stendarpaval commented 3 years ago

@Motara7 Glad to hear that spellEndedNotification worked for you! Please keep me posted if you manage to add a dialog box to add the name of the spell/effect, because that's something I'm definitely interested in.

spelltracker_queue is a macro that allows you to cancel the tracking of a given spell. This can be really handy when there are multiple spells active and one character fails a concentration check and stops concentrating on a spell.

Activating the macro should create a dialog box with a list of all currently tracked spells, along with the name of the character that was selected at the time as well as the date and the time at which the spell is scheduled to end. I'll try to remember to make a screenshot of it later and share it with you.

The reason you currently get that error is because in order for the spelltracker_queue macro to work, you need to edit a javascript file inside the About Time module. That is actually the reason I created this issue in the first place, and I also mentioned this in my previous comment.

  1. In order to make the macro work, you need to navigate to modules/about-time/module/ and open ElapsedTime.js (or perhaps ElapsedTime.ts) in a text editor.
  2. Somewhere in the first 60 lines you should find the following code snippet:

    static currentTime(): DTMod {
    return DTMod.fromSeconds(PseudoClock.currentTime);
    }
    
    static currentTimeSeconds() : number {
    return PseudoClock.currentTime % DTCalc.spd;
    }
  3. You should edit the above snippet to look like this: (basically, add a new function called toolCreateFromSeconds() to the ElapsedTime class)

    static currentTime(): DTMod {
    return DTMod.fromSeconds(PseudoClock.currentTime);
    }
    
    static toolCreateFromSeconds(seconds) {
    return DateTime.create(DTMod.fromSeconds(seconds));
    }
    
    static currentTimeSeconds() : number {
    return PseudoClock.currentTime % DTCalc.spd;
    }
  4. Save the file and restart Foundry. The spelltracker_queue macro should now work.

Note: You will need to redo this every time the About-Time module is updated, but luckily that module doesn't update very frequently.

If this doesn't work for you or if you don't want to edit module code, then you can use this simplified version of the macro below: spelltracker_queue_seconds.txt

This version should work (though I didn't test it, because I can't access Foundry from here), with the system time in seconds shown left of the character name of the tracked spells. (The only thing that the toolCreateFromSeconds() function does, is convert that number of seconds into a date and a timestamp.)

Cheers!

Motara7 commented 3 years ago

Hello again,

I've been working with @Tarbarian on the Foundry PF1e Discord and this is what we've (99% Tarbarian) come up with. I have given Tarbarian your name to give credit in his comments.

/**

if (!actor) { ui.notifications.warn('You need to select a token before using this macro!'); //ends macro and warns if token not selected } else {

const CL = token.actor.data.data.attributes.spells.spellbooks.primary.cl.total //Sets the constant CL based on tokens primary caster level let dialogContentlabel = <div><span style="flex:1">Spell Name: <input name="label" style="width:350px"/></span></div> //text box for inputting spell name let dialogContentduration = <div><span style="flex:1">Custom Duration in Minutes (leave blank for none): <input name="duration" style="width:350px"/></span></div> //text box for inputting duration let d = new Dialog({ // title: "Enter Spell Info", // content: dialogContentlabel + dialogContentduration, // buttons: { // done: { //* label: "Change!", //creates and defines the dialog box callback: (html) => { if (isNaN(parseFloat(html.find("[name=duration]")[0].value))) //determines if an integer was input for custom duration

{spellDurationNotification(html.find("[name=label]")[0].value, CL)} //if not, sets the custom duration same as one of the default, causing it to not be shown else

{spellDurationNotification(html.find("[name=label]")[0].value, parseFloat(html.find("[name=duration]")[0].value))} //if it is an int, sends it to the spell duration notification function } }, }, default: "done" }) d.render(true)

function spellDurationNotification(spellLabel, spellDuration) { const durationLengths = [1CL+" minutes", 10CL+" minutes", 1CL+" hours","24 hours",1CL+" days",spellDuration+" minutes"]; //sets the names of all the durations const durationNum = [1CL, 10CL, 60CL, 1440,1440CL, spellDuration]; //sets the durations in minutes const text = '

' + "Select spell duration:" + '
'; //creates the text box

//beyond this point I don't really understand what it's doing, all this

is unmodified from the original macro let buttons = {}, dialog, content = text;

durationLengths.forEach((str)=> {
    buttons[str] = {
        label : str,
        callback : () => {
        const targetTime = game.Gametime.DTNow();
        targetTime.minutes += durationNum[durationLengths.indexOf(str)];
        sendChatMsg("In " + str + ", the " + spellLabel + " spell will

end!", str); const endedMsg = msgFormat(actor.getActiveTokens()[0].name + "'s " + spellLabel + " spell, has ended", "The " + spellLabel + " spell cast " + str + " ago, has ended.", str); const spellDurationId = game.Gametime.reminderAt(targetTime, endedMsg); // actor.setFlag("dnd5e","spellDurationId",spellDurationId); // console.log("Spell Tracker: added spell id", spellDurationId, "at", game.Gametime.getTimeString(),"(in-game time)"); dialog.render(true); } } });

dialog = new Dialog({title : 'Set spell duration', content,

buttons}).render(true); };

function msgFormat(isActiveMsg, msgContent, durationText) {
const htmlMsg = '<div><div class="dnd5e chat-card item-card">\
                <header class="card-header flexrow red-header">\
                    <img

src="icons/tools/navigation/hourglass-yellow.webp" title="Spell Tracker" width="36" height="36">\

' + isActiveMsg + '

\ \
\

' + msgContent + '

\
\ Spell Duration Tracker\ ' + durationText + '\ ' + actor.name + '\
\
'; return htmlMsg; } function sendChatMsg(msgContent, durationText) { const chatData = { user: game.user.id, speaker: game.user, content: msgFormat(actor.getActiveTokens()[0].name + " is casting a Spell", msgContent, durationText), // Uncomment the line below this if you want the message to be whispered to the GM whisper: game.users.entities.filter(u => u.isGM).map(u => u._id) }; ChatMessage.create(chatData,{}); }; } On Fri, Dec 18, 2020 at 12:51 AM Stendarpaval wrote: > @Motara7 Glad to hear that > spellEndedNotification worked for you! Please keep me posted if you > manage to add a dialog box to add the name of the spell/effect, because > that's something I'm definitely interested in. > > spelltracker_queue is a macro that allows you to cancel the tracking of a > given spell. This can be really handy when there are multiple spells active > and one character fails a concentration check and stops concentrating on a > spell. > > Activating the macro should create a dialog box with a list of all > currently tracked spells, along with the name of the character that was > selected at the time as well as the date and the time at which the spell is > scheduled to end. I'll try to remember to make a screenshot of it later and > share it with you. > > The reason you currently get that error is because in order for the > spelltracker_queue macro to work, you need to edit a javascript file > inside the About Time module. That is actually the reason I created this > issue in the first place, and I also mentioned this in my previous comment. > > 1. In order to make the macro work, you need to navigate to > modules/about-time/module/ and open ElapsedTime.js (or perhaps > ElapsedTime.ts) in a text editor. > 2. Somewhere in the first 50 lines you should find the following code > snippet: > > static currentTime(): DTMod { > return DTMod.fromSeconds(PseudoClock.currentTime); > } > > static currentTimeSeconds() : number { > return PseudoClock.currentTime % DTCalc.spd; > } > > > 1. You should edit the above snippet to look like this: (basically, > add a new function called toolCreateeFromSeconds() to the ElapsedTime > class) > > static currentTime(): DTMod { > return DTMod.fromSeconds(PseudoClock.currentTime); > } > > static toolCreateFromSeconds(seconds) { > return DateTime.create(DTMod.fromSeconds(seconds)); > } > > static currentTimeSeconds() : number { > return PseudoClock.currentTime % DTCalc.spd; > } > > > 1. Save the file and restart Foundry. The spelltracker_queue macro > should now work. > > Note: You will need to redo this every time the About-Time module is > updated, but luckily that module doesn't update very frequently. > > If this doesn't work for you or if you don't want to edit module code, > then you can use this simplified version of the macro below: > spelltracker_queue_seconds.txt > > This version should work (though I didn't test it, because I can't access > Foundry from here), with the system time in seconds shown left of the > character name of the tracked spells. (The only thing that the > toolCreateFromSeconds() function does, is convert that number of seconds > into a date and a timestamp.) > > Cheers! > > — > You are receiving this because you were mentioned. > Reply to this email directly, view it on GitHub > , > or unsubscribe > > . >