Skip to content

Commit 62b99bb

Browse files
author
Wil Thieme
authored
Merge pull request #10 from FG-Unofficial-Developers-Guild/test
v1.14 - change getChildren to getChildList and migrate to DB API
2 parents 6921497 + 4ad8980 commit 62b99bb

File tree

4 files changed

+122
-134
lines changed

4 files changed

+122
-134
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ For example: Wand of Cure Light Wounds [13 charges]
2020
Originally created by [rmilmine](https://www.fantasygrounds.com/forums/member.php?215591-rmilmine).
2121

2222
# Compatibility
23-
This extension has been tested with [FantasyGrounds Unity](https://www.fantasygrounds.com/home/FantasyGroundsUnity.php) 4.3.0 (2022-10-20).
23+
This extension has been tested with [FantasyGrounds Unity](https://www.fantasygrounds.com/home/FantasyGroundsUnity.php) 4.3.0 4.3.3 (2023-02-21).

extension.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<root version="3.3.9" release="1">
33
<properties>
44
<name>Feature: Advanced Item Actions</name>
5-
<version>1.13</version>
5+
<version>1.14</version>
66
<loadorder>60</loadorder>
77
<author>rmilmine and bmos</author>
88
<description>This extension takes consumables equipped in the inventory and adds them to the action tab.</description>
@@ -15,12 +15,12 @@
1515
<loadorder>25</loadorder>
1616
</properties>
1717

18-
<announcement text="https://www.fantasygrounds.com/forums/showthread.php?57819-Advanced-Character-Iventory-Manager-for-3-5E-and-Pathfinder\rAdvanced Item Actions v1.13\rThis extension takes consumables equipped in the inventory and adds them to the action tab." font="emotefont" />
18+
<announcement text="https://www.fantasygrounds.com/forums/showthread.php?57819-Advanced-Character-Iventory-Manager-for-3-5E-and-Pathfinder\rAdvanced Item Actions v1.14\rThis extension takes consumables equipped in the inventory and adds them to the action tab." font="emotefont" />
1919

2020
<base>
2121
<string name="option_label_AIA_unequip_on_rest">Party: Unequip Consumables on Rest</string>
2222
<!-- Initialization -->
2323
<script name="CharManagerACIM" file="scripts/manager_char_ACIM.lua" />
2424
<script name="InvManagerACIM" file="scripts/char_invlist_ACIM.lua" />
2525
</base>
26-
</root>
26+
</root>

scripts/char_invlist_ACIM.lua

Lines changed: 116 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,11 @@ local _sSpellset = 'spellset'
3434
local function usingExt(sExt) return StringManager.contains(Extension.getExtensions(), sExt) end
3535

3636
function getSpellSet(nodeChar, sItemSource)
37-
if nodeChar and sItemSource ~= '' then
38-
-- Debug.chat('getSpellSet', 'sItemSource', sItemSource);
39-
for _, nodeSpellSet in pairs(DB.getChildren(nodeChar, _sSpellset)) do
40-
-- Debug.chat(sItemSource, nodeSpellSet);
41-
if DB.getValue(nodeSpellSet, 'source_name') == sItemSource then return nodeSpellSet end
42-
end
37+
if not nodeChar or sItemSource == '' then return end
38+
-- Debug.chat('getSpellSet', 'sItemSource', sItemSource);
39+
for _, nodeSpellSet in ipairs(DB.getChildList(nodeChar, _sSpellset)) do
40+
-- Debug.chat(sItemSource, nodeSpellSet);
41+
if DB.getValue(nodeSpellSet, 'source_name') == sItemSource then return nodeSpellSet end
4342
end
4443
end
4544

@@ -92,73 +91,63 @@ local function trim_spell_name(string_spell_name)
9291
return string_spell_name
9392
end
9493

95-
local function getSpellFromItemName(sItemName)
96-
local tLoadedModules
97-
98-
local function getLoadedModules()
99-
tLoadedModules = {}
100-
local tAllModules = Module.getModules()
101-
for _, sModuleName in ipairs(tAllModules) do
102-
local tModuleData = Module.getModuleInfo(sModuleName)
103-
if tModuleData.loaded then tLoadedModules[tModuleData.name] = tModuleData.name end
94+
local function findSpellInModule(sModuleName, sSpellName)
95+
local nodeSpellModule = DB.findNode('reference.spells' .. '@' .. sModuleName)
96+
if not nodeSpellModule then return end
97+
for _, nodeSpell in ipairs(DB.getChildList(nodeSpellModule)) do
98+
local sModuleSpellName = DB.getValue(nodeSpell, 'name', '')
99+
if sModuleSpellName ~= '' then
100+
if trim_spell_name(sModuleSpellName) == sSpellName then return nodeSpell end
104101
end
105102
end
103+
end
106104

107-
local function findSpellNode(sSpellName)
108-
local nodeSpellFast = DB.findNode('spelldesc.' .. trim_spell_key(sSpellName) .. '@PFRPG - Spellbook Extended')
109-
or DB.findNode('spelldesc.' .. trim_spell_key(sSpellName) .. '@PFRPG - Spellbook')
110-
or DB.findNode('spelldesc.' .. trim_spell_key(sSpellName) .. '@*')
111-
if nodeSpellFast then return nodeSpellFast end
112-
113-
sSpellName = trim_spell_name(sSpellName)
114-
getLoadedModules()
115-
116-
local function findSpellInModule(sModuleName)
117-
local nodeSpellModule = DB.findNode('reference.spells' .. '@' .. sModuleName)
118-
if not nodeSpellModule then return end
119-
for _, nodeSpell in pairs(DB.getChildren(nodeSpellModule)) do
120-
local sModuleSpellName = DB.getValue(nodeSpell, 'name', '')
121-
if sModuleSpellName ~= '' then
122-
if trim_spell_name(sModuleSpellName) == sSpellName then return nodeSpell end
123-
end
124-
end
125-
end
126-
127-
local nodeSpell
128-
for _, sModuleName in ipairs(tLoadedModules) do
129-
nodeSpell = findSpellInModule(sModuleName)
130-
if nodeSpell then break end
131-
end
132-
return nodeSpell
105+
local function getLoadedModules(tLoadedModules)
106+
local tAllModules = Module.getModules()
107+
for _, sModuleName in ipairs(tAllModules) do
108+
local tModuleData = Module.getModuleInfo(sModuleName)
109+
if tModuleData.loaded then tLoadedModules[tModuleData.name] = tModuleData.name end
133110
end
111+
end
134112

135-
local function getSpellBetweenParentheses()
136-
local string_spell_name = sItemName:match('%b()')
137-
if string_spell_name then return string_spell_name:sub(2, -2) end
138-
end
113+
local function findSpellNode(sSpellName)
114+
local nodeSpellFast = DB.findNode('spelldesc.' .. trim_spell_key(sSpellName) .. '@PFRPG - Spellbook Extended')
115+
or DB.findNode('spelldesc.' .. trim_spell_key(sSpellName) .. '@PFRPG - Spellbook')
116+
or DB.findNode('spelldesc.' .. trim_spell_key(sSpellName) .. '@*')
117+
if nodeSpellFast then return nodeSpellFast end
139118

140-
local function getSpellAfterOf()
141-
sItemName = sItemName:gsub('%[.+%]', '')
142-
local _, j = sItemName:find('of ')
143-
if j then return sItemName:sub(j) end
144-
end
119+
local tLoadedModules = {}
120+
getLoadedModules(tLoadedModules)
145121

146-
if sItemName and sItemName ~= '' then
147-
local sSpellName = getSpellBetweenParentheses()
148-
if sSpellName then
149-
return findSpellNode(sSpellName)
150-
else
151-
return findSpellNode(getSpellAfterOf())
152-
end
122+
local nodeSpell
123+
for _, sModuleName in pairs(tLoadedModules) do
124+
nodeSpell = findSpellInModule(sModuleName, trim_spell_name(sSpellName))
125+
if nodeSpell then break end
153126
end
127+
return nodeSpell
128+
end
129+
130+
local function getSpellBetweenParentheses(sItemName)
131+
local string_spell_name = sItemName:match('%b()')
132+
if string_spell_name then return string_spell_name:sub(2, -2) end
133+
end
134+
135+
local function getSpellAfterOf(sItemName)
136+
sItemName = sItemName:gsub('%[.+%]', '')
137+
local _, j = sItemName:find('of ')
138+
if j then return sItemName:sub(j) end
139+
end
140+
141+
local function getSpellFromItemName(sItemName)
142+
if not sItemName or sItemName == '' then return end
143+
local sSpellName = getSpellBetweenParentheses(sItemName) or getSpellAfterOf(sItemName)
144+
if sSpellName then return findSpellNode(sSpellName) end
154145
end
155146

156147
local function onItemChanged(nodeField)
157148
local nodeChar = DB.getChild(nodeField, '....')
158-
if ActorManager.resolveActor(nodeChar) then
159-
local nodeItem = DB.getParent(nodeField)
160-
inventoryChanged(nodeChar, nodeItem, nodeField)
161-
end
149+
if not ActorManager.resolveActor(nodeChar) then return end
150+
inventoryChanged(nodeChar, DB.getParent(nodeField), nodeField)
162151
end
163152

164153
local function addSpell(nodeSource, nodeSpellClass, nLevel)
@@ -176,7 +165,7 @@ local function addSpell(nodeSource, nodeSpellClass, nLevel)
176165
-- Convert the description field from module data
177166
SpellManager.convertSpellDescToString(nodeNewSpell)
178167

179-
local sNodeParent = DB.getName(DB.getParent(nodeTargetLevelSpells))
168+
local sNodeParent = DB.getName(nodeTargetLevelSpells, '..')
180169
-- Set the default cost for points casters
181170
local nCost = tonumber(string.sub(sNodeParent, -1)) or 0
182171
if nCost > 0 then nCost = ((nCost - 1) * 2) + 1 end
@@ -284,11 +273,71 @@ local function getUsesAvailable(nodeItem, bWand)
284273
nUsesAvailable = 50
285274
end
286275
else
287-
nUsesAvailable = DB.getChild(nodeItem, 'count').getValue()
276+
nUsesAvailable = DB.getValue(nodeItem, 'count')
288277
end
289278
return nUsesAvailable
290279
end
291280

281+
local function addSpellset(nodeChar, nodeSpell, nodeItem, sItemName, nSpellLevel, nCL, nUsesAvailable)
282+
if not nodeChar or not nodeSpell or sItemName == '' or DB.getPath(nodeItem) == '' or nSpellLevel < 0 or nSpellLevel > 9 then return end
283+
local nodeNewSpellClass = DB.createChild(DB.createChild(nodeChar, _sSpellset))
284+
if nodeNewSpellClass then
285+
DB.setValue(nodeNewSpellClass, 'label', 'string', sItemName)
286+
DB.setValue(nodeNewSpellClass, 'castertype', 'string', 'spontaneous')
287+
DB.setValue(nodeNewSpellClass, 'availablelevel' .. nSpellLevel, 'number', nUsesAvailable)
288+
DB.setValue(nodeNewSpellClass, 'source_name', 'string', DB.getPath(nodeItem))
289+
DB.setValue(nodeNewSpellClass, 'cl', 'number', nCL)
290+
DB.setValue(nodeChar, 'spellmode', 'string', 'standard')
291+
local nodeNew = addSpell(nodeSpell, nodeNewSpellClass, nSpellLevel)
292+
if nodeNew then
293+
for _, nodeAction in ipairs(DB.getChildList(nodeNew, 'actions')) do
294+
if DB.getValue(nodeAction, 'type', '') == 'cast' then DB.setValue(nodeAction, 'usereset', 'string', 'consumable') end
295+
end
296+
end
297+
end
298+
end
299+
300+
local function getSpellLevel(nodeSpell)
301+
if not nodeSpell then return 0 end
302+
local nSpellLevel = 0
303+
local sSpellLevelField = DB.getValue(nodeSpell, 'level', '')
304+
local nLowestCasterLevel = 0
305+
if sSpellLevelField == '' then return nSpellLevel, nLowestCasterLevel end
306+
307+
local aSpellClassChoices = StringManager.split(sSpellLevelField, ',')
308+
for _, sSpellClassChoice in ipairs(aSpellClassChoices) do
309+
local sComboClassName, sSpellClassLevel = sSpellClassChoice:match('(.*) (%d)')
310+
if sComboClassName then
311+
for _, sClassChoice in ipairs(StringManager.split(sComboClassName, '/', true)) do
312+
local nCasterLevel = getCasterLevelByClass(sClassChoice, sSpellClassLevel)
313+
if nCasterLevel ~= nil and (nLowestCasterLevel == 0 or nCasterLevel < nLowestCasterLevel) then
314+
nLowestCasterLevel = nCasterLevel
315+
nSpellLevel = tonumber(sSpellClassLevel)
316+
end
317+
end
318+
end
319+
end
320+
return nSpellLevel, nLowestCasterLevel
321+
end
322+
local function updateUsesRemaining(nodeTrigger, nodeItem, nodeSpellSet, nSpellLevel, bWand)
323+
local function writeUses(fieldName)
324+
-- don't update a field that triggered this code to be run
325+
if not (nodeTrigger and DB.getPath(nodeTrigger):match('.+%.inventorylist%..+%.' .. fieldName)) then
326+
DB.removeHandler('charsheet.*.inventorylist.*.' .. fieldName, 'onUpdate', onItemChanged)
327+
local nodeSpellLevel = DB.getChild(nodeSpellSet, 'levels.level' .. nSpellLevel)
328+
local nUsesRemaining = DB.getValue(nodeSpellSet, 'availablelevel' .. nSpellLevel, 0) - DB.getValue(nodeSpellLevel, 'totalcast', 0)
329+
DB.setValue(nodeItem, fieldName, 'number', nUsesRemaining)
330+
DB.addHandler('charsheet.*.inventorylist.*.' .. fieldName, 'onUpdate', onItemChanged)
331+
end
332+
end
333+
334+
if bWand then
335+
writeUses('charge')
336+
else
337+
writeUses('count')
338+
end
339+
end
340+
292341
function inventoryChanged(nodeChar, nodeItem, nodeTrigger)
293342
if not (nodeChar and nodeItem) then return end
294343

@@ -304,36 +353,12 @@ function inventoryChanged(nodeChar, nodeItem, nodeTrigger)
304353

305354
local nUsesAvailable = getUsesAvailable(nodeItem, bWand)
306355

307-
local sItemName = DB.getChild(nodeItem, 'name').getValue()
356+
local sItemName = DB.getValue(nodeItem, 'name')
308357

309358
local nodeSpell = getSpellFromItemName(sItemName)
310359
if not nodeSpell then return end
311360

312-
local function getSpellLevel()
313-
if not nodeSpell then return 0 end
314-
local nSpellLevel = 0
315-
local sSpellLevelField = DB.getValue(nodeSpell, 'level', '')
316-
local nLowestCasterLevel = 0
317-
if sSpellLevelField ~= '' then
318-
local aSpellClassChoices = StringManager.split(sSpellLevelField, ',')
319-
for _, sSpellClassChoice in ipairs(aSpellClassChoices) do
320-
local sComboClassName, sSpellClassLevel = sSpellClassChoice:match('(.*) (%d)')
321-
if sComboClassName then
322-
local aClassChoices = StringManager.split(sComboClassName, '/', true)
323-
for _, sClassChoice in ipairs(aClassChoices) do
324-
local nCasterLevel = getCasterLevelByClass(sClassChoice, sSpellClassLevel)
325-
if nCasterLevel ~= nil and (nLowestCasterLevel == 0 or nCasterLevel < nLowestCasterLevel) then
326-
nLowestCasterLevel = nCasterLevel
327-
nSpellLevel = tonumber(sSpellClassLevel)
328-
end
329-
end
330-
end
331-
end
332-
end
333-
return nSpellLevel, nLowestCasterLevel
334-
end
335-
336-
local nSpellLevel, nMinCasterLevel = getSpellLevel()
361+
local nSpellLevel, nMinCasterLevel = getSpellLevel(nodeSpell)
337362

338363
local function getCL()
339364
if not nodeItem then return 0 end
@@ -357,25 +382,7 @@ function inventoryChanged(nodeChar, nodeItem, nodeTrigger)
357382

358383
local nodeSpellSet = getSpellSet(nodeChar, DB.getPath(nodeItem))
359384
if nodeSpellSet then
360-
local function updateUsesRemaining()
361-
local function writeUses(fieldName)
362-
-- don't update a field that triggered this code to be run
363-
if not (nodeTrigger and DB.getPath(nodeTrigger):match('.+%.inventorylist%..+%.' .. fieldName)) then
364-
DB.removeHandler('charsheet.*.inventorylist.*.' .. fieldName, 'onUpdate', onItemChanged)
365-
local nodeSpellLevel = DB.getChild(nodeSpellSet, 'levels.level' .. nSpellLevel)
366-
local nUsesRemaining = DB.getValue(nodeSpellSet, 'availablelevel' .. nSpellLevel, 0) - DB.getValue(nodeSpellLevel, 'totalcast', 0)
367-
DB.setValue(nodeItem, fieldName, 'number', nUsesRemaining)
368-
DB.addHandler('charsheet.*.inventorylist.*.' .. fieldName, 'onUpdate', onItemChanged)
369-
end
370-
end
371-
372-
if bWand then
373-
writeUses('charge')
374-
else
375-
writeUses('count')
376-
end
377-
end
378-
updateUsesRemaining()
385+
updateUsesRemaining(nodeTrigger, nodeItem, nodeSpellSet, nSpellLevel, bWand)
379386

380387
if nCarried ~= 2 then
381388
local function removeSpellClass()
@@ -395,26 +402,7 @@ function inventoryChanged(nodeChar, nodeItem, nodeTrigger)
395402
bAdvancedItem = true
396403
end
397404
elseif nCarried == 2 then
398-
local function addSpellset()
399-
if not nodeChar or not nodeSpell or sItemName == '' or DB.getPath(nodeItem) == '' or nSpellLevel < 0 or nSpellLevel > 9 then return end
400-
local nodeNewSpellClass = DB.createChild(DB.createChild(nodeChar, _sSpellset))
401-
if nodeNewSpellClass then
402-
DB.setValue(nodeNewSpellClass, 'label', 'string', sItemName)
403-
DB.setValue(nodeNewSpellClass, 'castertype', 'string', 'spontaneous')
404-
DB.setValue(nodeNewSpellClass, 'availablelevel' .. nSpellLevel, 'number', nUsesAvailable)
405-
DB.setValue(nodeNewSpellClass, 'source_name', 'string', DB.getPath(nodeItem))
406-
DB.setValue(nodeNewSpellClass, 'cl', 'number', nCL)
407-
DB.setValue(nodeChar, 'spellmode', 'string', 'standard')
408-
local nodeNew = addSpell(nodeSpell, nodeNewSpellClass, nSpellLevel)
409-
if nodeNew then
410-
for _, nodeAction in pairs(DB.getChildren(nodeNew, 'actions')) do
411-
if DB.getValue(nodeAction, 'type', '') == 'cast' then DB.setValue(nodeAction, 'usereset', 'string', 'consumable') end
412-
end
413-
end
414-
end
415-
end
416-
417-
addSpellset()
405+
addSpellset(nodeChar, nodeSpell, nodeItem, sItemName, nSpellLevel, nCL, nUsesAvailable)
418406
end
419407
return bAdvancedItem
420408
end

scripts/manager_char_ACIM.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ end
2828
-- runs provided function on each nodeWeapon matching the provided nodeItem
2929
local function addEnergyDamage(nodeItem)
3030
local sPath = DB.getPath(nodeItem)
31-
for _, vWeapon in pairs(DB.getChildren(DB.getChild(nodeItem, '...'), 'weaponlist')) do
31+
for _, vWeapon in ipairs(DB.getChildList(nodeItem, '...weaponlist')) do
3232
local _, sRecord = DB.getValue(vWeapon, 'shortcut', '', '')
3333
if sRecord == sPath then
3434
local nodeDmgList = DB.createChild(vWeapon, 'damagelist')
@@ -90,7 +90,7 @@ end
9090
local resetSpells_old
9191
local function resetSpells_new(nodeCaster, ...)
9292
if ActorManager.isPC(nodeCaster) then
93-
for _, nodeItem in pairs(DB.getChildren(nodeCaster, 'inventorylist')) do
93+
for _, nodeItem in ipairs(DB.getChildList(nodeCaster, 'inventorylist')) do
9494
if InvManagerACIM.inventoryChanged(nodeCaster, nodeItem) then
9595
local nCarried = DB.getValue(nodeItem, 'carried', 1)
9696
DB.setValue(nodeItem, 'carried', 'number', 1)

0 commit comments

Comments
 (0)