222 lines
6.3 KiB
Lua
222 lines
6.3 KiB
Lua
local OFHotBrassPatch = {
|
|
patched = false,
|
|
}
|
|
|
|
local AMMO_TYPE_ALIAS_BY_ITEM = {
|
|
["Base.9x39Bullets"] = "9x39",
|
|
["Base.Bullets22LR"] = "22LR",
|
|
["Base.Bullets50Magnum"] = "50AE",
|
|
["Base.762x54rBullets"] = "762x54R",
|
|
["Base.792x57Bullets"] = "792x57Maus",
|
|
-- Common spelling variants seen in third-party weapon scripts.
|
|
["Base.308Bulets"] = "308Win",
|
|
["Base.762x54rBulets"] = "762x54R",
|
|
}
|
|
|
|
local function isPatchToggleEnabled()
|
|
local vars = SandboxVars and SandboxVars.OpinionatedFirearms
|
|
if vars and vars.HandleHotBrassCasingSpawnUseAmmoMaker ~= nil then
|
|
return vars.HandleHotBrassCasingSpawnUseAmmoMaker == true
|
|
end
|
|
|
|
-- Backward compatibility for existing worlds.
|
|
if vars and vars.HBVCEFAmmoMakerPatch ~= nil then
|
|
return vars.HBVCEFAmmoMakerPatch == true
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
local function isSessionEligible()
|
|
return isPatchToggleEnabled()
|
|
end
|
|
|
|
local function getAmmoMakerFiredFromAmmoDataKey(ammoDataKey)
|
|
if type(ammoDataKey) ~= "string" or ammoDataKey == "" then
|
|
return nil
|
|
end
|
|
|
|
if type(ammoMakerAmmoData) ~= "table" or type(ammoMakerAmmoParts) ~= "table" then
|
|
return nil
|
|
end
|
|
|
|
local ammoData = ammoMakerAmmoData[ammoDataKey]
|
|
if type(ammoData) ~= "table" then
|
|
return nil
|
|
end
|
|
|
|
local casingType = ammoData.casingType
|
|
if type(casingType) ~= "string" or casingType == "" then
|
|
return nil
|
|
end
|
|
|
|
local partData = ammoMakerAmmoParts[casingType]
|
|
if type(partData) ~= "table" then
|
|
return nil
|
|
end
|
|
|
|
local firedType = partData.partFired or partData.partOld
|
|
if type(firedType) ~= "string" or firedType == "" then
|
|
return nil
|
|
end
|
|
|
|
return firedType
|
|
end
|
|
|
|
local function getAmmoMakerFiredFromItemKey(ammoType)
|
|
if type(ammoType) ~= "string" or ammoType == "" then
|
|
return nil
|
|
end
|
|
|
|
if type(ammoMakerAmmoTypes) ~= "table" then
|
|
return nil
|
|
end
|
|
|
|
local typeData = ammoMakerAmmoTypes[ammoType]
|
|
if type(typeData) ~= "table" or type(typeData.ammoTypes) ~= "table" or #typeData.ammoTypes == 0 then
|
|
return nil
|
|
end
|
|
|
|
local activeIndex = 1
|
|
if type(typeData.modIds) == "table" and type(ammoMakerCompatibleMods) == "table" then
|
|
for i = 1, #typeData.modIds do
|
|
local modId = typeData.modIds[i]
|
|
if ammoMakerCompatibleMods[modId] == true then
|
|
activeIndex = i
|
|
end
|
|
end
|
|
end
|
|
|
|
if activeIndex < 1 or activeIndex > #typeData.ammoTypes then
|
|
activeIndex = 1
|
|
end
|
|
|
|
local activeAmmoKey = typeData.ammoTypes[activeIndex]
|
|
local activeFiredType = getAmmoMakerFiredFromAmmoDataKey(activeAmmoKey)
|
|
if activeFiredType then
|
|
return activeFiredType
|
|
end
|
|
|
|
for i = 1, #typeData.ammoTypes do
|
|
local fallbackFiredType = getAmmoMakerFiredFromAmmoDataKey(typeData.ammoTypes[i])
|
|
if fallbackFiredType then
|
|
return fallbackFiredType
|
|
end
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
local function getAmmoMakerFiredCasing(ammoType)
|
|
if type(ammoType) ~= "string" or ammoType == "" then
|
|
return nil
|
|
end
|
|
|
|
local directFiredType = getAmmoMakerFiredFromItemKey(ammoType)
|
|
if directFiredType then
|
|
return directFiredType
|
|
end
|
|
|
|
local aliasAmmoDataKey = AMMO_TYPE_ALIAS_BY_ITEM[ammoType]
|
|
if aliasAmmoDataKey then
|
|
local aliasFiredType = getAmmoMakerFiredFromAmmoDataKey(aliasAmmoDataKey)
|
|
if aliasFiredType then
|
|
return aliasFiredType
|
|
end
|
|
end
|
|
|
|
local lowerAmmoType = string.lower(ammoType)
|
|
for aliasItemType, ammoDataKey in pairs(AMMO_TYPE_ALIAS_BY_ITEM) do
|
|
if string.lower(aliasItemType) == lowerAmmoType then
|
|
local aliasFiredType = getAmmoMakerFiredFromAmmoDataKey(ammoDataKey)
|
|
if aliasFiredType then
|
|
return aliasFiredType
|
|
end
|
|
end
|
|
end
|
|
|
|
if type(ammoMakerAmmoTypes) == "table" then
|
|
for itemType, typeData in pairs(ammoMakerAmmoTypes) do
|
|
if type(itemType) == "string" and string.lower(itemType) == lowerAmmoType then
|
|
if type(typeData) == "table" and type(typeData.ammoTypes) == "table" then
|
|
for i = 1, #typeData.ammoTypes do
|
|
local fallbackFiredType = getAmmoMakerFiredFromAmmoDataKey(typeData.ammoTypes[i])
|
|
if fallbackFiredType then
|
|
return fallbackFiredType
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
local function applyPatch()
|
|
if OFHotBrassPatch.patched then
|
|
return true
|
|
end
|
|
|
|
if not isSessionEligible() then
|
|
return false
|
|
end
|
|
|
|
if type(SpentCasingPhysics) ~= "table" then
|
|
return false
|
|
end
|
|
|
|
if type(SpentCasingPhysics.getItemToEject) ~= "function" then
|
|
return false
|
|
end
|
|
|
|
if type(SpentCasingPhysics.doSpawnCasing) ~= "function" then
|
|
return false
|
|
end
|
|
|
|
local originalGetItemToEject = SpentCasingPhysics.getItemToEject
|
|
local originalDoSpawnCasing = SpentCasingPhysics.doSpawnCasing
|
|
|
|
SpentCasingPhysics.getItemToEject = function(ammoType)
|
|
local mappedType = getAmmoMakerFiredCasing(ammoType)
|
|
if mappedType then
|
|
return mappedType
|
|
end
|
|
|
|
return originalGetItemToEject(ammoType)
|
|
end
|
|
|
|
SpentCasingPhysics.doSpawnCasing = function(player, weapon, params, racking, optionalItem)
|
|
if not optionalItem and weapon and weapon.getAmmoType then
|
|
local ammoTypeObj = weapon:getAmmoType()
|
|
local ammoType = ammoTypeObj and ammoTypeObj.getItemKey and ammoTypeObj:getItemKey() or ammoTypeObj
|
|
if ammoType then
|
|
local mappedType = getAmmoMakerFiredCasing(tostring(ammoType))
|
|
if mappedType then
|
|
optionalItem = mappedType
|
|
if racking then
|
|
-- Force rack ejects to stay as empties for this patch.
|
|
racking = false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return originalDoSpawnCasing(player, weapon, params, racking, optionalItem)
|
|
end
|
|
|
|
OFHotBrassPatch.patched = true
|
|
return true
|
|
end
|
|
|
|
local function tryPatchOnTick()
|
|
if OFHotBrassPatch.patched then
|
|
Events.OnTick.Remove(tryPatchOnTick)
|
|
return
|
|
end
|
|
|
|
applyPatch()
|
|
end
|
|
|
|
Events.OnTick.Add(tryPatchOnTick)
|