mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
305
gamemodes/darkrp/plugins/weaponbalance/sv_hooks.lua
Normal file
305
gamemodes/darkrp/plugins/weaponbalance/sv_hooks.lua
Normal file
@@ -0,0 +1,305 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
local PLUGIN = PLUGIN
|
||||
|
||||
function PLUGIN:GetHookCallPriority(hook)
|
||||
if (hook == "EntityTakeDamage") then
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:FirefightActionMove(client, character, fightInfo)
|
||||
local weapon = client:GetActiveWeapon()
|
||||
if (IsValid(weapon) and ix.weapons:IsMelee(weapon:GetClass())) then
|
||||
if (fightInfo.turn.actions == 1) then
|
||||
fightInfo.turn.weapon = weapon:GetClass()
|
||||
fightInfo.turn.attacksLeft = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:FirefightTurnStart(fight, fightInfo, character)
|
||||
local client = character:GetPlayer()
|
||||
if (IsValid(client:GetActiveWeapon()) and ix.weapons:IsMelee(client:GetActiveWeapon():GetClass())) then
|
||||
fightInfo.turn.attacksLeft = 1
|
||||
fightInfo.turn.weapon = client:GetActiveWeapon():GetClass()
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:ScaleNPCDamage(npc, hitgroup, damage)
|
||||
local attacker = damage:GetAttacker()
|
||||
if (!IsValid(attacker) or (!attacker:IsPlayer())) then
|
||||
return
|
||||
end
|
||||
|
||||
local success, result, range, critChance, penalties, bonus = ix.weapons:BalanceDamage(npc, damage, attacker, hitgroup)
|
||||
|
||||
if (success == false) then
|
||||
return
|
||||
end
|
||||
|
||||
ix.weapons:QueueDamageMessage(attacker, {
|
||||
bCrit = result == "crit",
|
||||
target = npc,
|
||||
hitBox = PLUGIN.hitGroupName[hitgroup],
|
||||
range = math.Round(range),
|
||||
damage = damage:GetDamage(),
|
||||
calcCrit = critChance,
|
||||
penalties = penalties,
|
||||
bonus = bonus,
|
||||
messageType = ix.weapons.messageTypes.WEAPON_DAMAGE
|
||||
})
|
||||
end
|
||||
|
||||
function PLUGIN:EntityTakeDamage(victim, damage)
|
||||
if (!IsValid(victim)) then return end
|
||||
|
||||
-- Ensure we deal damage to the player if their ragdoll is hit
|
||||
local bIsRagdoll = false
|
||||
if (victim:GetClass() == "prop_ragdoll" and IsValid(victim.ixPlayer)) then
|
||||
if (IsValid(victim.ixHeldOwner)) then
|
||||
damage:SetDamage(0)
|
||||
return true
|
||||
end
|
||||
|
||||
if (damage:IsDamageType(DMG_CRUSH)) then
|
||||
if ((victim.ixFallGrace or 0) < CurTime()) then
|
||||
if (damage:GetDamage() <= 10) then
|
||||
damage:SetDamage(0)
|
||||
end
|
||||
|
||||
victim.ixFallGrace = CurTime() + 0.5
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
bIsRagdoll = victim
|
||||
victim = victim.ixPlayer
|
||||
end
|
||||
-- Not attacking player
|
||||
if (!victim:IsPlayer()) then
|
||||
if (victim:IsNPC()) then return end -- gets handled by ScaleNPCDamage
|
||||
|
||||
local attacker = damage:GetAttacker()
|
||||
if (!IsValid(attacker) or (!attacker:IsPlayer())) then
|
||||
return
|
||||
end
|
||||
|
||||
return ix.weapons:BalanceDamage(victim, damage, attacker, 0)
|
||||
end
|
||||
if (!victim:Alive()) then return end
|
||||
|
||||
-- Is attacking player
|
||||
local attacker = damage:GetAttacker()
|
||||
local hitgroup = !bIsRagdoll and victim:LastHitGroup() or self:CalculateRagdollHitGroup(victim, damage:GetDamagePosition())
|
||||
|
||||
-- Do schema damage hook if it exists
|
||||
if (Schema.EntityTakeDamage and Schema:EntityTakeDamage(victim, damage)) then
|
||||
return true
|
||||
end
|
||||
-- Do GM & addon damage hooks
|
||||
if (hook.ixCall("EntityTakeDamage", Schema.GM, victim, damage)) then
|
||||
return true
|
||||
end
|
||||
|
||||
-- Check if we are dealing invalid damage to a ragdoll
|
||||
if (bIsRagdoll and IsValid(attacker) and !attacker:IsPlayer() and (attacker:GetClass() == "prop_ragdoll" or attacker:IsDoor() or damage:GetDamage() < 5)) then
|
||||
damage:SetDamage(0)
|
||||
return true
|
||||
end
|
||||
|
||||
-- Allow for schema damage overrides
|
||||
if (hook.Run("CalculatePlayerDamage", victim, damage, hitgroup)) then
|
||||
return true
|
||||
end
|
||||
-- Do gunbalance damage limitations
|
||||
local success, result, range, critChance, penalties, bonus
|
||||
if (IsValid(attacker) and attacker:IsPlayer()) then
|
||||
success, result, range, critChance, penalties, bonus = ix.weapons:BalanceDamage(victim, damage, attacker, hitgroup)
|
||||
if (success == false or !range or !tonumber(range)) then
|
||||
-- we don't know what to do with this damage
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- If still dealing damage
|
||||
if (damage:GetDamage() > 0) then
|
||||
local messageType
|
||||
local finalDamage
|
||||
if (victim:Armor() > 0) then
|
||||
if (damage:IsBulletDamage() or damage:IsDamageType(DMG_CLUB) or damage:IsDamageType(DMG_SLASH)) then
|
||||
local weaponItem
|
||||
if (IsValid(attacker) and attacker:IsPlayer()) then
|
||||
weaponItem = attacker:GetActiveWeapon().ixItem
|
||||
end
|
||||
local armorPen = weaponItem and weaponItem.armorPen or ix.config.Get("defaultArmorPenetration", 0.5)
|
||||
if (IsValid(attacker) and attacker:IsNPC()) then
|
||||
armorPen = ix.config.Get("npcArmorPen", 0.5)
|
||||
end
|
||||
local armor = victim:Armor() - (damage:GetDamage() * armorPen)
|
||||
|
||||
if (armor < 0) then
|
||||
finalDamage = damage:GetDamage() * armorPen
|
||||
messageType = ix.weapons.messageTypes.ARMOR_BROKEN
|
||||
|
||||
victim:SetHealth(math.max(victim:Health() - math.abs(armor), 1))
|
||||
victim:SetArmor(0)
|
||||
else
|
||||
finalDamage = damage:GetDamage() * armorPen
|
||||
messageType = ix.weapons.messageTypes.ARMOR_DAMAGE
|
||||
|
||||
victim:SetArmor(armor)
|
||||
end
|
||||
|
||||
elseif (damage:IsDamageType(DMG_SHOCK)) then
|
||||
finalDamage = damage:GetDamage()
|
||||
messageType = ix.weapons.messageTypes.ARMOR_HALF_DAMAGE
|
||||
|
||||
victim:SetArmor(math.max(victim:Armor() - finalDamage / 2, 0))
|
||||
victim:SetHealth(math.max(victim:Health() - damage:GetDamage(), 1))
|
||||
else
|
||||
finalDamage = damage:GetDamage()
|
||||
messageType = ix.weapons.messageTypes.WEAPON_DAMAGE
|
||||
|
||||
victim:SetHealth(math.max(victim:Health() - damage:GetDamage(), 1))
|
||||
end
|
||||
else
|
||||
finalDamage = damage:GetDamage()
|
||||
messageType = ix.weapons.messageTypes.WEAPON_DAMAGE
|
||||
|
||||
victim:SetHealth(math.max(victim:Health() - damage:GetDamage(), 1))
|
||||
end
|
||||
|
||||
if (IsValid(attacker) and attacker:IsPlayer() and range) then
|
||||
ix.weapons:QueueDamageMessage(attacker, {
|
||||
bCrit = result == "crit",
|
||||
target = victim,
|
||||
hitBox = PLUGIN.hitGroupName[hitgroup],
|
||||
range = math.Round(range),
|
||||
damage = finalDamage,
|
||||
calcCrit = critChance,
|
||||
penalties = penalties,
|
||||
bonus = bonus,
|
||||
messageType = messageType
|
||||
})
|
||||
end
|
||||
else
|
||||
return true
|
||||
end
|
||||
|
||||
-- If Victim is dying
|
||||
if (victim:Health() == 1) then
|
||||
if (hook.Run("HandlePlayerDeath", victim, damage) != false) then
|
||||
self:HandlePlayerDeathFallback(victim, damage)
|
||||
end
|
||||
else
|
||||
hook.Run("PlayerHurt", victim, attacker, victim:Health(), damage:GetDamage())
|
||||
end
|
||||
|
||||
-- Stop further EntityTakeDamage stuff (we already called this!)
|
||||
damage:SetDamage(0)
|
||||
return true
|
||||
end
|
||||
|
||||
function PLUGIN:TFA_PreCanPrimaryAttack(weapon)
|
||||
local client = weapon.Owner
|
||||
if (!IsValid(client) or !client:IsPlayer()) then return end
|
||||
|
||||
client.ixCanDoDamage = weapon.Primary.NumShots
|
||||
end
|
||||
|
||||
function PLUGIN:TFA_PostPrimaryAttack(weapon)
|
||||
local client = weapon.Owner
|
||||
if (client:IsNPC()) then return end
|
||||
|
||||
local min, max = ix.weapons:GetWeaponSkillRequired(weapon:GetClass())
|
||||
local level = client:GetCharacter():GetSkill("guns")
|
||||
if (min <= level and level <= max) then
|
||||
client:GetCharacter():DoAction("guns_level_approp")
|
||||
else
|
||||
client:GetCharacter():DoAction("guns_level_unapprop")
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:ShouldSpawnClientRagdoll(client)
|
||||
return false
|
||||
end
|
||||
|
||||
function PLUGIN:PlayerSpawn(client)
|
||||
client:SetLocalVar("ragdoll", nil)
|
||||
end
|
||||
|
||||
function PLUGIN:ShouldRemoveRagdollOnDeath(client)
|
||||
return false
|
||||
end
|
||||
|
||||
function PLUGIN:PlayerInitialSpawn(client)
|
||||
self:CleanupCorpses()
|
||||
end
|
||||
|
||||
function PLUGIN:DoPlayerDeath(client)
|
||||
-- remove old corpse if we've hit the limit
|
||||
local maxCorpses = ix.config.Get("corpseMax", 8)
|
||||
if (maxCorpses > 0) then
|
||||
local entity = IsValid(client.ixRagdoll) and client.ixRagdoll or client:CreateServerRagdoll()
|
||||
local decayTime = ix.config.Get("corpseDecayTime", 60)
|
||||
local uniqueID = "ixCorpseDecay" .. entity:EntIndex()
|
||||
|
||||
entity:RemoveCallOnRemove("fixer")
|
||||
entity:CallOnRemove("ixPersistentCorpse", function(ragdoll)
|
||||
if (ragdoll.ixInventory) then
|
||||
ix.storage.Close(ragdoll.ixInventory)
|
||||
end
|
||||
|
||||
if (IsValid(client) and !client:Alive()) then
|
||||
client:SetLocalVar("ragdoll", nil)
|
||||
end
|
||||
|
||||
local index
|
||||
for k, v in ipairs(PLUGIN.corpses) do
|
||||
if (v == ragdoll) then
|
||||
index = k
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if (index) then
|
||||
table.remove(PLUGIN.corpses, index)
|
||||
end
|
||||
|
||||
if (timer.Exists(uniqueID)) then
|
||||
timer.Remove(uniqueID)
|
||||
end
|
||||
end)
|
||||
|
||||
if (decayTime > 0) then
|
||||
timer.Create(uniqueID, decayTime, 1, function()
|
||||
if (IsValid(entity)) then
|
||||
entity:Remove()
|
||||
else
|
||||
timer.Remove(uniqueID)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
client.ixRagdoll = nil
|
||||
entity.ixPlayer = nil
|
||||
self.corpses[#self.corpses + 1] = entity
|
||||
|
||||
if (#self.corpses >= maxCorpses) then
|
||||
self:CleanupCorpses(maxCorpses)
|
||||
end
|
||||
|
||||
hook.Run("OnPlayerCorpseCreated", client, entity)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user