Files
2026-05-29 15:11:31 +07:00

191 lines
10 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
local ____lualib = require("lualib_bundle")
local __TS__Class = ____lualib.__TS__Class
local Map = ____lualib.Map
local __TS__New = ____lualib.__TS__New
local __TS__ObjectKeys = ____lualib.__TS__ObjectKeys
local __TS__ObjectEntries = ____lualib.__TS__ObjectEntries
local __TS__ArrayFrom = ____lualib.__TS__ArrayFrom
local ____exports = {}
local ____modifier_donate_item = require("abilities.modifiers.modifier_donate_item")
local modifier_donate_item = ____modifier_donate_item.modifier_donate_item
--- Менеджер для автоматического надевания косметики (моделек) на кастомных героев при спавне
-- Использует подход с созданием отдельных юнитов и прикреплением их к герою
____exports.HeroCosmeticManager = __TS__Class()
local HeroCosmeticManager = ____exports.HeroCosmeticManager
HeroCosmeticManager.name = "HeroCosmeticManager"
HeroCosmeticManager.____file_path = "scripts/vscripts/HeroCosmeticManager.lua"
function HeroCosmeticManager.prototype.____constructor(self)
self.heroCosmeticsConfig = __TS__New(Map)
self.heroWearables = __TS__New(Map)
end
function HeroCosmeticManager.getInstance(self)
if not ____exports.HeroCosmeticManager.instance then
____exports.HeroCosmeticManager.instance = __TS__New(____exports.HeroCosmeticManager)
end
return ____exports.HeroCosmeticManager.instance
end
function HeroCosmeticManager.prototype.registerHeroCosmetics(self, heroName, config)
print("[HeroCosmeticManager] Регистрация косметики для героя: " .. heroName)
if config.model then
print("[HeroCosmeticManager] - Основная модель: " .. config.model)
end
if config.slots then
local slotNames = __TS__ObjectKeys(config.slots)
print((("[HeroCosmeticManager] - Слоты косметики (" .. tostring(#slotNames)) .. "): ") .. table.concat(slotNames, ", "))
for ____, ____value in ipairs(__TS__ObjectEntries(config.slots)) do
local slot = ____value[1]
local model = ____value[2]
if model then
print((("[HeroCosmeticManager] * " .. slot) .. ": ") .. model)
end
end
end
if config.scale ~= nil then
print("[HeroCosmeticManager] - Масштаб: " .. tostring(config.scale))
end
self.heroCosmeticsConfig:set(heroName, config)
print("[HeroCosmeticManager] ✅ Конфигурация зарегистрирована для " .. heroName)
end
function HeroCosmeticManager.prototype.unregisterHeroCosmetics(self, heroName)
self.heroCosmeticsConfig:delete(heroName)
end
function HeroCosmeticManager.prototype.onHeroSpawn(self, hero)
if not hero or not hero:IsRealHero() then
print("[HeroCosmeticManager] Пропуск: герой не является реальным героем")
return
end
local heroName = hero:GetUnitName()
print("[HeroCosmeticManager] Обработка спавна героя: " .. heroName)
local config = self.heroCosmeticsConfig:get(heroName)
if not config then
print("[HeroCosmeticManager] Конфигурация не найдена для героя: " .. heroName)
return
end
print(("[HeroCosmeticManager] Найдена конфигурация для " .. heroName) .. ", начинаем надевание косметики...")
Timers:CreateTimer(
0.2,
function()
if not IsValidEntity(hero) or not hero:IsAlive() then
print(("[HeroCosmeticManager] Герой " .. heroName) .. " больше не валиден или мертв, отмена")
return
end
if config.model then
print((("[HeroCosmeticManager] Устанавливаем основную модель для " .. heroName) .. ": ") .. config.model)
hero:SetModel(config.model)
hero:SetOriginalModel(config.model)
end
local heroId = hero:GetEntityIndex()
if not self.heroWearables:has(heroId) then
self.heroWearables:set(heroId, {})
end
if config.slots then
local slotCount = #__TS__ObjectKeys(config.slots)
print((("[HeroCosmeticManager] Начинаем надевание " .. tostring(slotCount)) .. " элементов косметики для ") .. heroName)
for ____, ____value in ipairs(__TS__ObjectEntries(config.slots)) do
local attachmentPoint = ____value[1]
local modelPath = ____value[2]
if modelPath then
print((("[HeroCosmeticManager] Надеваем модель на attachment point \"" .. attachmentPoint) .. "\": ") .. modelPath)
self:WearModel(hero, modelPath, attachmentPoint)
else
print(("[HeroCosmeticManager] Пропуск слота \"" .. attachmentPoint) .. "\" - модель не указана")
end
end
print("[HeroCosmeticManager] Завершено надевание косметики для " .. heroName)
else
print("[HeroCosmeticManager] Слоты косметики не указаны для " .. heroName)
end
if config.scale ~= nil then
print((("[HeroCosmeticManager] Устанавливаем масштаб модели для " .. heroName) .. ": ") .. tostring(config.scale))
hero:SetModelScale(config.scale)
end
end
)
end
function HeroCosmeticManager.prototype.getHeroCosmetics(self, heroName)
return self.heroCosmeticsConfig:get(heroName)
end
function HeroCosmeticManager.prototype.clearAll(self)
self.heroCosmeticsConfig:clear()
end
function HeroCosmeticManager.prototype.getRegisteredHeroes(self)
return __TS__ArrayFrom(self.heroCosmeticsConfig:keys())
end
function HeroCosmeticManager.prototype.WearModel(self, hero, modelPath, attachmentPoint)
do
local function ____catch(e)
print((((("[HeroCosmeticManager] ❌ КРИТИЧЕСКАЯ ОШИБКА при надевании модели " .. modelPath) .. " на attachment point ") .. attachmentPoint) .. ": ") .. tostring(e))
end
local ____try, ____hasReturned, ____returnValue = pcall(function()
print(((("[HeroCosmeticManager] WearModel: создаем wearable для " .. modelPath) .. " на attachment point \"") .. attachmentPoint) .. "\"")
local wearable = CreateUnitByName(
"npc_dota_donate_item",
Vector(0, 0, 0),
false,
nil,
nil,
hero:GetTeamNumber()
)
if not wearable then
print("[HeroCosmeticManager] ❌ ОШИБКА: Не удалось создать wearable для модели " .. modelPath)
return true
end
print("[HeroCosmeticManager] ✅ Wearable создан успешно, EntityIndex: " .. tostring(wearable:GetEntityIndex()))
if IsServer() then
wearable:SetRenderColor(255, 255, 255)
end
print("[HeroCosmeticManager] Цвет рендеринга установлен")
wearable:AddNewModifier(
hero,
getModifierSourceAbility(nil, hero),
modifier_donate_item.name,
{}
)
print("[HeroCosmeticManager] Модификатор modifier_donate_item добавлен")
wearable:SetModel(modelPath)
wearable:SetOriginalModel(modelPath)
print("[HeroCosmeticManager] Модель установлена: " .. modelPath)
wearable:SetTeam(hero:GetTeamNumber())
wearable:SetOwner(hero)
print(("[HeroCosmeticManager] Команда и владелец установлены (Team: " .. tostring(hero:GetTeamNumber())) .. ")")
wearable:SetParent(hero, attachmentPoint)
wearable:FollowEntity(hero, true)
print(("[HeroCosmeticManager] ✅ Wearable прикреплен к attachment point \"" .. attachmentPoint) .. "\"")
wearable:StartGesture(ACT_DOTA_IDLE)
print("[HeroCosmeticManager] Анимация установлена: DOTA_IDLE")
local heroId = hero:GetEntityIndex()
local wearables = self.heroWearables:get(heroId) or ({})
wearables[#wearables + 1] = wearable
self.heroWearables:set(heroId, wearables)
print(("[HeroCosmeticManager] Wearable сохранен в список (всего wearables для героя: " .. tostring(#wearables)) .. ")")
end)
if not ____try then
____hasReturned, ____returnValue = ____catch(____hasReturned)
end
if ____hasReturned then
return ____returnValue
end
end
end
function HeroCosmeticManager.prototype.RemoveAllCosmetics(self, hero)
local heroId = hero:GetEntityIndex()
local heroName = hero:GetUnitName()
local wearables = self.heroWearables:get(heroId)
if wearables then
print(((("[HeroCosmeticManager] Удаление косметики с героя " .. heroName) .. " (") .. tostring(#wearables)) .. " элементов)")
for ____, wearable in ipairs(wearables) do
if IsValidEntity(wearable) then
UTIL_Remove(wearable)
print(("[HeroCosmeticManager] Wearable удален (EntityIndex: " .. tostring(wearable:GetEntityIndex())) .. ")")
else
print("[HeroCosmeticManager] Wearable уже не валиден, пропуск")
end
end
self.heroWearables:delete(heroId)
print("[HeroCosmeticManager] ✅ Вся косметика удалена с " .. heroName)
else
print(("[HeroCosmeticManager] У героя " .. heroName) .. " нет косметики для удаления")
end
end
return ____exports