-
Notifications
You must be signed in to change notification settings - Fork 1
/
User_Manual.txt
executable file
·851 lines (687 loc) · 51.9 KB
/
User_Manual.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
====================================
= Illydth's Spell States =
====================================
See "Why Illydth's Spell States?" at the end of this document if you wonder what the capabiltiies of this library are
or why you should choose to use this in your campaign.
Requirements:
==========================
This library / macro code uses the Dialog5/Frame5 functionality of MapTool, this means MapTool version 1.6 or above
is required for best use of this tool. All development is being done with the concept that Dialog5/Frame5 is available
within the MapTool installation. No effort will be made to maintain a backaward compatable (dialong/frame) version of
the tool.
THAT SAID:
For those using a MapTool version below 1.6, at least at this moment, you SHOULD be able to modify the
"openStatesToolbox" macro in the "Spell States Toolbox" section of the Lib:SpellStates Library and change the
"dialog5" call to "dialog", and open the "Spell Info" campaign button macro and change "frame5" to "frame".
This should change things back to HTML 3.2 from HTML5 support. At this point in development, I don't think i'm using
any specific HTML 5 functionality that would break if run through the Dialog/Frame compatability frame.
That said, Frame/Dialog and Frame5/Dialog5 produce VERY different looking Frame boxes in Maptool, and all layout
is being done using the HTML5 versions of these dialogs, YMMV with regards to look and feel or even functionality if
you choose to use the Frame/Dialog versions.
Installation:
==========================
-------------------------
TOKEN INSTALLATION PROCESS
(To Import Into Your Own Campaign):
-------------------------
Unpack the issSpellStates_<version>.zip file.
* image_GreenBubbleCheck.rptok
* image_RedBubbleX.rptok
* issSpellStates.mttable
* issSpellStates_Base.cmpgn
* Lib_issSpellStates.rptok
* README.txt (this file)
* Open your Campaign File
Edit / Modify Your Campaign Properties:
* Edit -> Campaign Properties
* Create a New Token Property Type Called: "issSpellStates"
* Add the following to the issSpellStates Campaign Properties:
SpellList
libversion
optRefSpellDur
optAddCStateOnApply
optRemCStateOnRemove
* Add the following to the Campaign Properties for Monsters and PC Tokens (Basic Properties).
____ILLYDTH_TOKEN_SPELLSTATES_PROPERTIES____
issSpellBuffs
issSpellDebuffs
Deal with the Token Files:
* Copy the 3 Tokens to the library map of your campaign.
Lib_SpellStates.rptok
image_GreenBubbleCheck.rptok
image_RedBubbleX.rptok
[The Image Files are Optional, if you do not add them to your campaign, you will get a "Y" or "N" (text) in place of
the green Check Mark or Red X. This looks uglier, but is fully functional if you don't want the added Image Tokens.]
Open the Selection, GM and Campaign Windows.
* Click on "Lib:issSpellStates" in your Library map.
* Copy the "DM States Toolbox" macro to your GM Window.
* Copy the "Lookup Spell Info" macro to your Campaign Window.
* Copy the "States Management Form" macro to your GM Window (can go to Campaign if players are setting states)
* Copy the "Get Token Effects" macro to your Campaign Window.
* If applicable: Set all 4 buttons above to non-editible by players or you'll run into problems.
Import the Spells Table
* Open the Tables Window.
* In the Archive is a Directory for the Supported Frameworks (as of the initial Release, just D&D 5th Edition)
* Open the directory for a supported RPG platform.
* Import the "issSpellStates.mttable" file from that RPG Directory into your Campaign Tables.
* Make Sure this table is called "issSpellStates" (regardless of which RPG platform, the table neeeds to be called
issSpellStates for things to work).
Import the Campaign Macros/States (Optional)
* To use the Consolidated / Cohesive icons and coloration for 5e campaign states, import the Campaign States to
your campaign.
* Rename any Campaign Groups you have called:
2. Conditions
3. Exhaustion
4. Cover
5. Other States
* Open your Campaign Macros Window
* Right Click and Import Macro Group
* Open the issSpellStates_Campaign_State_Macros Maptool Campaign Macro Set for the RPG Platform of Choice.
* Macro Buttons for campaign states should be imported into the Campaign Macros Section.
Deal With Campaign States (If Needed)
(See Campaign States Later in this Document)
--------------------------
USING THE CAMPAIGN FILE
(To Create a New Campaign Using issSpellStates as a Base):
--------------------------
* Open the "issSpellStates_Base.cmpgn" File.
* Open the Selection, GM and Campaign Windows.
* Click on "Lib:issSpellStates" in your Library map.
* Copy the "DM States Toolbox" macro to your GM Window.
* Copy the "Lookup Spell Info" macro to your Campaign Window.
* Copy the "States Management Form" macro to your GM Window (can go to Campaign if players are setting states)
* Copy the "Get Token Effects" macro to your Campaign Window.
* Setup any Needed Campaign States
(See Campaign States Later in this Document)
USE:
(How to Use issSpellStates)
=====================================
Illydth's Spell States provides two very common capabilities to a tabletop campaign: Searching for and displaying
information related to a spell or ability and the capability of tracking the effects those abiltiies have on a target
token.
The easist way to learn how to use issSpellStates is to open the issSpellStates_Base.cmpgn file in Maptool, add a
token to the interface and start playing with it! If you want a walkthough example to learn how to use this, please
see the "Using issSpellStates by Example" document distributed with this archive for a detailed step by step walkthrough
of the software. Otherwise "Get Spell Info" and "Setting and Managing States" are the full documentation surrounding
the major elements of this framework. There is one "addon" feature of issSpellStates that is not generally used by the
UI elements of the framework (it's applied in API Only), which is the management of spell duration timers. See "Spell
Duration Management" toward the end of the "USE" section for more information.
Finally, see "issSpellStates API Extensions" below for integration points to other frameworks/abilties of
maptool.
Get Spell Info
-----------------
* Click the "Lookup Spell Info" macro button.
* The frame that opens is dockable.
* Type the name of a Spell into the Search Spells box.
* If the spell is in the Spells Table (see Spell Info and Extending This Framework below), its information will be
displayed in the box.
* Search must be done by full spell name, partial names will not be found.
Setting and Managing States
------------------
To begin with, states must be added to the "toolbox". Because of the large number of spells usually within tabletop
games, managing the large number of spells is done by adding a small subset of those spells to a "toolbox" which can
then be easily accessed to apply and remove states from tokens.
--- DM Toolbox of States ---
* Click the "DM States Toolbox" macro which should be on your "GM" Pannel. (This macro should likely only be available
to the GM).
* This opens a free floating MapTool Frame displaying a Search Box and the spells which are currently in the toolbox.
NOTE: This frame is built with "dialog5", not "frame5" so it cannot be docked.
* In the type-in box enter the name of a spell or ability in the issSpellStates database (by default any D&D 5th Edition
spell in the list under "Spell Info and Extending This Framework" below), for instance "Aid"
NOTE: This must be the FULL NAME and EXACT SPELLING of the spell in the Database. This version of the tool does not
support partial lookups.
* Click the "Search" button or hit Enter.
* If the spell is found, it will appear in the table below the search box.
* A Green Checkmark in either the "Buff" or "Debuff" column will allow the spell to be added to the toolbox. If a
red X is showing under both "Buff" and "Debuff" the spell does not set an effect that would need to be tracked
(spells such as Fireball or Magic Missile do not set effects on their targets, while spells like "Mage Armor"
or "Stoneskin" do).
* If the spell can be added to the toolbox, a "+" Button will appear on the left side of the DM Toolbox of States
window near the spell name in the table below the search box.
* Click the + Button to add that spell state to the toolbox. A button with the name of the spell or ability
(colored "Red" for Debuffs and colored "green" for Buffs) will be added to the "States in Toolbox" area at the
bottom of the window.
* Clicking a button in the "Staates in Toolbox" area will remove that state from the toolbox, causing it to disappear
from the "DM Toolbox of States" window. Once removed, it must be added again through the Search Spells method
above.
* Clicking the "Clear Toolbox" Link at the bottom will pop a window up displaying all the spells in the spell states
toolbox. If you click the check box and click "ok" to this window all states in the toolbox will be removed.
* Once Done adding Spell Effects and Ability states to the toolbox, click the "Close" button.
Once you have spells and abiltiies in the "DM's Toolbox of States", you can then apply those states / spells to
tokens through the use of the "States Management Form".
--- States Management Form ---
* Click the "States Management Form" Macro Button. This button can be in the GM or Campaign Window, depending on
whether or not players set their own states or the states on enemy tokens or whether only the DM does this.
* The Macro will open a Frame5 dialog box that is dockable anywhere on the maptool interface. The frame will
display all current states that are in the DM States Toolbox (all states added above will show up in this new
frame).
* Click a token to which to apply a spell effect or ability effect that is in the states toolbox.
* The Token Name should show up in the states box next to "Current States" (i.e. MyName Current States)
* Any existing spell states should show up under the "buffs" or "debuffs" list.
*** IMPORTANT NOTE ***: CAMPAIGN STATES DO NOT SHOW UP HERE, ONLY SPELLS AND EFFECTS APPLIED BY
ISSSPELLSTATES WILL SHOW IN THIS LIST.
* Click the button on the states toolbox to apply that state to the token. Almost all states will set
one ore more campaign states (see Campaign States below) to identify to the GM/DM that an effect is
set on the target.
* The Token should get one or more icons set on it to identify that a state exists on the PC or NPC, and
a spell/abiliity name will appear under the "Buffs/Debuffs" columns at the bottom of the "Manage Spell
States" frame.
* Clicking the Linked Spell Name under the "Buffs"/"Debuffs" area of the "Manage Spell States" frame will
open the "Spell Lookup" frame and automatically pull up the spell / ability information in that frame.
* Clicking the Button for a spell effect that is already applied to the target will remove that Spell Effect
from the target. (See Options Below).
* Clicking the Button for a spell effect that is NOT already applied to the target will add that spell effect
to the target.
- Options -
There are 3 options that can be set/unset when applying spell states to a token, each option has a
hover-over descritpion to assist the User with Understanding it's effect.
* Refresh Spell Duration - This changes the behavior of reapplying a spell from the States Toolbox.
With this set, when applying a spell that is already applied to the token, it's duration count
will be refreshed to it's original base duration instead of removing the spell effect from the target.
Effective, this acts as if the spell has been "reapplied" to the target.
* Add Campaign States when Applying Spells - This causes issSpellStates to automatically apply the campaign
states in the "States" part of the spell/ability data to the token along with it's own "state". For instance
"Flesh to Stone" sets a campaign state of "Petrified" in D&D 5th Edition. With this box checked the spell
state "Flesh to Stone" would be set on the token, but it would ALSO set the Campaign State "Petrified"
on the token as well. With this unchecked, the spell state "Flesh to Stone" would be set on the token, but
the Campaign State "Petrified" would not be set.
* Remove Campaign States when Removing Spells - This acts as the reverse of the previous option. With this checked
when a spell effect or ability is removed from a token that sets a campaign state, that campaign state is also
remvoved. Again, using the "Stone to Flesh" spell example above, when "Stone to Flesh" is removed from the
token, with this checked, the "Petrified" condition would also be removed. With this unchecked, the
"Petrified" condition would not be removed.
(See "Using issSpellStates by Example" in the file included in this archive for a "hands on" walkthrough of all the
features of this framework).
Spell Duration Management
---------------------------
Illydth's Spell States (issSpellStates) includes a very rudimentary system for tracking the duration of spells and
effects on a token.
The issSpellStates table includes a field "EffectCount" which is a calculated data field that contains the number
of units for which that effect persists. For instance, in D&D 5th Edition, the smallest unit of trackable time is
the "round", which is considered to be 6 seconds. Many spells last for 1 round or 1 minute, so their EffectCount
would be "1" or "10" respectively (1 round or 10 rounds which is 6 Seconds / Round Divided by 60 seconds in a minute).
A spell that lasts "1 hour" however would have an "EffectCount" of 600 (10 Rounds / Minute * 60 Minutes) while a spell
lasting a day would have an EffectCount of 14400.
Obviously, tracking 14400 units of time through a typical campaign play at 6 seconds at a time would not be feasable.
The framework does not "assist" in this, nor try to manage this. The only feature provided at this moment is a
single API "decrementSpellDuration" which reduces the duration by one on all effects applied to all selected tokens.
This functionality is included with the intent of being able to track short term buffs during combat which is held
in tracked increments of time. A framework could hook the MapTool Initiative tracker feature to call this decrement
API every time a single pass through the initiative order (combat round) is completed. For short term buffs and
debuffs, this provides functionality for a framework to automatically remove effects from tokens in combat by using a
combination of decrementSpellDuration as combat shifts from round to round, getEffectsOnToken which returns a list of
all effects on a token and their respective remaining durations, and removeEffectFromToken which provides an ability
to remove an expired effect. Given these three tools, designing a flexible "round" management system that
automatically removes buffs or debuffs that have hit 0 time left on them is within any framework designer's grasp.
What this system does NOT try to do is manage anything outside of an initiatve based system. There are no "timers"
to automatically decrement rounds after certain times have passed or after certain actions have been completed, there
is no "decrement by X amount" functionality that provides a framework the ability to say "an hour has passed, remove
600 rounds from the counter of each spell", or anything of the sort. This functionality is designed around short
term, in-combat effects.
HOWEVER, the issSpellStates table DOES include calculated spell durations for all spells up to 1 day in length.
While the system does NOTHING to help you manage spell durations of that length, they are included in case a
framework wants to implement something additional based around the EffectCount data.
An offical API has NOT been included to return the spell data in a format back to a calling framework, however
"getSpellByNum", "getSpellByName", "getSpellNameByNum" and "getSpellNumByName" are included on the Lib Token as
general functions being used internally by issSpellStates. For instance, "getSpellByName" expects the same input
as the "addEffectToToken" API (a Spell Name) and reutrns a JSON Object with all the spell data off of the spell
table, including the EffectCount.
A framework programmer intending to do something with EffectCounts can abuse the above basic functions to obtain
the EffectCount off the spell table.
I am open to suggestions on a better way to implement or use Spell/Effect Durations. However duration tracking
is NOT this library's main functionality, it is merely here as a convenience to framework maintainers to give
them the ability to save GMs/DMs some time and trouble managing effects on tokens. An extensive durations system
is outside the original intent of this functionality, but could be fleshed out through requests or contributions.
(WARNING: DO NOT MODIFY "getSpellByNum" or other noted functions above without knowing EXACTLY what you are doing.
Those functions are deeply ingrained and used by much of the issSpellStates code and changing anything about what
these functions take in or return or modifying anything about how they work risks causing issSpellStates to stop
functioning. If you modify anything within any of the "General Functions" code, please DO NOT contact me for
support if something is broken. Simply re-download a copy of my library token and re-apply it.)
issSpellStates API Extensions
-----------------------------
The intial version of issSpellStates ships with several integrations into the framework as defined below. The intent
is to provide other frameworks the capability of doing the basic things that the UI elements in this tool do: Namely
set and remove effect states from a token or tokens. This can be done individually or in bulk, and also includes an
ability to decrement spell duration timers if the user wishes to use that functionality.
PLEASE NOTE: The API functions listed below (those in the "ZZZ-API Hooks" group) are not used/called by anything
else within the issSpellStates code. While they do use general functions and other function calls on the Library
they, themselves, are not called by anything. This means the API macros are completely open for modification assuming
it is needed to do so to fit a framework. For instance, the getEffectsOnToken API call returns a JSON Object listing
of effects. Modifying the way that JSON is structured so that it fits within the campaign framework is a perfectly
acceptable thing to do. You will not break any of the base functionality of issSpellStates by doing so.
HOWEVER note that modifying anything CALLED BY these API functions WILL affect the behavior and stability of
the issSpellStates system. Adding an additional call of "getSpellByName" or "removeTokenEffect" to an API macro
is perfectly fine, but modifying the "getSpellByName" or "removeTokenEffect" macros (or any other macros called by
code within the issSpellStates system) will almost certainly break issSpellStates.
--- "Overloaded" Macro Inputs ---
(See "ZZZ-Example API Calls" on the Lib:Token for code examples of how to call each of the below APIs)
All of the APIs are "Overloaded" (as in the programming definition of "function overloading") with regards to their
input parameters. Each of the below APIs can take in 0, 1 or >1 TokenIDs and it will do the sane thing with them.
If No Token ID's are sent into the API call ([h: tokenIDList = ""]) each function will use "getSelected()" to
determine what to apply it's effects to. If the Token ID List is blank and there are no selected tokens, the APIs
will simply do nothing.
If the Token ID List is populated with one or more token IDs, the API functions will *ignore selected tokens* and
instead use the Token ID List that was passed to the function to perform it's actions. It is important enough to
call this out once again. If one or more TokenIDs are passed to an API Call THE API CALL WILL IGNORE SELECTED
TOKENS AND ***ONLY*** APPLY IT'S EFFECTS TO THE PASSED TOKEN IDS.
Because of this "overloading" all of the following are viable ways of calling any API listed below:
*** Calls <issAPIName> and lets it use getSelected() to perform it's actions ***
[h: tokenIDList = ""]
[h: testParams = json.append("", tokenIDList, <ADDITIONAL PARAMETER>, ...)]
[r, macro("<issAPIName>@Lib:issSpellStates"): testParams]
*** Calls <issAPIName> and has it use a token of Specified ID to perform it's actions ***
*** --- Important: Selected Tokens will not be affected.--- ***
[h: tokenIDList = "0764DC933DC7458CA06280C282A6A5CE"]
[h: testParams = json.append("", tokenIDList, <ADDITIONAL PARAMETER>, ...)]
[r, macro("<issAPIName>@Lib:issSpellStates"): testParams]
*** Calls <issAPIName> and has it use a token of Specified IDs to perform it's actions ***
*** --- Important: Selected Tokens will not be affected.--- ***
[h: tokenIDList = "0764DC933DC7458CA06280C282A6A5CE, 2DCA142F5E7B4F4582AB182DA2A20595"]
[h: testParams = json.append("", tokenIDList, <ADDITIONAL PARAMETER>, ...)]
[r, macro("<issAPIName>@Lib:issSpellStates"): testParams]
*** Calls <issAPIName> and has it use a calculated list of tokens to perform it's actions ***
*** --- Important: Selected Tokens will not be affected.--- ***
[h: cond = '{ "range": {"upto":2, "distancePerCell":0, "token":"' + getSelected() + '"}, "npc":1}']
[h: tokenIDList = getTokens("json", cond)]
[h: testParams = json.append("", tokenIDList, <ADDITIONAL PARAMETER>, ...)]
[r, macro("<issAPIName>@Lib:issSpellStates"): testParams]
Of note: The "Token List" is it's own separate JSON array with the ENTIRE array indexed as element 0.
All APIs use [h: tokenIDList = json.get(inputTokenList, 0)] to get the entire array into an element. Please follow
this format when calling the APIs.
--- The APIs available are as follows: ---
----
*** addEffectToToken@Lib:issSpellStates() ***
This API takes an effect name (the name of any spell or effect in the issSpellStates table) and applies the spell or
effect a selected token or group of tokens. This is used to allow other frameworks through it's own macros and features
to set a spell effect on a token.
For instance, if someone were to create a button to cast the "Aid" spell in a framework, that button could call
addEffectToToken and pass it "Aid" and issSpellStates would add the "Aid" spell to the selected token or tokens, and then
track that effect until removed.
Based upon the setting of the "optAddCStateOnApply" Library Option (token property on the Lib:issSpellStates token), the API
will manage the associated campaign states with any spell being cast.
* 0 - If "optAddCStateOnApply" is 0 in the Lib Token, the framework will skip managing campaign states. States that
spells apply will not be applied to the token.
* 1 - If "optAddCStateOnApply" is 1 in the Lib Token, the framework will apply campaign states when spell effects that
apply those states are cast.
For instance, if Flesh to Stone is cast on a target token, issSpellStates will track the spell "Flesh to Stone" on the
token. However, if "optAddCStateOnApply" is set to 1, it will ALSO set the "Petrified" campaign state on the token and
then track BOTH "Petrified" and "Flesh to Stone" on the target. This makes it easy for a framework to appropriately set
relevant states on a token through an effect, ability or spell.
----
*** clearEffectsFromToken@Lib:issSpellStates() ***
This API completely removes all effects from the target token or tokens. All tracked spell states (and their associated
campaign states) will be removed from the selected token or tokens when this API call is made. This is used when a
framework wants to completely clear all tracked issSpellStates effects associated with a token.
For instance, when implementing a "Long Rest" macro for a 5e campaign, that macro could call "clearEffectsFromToken"
to clear all spell states from the tokens taking a long rest.
The Lib Token Option "optRemCStateOnRemove" is used to determine whether or not the issSpellStates framework removes
campaign states from the token upon removing the spell effects that caused them.
* 0 - If "optRemCStateOnRemove" is 0 in the Lib Token, the framework will skip managing campaign states. Campaign States
that issSpellStates applied while applying spells (such as Stunned or Petrified) will not be removed.
* 1 - If "optRemCStateOnRemove" is 1 in the Lib Token, the framework will remove campaign states when a spell effect that
applies that state is removed.
For instance, if "Flesh to Stone" were cast on a target token, and that token had the "Petrified" condition set on it,
setting "optRemCStateOnRemove" to 1 would cause the "Petrified" contdition to be removed by the clearEffectsFromToken API
call when it goes to clear the "Flesh to Stone" spell effect.
----
*** decrementSpellDuration@Lib:issSpellStates() ***
By default, issSpellStates does very little with the duration of spells or effects. There is no inherent
mechanism to track spell durations or manage "how long does this thing have left".
That said, there is an API function "decrementSpellDuration@Lib:issSpellStates" that will decrement the duration
counter on any token it is run on. All spells WITH a duration being tracked in the spell's effect will have
that duration counter reduced by 1 for each time "decrementSpellDuration@Lib:issSpellStates" is called.
The macro assumes the tokens to run on are selected and it does a loop over every selected token when
called to decrement all duration counters on that token.
The intent of this macro is to allow DMs with their own "initiative"/"Next Round" custom code to hook
issSpellStates to decrement the duration counters automatically as combat shifts to a new round.
See "Spell Duration Management" Above for more information about this functionality.
----
*** getEffectsOnToken@Lib:issSpellStates() ***
This API call returns a JSON object with information about what issSpellStates are applied to the token. This is
somewhat akin to the "getState" functionality within Maptool Macros. Because issSpellStates is tracking states
that aren't campaign states (and thus cannot be retrieved using getState(), this API call allows frameworks to retrieve
the current set of conditions affecting a token (or group of tokens). Using "getState()" and "getEffectsOnToken" a
framework can identify every effect on a token.
(NOTE: The "Get Token Effects" button provided by the Lib:issSpellStates library already provides a way to retireve
both campaign states and issSpellStates together in one format. The "Get Token Effects" button should be used for a user
display of states while this API call would be used by the framework itself to make calculations or do things based around
the existance of states.)
(NOTE: The largest difference between this API call and the "Get Token Effects" macro button is that this returns ONLY
states tracked by issSpellStates, it does NOT return Campaign States).
The returned JSON is in the following format:
[
"TOKENID1",
{"buffs": [
{"BuffSpellName": duration},
{"BuffSpellName": duration},
...
{"BuffSpellName": duration}
]},
{"debuffs": [
{"DebuffSpellName": duration},
{"DebuffSpellName": duration},
...
{"DebuffSpellName": duration}
]},
"TOKENID2",
{"buffs": [
{"BuffSpellName": duration},
{"BuffSpellName": duration},
...
{"BuffSpellName": duration}
]},
{"debuffs": [
{"DebuffSpellName": duration},
{"DebuffSpellName": duration},
...
{"DebuffSpellName": duration}
]},
"TOKENID-N",
{"buffs": [
{"BuffSpellName": duration},
{"BuffSpellName": duration},
...
{"BuffSpellName": duration}
]},
{"debuffs": [
{"DebuffSpellName": duration},
{"DebuffSpellName": duration},
...
{"DebuffSpellName": duration}
]}
]
EXAMPLE:
[
"6BF32A570F894A40A9CA00A14B02F827",
{"buffs": [
{"Aid": 4800},
{"Bless": 10}
]},
{"debuffs": [
{"Bane": 10},
{"Banishment": 10}
]},
"D310F6322C2048D3886CF2884E5D15CE",
{"buffs": [
{"Aid": 4800},
{"Bless": 10}
]},
{"debuffs": [
{"Bane": 10},
{"Banishment": 10}
]}
]
----
*** isEffectOnToken@Lib:issSpellStates() ***
This is a macro that returns a simple 1 or 0 depending upon whether the input effect name is currently applied
to the token or not. This can be used by a framework in code to validate whether any given effect is applied to
any specific token.
NOTE: This will return 3 results:
* "0" - If the effect is not on the token.
* "1" - If the effect is on the token.
* "2" - If something other than 1 token is selected (0 or >1 Will Return a "2")
----
*** removeEffectFromToken@Lib:issSpellStates() ***
This API takes an effect name (the name of any spell or effect in the issSpellStates table) and removes the spell or
effect from a selected token or group of tokens. This is used to allow other frameworks through it's own macros and features
to remove a spell effect on a token.
For instance, if someone were to create a button to cast the "Dispel Magic" spell in a framework, that button could call
removeEffectFromToken and pass it a spell effect name like "Aid" and issSpellStates would remove the "Aid" spell from the
selected token or tokens.
The Lib Token Option "optRemCStateOnRemove" is used to determine whether or not the issSpellStates framework removes
campaign states from the token upon removing the spell effects that caused them.
* 0 - If "optRemCStateOnRemove" is 0 in the Lib Token, the framework will skip managing campaign states. Campaign States
that issSpellStates applied while applying spells (such as Stunned or Petrified) will not be removed.
* 1 - If "optRemCStateOnRemove" is 1 in the Lib Token, the framework will remove campaign states when a spell effect that
applies that state is removed.
For instance, if "Flesh to Stone" were cast on a target token, and that token had the "Petrified" condition set on it,
setting "optRemCStateOnRemove" to 1 would cause the "Petrified" contdition to be removed by the clearEffectsFromToken API
call when it goes to clear the "Flesh to Stone" spell effect.
----
*** isConcentrationEffect@Lib:issSpellStates() ***
This API takes in a spell or effect name and validates the "concentration" flag on the spell. Specific to D&D 5th Edition,
this allows a framework to check to see whether the concentration state needs to be set and/or if the conentration state
needs to be overriden with a new spell.
GENERALLY, however, the Concentration flag could be set for any RPG Platform to designate spells / effects that cannot
coincide with each other. A broader use for the ssytem would be to set different values for the concentration flag assuming
there are groups of abilites / spells that cannot coincide with each other. So if you can only have one "Group A" spell
or effect on you at one time, this API could return the information that the newly executed ability is a "Group A" ability
thus allowing the framework to do the correct things.
This API will simply return the value in the "Concentration" flag on the database. Out of the Box, for D&D 5th Edition this
is either a 1 or a 0, depending on whether the spell is a spell requiring concentration or not.
* 0 - The Spell is NOT a spell requiring concentration.
* 1 - The spell is a spell requiring concentration.
----
*** showSpellInfo@Lib:issSpellStates() ***
This API takes in a spell or effect name opens the "Lookup Spell Info" form tuned to that spell.
The lookup is a simple database table pull of the spell name as passed to the API, so any abiltity or spell in the table should
be able to be retrieved through use of the API. This is intended to allow "MonsterCreator" or any other drop-in to link a spell
name and allow that spell to be automatically looked up within issSpellStates. MonsterCreator, for instance, creates links to
spells that are castable by monsters. Those links will open the spell description in the issSpellStates lookup form.
The API has no "output" value, instead it opens the Spell Lookup form with the spell as passed focued.
----
*** Other APIs ***
There are plenty more integration points that could be included, however the above should provide the basic functionality
for dealing wtih the features of issSpellStates.
I am always open to ideas for additional/better integrations with frameworks.
SPELL INFO and EXTENDING THIS FRAMEWORK:
=====================================
By default, this framework is setup for D&D 5th Edition. The following spells have been included:
* Acquisitions Incorporated
* Eberron: Rising from the Last War
* Elemental Evil Player's Companion
* Explorer's Guide to Wildemount
* Guildmaster's Guide to Ravinica
* Mythic: Odysseys of Theros
* Player's Handbook
* Sword Coast Adventurer's Guide
* Volo's Guide to Monsters
* Xanathar's Guide to Everything
Extending issSpellStates to Your Framework...
There's nothing about issSpellStates that is specific to D&D 5th Edition or truely to any specific tabletop RPG.
At it's core, issSpellStates is a system by which to apply basic Campaign states and extended ability states to
a token in MapTool (See "Why Illydth's Spell States?" below).
To extend this framework to your game system, create a different version of the issSpellStates table. Important
fields for SpellStates are:
* Name - The Name of the Spell, used to index/look up the spell in the spells table.
* Buff - Set to "1" if the spell or ability sets a beneficial effect on the target, 0 if not.
* Debuff - Set to "1" if the spell sets an adverse effect on the target, 0 if not.
* State - The name of a campaign state (in the Campaign Properties -> States Tab) that is set by this effect.
* EffectCount - The number of units of time that this ability lasts. For D&D This would be "rounds".
All other fields are optional, but should provide enough information to recognize and identify what the spell or
ability does and what effects it has on the game. If you choose to include / not include fields from what's
included in issSpellStates.mttable file, you'll want to modify the form display for the "Lookup Spell Info" macro
to properly display the information from your RPG's table data.
Click the "Lib:issSpellStates" library token and look at the macro for "Lookup Spell Info" and the three macro
buttons under "Spell Lookup" (Specifically "spellLookupForm" where the layout of the information is kept).
CAMPAIGN STATES
======================================
issSpellStates expects several states to exist in your Campaign Properties by default.
What states must be set are based upon what is listed in your issSpellStates.mttable file under the "States"
data set. If a spell sets the state "Buffed", you will need to have a "buffed" state in your campaign properties
to set. This framework could be used entirely wtihout campaign states by simply ensuring that all spells and
ablities in the issSpellStates table have an empty "States" data section.
Out of the box, the D&D 5e Version of Spell States expects the following campaign states to exist:
* Advantage * Frightened
* Blinded * Grappeled
* Buffed * Hasted
* Changed * Immunity
* Charmed * Incapacitated
* Concentrating * Inspiration
* CoverFull * Invisible
* CoverHalf * Paralyzed
* CoverMost * Petrified
* Cursed * Poisoned
* Dead * Prone
* Deafened * Resistance
* Debuffed * Restrained
* Disabled * Slowed
* Disadvantage * Stable
* Dodging * Stunned
* Dying * Transformed
* EnhVision * Turned
* Flying * Unconscious
Along with the above for 5e, "Exhaustion" (generally Exhaustion 1 - Exhaustion 5) is usually a state within
the campaign properties, and many campaigns make use of Raging (Barbarian), Shifted (Eberon Ability), Squeezing,
Suffocating, and AFK.
A member of the community has been kind/generous enough to develop a cohesive and comprehensive set of state
icons for the above states (and others). A major shout out to "rogue_ronan" on the Maptool discord and forms
for the development of these icons. They can be found alongside this issSpellStates framework. (See
Acknowledgements Below).
If you are trying to get issSpellStates to work "out of the box", make sure your campaign has all of the listed
states in it. If you are getting popups or errors related to states not existing or not being found, please
re-check your configuration.
At worst, if you don't want to add a bunch of states to your campaign...or you don't want to change names or
re-do the entire spell table to fit your states...you can always uncheck the "Add Campaign States when Applying Spells"
and "Remove Campaign States when Removing Spells" options on the "Manage Spell States" frame to use the framework
without it managing your campaign states for you. This makes it SLIGHTLY more difficult to use, but could make
the framework work for you without a bunch of work on your part as well.
WHY ILLYDTH'S SPELL STATES?:
==================================
Introduction:
This is a "spell states" management system for D&D 5e...and by extension any RPG that has abilties that set effects
on PCs or NPCs.
The Problem...
The problem with 5e (though not unique to 5e...it's a problem with Pathfinder, GURPS, or, indeed, most tabletop systems)
is that 5th edition has almost 500 spells at the time this was developed, and a signficiant quantity of them set
some kind of state on a character, from Mage Armor and Stoneskin to Hex and Banishment. All of these states are
important for the DM and players to keep track of. Unfortunately, even with a 3x3 grid and other tools that MapTool
has to manage "states" a sufficiently powerful and prepared spellcaster a couple of rounds into combat will have more
"states" on them than MapTool is currently capable of displaying on the character token.
Along with this, while there are hundreds of spell states that a character has access to, any one campaign will only
tend to use a small handful of them. For instance, a campaign with a Warlock as a player character will almost
definately use Hex, a campaign without a Warlock might not. A campign with a Ranger in it will likely use Hunter's
Mark, without a Ranger? Almost Definately not.
Does this ring a bell with any of you DMs out there? Your Wizard finishes delving a dungeon only to find a new
spell scroll which they spend their next long rest scribing to their spellbook and then decide to use on the next
section of the adventure. So now they say "I'd like to cast ..." and you realize, you have no state available to
track the use of that spell. Worse, because it is a new spell none of you are familiar with in the campaign it's
easy to forget. So till you can get in and manage this new state (find an icon that makes sense, add the state to
your campaign, create macros to set/remove the state, etc.) you use one of the already current states in the
campaign as a "placeholder" state, which 2 more rounds into combat, gets used for it's original intent and now you
have to go back and find a different placeholder state for the new spell and figure out which tokens have what states
on them...all by little icons...
Definately less than ideal. The default method MapTool uses to handle states like this is pretty limited, and
generally leaves DMs with a plethora of bad choices with no really good alternatives.
* Do you load every one of the hundreds of different states into your campaign in the case that someone will use one
of them? Of course this opens you up to "state bloat" with hundreds of macros on the characters or campaign
pannel that are never used to set/remove these states on the off chance someone eventually chooses to use one.
Then there's the problem of having to find unique icons for each and every state and having to get hundreds of
states even loaded in and setup in your campaign.
* Do you leave out the majority of spell states hoping that the less popular ones won't be used and thus you don't have
"state bloat" in your campaign? What happens when your Warrior decides to Multi-class into Warlock in the middle
of a session and chooses "hex" for one of his spells, which isn't a state in the campaign?
* Do you try to manage states between sessions, adding new states and removing states between play sessions as spells
fall in and out of favor with your party in an effort to manage bloat but yet make states available for tracking?
Wouldn't this time be better spent preparing for the next part of the campaign?
* Do you try to add states on the fly during game play? As a player uses a new spell do you pause combat with "hang
on! I need to get a state added for that!" going through your library of icons to try to find one that even makes
sense while your players are waiting on their turns?
Most DMs seem to go for limiting the number of campaign states and then tracking things using placeholders or manual
notes or some form of "well, I don't have a state so we'll just set something and hope I remmeber it while combat is
going!" methodology. This makes sense, after all, 5th Edition implements 19 default conditions (blind, charmed,
concentrating, unconscious, dead, etc.), 6 Exhaustion States and 4 types of "cover" (none - full) all before taking
into account general tracking things like advantage/disadvantage, damage resistance and immunity, inspiration, raging,
shapechange (both beneficial and determental) and a host of other general conditions that cover abilities and spells.
Just implementing the default major conditions and states creates somewhere in the neighborhood of 40+ campaign states
and that takes into account almost no spells. That means 40+ macros on the Campaign window to set those states, and
40+ icons that could appear in places on the token identifying things. "There's an icon of a guy with an open mouth,
is that feared or silenced?...And that blue dot in the right corner, is that concentration or inspiration? Damn..."
How do we manage this much information on a small token? They say a picture is worth a thousand words, but we don't
need 9000 words to describe the effects on a token, we simply need 9 words stored in some logical and reasonable
format for easy retrieval...
The Answer...
Illydth's Spell States (you knew this was going to be the answer, of course it was). I've gone through every spell
in 5th Edition (all officially published materials) and created a table of spells useable both for lookup and (more
importantly) for identifying spells that set some kind of condition on a PC or NPC during the game. These spells
have been broken down into two types: buffs and debuffs, or spells that set a beneficial effect and spells that set
a determental effect on a PC or NPC.
I've then created a system whereby the DM can quickly and efficiently add spell states to the system (through a tool
I call the "DM States Toolbox") and then use that toolbox to track states on tokens. Using a small set of generic
icons (such as Buff, Debuff, Disabled, Immunity, Resistance, etc.) we set a visual state that represents a warning to
players and the DM that there's an effect set on the token, and then a way to "get info" on that token so that all of
the states can be displayed and investigated (if needed). For small combats or small numbers of buffs, just the general
"buff", "debuff", "disabled", etc. states are useful for generically tracking effects. However the power in the system
is that beyond these general states (which ARE campaign states), we can store an unlimited number of other effects on
the token that can then be displayed through an interface which can then also be linked back to the original spell.
This gives DMs an ability to investigate effects on a token in a multi-layered approach. If by looking at the token the
"debuffed" effect icon triggers the DM's memory that the token is "hexed", and the DM remembers what that effect does,
there's nothing more than needs to be done. Just the "debuffed" icon is enough. If, however, more information is
needed, the DM (or players!) can select the token and check it's current state through an interface that will show all
of the effects (buffs, debuffs, conditions, etc.) on the token. So now, the DM can see that the "debuffed" effect icon
is referencing the spell state "Hexed". Again, if the DM is familiar with that condition no further information is
needed. However, if the DM wants to see exactly what that state is referencing, the interface will allow the DM to
simply click a link and pull up the information about the spell that caused that state directly.
Because we can set an unlimited number of effects on a token, we're not limited to 9 icons or missing the fact that
a token is affected by something, or reusing states/effects/icons for things that they really don't pertain to.
Because the DM has access to every effect causing capability in the game, there's no "mad dash" to add something
new to an in-progress session, or to "placeholder" an effect becuase one doesn't exist for that spell or ability.
Because we're tracking EVERY effect and can link it back to it's source, we have the capability of providing every
bit of information needed in a quick and efficient manner when a question comes up as to how that state affects
gameplay. And because of the "toolbox" methodology, adding and removing states becomes easy enough that there's no
reason for a DM to have to manage more than what pertains to this session! A state no longer needed? Delete it!
A new state being used? Add it! It only takes seconds to manage the toolbox.
Don't know what needs tracked and what doesn't? That's easy enough as well. All of the work into determining what does
and doesn't set effects has already been done. Not sure if "Fireball" sets an effect on a token? Go into the toolbox and
try to add it. If it shows as either providing a beneficial or determental effect, it can be added to the toolbox!
When you go to apply an effect to a token, the effects are helpfully color coded (Green = Good, Red = Bad!) so that a DM
need not know what the effect being applied is, the color coding tells the DM who to apply it to (an Enemy NPC or a
friendly PC).
Finally, everything is driven by an easily modified table in MapTool. Everything is stored in JSON Format which can be
easily modified by any DM. Did I miss something? Have a homebrew ability or spell that isn't in the Spells table? Is
a spell listed as Determental when it should be listed as Beneficial? Fixing it is as easy as modifying a piece of data
in a JSON object (which is MUCH easier than it sounds since JSON is just a fancy text format).
The system is ultimately extendable to any tabletop RPG that sets and removes effects on a token because it has been
designed to be generic. Replace the 5e version of the "Spells" table with a Pathfinder 2e version of that table and the
system is now tuned for Pathfinder. Not playing D&D or D20? Modify the table for your game's spells and abilities and
it should STILL work.
Support Expectations:
============================
I've run a widely available open source project in my past lifetime and the one thing I learned from that
project was that support can be a full time job. I have a full time job and really can't afford to make Illydth's
Spell States my next one. While I am as dedicated as any creator with regards to his or her creations, I also have
limited time available to me.
I will try to answer questions regarding the tool, installation, or anything else related to this. I'm more than
happy to take suggestions and constructive feedback on how to make the tool better. Contributions back to the project
(such as bug fixes, WORKING code samples doing things in a better way, etc.) are more than appricated and will get you
a likely "Thank You" at the end of this document. I maintain a "backlog" list of changes and suggestions that I find
useful and want to implement in the future, however I make no guarantees that your suggestion will reach that backlog.
I also do not guarantee anything in the backlog will ever make it into the tool, nor the timing by which that will
happen. Any requests for "any idea how long it'll be before..." will likely be answered with "whenever it happens, if
it happens". I'm not trying to be the south bound end of a north bound horse, it's just that I have a life and don't
plan to make this project too significant a part of it.
Also, I maintain creative control over this code. If you do not like how something is done or have problems with the
way it's being done, or if you feel you need something changed that I'm just not doing, you are MORE than welcome to
take this code and modify it to your needs. I'm happy to (as opportunity provides) answer questions on how I did
something so you can modify it. The only thing I'd ask is if you do use this code as a starter for your own project
to please let me know, and to provide an acknowledgement to that fact.
All this said, this entire set of functionality is being provided "as is" in the hopes that it helps DMs better run
their campaigns through MapTool. While I do not take responsibility for any destroyed campaigns, or other problems
caused by my code, this system was first, and foremost, designed for MY use in MY own personal campains. I assure
everyone I am using my own system, so if you've discovered something that broke your campaign, you can probably take
comfort in the fact that I likely destroyed my own right beside yours.
Despite how the above might read, I am a colaborative person. Don't hesitate to reach out with questions or comments,
just don't be offended if I don't immediately respond. I'd prefer an "@" on the MapTool discord or a resposne to a
thread on the MapTool forums to a Direct Message (on either platform) simply because I use both tools for things other
than answering questions.
Acknowledgements:
======================
No significant development effort is done "in a silo" and this effort was on the backs of giants larger than myself.
Melek: First, and foremost, I want to thank "Melek" for the Simple5e Framework and continued support through this
project. From questions, ideas, brainstorming sessions, and many "how the hell does this work?!?!?!" frustrations a plenty
Melek has been exceptionally kind and patient with me as I've delved into this project.
rogue_ronin: Secondly, I need to throw a HUGE thank you out to rogue_ronin who's icons are at the very heart of this
states system. With nothing more than a simple request rogue spent a significant amount of time and effort to build a
set of icons that became a bit of the centerpiece of this project. I do not have these skills and without these, this
project wouldn't be what it is. I'd also like to thank rogue for NOT tracking me down with a pitchfork and torch, even
after the third "hey, could you re-make this icon for me in this minorly changed way?" request I made. :)
KellyENDER: Next, a big thanks to KellyENDER for development of the original spells table, reducing my once unheard of
hours of mind numbing work trying to get all the 5e Spells into a proper format to 20 seconds of "Import table", and
then going farther to teach a guy to fish by showing me how to create my own copy of that thing in like 5 minutes. Also
a significant portion of the initial development on "Spell Info" was done by KellyENDER which was also a great starting
point for the functionality in this project.
Jason_c_o: Also a shout out to Jason_c_o who did some great work with the layout of Spell Info and the underlying HTML
on the 5e data table itself.
And, finally, a shout out to all of those on the MapTool Discord Server, especially Wolph42, aliasmask, Phergus, Reverend,
and rogue_ronin, for your continued answering of my often silly questions about how Maptool works and how to get effect X
out of the uber powerful, fairly well documented, and yet fiddly macro language.