Система резистов по типу боеприпаса и типу урона

И так, делал на днях систему резистов и подумал что почему бы и не поделится, может кому пригодится, делал на 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(эти два урона отвечают за урон от огня и урон от падений). Думаю это будет интересно кому-то.
Основу я вам дал, а дальше думаю поймете что к чему :wink: , :blush:
Примечание: 1 в формуле обязательна! продублирую формулу еще раз damage * (1 - 0.5) * (1-0.6)

1 лайк

Перенес пост в info :wave:

1 лайк

Спасибо. :+1:

А где shared находится? Я прост забыл, пробывал искать, но не нашел

В папке lua/autorun/sh_shared.lua(название любое можешь придумать хоть sh_config.lua). Где обычно находятся еще две папки server и client

Спасибо. А можно ли создать папку shared а в этой папке создать луа sh_shared.lua?

А смысл?

Да я уже понял