initial commit
This commit is contained in:
@@ -0,0 +1,512 @@
|
||||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__Class = ____lualib.__TS__Class
|
||||
local Map = ____lualib.Map
|
||||
local __TS__New = ____lualib.__TS__New
|
||||
local __TS__Iterator = ____lualib.__TS__Iterator
|
||||
local __TS__ArrayIncludes = ____lualib.__TS__ArrayIncludes
|
||||
local ____exports = {}
|
||||
local ____WaveManager = require("WaveManager")
|
||||
local WaveManager = ____WaveManager.WaveManager
|
||||
local ____blackshop = require("blackshop")
|
||||
local BlackShop = ____blackshop.BlackShop
|
||||
local ____custom_game_events = require("custom_game_events")
|
||||
local broadcastZiCyclePhase = ____custom_game_events.broadcastZiCyclePhase
|
||||
local ____CardSystem = require("cards.CardSystem")
|
||||
local shouldPlayerSkipDawnCardSelection = ____CardSystem.shouldPlayerSkipDawnCardSelection
|
||||
local ShowCardSelectionToPlayer = ____CardSystem.ShowCardSelectionToPlayer
|
||||
local ____card_22 = require("cards.examples.card_22")
|
||||
local notifyCard22MorningStarted = ____card_22.notifyCard22MorningStarted
|
||||
local notifyCard22NightStarted = ____card_22.notifyCard22NightStarted
|
||||
local ____card_38 = require("cards.examples.card_38")
|
||||
local notifyCard38MorningStarted = ____card_38.notifyCard38MorningStarted
|
||||
local ____card_45 = require("cards.examples.card_45")
|
||||
local notifyCard45MorningStarted = ____card_45.notifyCard45MorningStarted
|
||||
local ____card_49 = require("cards.examples.card_49")
|
||||
local notifyCard49MorningStarted = ____card_49.notifyCard49MorningStarted
|
||||
local ____card_51 = require("cards.examples.card_51")
|
||||
local notifyCard51MorningStarted = ____card_51.notifyCard51MorningStarted
|
||||
local ____card_63 = require("cards.examples.card_63")
|
||||
local notifyCard63MorningStarted = ____card_63.notifyCard63MorningStarted
|
||||
local notifyCard63NightStarted = ____card_63.notifyCard63NightStarted
|
||||
local ____card_52_effects = require("cards.card_52_effects")
|
||||
local CARD_52_MIN_NIGHT_DURATION_SEC = ____card_52_effects.CARD_52_MIN_NIGHT_DURATION_SEC
|
||||
local getNightDurationReductionSecFromCard52 = ____card_52_effects.getNightDurationReductionSecFromCard52
|
||||
local ____modifier_stats_multiplier = require("modifiers.modifier_stats_multiplier")
|
||||
local invalidateStatsMultiplierSumCache = ____modifier_stats_multiplier.invalidateStatsMultiplierSumCache
|
||||
--- Номер финальной ночи (совпадает с WAVE_SETTINGS в WaveManager).
|
||||
local FINAL_NIGHT_NUMBER = 7
|
||||
--- Сколько секунд длится эта ночь на таймере UI и до утра.
|
||||
local FINAL_NIGHT_DURATION_SEC = 9999
|
||||
--- Огонь на зомби в дневной фазе (Crownfall).
|
||||
local DAYTIME_ZOMBIE_BURN_FIRE_PFX = "particles/econ/items/wraith_king/wraith_king_ti6_bracer/wraith_king_ti6_hellfireblast_debuff_fire.vpcf"
|
||||
local ENABLE_DAY_NIGHT_DEBUG_LOG = false
|
||||
____exports.DayNightCycleManager = __TS__Class()
|
||||
local DayNightCycleManager = ____exports.DayNightCycleManager
|
||||
DayNightCycleManager.name = "DayNightCycleManager"
|
||||
DayNightCycleManager.____file_path = "scripts/vscripts/DayNightCycleManager.lua"
|
||||
function DayNightCycleManager.prototype.____constructor(self)
|
||||
self.dayNightCycleDuration = 300
|
||||
self.isDayTime = false
|
||||
self.dayNightTimer = "DayNightTimer"
|
||||
self.dayDuration = 300
|
||||
self.nightDuration = 300
|
||||
self.nextDayDuration = 300
|
||||
self.nextNightDuration = 300
|
||||
self.timeLeft = 0
|
||||
self.morningSequence = 0
|
||||
self.cutsceneDayNightFreezeDepth = 0
|
||||
self.freezeTimeLeftDecrement = false
|
||||
self.zombieUnitNames = {
|
||||
"npc_wave_zombie",
|
||||
"npc_wave_dead_skeleton",
|
||||
"npc_wave_half_zombie",
|
||||
"npc_wave_bearst_zombie",
|
||||
"npc_wave_toxin_zombie",
|
||||
"npc_wave_skeleton_zombie",
|
||||
"npc_wave_skeleton_zombie_half",
|
||||
"npc_wave_dead_skeleton_archer"
|
||||
}
|
||||
self.zombieDayBurnFireByEnt = __TS__New(Map)
|
||||
end
|
||||
function DayNightCycleManager.prototype.clearAllDayBurnFireParticles(self)
|
||||
for ____, ____value in __TS__Iterator(self.zombieDayBurnFireByEnt) do
|
||||
local pfx = ____value[2]
|
||||
ParticleManager:DestroyParticle(pfx, false)
|
||||
ParticleManager:ReleaseParticleIndex(pfx)
|
||||
end
|
||||
self.zombieDayBurnFireByEnt:clear()
|
||||
end
|
||||
function DayNightCycleManager.prototype.pruneDayBurnFireParticles(self)
|
||||
local toRemove = {}
|
||||
for ____, ____value in __TS__Iterator(self.zombieDayBurnFireByEnt) do
|
||||
local ei = ____value[1]
|
||||
local pfx = ____value[2]
|
||||
local u = EntIndexToHScript(ei)
|
||||
if not u or not IsValidEntity(u) or not u:IsAlive() then
|
||||
ParticleManager:DestroyParticle(pfx, false)
|
||||
ParticleManager:ReleaseParticleIndex(pfx)
|
||||
toRemove[#toRemove + 1] = ei
|
||||
end
|
||||
end
|
||||
for ____, ei in ipairs(toRemove) do
|
||||
self.zombieDayBurnFireByEnt:delete(ei)
|
||||
end
|
||||
end
|
||||
function DayNightCycleManager.prototype.ensureDayBurnFireOnZombie(self, zombieNPC)
|
||||
local ei = zombieNPC:entindex()
|
||||
if self.zombieDayBurnFireByEnt:has(ei) then
|
||||
return
|
||||
end
|
||||
local pfx = ParticleManager:CreateParticle(DAYTIME_ZOMBIE_BURN_FIRE_PFX, PATTACH_ABSORIGIN_FOLLOW, zombieNPC)
|
||||
self.zombieDayBurnFireByEnt:set(ei, pfx)
|
||||
end
|
||||
function DayNightCycleManager.prototype.applyDaytimeZombieBurnDamage(self)
|
||||
if GetMapName() ~= "invasion" then
|
||||
return
|
||||
end
|
||||
self:pruneDayBurnFireParticles()
|
||||
for ____, zombieNPC in ipairs(WaveManager:getInstance():getAliveSpawnedWaveUnits()) do
|
||||
do
|
||||
if not __TS__ArrayIncludes(
|
||||
self.zombieUnitNames,
|
||||
zombieNPC:GetUnitName()
|
||||
) then
|
||||
goto __continue16
|
||||
end
|
||||
ApplyDamage({
|
||||
victim = zombieNPC,
|
||||
attacker = zombieNPC,
|
||||
damage = 50 + zombieNPC:GetMaxHealth() * 0.02,
|
||||
damage_type = DAMAGE_TYPE_PURE
|
||||
})
|
||||
self:ensureDayBurnFireOnZombie(zombieNPC)
|
||||
end
|
||||
::__continue16::
|
||||
end
|
||||
end
|
||||
function DayNightCycleManager.getInstance(self)
|
||||
if not ____exports.DayNightCycleManager.instance then
|
||||
____exports.DayNightCycleManager.instance = __TS__New(____exports.DayNightCycleManager)
|
||||
end
|
||||
return ____exports.DayNightCycleManager.instance
|
||||
end
|
||||
function DayNightCycleManager.prototype.Initialize(self)
|
||||
self.isDayTime = false
|
||||
self.dayDuration = 300
|
||||
self.nightDuration = 300
|
||||
self.nextDayDuration = 300
|
||||
self.nextNightDuration = 300
|
||||
self:StartDayNightCycle()
|
||||
end
|
||||
function DayNightCycleManager.prototype.StartDayNightCycle(self)
|
||||
self.timeLeft = self.isDayTime and self.dayDuration or self.nightDuration
|
||||
Timers:CreateTimer(
|
||||
"TimeLeftTimer",
|
||||
{
|
||||
callback = function()
|
||||
if not self.freezeTimeLeftDecrement then
|
||||
self.timeLeft = self.timeLeft - 1
|
||||
end
|
||||
do
|
||||
pcall(function()
|
||||
CustomGameEventManager:Send_ServerToAllClients("day_night_timer_update", {isDay = self.isDayTime, timeLeft = self.timeLeft})
|
||||
end)
|
||||
end
|
||||
return 1
|
||||
end,
|
||||
endTime = 0
|
||||
}
|
||||
)
|
||||
Timers:CreateTimer(
|
||||
self.dayNightTimer,
|
||||
{
|
||||
callback = function() return self:SwitchDayNight() end,
|
||||
endTime = 0
|
||||
}
|
||||
)
|
||||
end
|
||||
function DayNightCycleManager.prototype.runMorningSequenceAndPostNightCardSelection(self)
|
||||
self.morningSequence = self.morningSequence + 1
|
||||
local nightForCards = WaveManager:getInstance():GetCurrentNight()
|
||||
notifyCard22MorningStarted(nil, nightForCards, self.morningSequence)
|
||||
notifyCard38MorningStarted(nil, nightForCards, self.morningSequence)
|
||||
notifyCard45MorningStarted(nil, self.morningSequence)
|
||||
notifyCard49MorningStarted(nil, self.morningSequence)
|
||||
notifyCard63MorningStarted(nil, self.morningSequence)
|
||||
notifyCard51MorningStarted(nil, self.morningSequence)
|
||||
broadcastZiCyclePhase(nil, {isDay = true, morningSequence = self.morningSequence, nightIndex = nightForCards})
|
||||
self:ShowCardSelectionAfterNight()
|
||||
end
|
||||
function DayNightCycleManager.prototype.SwitchDayNight(self)
|
||||
self.isDayTime = not self.isDayTime
|
||||
BlackShop:getInstance():RefreshShop()
|
||||
self:refreshHeroStatsAfterDayNightSwitch()
|
||||
if self.isDayTime then
|
||||
GameRules:SetTimeOfDay(0.75)
|
||||
self.dayDuration = self.nextDayDuration
|
||||
self.timeLeft = self.dayDuration
|
||||
self:runMorningSequenceAndPostNightCardSelection()
|
||||
self:clearAllDayBurnFireParticles()
|
||||
Timers:CreateTimer(
|
||||
"ZombieBurnTimer",
|
||||
{
|
||||
callback = function()
|
||||
if self.isDayTime then
|
||||
self:applyDaytimeZombieBurnDamage()
|
||||
return 1
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
endTime = 0
|
||||
}
|
||||
)
|
||||
return self.dayDuration
|
||||
else
|
||||
broadcastZiCyclePhase(
|
||||
nil,
|
||||
{
|
||||
isDay = false,
|
||||
morningSequence = self.morningSequence,
|
||||
nightIndex = WaveManager:getInstance():GetCurrentNight()
|
||||
}
|
||||
)
|
||||
GameRules:SetTimeOfDay(0.25)
|
||||
local card52NightReduce = getNightDurationReductionSecFromCard52(nil)
|
||||
self.nightDuration = math.max(CARD_52_MIN_NIGHT_DURATION_SEC, self.nextNightDuration - card52NightReduce)
|
||||
self.timeLeft = self.nightDuration
|
||||
notifyCard63NightStarted(nil)
|
||||
notifyCard22NightStarted(nil)
|
||||
Timers:RemoveTimer("ZombieBurnTimer")
|
||||
self:clearAllDayBurnFireParticles()
|
||||
local waveManager = WaveManager:getInstance()
|
||||
Timers:CreateTimer(
|
||||
0.1,
|
||||
function()
|
||||
waveManager:SetCurrentNight(waveManager:GetCurrentNight() + 1)
|
||||
local night = waveManager:GetCurrentNight()
|
||||
if night == FINAL_NIGHT_NUMBER then
|
||||
self:SetNightDuration(FINAL_NIGHT_DURATION_SEC)
|
||||
self.nightDuration = FINAL_NIGHT_DURATION_SEC
|
||||
self:SetTimeLeft(FINAL_NIGHT_DURATION_SEC)
|
||||
end
|
||||
waveManager:SpawnNextWave()
|
||||
CustomGameEventManager:Send_ServerToAllClients(
|
||||
"wave_started",
|
||||
{night = waveManager:GetCurrentNight()}
|
||||
)
|
||||
return nil
|
||||
end
|
||||
)
|
||||
return self.nightDuration
|
||||
end
|
||||
end
|
||||
function DayNightCycleManager.prototype.refreshHeroStatsAfterDayNightSwitch(self)
|
||||
local n = 0
|
||||
do
|
||||
local i = 0
|
||||
while i < DOTA_MAX_PLAYERS do
|
||||
local hero = PlayerResource:GetSelectedHeroEntity(i)
|
||||
if hero and IsValidEntity(hero) and hero:IsRealHero() then
|
||||
invalidateStatsMultiplierSumCache(nil, hero)
|
||||
hero:CalculateStatBonus(true)
|
||||
n = n + 1
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
if ENABLE_DAY_NIGHT_DEBUG_LOG then
|
||||
print((("[DayNight] refreshHeroStatsAfterDayNightSwitch isDay=" .. tostring(self.isDayTime)) .. " героев=") .. tostring(n))
|
||||
end
|
||||
end
|
||||
function DayNightCycleManager.prototype.SetDayNightCycleDuration(self, seconds)
|
||||
if seconds < 60 then
|
||||
seconds = 60
|
||||
end
|
||||
self.dayNightCycleDuration = seconds
|
||||
Timers:RemoveTimer(self.dayNightTimer)
|
||||
Timers:RemoveTimer("TimeLeftTimer")
|
||||
self:StartDayNightCycle()
|
||||
end
|
||||
function DayNightCycleManager.prototype.GetDayNightCycleDuration(self)
|
||||
return self.dayNightCycleDuration
|
||||
end
|
||||
function DayNightCycleManager.prototype.IsDaytime(self)
|
||||
return self.isDayTime
|
||||
end
|
||||
function DayNightCycleManager.prototype.CanVoteSkipToNight(self)
|
||||
if GameRules:State_Get() ~= DOTA_GAMERULES_STATE_GAME_IN_PROGRESS then
|
||||
return false
|
||||
end
|
||||
if not self.isDayTime then
|
||||
return false
|
||||
end
|
||||
if self.cutsceneDayNightFreezeDepth > 0 then
|
||||
return false
|
||||
end
|
||||
if self.freezeTimeLeftDecrement then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
function DayNightCycleManager.prototype.SetDayDuration(self, seconds)
|
||||
if seconds < 60 then
|
||||
seconds = 60
|
||||
end
|
||||
self.nextDayDuration = seconds
|
||||
end
|
||||
function DayNightCycleManager.prototype.adjustNextDayDurationBy(self, deltaSec)
|
||||
if deltaSec == 0 then
|
||||
return
|
||||
end
|
||||
self:SetDayDuration(self.nextDayDuration + deltaSec)
|
||||
end
|
||||
function DayNightCycleManager.prototype.SetNightDuration(self, seconds)
|
||||
if seconds < 60 then
|
||||
seconds = 60
|
||||
end
|
||||
self.nextNightDuration = seconds
|
||||
end
|
||||
function DayNightCycleManager.prototype.GetDayDuration(self)
|
||||
return self.dayDuration
|
||||
end
|
||||
function DayNightCycleManager.prototype.GetNightDuration(self)
|
||||
return self.nightDuration
|
||||
end
|
||||
function DayNightCycleManager.prototype.GetTimeLeft(self)
|
||||
return self.timeLeft
|
||||
end
|
||||
function DayNightCycleManager.prototype.onCutsceneStarted(self)
|
||||
if GameRules:State_Get() < DOTA_GAMERULES_STATE_GAME_IN_PROGRESS then
|
||||
return
|
||||
end
|
||||
self.cutsceneDayNightFreezeDepth = self.cutsceneDayNightFreezeDepth + 1
|
||||
if self.cutsceneDayNightFreezeDepth ~= 1 then
|
||||
return
|
||||
end
|
||||
Timers:RemoveTimer(self.dayNightTimer)
|
||||
self.freezeTimeLeftDecrement = true
|
||||
GameRules:SetTimeOfDay(0.25)
|
||||
end
|
||||
function DayNightCycleManager.prototype.onCutsceneEnded(self)
|
||||
self.cutsceneDayNightFreezeDepth = self.cutsceneDayNightFreezeDepth - 1
|
||||
if self.cutsceneDayNightFreezeDepth < 0 then
|
||||
self.cutsceneDayNightFreezeDepth = 0
|
||||
end
|
||||
if self.cutsceneDayNightFreezeDepth > 0 then
|
||||
return
|
||||
end
|
||||
self.freezeTimeLeftDecrement = false
|
||||
if GameRules:State_Get() < DOTA_GAMERULES_STATE_GAME_IN_PROGRESS then
|
||||
return
|
||||
end
|
||||
GameRules:SetTimeOfDay(self.isDayTime and 0.75 or 0.25)
|
||||
Timers:RemoveTimer(self.dayNightTimer)
|
||||
Timers:CreateTimer(
|
||||
self.dayNightTimer,
|
||||
{
|
||||
callback = function() return self:SwitchDayNight() end,
|
||||
endTime = self.timeLeft
|
||||
}
|
||||
)
|
||||
do
|
||||
pcall(function()
|
||||
CustomGameEventManager:Send_ServerToAllClients("day_night_timer_update", {isDay = self.isDayTime, timeLeft = self.timeLeft})
|
||||
end)
|
||||
end
|
||||
end
|
||||
function DayNightCycleManager.prototype.SyncStateToPlayer(self, playerId)
|
||||
do
|
||||
local ____try, ____hasReturned, ____returnValue = pcall(function()
|
||||
local player = PlayerResource:GetPlayer(playerId)
|
||||
if not player then
|
||||
return true
|
||||
end
|
||||
CustomGameEventManager:Send_ServerToPlayer(player, "day_night_timer_update", {isDay = self.isDayTime, timeLeft = self.timeLeft})
|
||||
end)
|
||||
if ____try and ____hasReturned then
|
||||
return ____returnValue
|
||||
end
|
||||
end
|
||||
end
|
||||
function DayNightCycleManager.prototype.AdjustTimeLeft(self, delta)
|
||||
local minTime = 1
|
||||
local maxTime = 356400
|
||||
local newTimeLeft = self.timeLeft + delta
|
||||
if newTimeLeft < minTime then
|
||||
newTimeLeft = minTime
|
||||
elseif newTimeLeft > maxTime then
|
||||
newTimeLeft = maxTime
|
||||
end
|
||||
self.timeLeft = newTimeLeft
|
||||
Timers:RemoveTimer(self.dayNightTimer)
|
||||
Timers:CreateTimer(
|
||||
self.dayNightTimer,
|
||||
{
|
||||
callback = function() return self:SwitchDayNight() end,
|
||||
endTime = self.timeLeft
|
||||
}
|
||||
)
|
||||
end
|
||||
function DayNightCycleManager.prototype.SetTimeLeft(self, seconds)
|
||||
local minTime = 1
|
||||
local maxTime = 356400
|
||||
local newTimeLeft = math.floor(seconds)
|
||||
if newTimeLeft < minTime then
|
||||
newTimeLeft = minTime
|
||||
elseif newTimeLeft > maxTime then
|
||||
newTimeLeft = maxTime
|
||||
end
|
||||
self.timeLeft = newTimeLeft
|
||||
Timers:RemoveTimer(self.dayNightTimer)
|
||||
Timers:CreateTimer(
|
||||
self.dayNightTimer,
|
||||
{
|
||||
callback = function() return self:SwitchDayNight() end,
|
||||
endTime = self.timeLeft
|
||||
}
|
||||
)
|
||||
end
|
||||
function DayNightCycleManager.prototype.TryInstantSwitchDayToNightFromVote(self)
|
||||
if GameRules:State_Get() ~= DOTA_GAMERULES_STATE_GAME_IN_PROGRESS then
|
||||
return false
|
||||
end
|
||||
if not self.isDayTime then
|
||||
return false
|
||||
end
|
||||
if self.cutsceneDayNightFreezeDepth > 0 or self.freezeTimeLeftDecrement then
|
||||
return false
|
||||
end
|
||||
Timers:RemoveTimer(self.dayNightTimer)
|
||||
self:SwitchDayNight()
|
||||
Timers:CreateTimer(
|
||||
self.dayNightTimer,
|
||||
{
|
||||
callback = function() return self:SwitchDayNight() end,
|
||||
endTime = self.timeLeft
|
||||
}
|
||||
)
|
||||
do
|
||||
pcall(function()
|
||||
CustomGameEventManager:Send_ServerToAllClients("day_night_timer_update", {isDay = self.isDayTime, timeLeft = self.timeLeft})
|
||||
end)
|
||||
end
|
||||
return true
|
||||
end
|
||||
function DayNightCycleManager.prototype.ForceNightIn(self, seconds)
|
||||
if not self.isDayTime then
|
||||
return
|
||||
end
|
||||
local delay = math.max(
|
||||
1,
|
||||
math.floor(seconds)
|
||||
)
|
||||
self.timeLeft = delay
|
||||
Timers:RemoveTimer(self.dayNightTimer)
|
||||
Timers:CreateTimer(
|
||||
self.dayNightTimer,
|
||||
{
|
||||
callback = function() return self:SwitchDayNight() end,
|
||||
endTime = delay
|
||||
}
|
||||
)
|
||||
end
|
||||
function DayNightCycleManager.prototype.ForceDay(self)
|
||||
if self.isDayTime then
|
||||
return
|
||||
end
|
||||
Timers:RemoveTimer(self.dayNightTimer)
|
||||
Timers:RemoveTimer("ZombieBurnTimer")
|
||||
self:clearAllDayBurnFireParticles()
|
||||
self.isDayTime = true
|
||||
BlackShop:getInstance():RefreshShop()
|
||||
self:refreshHeroStatsAfterDayNightSwitch()
|
||||
GameRules:SetTimeOfDay(0.75)
|
||||
self.dayDuration = self.nextDayDuration
|
||||
self.timeLeft = self.dayDuration
|
||||
self:runMorningSequenceAndPostNightCardSelection()
|
||||
Timers:CreateTimer(
|
||||
"ZombieBurnTimer",
|
||||
{
|
||||
callback = function()
|
||||
if self.isDayTime then
|
||||
self:applyDaytimeZombieBurnDamage()
|
||||
return 1
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
endTime = 0
|
||||
}
|
||||
)
|
||||
Timers:CreateTimer(
|
||||
self.dayNightTimer,
|
||||
{
|
||||
callback = function() return self:SwitchDayNight() end,
|
||||
endTime = self.dayDuration
|
||||
}
|
||||
)
|
||||
end
|
||||
function DayNightCycleManager.prototype.ShowCardSelectionAfterNight(self)
|
||||
do
|
||||
local playerId = 0
|
||||
while playerId < PlayerResource:GetPlayerCount() do
|
||||
do
|
||||
local pid = playerId
|
||||
local player = PlayerResource:GetPlayer(pid)
|
||||
if not player then
|
||||
goto __continue92
|
||||
end
|
||||
local hero = player:GetAssignedHero()
|
||||
if not hero or not hero:IsAlive() then
|
||||
goto __continue92
|
||||
end
|
||||
if shouldPlayerSkipDawnCardSelection(nil, pid) then
|
||||
goto __continue92
|
||||
end
|
||||
ShowCardSelectionToPlayer(nil, pid, 3, "night_completion")
|
||||
end
|
||||
::__continue92::
|
||||
playerId = playerId + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
return ____exports
|
||||
Reference in New Issue
Block a user