local OFHotBrassPatch = { patched = false, } local function isPatchToggleEnabled() local vars = SandboxVars and SandboxVars.OpinionatedFirearms if vars and vars.HBVCEFAmmoMakerPatch ~= nil then return vars.HBVCEFAmmoMakerPatch == true end return true end local function isSessionEligible() return isPatchToggleEnabled() end local function getAmmoMakerFiredCasing(ammoType) if type(ammoType) ~= "string" or ammoType == "" then return nil end local function getAmmoTypeData() if type(ammoMakerAmmoTypes) ~= "table" then return nil end local data = ammoMakerAmmoTypes[ammoType] if type(data) ~= "table" or type(data.ammoTypes) ~= "table" or #data.ammoTypes == 0 then return nil end return data end local function getActiveAmmoData(typeData) if type(typeData) ~= "table" or type(typeData.ammoTypes) ~= "table" or type(ammoMakerAmmoData) ~= "table" 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] if type(activeAmmoKey) == "string" then local activeAmmoData = ammoMakerAmmoData[activeAmmoKey] if type(activeAmmoData) == "table" then return activeAmmoData end end for i = 1, #typeData.ammoTypes do local ammoKey = typeData.ammoTypes[i] if type(ammoKey) == "string" then local ammoData = ammoMakerAmmoData[ammoKey] if type(ammoData) == "table" then return ammoData end end end return nil end local function partDataToFiredType(partData) 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 if type(ammoMakerAmmoParts) ~= "table" then return nil end local ammoTypeData = getAmmoTypeData() if not ammoTypeData then return nil end local ammoData = getActiveAmmoData(ammoTypeData) if type(ammoData) == "table" and type(ammoData.casingType) == "string" then local firedType = partDataToFiredType(ammoMakerAmmoParts[ammoData.casingType]) if firedType then return firedType 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 ammoType = weapon:getAmmoType() 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)