Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update starfinder ammo reloading #30

Merged
merged 23 commits into from Nov 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
111 changes: 111 additions & 0 deletions campaign/scripts/sfrpg_char_reload.lua
@@ -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
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
@@ -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