initial commit
This commit is contained in:
@@ -0,0 +1,920 @@
|
||||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__Class = ____lualib.__TS__Class
|
||||
local Map = ____lualib.Map
|
||||
local __TS__New = ____lualib.__TS__New
|
||||
local __TS__StringStartsWith = ____lualib.__TS__StringStartsWith
|
||||
local __TS__StringSubstring = ____lualib.__TS__StringSubstring
|
||||
local __TS__ArrayIndexOf = ____lualib.__TS__ArrayIndexOf
|
||||
local __TS__ArraySplice = ____lualib.__TS__ArraySplice
|
||||
local __TS__ObjectEntries = ____lualib.__TS__ObjectEntries
|
||||
local __TS__Delete = ____lualib.__TS__Delete
|
||||
local __TS__StringIncludes = ____lualib.__TS__StringIncludes
|
||||
local __TS__NumberToFixed = ____lualib.__TS__NumberToFixed
|
||||
local ____exports = {}
|
||||
local ____modifier_general_arc = require("abilities.modifiers.modifier_general_arc")
|
||||
local modifier_general_arc = ____modifier_general_arc.modifier_general_arc
|
||||
local ____modifier_kitty_flex_catakeet = require("abilities.modifiers.modifier_kitty_flex_catakeet")
|
||||
local KITTY_FLEX_CATAKEET_MODEL = ____modifier_kitty_flex_catakeet.KITTY_FLEX_CATAKEET_MODEL
|
||||
local modifier_kitty_flex_catakeet = ____modifier_kitty_flex_catakeet.modifier_kitty_flex_catakeet
|
||||
local DEFAULT_SOUND_CONFIG = {cooldown = 15, globalCooldown = 0, blocksOtherSounds = false, blockDuration = 0}
|
||||
local SOUND_CONFIGS = {
|
||||
i_am_sad = {
|
||||
cooldown = 300,
|
||||
globalCooldown = 300,
|
||||
blocksOtherSounds = true,
|
||||
blockDuration = 5.7,
|
||||
effect = "rain",
|
||||
effectDuration = 5.7,
|
||||
timescale = 0.1
|
||||
},
|
||||
jump = {
|
||||
cooldown = 300,
|
||||
globalCooldown = 300,
|
||||
blocksOtherSounds = true,
|
||||
blockDuration = 38,
|
||||
effect = "jump",
|
||||
effectDuration = 38,
|
||||
jumpInterval = 0.35,
|
||||
jumpRadius = 350,
|
||||
jumpHeight = 250,
|
||||
jumpHeightOnPlace = 250
|
||||
},
|
||||
agent_gabena = DEFAULT_SOUND_CONFIG,
|
||||
byd_dobr_idi = DEFAULT_SOUND_CONFIG,
|
||||
cat_shnapy = DEFAULT_SOUND_CONFIG,
|
||||
dobro_pozhalovat_v_club = DEFAULT_SOUND_CONFIG,
|
||||
eto_prosto_okhueno = DEFAULT_SOUND_CONFIG,
|
||||
get_out = DEFAULT_SOUND_CONFIG,
|
||||
ia_vas_unichtozhu = DEFAULT_SOUND_CONFIG,
|
||||
kak_rulit = DEFAULT_SOUND_CONFIG,
|
||||
kto_myaukaet = DEFAULT_SOUND_CONFIG,
|
||||
Muhehehehe = DEFAULT_SOUND_CONFIG,
|
||||
ne_tvoy_uroven_dorogoy = DEFAULT_SOUND_CONFIG,
|
||||
ne_ponimaiu_karina_strimersha_slozhno_slozhno = DEFAULT_SOUND_CONFIG,
|
||||
nikhuia_ne_ponial_no_ochen_interesno = DEFAULT_SOUND_CONFIG,
|
||||
oi_tak_nravitsa = DEFAULT_SOUND_CONFIG,
|
||||
olyhi_bezdari_ogyzki = DEFAULT_SOUND_CONFIG,
|
||||
ou_mai = DEFAULT_SOUND_CONFIG,
|
||||
po_syobam = DEFAULT_SOUND_CONFIG,
|
||||
poshel_process = DEFAULT_SOUND_CONFIG,
|
||||
posledniy_ponedelnik_zivesh = DEFAULT_SOUND_CONFIG,
|
||||
rot_etogo_kazino = DEFAULT_SOUND_CONFIG,
|
||||
s_kakoy_stati = DEFAULT_SOUND_CONFIG,
|
||||
sir_no_sir = DEFAULT_SOUND_CONFIG,
|
||||
sir_yes_sir = DEFAULT_SOUND_CONFIG,
|
||||
stop_mne_ne_priyatno = DEFAULT_SOUND_CONFIG,
|
||||
stoyat_ya_yzhe_eto_sosal = DEFAULT_SOUND_CONFIG,
|
||||
ura_pobeda = DEFAULT_SOUND_CONFIG,
|
||||
uvorot_ot_spelov = DEFAULT_SOUND_CONFIG,
|
||||
v_komp_igri_igral = DEFAULT_SOUND_CONFIG,
|
||||
vot_eto_nikhuia_sebe = DEFAULT_SOUND_CONFIG,
|
||||
zachem_ya_suda_prishel = DEFAULT_SOUND_CONFIG,
|
||||
zaika = DEFAULT_SOUND_CONFIG,
|
||||
kitty_flex = {
|
||||
cooldown = 15,
|
||||
globalCooldown = 0,
|
||||
blocksOtherSounds = true,
|
||||
blockDuration = 13.6,
|
||||
effect = "kitty_flex",
|
||||
effectDuration = 13.6,
|
||||
initialThrowCount = 5,
|
||||
incrementThrowCount = 1,
|
||||
throwRadiusMin = 120,
|
||||
throwRadiusMax = 420,
|
||||
throwHeightMin = 160,
|
||||
throwHeightMax = 340,
|
||||
throwDuration = 0.45,
|
||||
throwInterval = 1,
|
||||
bounceRadiusMin = 80,
|
||||
bounceRadiusMax = 360,
|
||||
bounceHeightMin = 110,
|
||||
bounceHeightMax = 220,
|
||||
bounceIntervalMin = 0.55,
|
||||
bounceIntervalMax = 1,
|
||||
lookIntervalMin = 0.35,
|
||||
lookIntervalMax = 0.75,
|
||||
shakeInterval = 0.35
|
||||
},
|
||||
eblo_razraba = DEFAULT_SOUND_CONFIG,
|
||||
kuda = DEFAULT_SOUND_CONFIG,
|
||||
bruh = DEFAULT_SOUND_CONFIG,
|
||||
shizofreniya = DEFAULT_SOUND_CONFIG,
|
||||
vot_eto_povorot = DEFAULT_SOUND_CONFIG,
|
||||
fbi_open_up = DEFAULT_SOUND_CONFIG,
|
||||
nepravilno_poprobuy_esche_raz = DEFAULT_SOUND_CONFIG,
|
||||
dobro_pozhalovat_na_server_shizofreniya = DEFAULT_SOUND_CONFIG,
|
||||
nya = DEFAULT_SOUND_CONFIG,
|
||||
na_nas_napali = DEFAULT_SOUND_CONFIG,
|
||||
murlok = DEFAULT_SOUND_CONFIG,
|
||||
kak_zhit_to_a = DEFAULT_SOUND_CONFIG
|
||||
}
|
||||
____exports.SoundCooldownSystem = __TS__Class()
|
||||
local SoundCooldownSystem = ____exports.SoundCooldownSystem
|
||||
SoundCooldownSystem.name = "SoundCooldownSystem"
|
||||
SoundCooldownSystem.____file_path = "scripts/vscripts/SoundSystem.lua"
|
||||
function SoundCooldownSystem.prototype.____constructor(self)
|
||||
self.cooldowns = __TS__New(Map)
|
||||
self.cooldownSettings = __TS__New(Map)
|
||||
self.globalCooldowns = __TS__New(Map)
|
||||
self.globalCooldownSettings = __TS__New(Map)
|
||||
self.soundConfigs = __TS__New(Map)
|
||||
self.blockingSounds = __TS__New(Map)
|
||||
end
|
||||
function SoundCooldownSystem.getInstance(self)
|
||||
if not ____exports.SoundCooldownSystem.instance then
|
||||
____exports.SoundCooldownSystem.instance = __TS__New(____exports.SoundCooldownSystem)
|
||||
end
|
||||
return ____exports.SoundCooldownSystem.instance
|
||||
end
|
||||
function SoundCooldownSystem.prototype.setSoundConfig(self, soundId, config)
|
||||
self.soundConfigs:set(soundId, config)
|
||||
if config.cooldown ~= nil and config.cooldown > 0 then
|
||||
self.cooldownSettings:set(soundId, config.cooldown)
|
||||
print(((("[SoundCooldownSystem] Установлен индивидуальный кулдаун для звука " .. soundId) .. ": ") .. tostring(config.cooldown)) .. " сек")
|
||||
end
|
||||
if config.globalCooldown ~= nil and config.globalCooldown > 0 then
|
||||
self.globalCooldownSettings:set(soundId, config.globalCooldown)
|
||||
print(((("[SoundCooldownSystem] Установлен глобальный кулдаун для звука " .. soundId) .. ": ") .. tostring(config.globalCooldown)) .. " сек")
|
||||
end
|
||||
print((((((("[SoundCooldownSystem] Конфигурация для звука " .. soundId) .. ": cooldown=") .. tostring(config.cooldown or 0)) .. ", globalCooldown=") .. tostring(config.globalCooldown or 0)) .. ", blocksOtherSounds=") .. tostring(config.blocksOtherSounds or false))
|
||||
end
|
||||
function SoundCooldownSystem.prototype.setCooldown(self, soundId, duration)
|
||||
self.cooldownSettings:set(soundId, duration)
|
||||
print(((("[SoundCooldownSystem] Установлен индивидуальный кулдаун для звука " .. soundId) .. ": ") .. tostring(duration)) .. " сек")
|
||||
end
|
||||
function SoundCooldownSystem.prototype.setGlobalCooldown(self, soundId, duration)
|
||||
self.globalCooldownSettings:set(soundId, duration)
|
||||
print(((("[SoundCooldownSystem] Установлен глобальный кулдаун для звука " .. soundId) .. ": ") .. tostring(duration)) .. " сек")
|
||||
end
|
||||
function SoundCooldownSystem.prototype.getSoundConfig(self, soundId, soundName)
|
||||
return self.soundConfigs:get(self:resolveSoundConfigKey(soundId, soundName))
|
||||
end
|
||||
function SoundCooldownSystem.prototype.resolveSoundConfigKey(self, soundId, soundName)
|
||||
local function stripStorePrefix(____, value)
|
||||
local prefix = "chat_wheel_sound_"
|
||||
if __TS__StringStartsWith(value, prefix) then
|
||||
return __TS__StringSubstring(value, #prefix)
|
||||
end
|
||||
return value
|
||||
end
|
||||
local candidates = {}
|
||||
if soundId ~= "" then
|
||||
candidates[#candidates + 1] = soundId
|
||||
candidates[#candidates + 1] = stripStorePrefix(nil, soundId)
|
||||
end
|
||||
if soundName ~= nil and soundName ~= "" then
|
||||
candidates[#candidates + 1] = soundName
|
||||
candidates[#candidates + 1] = stripStorePrefix(nil, soundName)
|
||||
end
|
||||
for ____, key in ipairs(candidates) do
|
||||
if self.soundConfigs:has(key) then
|
||||
return key
|
||||
end
|
||||
end
|
||||
return soundName or soundId
|
||||
end
|
||||
function SoundCooldownSystem.prototype.isBlockingOtherSounds(self, soundId)
|
||||
local config = self.soundConfigs:get(soundId)
|
||||
return (config and config.blocksOtherSounds) == true
|
||||
end
|
||||
function SoundCooldownSystem.prototype.getBlockDuration(self, soundId)
|
||||
local config = self.soundConfigs:get(soundId)
|
||||
return config and config.blockDuration or 0
|
||||
end
|
||||
function SoundCooldownSystem.prototype.setBlocking(self, soundId, isBlocking)
|
||||
if isBlocking then
|
||||
self.blockingSounds:set(soundId, true)
|
||||
else
|
||||
self.blockingSounds:delete(soundId)
|
||||
end
|
||||
end
|
||||
function SoundCooldownSystem.prototype.isAnySoundBlocking(self)
|
||||
return self.blockingSounds.size > 0
|
||||
end
|
||||
function SoundCooldownSystem.prototype.canPlaySound(self, soundId, playerId)
|
||||
local steamId = PlayerResource:GetSteamAccountID(playerId)
|
||||
if steamId == ____exports.SoundCooldownSystem.NO_COOLDOWN_STEAM_ID then
|
||||
return true
|
||||
end
|
||||
local currentTime = GameRules:GetGameTime()
|
||||
local cooldown = self.cooldownSettings:get(soundId)
|
||||
if cooldown and cooldown > 0 then
|
||||
local playerCooldowns = self.cooldowns:get(soundId)
|
||||
if playerCooldowns then
|
||||
local endTime = playerCooldowns:get(playerId)
|
||||
if endTime and currentTime < endTime then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
local globalCooldown = self.globalCooldownSettings:get(soundId)
|
||||
if globalCooldown and globalCooldown > 0 then
|
||||
local globalEndTime = self.globalCooldowns:get(soundId)
|
||||
if globalEndTime and currentTime < globalEndTime then
|
||||
local playerCooldowns = self.cooldowns:get(soundId)
|
||||
if playerCooldowns and playerCooldowns:has(playerId) then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
function SoundCooldownSystem.prototype.getRemainingCooldown(self, soundId, playerId)
|
||||
local currentTime = GameRules:GetGameTime()
|
||||
local globalRemaining = 0
|
||||
local individualRemaining = 0
|
||||
local playerCooldowns = self.cooldowns:get(soundId)
|
||||
if playerCooldowns then
|
||||
local endTime = playerCooldowns:get(playerId)
|
||||
if endTime then
|
||||
individualRemaining = endTime - currentTime
|
||||
if individualRemaining < 0 then
|
||||
individualRemaining = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
if playerCooldowns and playerCooldowns:has(playerId) then
|
||||
return individualRemaining
|
||||
end
|
||||
local globalCooldown = self.globalCooldownSettings:get(soundId)
|
||||
if globalCooldown and globalCooldown > 0 then
|
||||
local globalEndTime = self.globalCooldowns:get(soundId)
|
||||
if globalEndTime then
|
||||
globalRemaining = globalEndTime - currentTime
|
||||
if globalRemaining < 0 then
|
||||
globalRemaining = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
return math.max(globalRemaining, individualRemaining)
|
||||
end
|
||||
function SoundCooldownSystem.prototype.setPlayerCooldown(self, soundId, playerId)
|
||||
local currentTime = GameRules:GetGameTime()
|
||||
local globalCooldown = self.globalCooldownSettings:get(soundId)
|
||||
if globalCooldown and globalCooldown > 0 then
|
||||
local globalEndTime = currentTime + globalCooldown
|
||||
self.globalCooldowns:set(soundId, globalEndTime)
|
||||
print(((((("[SoundCooldownSystem] Установлен глобальный кулдаун для звука " .. soundId) .. ": до ") .. tostring(globalEndTime)) .. " (через ") .. tostring(globalCooldown)) .. " сек)")
|
||||
end
|
||||
local cooldown = self.cooldownSettings:get(soundId)
|
||||
if cooldown and cooldown > 0 then
|
||||
if not self.cooldowns:has(soundId) then
|
||||
self.cooldowns:set(
|
||||
soundId,
|
||||
__TS__New(Map)
|
||||
)
|
||||
end
|
||||
local playerCooldowns = self.cooldowns:get(soundId)
|
||||
local endTime = currentTime + cooldown
|
||||
playerCooldowns:set(playerId, endTime)
|
||||
print(((((((("[SoundCooldownSystem] Установлен индивидуальный кулдаун для игрока " .. tostring(playerId)) .. ", звук ") .. soundId) .. ": до ") .. tostring(endTime)) .. " (через ") .. tostring(cooldown)) .. " сек)")
|
||||
end
|
||||
end
|
||||
function SoundCooldownSystem.prototype.clearCooldown(self, soundId, playerId)
|
||||
local playerCooldowns = self.cooldowns:get(soundId)
|
||||
if playerCooldowns then
|
||||
playerCooldowns:delete(playerId)
|
||||
print((("[SoundCooldownSystem] Кулдаун очищен для игрока " .. tostring(playerId)) .. ", звук ") .. soundId)
|
||||
end
|
||||
end
|
||||
SoundCooldownSystem.NO_COOLDOWN_STEAM_ID = 877002179
|
||||
____exports.SoundEventSystem = __TS__Class()
|
||||
local SoundEventSystem = ____exports.SoundEventSystem
|
||||
SoundEventSystem.name = "SoundEventSystem"
|
||||
SoundEventSystem.____file_path = "scripts/vscripts/SoundSystem.lua"
|
||||
function SoundEventSystem.prototype.____constructor(self)
|
||||
self.soundHandlers = __TS__New(Map)
|
||||
self.globalHandlers = {}
|
||||
end
|
||||
function SoundEventSystem.getInstance(self)
|
||||
if not ____exports.SoundEventSystem.instance then
|
||||
____exports.SoundEventSystem.instance = __TS__New(____exports.SoundEventSystem)
|
||||
end
|
||||
return ____exports.SoundEventSystem.instance
|
||||
end
|
||||
function SoundEventSystem.prototype.onSound(self, soundId, handler)
|
||||
if not self.soundHandlers:has(soundId) then
|
||||
self.soundHandlers:set(soundId, {})
|
||||
end
|
||||
local ____temp_4 = self.soundHandlers:get(soundId)
|
||||
____temp_4[#____temp_4 + 1] = handler
|
||||
end
|
||||
function SoundEventSystem.prototype.onAnySound(self, handler)
|
||||
local ____self_globalHandlers_5 = self.globalHandlers
|
||||
____self_globalHandlers_5[#____self_globalHandlers_5 + 1] = handler
|
||||
end
|
||||
function SoundEventSystem.prototype.triggerSoundEvent(self, playerId, soundId, soundName, soundData)
|
||||
local eventData = {playerId = playerId, soundId = soundId, soundName = soundName, soundData = soundData}
|
||||
for ____, handler in ipairs(self.globalHandlers) do
|
||||
do
|
||||
local function ____catch(e)
|
||||
print("[SoundEventSystem] Ошибка в глобальном обработчике звука: " .. tostring(e))
|
||||
end
|
||||
local ____try, ____hasReturned = pcall(function()
|
||||
handler(nil, eventData)
|
||||
end)
|
||||
if not ____try then
|
||||
____catch(____hasReturned)
|
||||
end
|
||||
end
|
||||
end
|
||||
local handlers = self.soundHandlers:get(soundId)
|
||||
if handlers then
|
||||
for ____, handler in ipairs(handlers) do
|
||||
do
|
||||
local function ____catch(e)
|
||||
print((("[SoundEventSystem] Ошибка в обработчике звука " .. soundId) .. ": ") .. tostring(e))
|
||||
end
|
||||
local ____try, ____hasReturned = pcall(function()
|
||||
handler(nil, eventData)
|
||||
end)
|
||||
if not ____try then
|
||||
____catch(____hasReturned)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if soundName and soundName ~= soundId then
|
||||
local handlersByName = self.soundHandlers:get(soundName)
|
||||
if handlersByName then
|
||||
for ____, handler in ipairs(handlersByName) do
|
||||
do
|
||||
local function ____catch(e)
|
||||
print((("[SoundEventSystem] Ошибка в обработчике звука " .. soundName) .. ": ") .. tostring(e))
|
||||
end
|
||||
local ____try, ____hasReturned = pcall(function()
|
||||
handler(nil, eventData)
|
||||
end)
|
||||
if not ____try then
|
||||
____catch(____hasReturned)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function SoundEventSystem.prototype.removeHandler(self, soundId, handler)
|
||||
local handlers = self.soundHandlers:get(soundId)
|
||||
if handlers then
|
||||
local index = __TS__ArrayIndexOf(handlers, handler)
|
||||
if index > -1 then
|
||||
__TS__ArraySplice(handlers, index, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
function SoundEventSystem.prototype.removeGlobalHandler(self, handler)
|
||||
local index = __TS__ArrayIndexOf(self.globalHandlers, handler)
|
||||
if index > -1 then
|
||||
__TS__ArraySplice(self.globalHandlers, index, 1)
|
||||
end
|
||||
end
|
||||
____exports.SoundSystemManager = __TS__Class()
|
||||
local SoundSystemManager = ____exports.SoundSystemManager
|
||||
SoundSystemManager.name = "SoundSystemManager"
|
||||
SoundSystemManager.____file_path = "scripts/vscripts/SoundSystem.lua"
|
||||
function SoundSystemManager.prototype.____constructor(self)
|
||||
self.rainStopTimer = nil
|
||||
self.originalTimescale = 1
|
||||
self.jumpStopTimer = nil
|
||||
self.jumpCycleTimer = nil
|
||||
self.kittyFlexStopTimer = nil
|
||||
self.kittyFlexShakeTimer = nil
|
||||
self.kittyFlexThrowTimer = nil
|
||||
self.kittyFlexUnits = {}
|
||||
end
|
||||
function SoundSystemManager.getInstance(self)
|
||||
if not ____exports.SoundSystemManager.instance then
|
||||
____exports.SoundSystemManager.instance = __TS__New(____exports.SoundSystemManager)
|
||||
end
|
||||
return ____exports.SoundSystemManager.instance
|
||||
end
|
||||
function SoundSystemManager.prototype.initialize(self)
|
||||
self:setupSoundCooldowns()
|
||||
self:setupSoundWeatherHandler()
|
||||
self:setupJumpSoundHandler()
|
||||
self:setupKittyFlexSoundHandler()
|
||||
end
|
||||
function SoundSystemManager.prototype.setupSoundCooldowns(self)
|
||||
local cooldownSystem = ____exports.SoundCooldownSystem:getInstance()
|
||||
for ____, ____value in ipairs(__TS__ObjectEntries(SOUND_CONFIGS)) do
|
||||
local soundId = ____value[1]
|
||||
local config = ____value[2]
|
||||
cooldownSystem:setSoundConfig(soundId, {cooldown = config.cooldown, globalCooldown = config.globalCooldown, blocksOtherSounds = config.blocksOtherSounds, blockDuration = config.blockDuration})
|
||||
end
|
||||
end
|
||||
function SoundSystemManager.prototype.updateSoundCooldownInNetTables(self, playerId, soundId, remainingTime)
|
||||
local soundCooldowns = CustomNetTables:GetTableValue(
|
||||
"sound_cooldowns",
|
||||
tostring(playerId)
|
||||
)
|
||||
if not soundCooldowns then
|
||||
soundCooldowns = {}
|
||||
end
|
||||
soundCooldowns[soundId] = remainingTime
|
||||
CustomNetTables:SetTableValue(
|
||||
"sound_cooldowns",
|
||||
tostring(playerId),
|
||||
soundCooldowns
|
||||
)
|
||||
end
|
||||
function SoundSystemManager.prototype.startSoundCooldownTimer(self, playerId, soundId)
|
||||
local cooldownSystem = ____exports.SoundCooldownSystem:getInstance()
|
||||
local timerId = (("sound_cooldown_" .. tostring(playerId)) .. "_") .. soundId
|
||||
Timers:RemoveTimer(timerId)
|
||||
Timers:CreateTimer(
|
||||
timerId,
|
||||
{
|
||||
useGameTime = true,
|
||||
endTime = 1,
|
||||
callback = function()
|
||||
local remaining = cooldownSystem:getRemainingCooldown(soundId, playerId)
|
||||
if remaining > 0 then
|
||||
self:updateSoundCooldownInNetTables(playerId, soundId, remaining)
|
||||
return 1
|
||||
else
|
||||
local soundCooldowns = CustomNetTables:GetTableValue(
|
||||
"sound_cooldowns",
|
||||
tostring(playerId)
|
||||
)
|
||||
if soundCooldowns then
|
||||
__TS__Delete(soundCooldowns, soundId)
|
||||
CustomNetTables:SetTableValue(
|
||||
"sound_cooldowns",
|
||||
tostring(playerId),
|
||||
soundCooldowns
|
||||
)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
end
|
||||
}
|
||||
)
|
||||
end
|
||||
function SoundSystemManager.prototype.setupSoundWeatherHandler(self)
|
||||
local config = SOUND_CONFIGS.i_am_sad
|
||||
local function handleSadSound(____, data)
|
||||
local isIAmSadSound = data.soundName == "i_am_sad" or data.soundId == "i_am_sad" or data.soundId and __TS__StringIncludes(data.soundId, "i_am_sad") or data.soundName and __TS__StringIncludes(data.soundName, "i_am_sad")
|
||||
if not isIAmSadSound then
|
||||
return
|
||||
end
|
||||
print(((("[SoundSystem] Звук " .. data.soundName) .. " воспроизведен игроком ") .. tostring(data.playerId)) .. ", начинаем дождь")
|
||||
if self.rainStopTimer then
|
||||
Timers:RemoveTimer(self.rainStopTimer)
|
||||
self.rainStopTimer = nil
|
||||
end
|
||||
local currentTimescale = Convars:GetFloat("host_timescale") or 1
|
||||
if currentTimescale >= 0.9 then
|
||||
self.originalTimescale = currentTimescale
|
||||
end
|
||||
Convars:SetFloat("host_timescale", config.timescale)
|
||||
print("[SoundSystem] host_timescale установлен в " .. tostring(config.timescale))
|
||||
self:startRainForAllPlayers()
|
||||
self.rainStopTimer = Timers:CreateTimer({
|
||||
useGameTime = false,
|
||||
endTime = config.effectDuration,
|
||||
callback = function()
|
||||
print(("[SoundSystem] Звук " .. data.soundName) .. " закончился, останавливаем дождь и восстанавливаем время")
|
||||
self:stopRainForAllPlayers()
|
||||
Convars:SetFloat("host_timescale", self.originalTimescale)
|
||||
print("[SoundSystem] host_timescale восстановлен в " .. tostring(self.originalTimescale))
|
||||
self.originalTimescale = 1
|
||||
self.rainStopTimer = nil
|
||||
return nil
|
||||
end
|
||||
})
|
||||
end
|
||||
____exports.SoundEventSystem:getInstance():onSound("i_am_sad", handleSadSound)
|
||||
____exports.SoundEventSystem:getInstance():onAnySound(handleSadSound)
|
||||
end
|
||||
function SoundSystemManager.prototype.setupJumpSoundHandler(self)
|
||||
local config = SOUND_CONFIGS.jump
|
||||
local function performScreenShake()
|
||||
local SHAKE_START = 0
|
||||
local SHAKE_STOP = 1
|
||||
do
|
||||
local playerID = 0
|
||||
while playerID < DOTA_MAX_PLAYERS do
|
||||
if PlayerResource:IsValidPlayerID(playerID) then
|
||||
local hero = PlayerResource:GetSelectedHeroEntity(playerID)
|
||||
if hero and IsValidEntity(hero) and not hero:IsNull() then
|
||||
local pos = hero:GetAbsOrigin()
|
||||
ScreenShake(
|
||||
pos,
|
||||
1500,
|
||||
1600,
|
||||
0.5,
|
||||
1700,
|
||||
SHAKE_STOP,
|
||||
true
|
||||
)
|
||||
ScreenShake(
|
||||
pos,
|
||||
1500,
|
||||
1600,
|
||||
0.5,
|
||||
1700,
|
||||
SHAKE_START,
|
||||
true
|
||||
)
|
||||
end
|
||||
end
|
||||
playerID = playerID + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
local jumpCycleCount = 0
|
||||
local function performJump()
|
||||
jumpCycleCount = jumpCycleCount + 1
|
||||
performScreenShake(nil)
|
||||
local JUMP_DURATION = 0.3
|
||||
local heroes = {}
|
||||
do
|
||||
local i = 0
|
||||
while i < PlayerResource:GetPlayerCount() do
|
||||
local hero = PlayerResource:GetSelectedHeroEntity(i)
|
||||
if hero and IsValidEntity(hero) and not hero:IsNull() and hero.IsAlive and hero:IsAlive() then
|
||||
heroes[#heroes + 1] = hero
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
local classnames = {"npc_dota_creature", "npc_dota_base", "npc_dota_creep_neutral"}
|
||||
local allUnits = {}
|
||||
for ____, hero in ipairs(heroes) do
|
||||
allUnits[#allUnits + 1] = hero
|
||||
end
|
||||
for ____, classname in ipairs(classnames) do
|
||||
local units = Entities:FindAllByClassname(classname)
|
||||
for ____, unit in ipairs(units) do
|
||||
if unit and IsValidEntity(unit) and not unit:IsNull() then
|
||||
if unit.IsAlive and unit:IsAlive() then
|
||||
if not (unit.IsRealHero and unit:IsRealHero()) then
|
||||
allUnits[#allUnits + 1] = unit
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
print(((((("[SoundSystem] Прыжок #" .. tostring(jumpCycleCount)) .. ", юнитов: ") .. tostring(#allUnits)) .. " (героев: ") .. tostring(#heroes)) .. ")")
|
||||
for ____, unit in ipairs(allUnits) do
|
||||
do
|
||||
if not unit or unit:IsNull() or not IsValidEntity(unit) then
|
||||
goto __continue112
|
||||
end
|
||||
if unit:HasModifier(modifier_general_arc.name) then
|
||||
goto __continue112
|
||||
end
|
||||
local unitOrigin = unit:GetAbsOrigin()
|
||||
local targetX
|
||||
local targetY
|
||||
local targetZ
|
||||
local jumpDistance
|
||||
local isHero = unit.IsRealHero and unit:IsRealHero()
|
||||
if isHero then
|
||||
local forwardVector = unit:GetForwardVector()
|
||||
jumpDistance = RandomFloat(config.jumpRadius * 0.5, config.jumpRadius)
|
||||
targetX = unitOrigin.x + forwardVector.x * jumpDistance
|
||||
targetY = unitOrigin.y + forwardVector.y * jumpDistance
|
||||
targetZ = unitOrigin.z
|
||||
else
|
||||
targetX = unitOrigin.x
|
||||
targetY = unitOrigin.y
|
||||
targetZ = unitOrigin.z
|
||||
jumpDistance = 0
|
||||
end
|
||||
modifier_general_arc:apply(unit, unit, nil, {
|
||||
x = targetX,
|
||||
y = targetY,
|
||||
z = targetZ,
|
||||
duration = JUMP_DURATION,
|
||||
distance = jumpDistance,
|
||||
height = isHero and config.jumpHeight or config.jumpHeightOnPlace,
|
||||
isFlail = false
|
||||
})
|
||||
if isHero then
|
||||
print((((((("[SoundSystem] Герой " .. unit:GetUnitName()) .. " прыгает в направлении взгляда (") .. __TS__NumberToFixed(targetX, 2)) .. ", ") .. __TS__NumberToFixed(targetY, 2)) .. ") на расстояние ") .. __TS__NumberToFixed(jumpDistance, 2))
|
||||
else
|
||||
print(("[SoundSystem] Юнит " .. unit:GetUnitName()) .. " прыгает на месте")
|
||||
end
|
||||
end
|
||||
::__continue112::
|
||||
end
|
||||
end
|
||||
local function handleJumpSound(____, data)
|
||||
local isJumpSound = data.soundName == "jump" or data.soundId == "jump" or data.soundId and __TS__StringIncludes(data.soundId, "jump") or data.soundName and __TS__StringIncludes(data.soundName, "jump")
|
||||
if not isJumpSound then
|
||||
return
|
||||
end
|
||||
print(((((((("[SoundSystem] Звук " .. data.soundName) .. " (soundId: ") .. data.soundId) .. ") воспроизведен игроком ") .. tostring(data.playerId)) .. ", начинаем цикл прыжков на ") .. tostring(config.effectDuration)) .. " секунд")
|
||||
if self.jumpStopTimer then
|
||||
Timers:RemoveTimer(self.jumpStopTimer)
|
||||
self.jumpStopTimer = nil
|
||||
end
|
||||
if self.jumpCycleTimer then
|
||||
Timers:RemoveTimer(self.jumpCycleTimer)
|
||||
self.jumpCycleTimer = nil
|
||||
end
|
||||
jumpCycleCount = 0
|
||||
performJump(nil)
|
||||
local function startJumpCycle()
|
||||
self.jumpCycleTimer = Timers:CreateTimer(
|
||||
config.jumpInterval,
|
||||
function()
|
||||
performJump(nil)
|
||||
return config.jumpInterval
|
||||
end
|
||||
)
|
||||
end
|
||||
startJumpCycle(nil)
|
||||
self.jumpStopTimer = Timers:CreateTimer(
|
||||
config.effectDuration,
|
||||
function()
|
||||
print(("[SoundSystem] Звук " .. data.soundName) .. " закончился, останавливаем прыжки")
|
||||
if self.jumpCycleTimer then
|
||||
Timers:RemoveTimer(self.jumpCycleTimer)
|
||||
self.jumpCycleTimer = nil
|
||||
end
|
||||
self.jumpStopTimer = nil
|
||||
return nil
|
||||
end
|
||||
)
|
||||
end
|
||||
____exports.SoundEventSystem:getInstance():onSound("jump", handleJumpSound)
|
||||
____exports.SoundEventSystem:getInstance():onAnySound(handleJumpSound)
|
||||
end
|
||||
function SoundSystemManager.prototype.setupKittyFlexSoundHandler(self)
|
||||
local config = SOUND_CONFIGS.kitty_flex
|
||||
local KITTY_FLEX_UNIT = "npc_attack_box"
|
||||
local function performScreenShake()
|
||||
local SHAKE_START = 0
|
||||
local SHAKE_STOP = 1
|
||||
do
|
||||
local playerID = 0
|
||||
while playerID < DOTA_MAX_PLAYERS do
|
||||
do
|
||||
if not PlayerResource:IsValidPlayerID(playerID) then
|
||||
goto __continue130
|
||||
end
|
||||
local hero = PlayerResource:GetSelectedHeroEntity(playerID)
|
||||
if hero and IsValidEntity(hero) and not hero:IsNull() then
|
||||
local pos = hero:GetAbsOrigin()
|
||||
ScreenShake(
|
||||
pos,
|
||||
2800,
|
||||
2600,
|
||||
0.65,
|
||||
3200,
|
||||
SHAKE_STOP,
|
||||
true
|
||||
)
|
||||
ScreenShake(
|
||||
pos,
|
||||
2800,
|
||||
2600,
|
||||
0.65,
|
||||
3200,
|
||||
SHAKE_START,
|
||||
true
|
||||
)
|
||||
end
|
||||
end
|
||||
::__continue130::
|
||||
playerID = playerID + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
local function stopKittyFlexTimers()
|
||||
if self.kittyFlexShakeTimer then
|
||||
Timers:RemoveTimer(self.kittyFlexShakeTimer)
|
||||
self.kittyFlexShakeTimer = nil
|
||||
end
|
||||
if self.kittyFlexThrowTimer then
|
||||
Timers:RemoveTimer(self.kittyFlexThrowTimer)
|
||||
self.kittyFlexThrowTimer = nil
|
||||
end
|
||||
end
|
||||
local function cleanupKittyFlexCatakeets()
|
||||
for ____, unit in ipairs(self.kittyFlexUnits) do
|
||||
if unit and IsValidEntity(unit) and not unit:IsNull() then
|
||||
unit:RemoveModifierByName(modifier_kitty_flex_catakeet.name)
|
||||
if IsValidEntity(unit) and not unit:IsNull() then
|
||||
UTIL_Remove(unit)
|
||||
end
|
||||
end
|
||||
end
|
||||
self.kittyFlexUnits = {}
|
||||
end
|
||||
local function throwCatakeetsFromHero(____, hero, count)
|
||||
local origin = hero:GetAbsOrigin()
|
||||
do
|
||||
local i = 0
|
||||
while i < count do
|
||||
do
|
||||
local spawnOffset = RandomVector(RandomFloat(20, 70))
|
||||
local spawnPos = origin + Vector(spawnOffset.x, spawnOffset.y, 0)
|
||||
spawnPos = GetGroundPosition(spawnPos, hero)
|
||||
local angle = RandomFloat(0, 2 * math.pi)
|
||||
local distance = RandomFloat(config.throwRadiusMin, config.throwRadiusMax)
|
||||
local targetPos = Vector(
|
||||
origin.x + math.cos(angle) * distance,
|
||||
origin.y + math.sin(angle) * distance,
|
||||
origin.z
|
||||
)
|
||||
targetPos = GetGroundPosition(targetPos, hero)
|
||||
local unit = CreateUnitByName(
|
||||
KITTY_FLEX_UNIT,
|
||||
spawnPos,
|
||||
true,
|
||||
hero,
|
||||
hero,
|
||||
hero:GetTeamNumber()
|
||||
)
|
||||
if not unit or unit:IsNull() or not IsValidEntity(unit) then
|
||||
goto __continue142
|
||||
end
|
||||
FindClearSpaceForUnit(unit, spawnPos, true)
|
||||
unit:AddNewModifier(
|
||||
hero,
|
||||
getModifierSourceAbility(nil, hero),
|
||||
modifier_kitty_flex_catakeet.name,
|
||||
{
|
||||
bounce_radius_min = config.bounceRadiusMin,
|
||||
bounce_radius_max = config.bounceRadiusMax,
|
||||
bounce_height_min = config.bounceHeightMin,
|
||||
bounce_height_max = config.bounceHeightMax,
|
||||
bounce_interval_min = config.bounceIntervalMin,
|
||||
bounce_interval_max = config.bounceIntervalMax,
|
||||
look_interval_min = config.lookIntervalMin,
|
||||
look_interval_max = config.lookIntervalMax
|
||||
}
|
||||
)
|
||||
local ____self_kittyFlexUnits_6 = self.kittyFlexUnits
|
||||
____self_kittyFlexUnits_6[#____self_kittyFlexUnits_6 + 1] = unit
|
||||
local throwDistance = (targetPos - spawnPos):Length2D()
|
||||
modifier_general_arc:apply(
|
||||
unit,
|
||||
hero,
|
||||
nil,
|
||||
{
|
||||
x = targetPos.x,
|
||||
y = targetPos.y,
|
||||
z = targetPos.z,
|
||||
duration = config.throwDuration,
|
||||
distance = throwDistance,
|
||||
height = RandomFloat(config.throwHeightMin, config.throwHeightMax),
|
||||
isFlail = true
|
||||
}
|
||||
)
|
||||
end
|
||||
::__continue142::
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
local function handleKittyFlexSound(____, data)
|
||||
local isKittyFlexSound = data.soundName == "kitty_flex" or data.soundId == "kitty_flex" or data.soundId and __TS__StringIncludes(data.soundId, "kitty_flex") or data.soundName and __TS__StringIncludes(data.soundName, "kitty_flex")
|
||||
if not isKittyFlexSound then
|
||||
return
|
||||
end
|
||||
print(((("[SoundSystem] kitty_flex от игрока " .. tostring(data.playerId)) .. ", запускаем catakeet + screen shake на ") .. tostring(config.effectDuration)) .. " сек")
|
||||
if self.kittyFlexStopTimer then
|
||||
Timers:RemoveTimer(self.kittyFlexStopTimer)
|
||||
self.kittyFlexStopTimer = nil
|
||||
end
|
||||
stopKittyFlexTimers(nil)
|
||||
cleanupKittyFlexCatakeets(nil)
|
||||
local hero = PlayerResource:GetSelectedHeroEntity(data.playerId)
|
||||
local function throwFromHero(____, count)
|
||||
if not hero or not IsValidEntity(hero) or hero:IsNull() or not hero:IsAlive() then
|
||||
return
|
||||
end
|
||||
throwCatakeetsFromHero(nil, hero, count)
|
||||
end
|
||||
throwFromHero(nil, config.initialThrowCount)
|
||||
performScreenShake(nil)
|
||||
self.kittyFlexShakeTimer = Timers:CreateTimer(
|
||||
config.shakeInterval,
|
||||
function()
|
||||
performScreenShake(nil)
|
||||
return config.shakeInterval
|
||||
end
|
||||
)
|
||||
self.kittyFlexThrowTimer = Timers:CreateTimer(
|
||||
config.throwInterval,
|
||||
function()
|
||||
throwFromHero(nil, config.incrementThrowCount)
|
||||
return config.throwInterval
|
||||
end
|
||||
)
|
||||
self.kittyFlexStopTimer = Timers:CreateTimer(
|
||||
config.effectDuration,
|
||||
function()
|
||||
print("[SoundSystem] kitty_flex закончился, убираем catakeet, screen shake и броски")
|
||||
stopKittyFlexTimers(nil)
|
||||
cleanupKittyFlexCatakeets(nil)
|
||||
self.kittyFlexStopTimer = nil
|
||||
return nil
|
||||
end
|
||||
)
|
||||
end
|
||||
____exports.SoundEventSystem:getInstance():onSound("kitty_flex", handleKittyFlexSound)
|
||||
____exports.SoundEventSystem:getInstance():onAnySound(handleKittyFlexSound)
|
||||
end
|
||||
function SoundSystemManager.prototype.startRainForAllPlayers(self)
|
||||
local players = self:getAllPlayers()
|
||||
for ____, ____value in ipairs(players) do
|
||||
local player = ____value.player
|
||||
if player ~= nil and player ~= nil then
|
||||
self:setWeatherPlayer(player, "dityRain")
|
||||
end
|
||||
end
|
||||
end
|
||||
function SoundSystemManager.prototype.stopRainForAllPlayers(self)
|
||||
local players = self:getAllPlayers()
|
||||
for ____, ____value in ipairs(players) do
|
||||
local player = ____value.player
|
||||
if player ~= nil and player ~= nil then
|
||||
self:setWeatherPlayer(player, "none")
|
||||
end
|
||||
end
|
||||
end
|
||||
function SoundSystemManager.prototype.getAllPlayers(self)
|
||||
local players = {}
|
||||
do
|
||||
local playerID = 0
|
||||
while playerID < DOTA_MAX_PLAYERS do
|
||||
do
|
||||
if not PlayerResource:IsValidPlayerID(playerID) then
|
||||
goto __continue161
|
||||
end
|
||||
local player = PlayerResource:GetPlayer(playerID)
|
||||
if player == nil or player == nil then
|
||||
goto __continue161
|
||||
end
|
||||
local hero = PlayerResource:GetSelectedHeroEntity(playerID)
|
||||
players[#players + 1] = {player = player, hero = hero or nil}
|
||||
end
|
||||
::__continue161::
|
||||
playerID = playerID + 1
|
||||
end
|
||||
end
|
||||
return players
|
||||
end
|
||||
function SoundSystemManager.prototype.setWeatherPlayer(self, player, ____type)
|
||||
if not player.weatherEffect then
|
||||
player.weatherEffect = {}
|
||||
end
|
||||
local ____player_weatherEffect_7 = player.weatherEffect
|
||||
local sound = ____player_weatherEffect_7.sound
|
||||
local effect = ____player_weatherEffect_7.effect
|
||||
if sound and sound.timer then
|
||||
Timers:RemoveTimer(sound.timer)
|
||||
end
|
||||
if sound then
|
||||
StopGlobalSound(sound.name)
|
||||
end
|
||||
if effect then
|
||||
ParticleManager:DestroyParticle(effect, false)
|
||||
end
|
||||
if ____type == "none" then
|
||||
player.weatherEffect.effect = nil
|
||||
player.weatherEffect.sound = nil
|
||||
return
|
||||
end
|
||||
local weatherEffects = {none = "", desertStorm = "particles/rain_fx/econ_weather_sirocco.vpcf", dityRain = "particles/rain_fx/econ_rain.vpcf", snowstorm = "particles/winter_fx/weather_plateau_snow.vpcf"}
|
||||
local weatherSounds = {none = nil, dityRain = {duration = 175, name = "rain"}, desertStorm = nil, snowstorm = {duration = 140, name = "snowstorm"}}
|
||||
local weatherSound = weatherSounds[____type]
|
||||
if weatherSound then
|
||||
local timer = Timers:CreateTimer({
|
||||
endTime = 0.1,
|
||||
useGameTime = false,
|
||||
callback = function()
|
||||
EmitGlobalSound(weatherSound.name)
|
||||
return weatherSound.duration
|
||||
end
|
||||
})
|
||||
player.weatherEffect.sound = {name = weatherSound.name, timer = timer}
|
||||
end
|
||||
local effectPath = weatherEffects[____type]
|
||||
if effectPath ~= nil and effectPath ~= nil and effectPath ~= "" then
|
||||
local hero = PlayerResource:GetSelectedHeroEntity(player:GetPlayerID())
|
||||
if hero ~= nil and hero ~= nil then
|
||||
local particle = ParticleManager:CreateParticleForPlayer(effectPath, PATTACH_EYES_FOLLOW, hero, player)
|
||||
player.weatherEffect.effect = particle
|
||||
end
|
||||
end
|
||||
end
|
||||
--- Частицы погоды (чат-колесо)
|
||||
function ____exports.precacheWeatherParticles(self, context)
|
||||
PrecacheResource("particle", "particles/rain_fx/econ_weather_sirocco.vpcf", context)
|
||||
PrecacheResource("particle", "particles/rain_fx/econ_weather_pestilence.vpcf", context)
|
||||
PrecacheResource("particle", "particles/winter_fx/weather_plateau_snow.vpcf", context)
|
||||
PrecacheResource("particle", "particles/rain_fx/econ_rain.vpcf", context)
|
||||
end
|
||||
--- Модель catakeet для эффекта kitty_flex
|
||||
function ____exports.precacheKittyFlexResources(self, context)
|
||||
PrecacheResource("model", KITTY_FLEX_CATAKEET_MODEL, context)
|
||||
end
|
||||
return ____exports
|
||||
Reference in New Issue
Block a user