Skip to content

Commit

Permalink
Merge pull request #30 from SoxMax/starfinder-container-ammo
Browse files Browse the repository at this point in the history
Update starfinder ammo reloading
  • Loading branch information
bmos committed Nov 9, 2022
2 parents 7c8aaa4 + 0ada849 commit 331cb6b
Show file tree
Hide file tree
Showing 7 changed files with 288 additions and 78 deletions.
111 changes: 111 additions & 0 deletions campaign/scripts/sfrpg_char_reload.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
--
-- Please see the LICENSE.md file included with this distribution for attribution and copyright information.
--

local function parseWeaponCapacity(capacity)
capacity = capacity:lower()
if capacity == 'drawn' then
return 0, capacity
end
local splitCapacity = StringManager.splitWords(capacity)
return tonumber(splitCapacity[1]), splitCapacity[2]
end

local function getContainedItems(nodeContainer)
local containerName = ItemManager.getSortName(nodeContainer)
local containedItems = {}
if containerName ~= '' then
for _, nodeItem in pairs(nodeContainer.getParent().getChildren()) do
if DB.getValue(nodeItem, 'carried', 0) ~= 0 then
local itemContainerName = StringManager.trim(DB.getValue(nodeItem, 'location', '')):lower()
if itemContainerName == containerName then
table.insert(containedItems, nodeItem)
end
end
end
end
return containedItems
end

local function loadCartridges(weaponActionNode, newAmmoNode, loadedAmmoNode)
local weaponInventoryNode = AmmunitionManager.getShortcutNode(weaponActionNode, 'shortcut')
local maxAmmo, _ = parseWeaponCapacity(DB.getValue(weaponInventoryNode, 'capacity', ''))
local currentAmmoCount = 0
if loadedAmmoNode then
currentAmmoCount = DB.getValue(loadedAmmoNode, 'count', 0)
else
loadedAmmoNode = newAmmoNode.getParent().createChild()
loadedAmmoNode = DB.copyNode(newAmmoNode, loadedAmmoNode)
DB.setValue(loadedAmmoNode, 'location', 'string', ItemManager.getDisplayName(weaponInventoryNode, true))
end
local newAmmoCount = DB.getValue(newAmmoNode, 'count', 0)
local ammoNeeded = maxAmmo - currentAmmoCount
if ammoNeeded > newAmmoCount then
ammoNeeded = newAmmoCount
end
DB.setValue(loadedAmmoNode, 'count', 'number', currentAmmoCount + ammoNeeded)
DB.setValue(newAmmoNode, 'count', 'number', newAmmoCount - ammoNeeded)
return loadedAmmoNode
end

local function isSameAmmo(ammo1, ammo2)
return ammo1 and ammo2 and ItemManager.compareFields(ammo1, ammo2, true)
end

local function unloadAmmunition(loadedAmmoNode)
if loadedAmmoNode then
DB.setValue(loadedAmmoNode, 'location', 'string', '')
end
end

local function moveInventoryAmmunition(weaponActionNode, newAmmoNode)
local weaponInventoryNode = AmmunitionManager.getShortcutNode(weaponActionNode, 'shortcut')
local loadedAmmoNode = getContainedItems(weaponInventoryNode)[1]
if not newAmmoNode then -- no new ammo, unload old
unloadAmmunition(loadedAmmoNode)
return newAmmoNode
end

local _, ammoType = parseWeaponCapacity(DB.getValue(weaponInventoryNode, 'capacity', ''))
if ammoType == 'drawn' then
return newAmmoNode
end

if ammoType == 'charges' then
if loadedAmmoNode then
DB.setValue(loadedAmmoNode, 'location', 'string', '')
end
DB.setValue(newAmmoNode, 'location', 'string', ItemManager.getDisplayName(weaponInventoryNode, true))
return newAmmoNode
end
if isSameAmmo(loadedAmmoNode, newAmmoNode) then
return loadCartridges(weaponActionNode, newAmmoNode, loadedAmmoNode)
else
unloadAmmunition(loadedAmmoNode)
return loadCartridges(weaponActionNode, newAmmoNode)
end
end

