Bump to mod version and changed folder for specific game version
This commit is contained in:
157
42.6/media/lua/client/TOC/Zombies/ZombiesAmputation.lua
Normal file
157
42.6/media/lua/client/TOC/Zombies/ZombiesAmputation.lua
Normal file
@@ -0,0 +1,157 @@
|
||||
require "lua_timers"
|
||||
|
||||
local ItemsController = require("TOC/Controllers/ItemsController")
|
||||
local StaticData = require("TOC/StaticData")
|
||||
local CommandsData = require("TOC/CommandsData")
|
||||
-------------------------------
|
||||
|
||||
---@param zombie IsoZombie|IsoGameCharacter|IsoMovingObject|IsoObject
|
||||
---@return integer trueID
|
||||
local function GetZombieID(zombie)
|
||||
-- Big love to Chuck and Sir Doggy Jvla for this code
|
||||
---@diagnostic disable-next-line: param-type-mismatch
|
||||
local pID = zombie:getPersistentOutfitID()
|
||||
local bits = string.split(string.reverse(Long.toUnsignedString(pID, 2)), "")
|
||||
while #bits < 16 do bits[#bits + 1] = 0 end
|
||||
|
||||
-- trueID
|
||||
bits[16] = 0
|
||||
local trueID = Long.parseUnsignedLong(string.reverse(table.concat(bits, "")), 2)
|
||||
|
||||
return trueID
|
||||
end
|
||||
|
||||
-------------------------------
|
||||
|
||||
|
||||
---@param item InventoryItem
|
||||
local function PredicateAmputationItems(item)
|
||||
return item:getType():contains("Amputation_")
|
||||
end
|
||||
|
||||
---@param item InventoryItem
|
||||
local function PredicateAmputationItemLeft(item)
|
||||
return item:getType():contains("Amputation_") and item:getType():contains("_L")
|
||||
end
|
||||
|
||||
---@param item InventoryItem
|
||||
local function PredicateAmputationItemRight(item)
|
||||
return item:getType():contains("Amputation_") and item:getType():contains("_R")
|
||||
end
|
||||
|
||||
---@param zombie IsoZombie
|
||||
local function SpawnAmputation(zombie, side)
|
||||
local index = ZombRand(1, #StaticData.PARTS_STR)
|
||||
local limb = StaticData.PARTS_STR[index] .. "_" .. side
|
||||
local amputationFullType = StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. limb
|
||||
|
||||
|
||||
ItemsController.Zombie.SpawnAmputationItem(zombie, amputationFullType)
|
||||
|
||||
|
||||
-- Add reference and transmit it to server
|
||||
local pID = GetZombieID(zombie)
|
||||
local zombieKey = CommandsData.GetZombieKey()
|
||||
local zombiesMD = ModData.getOrCreate(zombieKey)
|
||||
if zombiesMD[pID] == nil then zombiesMD[pID] = {} end
|
||||
zombiesMD[pID][side] = amputationFullType
|
||||
ModData.add(zombieKey, zombiesMD)
|
||||
ModData.transmit(zombieKey)
|
||||
end
|
||||
|
||||
-------------------------------
|
||||
|
||||
local bloodAmount = 10
|
||||
|
||||
|
||||
---@param player IsoGameCharacter
|
||||
---@param zombie IsoZombie
|
||||
---@param handWeapon HandWeapon
|
||||
local function HandleZombiesAmputations(player, zombie, handWeapon, damage)
|
||||
if not SandboxVars.TOC.EnableZombieAmputations then return end
|
||||
|
||||
if not instanceof(zombie, "IsoZombie") or not instanceof(player, "IsoPlayer") then return end
|
||||
if player ~= getPlayer() then return end
|
||||
|
||||
-- Check type of weapon. No hands, only knifes or such
|
||||
local weaponCategories = handWeapon:getScriptItem():getCategories()
|
||||
if not (weaponCategories:contains("Axe") or weaponCategories:contains("LongBlade")) then return end
|
||||
|
||||
local isCrit = player:isCriticalHit()
|
||||
local randomChance = ZombRand(0, 100) > (100 - SandboxVars.TOC.ZombieAmputationDamageChance)
|
||||
if (damage > SandboxVars.TOC.ZombieAmputationDamageThreshold and randomChance) or isCrit then
|
||||
TOC_DEBUG.print("Amputating zombie limbs - damage: " .. tostring(damage))
|
||||
local zombieInv = zombie:getInventory()
|
||||
|
||||
-- Check left or right
|
||||
local randSide = ZombRand(2) -- Random side
|
||||
local preferredSide = randSide == 0 and "L" or "R"
|
||||
local alternateSide = preferredSide == "L" and "R" or "L"
|
||||
|
||||
local predicatePreferred = preferredSide == "L" and PredicateAmputationItemLeft or PredicateAmputationItemRight
|
||||
local predicateAlternate = alternateSide == "L" and PredicateAmputationItemLeft or PredicateAmputationItemRight
|
||||
|
||||
if not zombieInv:containsEval(predicatePreferred) then
|
||||
SpawnAmputation(zombie, preferredSide)
|
||||
elseif not zombieInv:containsEval(predicateAlternate) then
|
||||
SpawnAmputation(zombie, alternateSide)
|
||||
end
|
||||
|
||||
TOC_DEBUG.print("Amputating zombie limbs - damage: " .. tostring(damage) .. ", preferred limb side: " .. preferredSide)
|
||||
|
||||
-- add blood splat every couple of seconds for a while
|
||||
addBloodSplat(getCell():getGridSquare(zombie:getX(), zombie:getY(), zombie:getZ()), bloodAmount)
|
||||
local timerName = tostring(GetZombieID(zombie)) .. "_timer"
|
||||
timer:Create(timerName, 1, 10, function()
|
||||
addBloodSplat(getCell():getGridSquare(zombie:getX(), zombie:getY(), zombie:getZ()), bloodAmount)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
Events.OnWeaponHitCharacter.Add(HandleZombiesAmputations)
|
||||
|
||||
-----------------------------
|
||||
|
||||
local localOnlyZombiesMD
|
||||
|
||||
local function SetupZombiesModData()
|
||||
if not SandboxVars.TOC.EnableZombieAmputations then return end
|
||||
local zombieKey = CommandsData.GetZombieKey()
|
||||
localOnlyZombiesMD = ModData.getOrCreate(zombieKey)
|
||||
end
|
||||
|
||||
Events.OnInitGlobalModData.Add(SetupZombiesModData)
|
||||
|
||||
|
||||
---@param zombie IsoZombie
|
||||
local function ReapplyAmputation(zombie)
|
||||
if not SandboxVars.TOC.EnableZombieAmputations then return end
|
||||
|
||||
local pID = GetZombieID(zombie)
|
||||
|
||||
if localOnlyZombiesMD[pID] ~= nil then
|
||||
-- check if zombie has amputation
|
||||
local zombiesAmpData = localOnlyZombiesMD[pID]
|
||||
local zombieInv = zombie:getInventory()
|
||||
local foundItem = zombieInv:containsEvalRecurse(PredicateAmputationItems)
|
||||
|
||||
if foundItem then
|
||||
return
|
||||
else
|
||||
local leftAmp = zombiesAmpData['L']
|
||||
if leftAmp then
|
||||
ItemsController.Zombie.SpawnAmputationItem(zombie, leftAmp)
|
||||
end
|
||||
|
||||
local rightAmp = zombiesAmpData['R']
|
||||
if rightAmp then
|
||||
ItemsController.Zombie.SpawnAmputationItem(zombie, rightAmp)
|
||||
end
|
||||
|
||||
-- Removes reference, local only
|
||||
localOnlyZombiesMD[pID] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Events.OnZombieUpdate.Add(ReapplyAmputation)
|
||||
Reference in New Issue
Block a user