И так, делал на днях систему резистов и подумал что почему бы и не поделится, может кому пригодится, делал на helix, но пример напишу и для DarkRP.
Начнем с того что там нужен будет массив, в котором мы и укажем все резисты которые нам нужны. (Можно сделать резисты на основе профессии TEAM_* или же моделей).
И так приступим:
--[[-----------------------------
SHARED - часть
---------------------------------]]--
RESIST_MODEL = RESIST_MODEL or {} -- Создаем всеобщую таблицу, которую мы сможем вызвать где нам нужно.
-- Создаем еще один тип таблицы для разделения на другие части кода
RESIST_MODEL.model = {}
-- Пример массива на резист
RESIST_MODEL.model["models/Combine_Super_Soldier.mdl"] = {
-- Объявялем ключ-таблицу(damageResists) куда укажем защиту от типа урона! Обратите внимание что защита в процентах от 0 до 1. Например 0.1 = 10%, а 1 = 100%
damageResists = {
ballistic = 0.1, -- баллистическая защита, тип урона DMG_BULLET
shock = 0.5, -- защита от урона типа DMG_SHOCK, урон электричеством, сталкера или вортигонта
club = 1, -- Делаем полную зиту от урона типа DMG_CLUB, то есть от удара монтировкой, электрошокером и т.д
},
-- Объявялем ключ-таблицу(ammoResist) по аналогии с damageResists. Резист так-же от 0 до 1
ammoResist = {
ar2 = 0.7, -- Здаем защиту от попаданий БП(Боеприпаса) типа ar2 на 70%
pistol = 1, -- Полная защита от пистолетного БП
smg1 = 0.5, -- Защита от БП автомата на 50%.
}
}
--[[------------------------------------------------
Для примера думаю хватит и этой таблицы
----------------------------------------------------]]--
Теперь идем в серверную часть
--[[------------------------------------------------
SERVERSIDE - СЕРВЕРНАЯ ЧАСТЬ
----------------------------------------------------]]--
-- Вызываем хук EntityTakeDamage
-- Объявляем две таблицы
local ammoTypeGame = {}
local damageTypeGame = {}
hook.Add("EntityTakeDamage", "ResistsSystem", function(client, dmgInfo)
-- Делаем проверку что игрок существует, если нет, то код дальше return не запустится
if (!IsValid(client) or !dmgInfo:IsPlayer()) then return end
-- Получаем информацию о уроне и типе урона (damage) и (damageType) соответственно
local damage = dmgInfo:GetDamage() -- получаем кол-во урона
local damageType = dmgInfo:GetDamageType() -- получаем тип урона
local getModel = client:GetModel() -- получаем модель игрока
if (!attacker:IsPlayer() or !IsValid(attacker)) then return end -- Добавляем проверку
local weapon = attacker:GetActiveWeapon() -- Получаем активное оружие атакующего
local ammoType = weapon:GetPrimaryAmmoType() -- Получаем тип боеприпаса
local ammoName = game.GetAmmoName(ammoType):lower() -- Получаем имя боеприпаса
local ammoDamageType = game.GetAmmoDamageType(ammoType) -- Получаем тип урона от Боеприпаса
local modelResits = RESIST_MODEL.model[getModel] -- Определяем модель игрока с таблицей.
-- Разделим modelResits на два типа защиты
local dmgProtect = modelResits.damageResists -- Тип урона
local ammoProtect = modelResits.ammoResist -- Тип боеприпаса
-- Сделаем проверку что модель игрока валдина по отношению к таблице и резист можно применить, чтобы не было ошибок.
if (modelResits) then
-- Теперь делаем то зачем вы сюда пришли)
-- Запихиваем тип урона и резит к нему в массив damageTypeGame, который мы объявили до хука
damageTypeGame[DMG_BULLET] = dmgProtect.ballistic -- Баллистическая защита
damageTypeGame[DMG_SHOCK] = dmgProtect.shock -- Защита от электричества которым обладают сталкеры и вортигонты
damageTypeGame[DMG_CLUB] = dmgProtect.club -- Защита от ударного урона(DMG_CLUB), монтировкой и т.д
-- Запихиваем тип боеприпаса и резист к нему в массив ammoTypeGame, который мы объявили до хука
ammoTypeGame["pistol"] = ammoProtect.pistol -- Резист для боеприпаса от пистолета
ammoTypeGame["ar2"] = ammoProtect.ar2 -- Резист для боеприпаса от ar2
ammoTypeGame["smg1"] = ammoProtect.smg1 -- Резист для боеприпаса от sgm1
-- А вот теперь самое интересное. Делаем вычисления
-- Объявим переменную которая помощет нам в будущей формуле урона
local ammoTotalDamage = 0
-- Просчитываем резит от типа боеприпаса
if (ammoTypeGame[ammoName]) then
ammoTotalDamage = ammoTypeGame[ammoName]
end
-- Просчитываем окончательный урон вместе с резистом от боеприпаса и резистом от типа урона
if (damageTypeGame[ammoDamageType] or damageTypeGame[damageType]) then
dmgInfo:SetDamage(damage * (1 - ammoTotalDamage) * (1 - damageTypeGame[damageType]))
end
end
end)
Это не сложно, а все типы урона можете посмотреть тут: DMG - Garry's Mod Wiki
и тут: Default Ammo Types - Garry's Mod Wiki
. В коде можно увидеть много не использованного урона по типу DMG_BURN, DMG_FALL(эти два урона отвечают за урон от огня и урон от падений). Думаю это будет интересно кому-то.
Основу я вам дал, а дальше думаю поймете что к чему ,
Примечание: 1 в формуле обязательна! продублирую формулу еще раз damage * (1 - 0.5) * (1-0.6)