-- luacheck: globals loadAmmo
function loadAmmo(ammoItem)
local nodeWeaponAction = getDatabaseNode()
if ammoItem then
local nodeAmmoItem = ammoItem.getDatabaseNode()
local loadedAmmo = moveInventoryAmmunition(nodeWeaponAction, nodeAmmoItem)
DB.setValue(nodeWeaponAction, 'ammopicker', 'string', ItemManager.getDisplayName(nodeAmmoItem, true))
DB.setValue(nodeWeaponAction, 'ammoshortcut', 'windowreference', 'item', '....inventorylist.' .. loadedAmmo.getName())
local rActor = CharManager.getWeaponAttackRollStructures(nodeWeaponAction)
local messagedata = {
text = Interface.getString('char_message_reloadammo'),
sender = rActor.sName,
font = 'emotefont'
}
Comm.deliverChatMessage(messagedata)
else
moveInventoryAmmunition(nodeWeaponAction)
DB.setValue(nodeWeaponAction, 'ammopicker', 'string', '')
DB.setValue(nodeWeaponAction, 'ammoshortcut', 'windowreference', 'item', '')
end

parentcontrol.window.close()
end
26 changes: 23 additions & 3 deletions campaign/scripts/sfrpg_char_weapon.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,24 @@ function onDataChanged()
local bLinkedAmmoEnabled = (DB.getValue(nodeWeapon, 'ammopicker_enabled', 1) == 1)
local _, bInfiniteAmmo = AmmunitionManager.getAmmoRemaining(rActor, nodeWeapon, nodeAmmoLink)
local bDrawnCapacity = (DB.getValue(nodeWeaponSource, 'capacity', ''):lower() == 'drawn')
local sSpecial = DB.getValue(nodeWeapon, 'special', ''):lower()
local bThrownAttack = (string.find(sSpecial, 'thrown') and bRanged)

label_range.setVisible(bRanged)
rangeincrement.setVisible(bRanged)
-- isloaded.setVisible(bRanged and hasLoadAction(nodeWeapon));
label_ammo.setVisible(bRanged)
uses.setVisible(bRanged and not bLinkedAmmoEnabled)
current_ammo.setVisible(bRanged and bLinkedAmmoEnabled)
ammocounter.setVisible(bRanged and not bInfiniteAmmo and not bDrawnCapacity)
ammocounter.setVisible(bRanged and not bInfiniteAmmo and not (bDrawnCapacity or bThrownAttack and bLinkedAmmoEnabled))


local sSpecial = DB.getValue(nodeWeapon, 'special', ''):lower()
local bNoFull = false
if string.find(sSpecial, 'unwieldy') then
bNoFull = true
elseif string.find(sSpecial, 'explode') then
bNoFull = true
elseif string.find(sSpecial, 'thrown') and bRanged then
elseif bThrownAttack then
bNoFull = true
end

Expand Down Expand Up @@ -168,3 +170,21 @@ function generateAttackRolls(rActor, nodeWeapon, rAttack, nAttacksCount)
end
return rRolls, bAttack
end

-- luacheck: globals isThrownAttack
function isThrownAttack()
local sSpecial = DB.getValue(getDatabaseNode(), 'special', ''):lower()
local bRanged = (type.getValue() == 1)
return (string.find(sSpecial, 'thrown') and bRanged)
end

-- luacheck: globals onInit
function onInit()
if isThrownAttack() then
local attackNode = getDatabaseNode()
local itemNode = AmmunitionManager.getShortcutNode(attackNode, 'shortcut')
if itemNode then
DB.setValue(attackNode, "ammoshortcut", "windowreference", "item", "....inventorylist." .. itemNode.getName())
end
end
end
15 changes: 0 additions & 15 deletions campaign/scripts/sfrpg_current_ammo.lua

This file was deleted.

21 changes: 21 additions & 0 deletions campaign/scripts/sfrpg_inventorylist.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--
-- Please see the LICENSE.md file included with this distribution for
-- attribution and copyright information.
--
-- luacheck: globals onLocationChanged onInit onClose

local function onLocationChanged()
self.updateContainers()
end

function onInit()
if super and super.onInit then super.onInit() end

DB.addHandler(DB.getPath(getDatabaseNode(), "*.location"), "onUpdate", onLocationChanged)
end

function onClose()
if super and super.onClose then super.onClose() end

DB.removeHandler(DB.getPath(getDatabaseNode(), "*.location"), "onUpdate", onLocationChanged)
end
Loading

0 comments on commit 331cb6b

Please sign in to comment.