Files
Dota-Zombie-Invasion/scripts/vscripts/events/random_events.lua
T
2026-05-29 15:11:31 +07:00

262 lines
9.4 KiB
Lua

local ____lualib = require("lualib_bundle")
local __TS__Class = ____lualib.__TS__Class
local __TS__New = ____lualib.__TS__New
local __TS__ArrayFind = ____lualib.__TS__ArrayFind
local __TS__ArrayForEach = ____lualib.__TS__ArrayForEach
local ____exports = {}
local ____DayNightCycleManager = require("DayNightCycleManager")
local DayNightCycleManager = ____DayNightCycleManager.DayNightCycleManager
____exports.RandomEventsManager = __TS__Class()
local RandomEventsManager = ____exports.RandomEventsManager
RandomEventsManager.name = "RandomEventsManager"
RandomEventsManager.____file_path = "scripts/vscripts/events/random_events.lua"
function RandomEventsManager.prototype.____constructor(self)
self.events = {}
self.gameTimer = 0
self.nextEventTime = 0
self:registerEvents()
self:startEventLoop()
end
function RandomEventsManager.getInstance(self)
if not ____exports.RandomEventsManager.instance then
____exports.RandomEventsManager.instance = __TS__New(____exports.RandomEventsManager)
end
return ____exports.RandomEventsManager.instance
end
function RandomEventsManager.prototype.registerEvents(self)
self.events = {
{
name = "gold_rush",
chance = 0.1,
minInterval = 600,
maxInterval = 3600,
duration = 45,
execute = function() return self:startGoldRush() end
},
{
name = "midas_hands",
chance = 0.1,
minInterval = 1200,
maxInterval = 2400,
duration = 25,
execute = function() return self:StartMidasHands() end
}
}
end
function RandomEventsManager.prototype.startEventLoop(self)
Timers:CreateTimer(function()
self.gameTimer = self.gameTimer + 1
if self.gameTimer % 60 == 0 then
local dayNightManager = DayNightCycleManager:getInstance()
local isDaytime = dayNightManager:IsDaytime()
if isDaytime then
self:triggerRandomEvent()
end
end
return 1
end)
end
function RandomEventsManager.prototype.checkAndTriggerEvents(self)
if self.gameTimer >= self.nextEventTime then
local dayNightManager = DayNightCycleManager:getInstance()
if dayNightManager:IsDaytime() then
self:triggerRandomEvent()
end
local randomEvent = self:getRandomEvent()
if randomEvent then
self.nextEventTime = self.gameTimer + RandomInt(randomEvent.minInterval, randomEvent.maxInterval)
end
end
end
function RandomEventsManager.prototype.getRandomEvent(self)
local roll = RandomInt(1, 100)
local chanceSum = 0
for ____, event in ipairs(self.events) do
chanceSum = chanceSum + event.chance
if roll <= chanceSum then
return event
end
end
return nil
end
function RandomEventsManager.prototype.triggerRandomEvent(self)
local event = self:getRandomEvent()
if event then
event:execute()
end
end
function RandomEventsManager.prototype.sendEventNotification(self, eventName, duration, description)
CustomGameEventManager:Send_ServerToAllClients("random_event_started", {event_name = eventName, duration = duration, description = description})
end
function RandomEventsManager.prototype.startGoldRush(self)
local event = __TS__ArrayFind(
self.events,
function(____, e) return e.name == "gold_rush" end
)
local duration = 45
self:sendEventNotification("#event_gold_rush", duration, "#event_gold_rush_description")
local numGoldPiles = 10 * PlayerResource:GetPlayerCountForTeam(DOTA_TEAM_GOODGUYS)
local currentPile = 0
local spawnNextGold
spawnNextGold = function()
if currentPile >= numGoldPiles then
return
end
local heroes = FindUnitsInRadius(
DOTA_TEAM_GOODGUYS,
Vector(0, 0, 0),
nil,
FIND_UNITS_EVERYWHERE,
DOTA_UNIT_TARGET_TEAM_FRIENDLY,
DOTA_UNIT_TARGET_HERO,
DOTA_UNIT_TARGET_FLAG_NONE,
FIND_ANY_ORDER,
false
)
if #heroes > 0 then
local randomHero = heroes[RandomInt(0, #heroes - 1) + 1]
local heroPos = randomHero:GetAbsOrigin()
local spawnDistance = RandomFloat(300, 800)
local randomAngle = RandomFloat(0, 2 * math.pi)
local randomX = heroPos.x + spawnDistance * math.cos(randomAngle)
local randomY = heroPos.y + spawnDistance * math.sin(randomAngle)
local location = Vector(randomX, randomY, 0)
local groundHeight = GetGroundHeight(location, nil)
local spawnPos = Vector(randomX, randomY)
local item = CreateItem("item_bag_of_gold", nil, nil)
if item ~= nil then
local container = CreateItemOnPositionSync(spawnPos, item)
local dropRadius = RandomFloat(50, 100)
item:LaunchLootInitialHeight(
false,
1000,
150,
1,
spawnPos + RandomVector(dropRadius)
)
if container ~= nil then
Timers:CreateTimer(
30,
function()
if IsValidEntity(container) then
container:RemoveSelf()
end
end
)
currentPile = currentPile + 1
Timers:CreateTimer(
duration / numGoldPiles,
function() return spawnNextGold(nil) end
)
end
end
end
end
spawnNextGold(nil)
GameRules:SendCustomMessage(
("Золотая лихорадка! (" .. tostring(duration)) .. " сек) Собирайте золото, пока оно не исчезло!",
0,
0
)
end
function RandomEventsManager.prototype.StartMidasHands(self)
local event = __TS__ArrayFind(
self.events,
function(____, e) return e.name == "midas_hands" end
)
local duration = event and event.duration or 180
self:sendEventNotification("#event_midas_hands", duration, "#event_midas_hands_description")
local eventHandler = ListenToGameEvent(
"entity_killed",
function(event)
local killedUnit = EntIndexToHScript(event.entindex_killed)
if killedUnit and killedUnit:GetTeamNumber() ~= DOTA_TEAM_GOODGUYS then
local position = killedUnit:GetAbsOrigin()
if RandomFloat(1, 100) <= 15 then
local item = CreateItem("item_bag_of_gold", nil, nil)
if item then
CreateItemOnPositionSync(position, item)
local dropRadius = RandomFloat(50, 100)
item:LaunchLootInitialHeight(
false,
0,
150,
0.5,
position + RandomVector(dropRadius)
)
end
end
end
end,
nil
)
Timers:CreateTimer(
duration,
function()
StopListeningToGameEvent(eventHandler)
GameRules:SendCustomMessage("Благословение Мидаса закончилось!", 0, 0)
end
)
GameRules:SendCustomMessage(
("Благословение Мидаса! (" .. tostring(duration)) .. " сек) После убийства любого врага, вы получите мешок с золотом!",
0,
0
)
end
function RandomEventsManager.prototype.createHealingSprings(self)
local event = __TS__ArrayFind(
self.events,
function(____, e) return e.name == "healing_springs" end
)
local duration = event and event.duration or 120
local springLocations = Entities:FindAllByName("spring_point_*")
local springs = {}
__TS__ArrayForEach(
springLocations,
function(____, location)
local spring = CreateUnitByName(
"npc_healing_spring",
location:GetAbsOrigin(),
true,
nil,
nil,
DOTA_TEAM_NEUTRALS
)
springs[#springs + 1] = spring
end
)
Timers:CreateTimer(
duration,
function()
__TS__ArrayForEach(
springs,
function(____, spring)
if IsValidEntity(spring) then
spring:RemoveSelf()
end
end
)
GameRules:SendCustomMessage("Целебные источники иссякли!", 0, 0)
end
)
GameRules:SendCustomMessage(
("Появились целебные источники! (" .. tostring(duration)) .. " сек) Восстановите здоровье и ману!",
0,
0
)
end
function RandomEventsManager.prototype.triggerEvent(self, eventName)
local dayNightManager = DayNightCycleManager:getInstance()
if not dayNightManager:IsDaytime() then
return
end
local event = __TS__ArrayFind(
self.events,
function(____, e) return e.name == eventName end
)
if event then
event:execute()
end
end
return ____exports