Repository navigation
feat(SmartAoE): Enhances 2024 sheet support and updates help - #2359
Open
steverobertsuk wants to merge 18 commits into
Open
steverobertsuk wants to merge 18 commits into
steverobertsuk wants to merge 18 commits into
Conversation
Version 1.0.0 has been merged into the Roll20 repository, so the follow-up fixes for D&D 2024 (Beacon) sheets go into a new patch release. - Set the script, header and script.json to 1.0.1, and add 1.0.0 to previousversions. - Describe 1.0.1 in the script.json description. - Add the 1.0.1/ snapshot, matching the root script. - Add the 1.0.1 changelog section and expect v1.0.1 in TESTING.md. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
A 2024 (Beacon) character can carry legacy attribute objects with the same names as its sheet values, for example after a 2014 character is moved to the 2024 sheet or when another mod creates them. SmartAoE used such an attribute even when it was empty, so an empty npc_immunities hid the sheet's "Fire" and a Fire Giant took full fire damage, although a chat roll showed the immunity (forum report). An empty legacy attribute is now skipped and the sheet's value is read instead. This applies to --resistAttr, --vulnerableAttr, --immunityAttr, --ignore and --resource. A legacy attribute with a value is still used, so 2014-sheet games behave as before. Documented in the README's 2024 sheet section, with a TESTING.md step that adds an empty npc_immunities to the Fire Giant. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
On the 2024 sheet, lvlN_slots_expended holds the slots used, but without a limit --resource counted it down. With no slots used it always said there weren't enough, and casting after using a slot took the count back to 0 (forum report). When the resource is a 2024-sheet lvlN_slots_expended and no limit is given, SmartAoE now uses lvlN_slots_total as the limit, so existing macros such as --resource|lvl3_slots_expended work unchanged. An explicit limit still takes precedence. 2014 sheets, where the attribute is a legacy object holding the slots left, still count down. The help handout, README and TESTING.md describe the default. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Running !smarttrigger before the control token had been moved stopped with "Cannot read properties of undefined (reading 'x')", because the AoE has no squares or bounding box until the control token moves. Such an AoE is now skipped with a whisper asking the GM to move the control token first. Found while testing the forum report in a live game; TESTING.md has a matching step. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
The tip still said the 5eSTR to 5eCHA shortcuts only work on the 2014 sheet and that the 2024 sheet needs a custom --saveFormula and --dc. That stopped being true when 1.0.0 learned to read Beacon sheets. The tip now says to use the Mod Script Sandbox v1.5, that saves, damage-type attributes, --ignore and --resource read the 2024 sheet, that spell slots count up to the slot total, and that Magic Resistance is only detected on 2014 sheets. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
DMs asked whether SmartAoE follows the 2014 or the 2024 D&D rule for which squares an area hits. It follows neither by default: --minGridArea and --minTokArea decide it, and they default to almost any overlap. Add a "Grid rules by game system" section to the README and the help handout. It gives the settings that match: - D&D 5e 2024 (half a square); - D&D 5e 2014 (DMG and Xanathar's template method); - Pathfinder 1e, D&D 3.5 and Starfinder 1e (far-edge rule); - Pathfinder 2e and Starfinder 2e; - systems where any touch counts or only a square's centre counts. The section also notes that the drawn squares are the ruling, and that a creature in a counted square is hit however small its token, which was checked with a Tiny token in a live game. The README's feature list and Pathfinder tip link to the new section, and TESTING.md lists it among the handout's sections. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Inline code in the help handout was only set in a monospace font, so settings such as --minGridArea|0.5 were hard to tell apart from the text around them. - Inline code now has a light tint, a thin outline and rounded corners. The semi-transparent colours read in both Roll20 light and dark mode. - The grid rules settings and the tips mark their code with backticks. A new handoutText helper shows those parts as code chips that don't wrap, so a parameter such as --forceIntersection|1 no longer breaks after its "--". Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Magic Resistance was only detected on 2014 sheets. SmartAoE searches each attribute's text for "magic resist", but a 2024 (Beacon) sheet keeps its features in a single "store" attribute that holds an object, and that object's text is "[object Object]". A Yuan-ti on the 2024 sheet therefore rolled its saves once. - A new hasBeaconMagicResistance helper looks through the store's features for an enabled one whose name includes "Magic Resistance". The save is then rolled twice and shown as A, as on the 2014 sheet. - Only feature names are checked. The store also holds item and spell text, and a whole-store search matched a 2024 shop character that only sells items mentioning magic resistance. - The 2014 check is unchanged. Tested in a live game: a 2024 Yuan-ti Infiltrator rolled two saves and kept the higher; creatures without the trait rolled once. The README, the help handout's 2024 tip, the changelog, script.json and TESTING.md no longer say Magic Resistance is 2014-only. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
The damage-type check is a plain text search of the target's resistance, vulnerability and immunity attributes. A 2014 stat block's "bludgeoning, piercing, and slashing from nonmagical attacks" (a Gargoyle, many devils and lycanthropes) contains "bludgeoning", so a bludgeoning AoE was halved or cancelled even though AoEs are magical. A new removeNonmagicalDamage helper drops these groups from each value before the check, in both the "... from nonmagical attacks" and the "nonmagical bludgeoning, ..." wordings, up to the next semicolon. Other damage types on the same line still apply, so "cold; bludgeoning, ... from nonmagical attacks" still resists cold. AoEs count as magical, which SmartAoE already assumes for Magic Resistance. 2024 stat blocks no longer have nonmagical resistances, so only 2014 creatures were affected. Tested in a live game with a temporary resistance attribute: bludgeoning was no longer resisted, cold still was, and the existing resistances, vulnerabilities and immunities were unchanged. The README's --resistAttr row, the changelog, script.json and TESTING.md describe the change. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
The previous commit made SmartAoE ignore damage types that are only resisted from nonmagical attacks, and the README's --resistAttr row explains this. The help handout's row still only said "attributes listing the target's defences", so a GM reading the handout wouldn't know why a Gargoyle's bludgeoning resistance no longer applies. The handout's --resistAttr / --vulnerableAttr / --immunityAttr row now says that AoEs count as magical, so those damage types are ignored. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Version 1.0.1 is still in its pull request, so stopping AoEs at walls goes into a new patch release in the same pull request. - Set the script, header and script.json to 1.0.2, and add 1.0.1 to previousversions; the 1.0.1/ snapshot is left as it was. - Add the 1.0.2/ snapshot, matching the root script. - Add the 1.0.2 changelog section and expect v1.0.2 in TESTING.md. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
A fireball hit tokens in the next room just because they were inside its radius. With --blockedBy|walls, the squares of an AoE that no straight line from the point of origin can reach past a dynamic lighting wall (pathv2 or path on the walls layer), or a closed door or window, are left out, as the D&D 5e rules say. The square's centre and four points near its corners are tried, so a square seen through a doorway still counts, and open doors and windows let the AoE through. --blockedBy|walls, spread also lets the AoE flow round corners from square to square, as far as its reach, as the 2014 Fireball does. The squares are cut when the AoE is drawn, so the template on the map shows what will be hit and triggering needs no change. An origin on the caster's edge is measured from just inside the caster, so a caster standing against a wall is not blocked by it. AoEs without --blockedBy are unchanged. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Describe --blockedBy in the README's features, parameters, examples and tips (walls are checked when the AoE is drawn, so nudge the control token after opening a door), and add a Walls section to the testing checklist for Jumpgate and Legacy games. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Version 1.0.2 is still unreleased in the same pull request, so the fix for a crash reported on Discord goes into a new patch release. - Set the script, header and script.json to 1.0.3, and add 1.0.2 to previousversions; the 1.0.2/ snapshot is left as it was. - Add the 1.0.3/ snapshot, matching the root script. - Add the 1.0.3 changelog section and expect v1.0.3 in TESTING.md. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…shing
SelectManager's !forselected sends the command on with sendChat, but the
new message has none of the original's inline rolls. A roll such as
--damageFormula1|[[(5+?{Cast at what level?})d6]] reached SmartAoE as
$[[0]] with no result, and parseArgs stopped with "Cannot read
properties of undefined (reading 'total')".
- substituteInlineRolls now whispers which roll has no result and
suggests <<...>>, which SmartAoE rolls itself.
- The brackets in that whisper are sent as entities. A literal
[[formula]] in sendChat text is rolled by Roll20, and the dice error
crashed the whole sandbox during live testing.
- An argument with no |value, such as a bare --instant, is read as empty
instead of stopping with "reading 'match'".
- Add Node tests (node:test, no dependencies) and the !forselected
steps to TESTING.md. The new Playwright cases passed live with
SelectManager.
Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
Users who run SmartAoE through SelectManager's !forselected need to know why a [[...]] roll fails and what to write instead. - Add a tip to the README and the help handout: write rolls in a !forselected command as <<...>>, which SmartAoE rolls itself. - Note the tip in the 1.0.3 changelog and describe 1.0.3 in script.json. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
The Help & Reference handout now use the plain SmartAoE icon from Roll20's file store as their journal icon (the handout avatar). The icon is set when a handout is created and added to handouts from earlier versions, so existing games get it too. Roll20 stores the avatar as max.webp with a number, so a handout counts as having the icon when its avatar contains the image's path. Only the webp files exist (thumb.png is a 404), so the URL uses thumb.webp. The root script and the 1.0.3 snapshot stay identical. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
…dout Roll20 always stores a handout's journal icon as the full-size file, whatever size the Mod asks for, and shows that file at its natural size at the top of an open handout. The SmartAoE icon was a 1024 pixel upload, so it filled the handout above the text. The icon now points at a 100 pixel copy of the same artwork. Handouts from earlier builds are matched on the image path, so they change to the small icon the next time the Mod starts. The 1.0.3 copy is updated with the script. The version number is unchanged. Signed-off-by: Steve Roberts <steve@shadowcomputers.co.uk>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
[1.0.3] – 2026-11-02
A crash fix from user feedback. There are no breaking changes.
Changed
!forselecteddrops inline rolls, so rolls in a!forselectedcommand should be written as<<…>>.Fixed
!forselectedsends the command on withsendChatbut without the original message's inline rolls, so a roll such as--damageFormula1|[[(5+?{Cast at what level?})d6]]reached SmartAoE as$[[0]]with no result, and SmartAoE stopped with "Cannot read properties of undefined (reading 'total')". SmartAoE now whispers which roll has no result and suggests<<…>>, which SmartAoE rolls itself.|value, such as a bare--instant, no longer stops with "Cannot read properties of undefined (reading 'match')". It is read as an empty value.[1.0.2] – 2026-10-31
AoEs can stop at walls, from user feedback. There are no breaking changes.
Added
--blockedBy|wallsstops an AoE at dynamic lighting walls (Jumpgatepathv2and Legacypathdrawings on the walls layer) and at closed doors and windows, so a fireball no longer reaches tokens in the next room just because they are inside its radius. A square is left out when no straight line from the point of origin reaches it past a wall, as the D&D 5e rules say; its centre and four points near its corners are tried, so a square seen through a doorway still counts. Open doors and windows let the AoE through. An origin on the caster's edge is measured from just inside the caster, so a caster standing against a wall is not blocked by it.--blockedBy|walls, spreadalso lets the AoE flow round corners from square to square, as the 2014 Fireball does, as far as its reach. Without--blockedBy, walls are ignored as before.[1.0.1] – 2026-10-28
Further D&D 2024 (Beacon) sheet fixes from the forum report. There are no breaking changes.
Added
--minGridArea,--minTokArea, shape and origin settings that match D&D 5e 2014 and 2024, Pathfinder 1e and 2e, Starfinder and other systems, with notes on how creature size affects hits (a Tiny creature in a counted square is hit).Changed
5eSTR…5eCHAshortcuts need a custom--saveFormulaon the 2024 sheet (they have worked there since 1.0.0); it now gives the Sandbox v1.5 and spell-slot notes.--resource|lvl3_slots_expended(any level) now counts the slots used up tolvl3_slots_totalwhen no limit is given. In 1.0.0 it counted down, so with no slots used it always said there weren't enough, and casting with one slot used took it back to 0. 2014 sheets, wherelvlN_slots_expendedholds the slots left, still count down.Fixed
npc_immunities(ornpc_resistances,npc_vulnerabilities,--ignoreor--resourceattribute) was used as the value, so a Fire Giant took full fire damage even though a chat roll showed "Fire". An empty legacy attribute is now skipped and the sheet's value used.!smarttriggerbefore the control token has moved no longer stops with "Cannot read properties of undefined (reading 'x')". The AoE has no squares yet, so SmartAoE whispers to move the control token first.storeobject, which SmartAoE read as "[object Object]". Only feature names are checked, so text elsewhere on the sheet, such as an item's description, doesn't count.