Diff
checker
Testo
Testo
Immagini
Documenti
Excel
Cartelle
Legal
Enterprise
Applicazione per desktop
Prezzi
Accedi
Scarica Diffchecker Desktop
Confronta il testo
Trova la differenza tra due file di testo
Strumenti
Cronologia
Editor live
Comprimi invariate
Senza a capo
Layout
Diviso
Unificato
Livello di dettaglio
Intelligente
Parola
Carattere
Evidenziazione sintassi
Scegli sintassi
Ignora
Trasforma testo
Vai alla prima modifica
Modifica input
Diffchecker Desktop
Il modo più sicuro per usare Diffchecker. Ottieni l'app Diffchecker Desktop: i tuoi diff non lasciano mai il tuo computer!
Ottieni Desktop
Untitled diff
Creato
11 anni fa
Il diff non scade mai
Eliminare
Esporta
Condividere
Spiegare
16 rimozioni
Linee
Totale
Rimosso
Caratteri
Totale
Rimosso
Per continuare a utilizzare questa funzione, aggiorna a
Diff
checker
Pro
Visualizza prezzi
246 linee
Copia tutti
9 aggiunte
Linee
Totale
Aggiunto
Caratteri
Totale
Aggiunto
Per continuare a utilizzare questa funzione, aggiorna a
Diff
checker
Pro
Visualizza prezzi
239 linee
Copia tutti
local BaseHassler = Class(function(self, inst)
local BaseHassler = Class(function(self, inst)
self.inst = inst
self.inst = inst
self.warning = false
self.warning = false
self.timetoattack = nil
self.timetoattack = nil
self.warnduration = 60
self.warnduration = 60
self.timetonextwarningsound = 0
self.timetonextwarningsound = 0
self.announcewarningsoundinterval = 4
self.announcewarningsoundinterval = 4
self.hasslerprefab = "deerclops"
self.hasslerprefab = "deerclops"
self.warningsound = "dontstarve/creatures/deerclops/distant"
self.warningsound = "dontstarve/creatures/deerclops/distant"
self.attacksperwinter = 1
self.attacksperwinter = 1
self.attackduringsummer = false
self.attackduringsummer = false
self.attackdelay = nil
self.attackdelay = nil
self.attackrandom = nil
self.attackrandom = nil
Copia
Copiato
Copia
Copiato
self.inst:ListenForEvent("snowcoverchange", function(inst
)
self.inst:ListenForEvent("snowcoverchange", function(inst
, data)
local snow_cover = GetSeasonManager() and GetSeasonManager():GetSnowPercent() or 0
if
data and data.
snow
>= 0.2 then
if
snow
_cover
>= 0.2 then
if not self.timetoattack then
if not self.timetoattack then
self:StartAttacks()
self:StartAttacks()
end
end
Copia
Copiato
Copia
Copiato
elseif
snow
_cover
<= 0 and self.attackduringsummer and not self.timetoattack then
elseif
data and data.
snow
<= 0 and self.attackduringsummer and not self.timetoattack then
self:StartAttacks()
self:StartAttacks()
else
else
self:CeaseAttacks()
self:CeaseAttacks()
end
end
end, GetWorld() )
end, GetWorld() )
end)
end)
local HASSLER_SPAWN_DIST = 40
local HASSLER_SPAWN_DIST = 40
local WANDER_AWAY_DIST = 100
local WANDER_AWAY_DIST = 100
function BaseHassler:SetHasslerPrefab(prefab)
function BaseHassler:SetHasslerPrefab(prefab)
self.hasslerprefab = prefab
self.hasslerprefab = prefab
end
end
function BaseHassler:SetWarningSound(sound)
function BaseHassler:SetWarningSound(sound)
self.warningsound = sound
self.warningsound = sound
end
end
function BaseHassler:SetAttacksPerWinter(attacks)
function BaseHassler:SetAttacksPerWinter(attacks)
self.attacksperwinter = attacks
self.attacksperwinter = attacks
end
end
function BaseHassler:SetAttackDuringSummer(attack)
function BaseHassler:SetAttackDuringSummer(attack)
self.attackduringsummer = attack
self.attackduringsummer = attack
end
end
function BaseHassler:OnSave()
function BaseHassler:OnSave()
if not self.noserial then
if not self.noserial then
return
return
{
{
warning = self.warning,
warning = self.warning,
timetoattack = self.timetoattack,
timetoattack = self.timetoattack,
attackdelay = self.attackdelay,
attackdelay = self.attackdelay,
attackrandom = self.attackrandom,
attackrandom = self.attackrandom,
}
}
end
end
self.noserial = false
self.noserial = false
end
end
function BaseHassler:OnLoad(data)
function BaseHassler:OnLoad(data)
self.warning = data.warning or false
self.warning = data.warning or false
self.timetoattack = data.timetoattack
self.timetoattack = data.timetoattack
self.attackdelay = data.attackdelay
self.attackdelay = data.attackdelay
self.attackrandom = data.attackrandom
self.attackrandom = data.attackrandom
if self.timetoattack then
if self.timetoattack then
self.inst:StartUpdatingComponent(self)
self.inst:StartUpdatingComponent(self)
end
end
end
end
function BaseHassler:OnProgress()
function BaseHassler:OnProgress()
self.noserial = true
self.noserial = true
end
end
function BaseHassler:GetDebugString()
function BaseHassler:GetDebugString()
if not self.timetoattack then
if not self.timetoattack then
return "DORMANT"
return "DORMANT"
elseif self.timetoattack > 0 then
elseif self.timetoattack > 0 then
return string.format("%s Deerclops is coming in %2.2f", self.warning and "WARNING" or "WAITING", self.timetoattack)
return string.format("%s Deerclops is coming in %2.2f", self.warning and "WARNING" or "WAITING", self.timetoattack)
else
else
return string.format("ATTACKING!!!")
return string.format("ATTACKING!!!")
end
end
end
end
Copia
Copiato
Copia
Copiato
function BaseHassler:LongUpdate(dt)
self:OnUpdate(dt)
end
function BaseHassler:OnUpdate(dt)
function BaseHassler:OnUpdate(dt)
if not self.timetoattack then
if not self.timetoattack then
self:CeaseAttacks()
self:CeaseAttacks()
return
return
end
end
self.timetoattack = self.timetoattack - dt
self.timetoattack = self.timetoattack - dt
if self.timetoattack <= 0 then
if self.timetoattack <= 0 then
self.warning = false
self.warning = false
self:ReleaseHassler()
self:ReleaseHassler()
self:CeaseAttacks()
self:CeaseAttacks()
else
else
if not self.warning and self.timetoattack < self.warnduration then
if not self.warning and self.timetoattack < self.warnduration then
self.warning = true
self.warning = true
self.timetonextwarningsound = 0
self.timetonextwarningsound = 0
end
end
end
end
if self.warning then
if self.warning then
self.timetonextwarningsound = self.timetonextwarningsound - dt
self.timetonextwarningsound = self.timetonextwarningsound - dt
if self.timetonextwarningsound <= 0 then
if self.timetonextwarningsound <= 0 then
self.announcewarningsoundinterval = self.announcewarningsoundinterval - 1
self.announcewarningsoundinterval = self.announcewarningsoundinterval - 1
if self.announcewarningsoundinterval <= 0 then
if self.announcewarningsoundinterval <= 0 then
self.announcewarningsoundinterval = 10 + math.random(5)
self.announcewarningsoundinterval = 10 + math.random(5)
Copia
Copiato
Copia
Copiato
GetPlayer()
.components.talker:Say(GetString(
GetPlayer()
.prefab, "ANNOUNCE_DEERCLOPS"))
self.inst
.components.talker:Say(GetString(
self.inst
.prefab, "ANNOUNCE_DEERCLOPS"))
end
end
local inst = CreateEntity()
local inst = CreateEntity()
inst.entity:AddTransform()
inst.entity:AddTransform()
inst.entity:AddSoundEmitter()
inst.entity:AddSoundEmitter()
inst.persists = false
inst.persists = false
local theta = math.random() * 2 * PI
local theta = math.random() * 2 * PI
local radius = 5
local radius = 5
self.timetonextwarningsound = 15 + math.random(4)
self.timetonextwarningsound = 15 + math.random(4)
if self.timetoattack < 30 then
if self.timetoattack < 30 then
self.timetonextwarningsound = 10 + math.random(1)
self.timetonextwarningsound = 10 + math.random(1)
radius = radius
radius = radius
elseif self.timetoattack < 60 then
elseif self.timetoattack < 60 then
radius = radius + 10
radius = radius + 10
elseif self.timetoattack < 90 then
elseif self.timetoattack < 90 then
radius = radius + 15
radius = radius + 15
else
else
radius = radius + 20
radius = radius + 20
end
end
Copia
Copiato
Copia
Copiato
local offset = Vector3(
GetPlayer()
.Transform:GetWorldPosition()) + Vector3(radius * math.cos( theta ), 0, -radius * math.sin( theta ))
local offset = Vector3(
self.inst
.Transform:GetWorldPosition()) + Vector3(radius * math.cos( theta ), 0, -radius * math.sin( theta ))
inst.Transform:SetPosition(offset.x,offset.y,offset.z)
inst.Transform:SetPosition(offset.x,offset.y,offset.z)
inst.SoundEmitter:PlaySound(self.warningsound)
inst.SoundEmitter:PlaySound(self.warningsound)
inst:DoTaskInTime(1.5, function() inst:Remove() end)
inst:DoTaskInTime(1.5, function() inst:Remove() end)
end
end
end
end
end
end
function BaseHassler:StartAttacks()
function BaseHassler:StartAttacks()
local timeLeftInSeason = GetSeasonManager():GetDaysLeftInSeason() * TUNING.TOTAL_DAY_TIME
local timeLeftInSeason = GetSeasonManager():GetDaysLeftInSeason() * TUNING.TOTAL_DAY_TIME
if self.attacksperwinter > 0 then
if self.attacksperwinter > 0 then
if self.attacksperwinter < 1 then
if self.attacksperwinter < 1 then
--special case: plan attack for NEXT season
--special case: plan attack for NEXT season
local summersToSkip = math.floor( (1 / self.attacksperwinter) - 1 )
local summersToSkip = math.floor( (1 / self.attacksperwinter) - 1 )
local wintersToSkip = math.max(0, summersToSkip-1)
local wintersToSkip = math.max(0, summersToSkip-1)
self.attackdelay = 0.5*timeLeftInSeason + TUNING.TOTAL_DAY_TIME*(summersToSkip*GetSeasonManager().summerlength + wintersToSkip*GetSeasonManager().winterlength)
self.attackdelay = 0.5*timeLeftInSeason + TUNING.TOTAL_DAY_TIME*(summersToSkip*GetSeasonManager().summerlength + wintersToSkip*GetSeasonManager().winterlength)
self.attackrandom = 0.25*timeLeftInSeason
self.attackrandom = 0.25*timeLeftInSeason
else
else
self.attackdelay = timeLeftInSeason / self.attacksperwinter
self.attackdelay = timeLeftInSeason / self.attacksperwinter
self.attackrandom = 0.25*self.attackdelay
self.attackrandom = 0.25*self.attackdelay
end
end
self:PlanNextAttack()
self:PlanNextAttack()
self.inst:StartUpdatingComponent(self)
self.inst:StartUpdatingComponent(self)
end
end
end
end
function BaseHassler:PlanNextAttack()
function BaseHassler:PlanNextAttack()
if (not GetSeasonManager():IsWinter() and not self.attackduringsummer) or not self.attackdelay then
if (not GetSeasonManager():IsWinter() and not self.attackduringsummer) or not self.attackdelay then
self:CeaseAttacks()
self:CeaseAttacks()
return
return
end
end
self.timetoattack = GetRandomWithVariance(self.attackdelay, self.attackrandom or 0)
self.timetoattack = GetRandomWithVariance(self.attackdelay, self.attackrandom or 0)
end
end
function BaseHassler:CeaseAttacks()
function BaseHassler:CeaseAttacks()
self.timetoattack = nil
self.timetoattack = nil
self.warning = false
self.warning = false
self.inst:StopUpdatingComponent(self)
self.inst:StopUpdatingComponent(self)
end
end
function BaseHassler:GetSpawnPoint(pt)
function BaseHassler:GetSpawnPoint(pt)
local theta = math.random() * 2 * PI
local theta = math.random() * 2 * PI
local radius = HASSLER_SPAWN_DIST
local radius = HASSLER_SPAWN_DIST
local offset = FindWalkableOffset(pt, theta, radius, 12, true)
local offset = FindWalkableOffset(pt, theta, radius, 12, true)
if offset then
if offset then
return pt+offset
return pt+offset
end
end
end
end
function BaseHassler:GetWanderAwayPoint(pt)
function BaseHassler:GetWanderAwayPoint(pt)
local theta = math.random() * 2 * PI
local theta = math.random() * 2 * PI
local radius = WANDER_AWAY_DIST
local radius = WANDER_AWAY_DIST
local ground = GetWorld()
local ground = GetWorld()
-- Walk the circle trying to find a valid spawn point
-- Walk the circle trying to find a valid spawn point
local steps = 12
local steps = 12
for i = 1, 12 do
for i = 1, 12 do
local offset = Vector3(radius * math.cos( theta ), 0, -radius * math.sin( theta ))
local offset = Vector3(radius * math.cos( theta ), 0, -radius * math.sin( theta ))
local wander_point = pt + offset
local wander_point = pt + offset
if ground.Map and ground.Map:GetTileAtPoint(wander_point.x, wander_point.y, wander_point.z) ~= GROUND.IMPASSABLE
if ground.Map and ground.Map:GetTileAtPoint(wander_point.x, wander_point.y, wander_point.z) ~= GROUND.IMPASSABLE
and ground.Pathfinder:IsClear(pt.x, pt.y, pt.z, wander_point.x, wander_point.y, wander_point.z, {ignorewalls = true} ) then
and ground.Pathfinder:IsClear(pt.x, pt.y, pt.z, wander_point.x, wander_point.y, wander_point.z, {ignorewalls = true} ) then
return wander_point
return wander_point
end
end
theta = theta - (2 * PI / steps)
theta = theta - (2 * PI / steps)
end
end
end
end
function BaseHassler:ReleaseHassler()
function BaseHassler:ReleaseHassler()
Copia
Copiato
Copia
Copiato
local pt = Vector3(
GetPlayer()
.Transform:GetWorldPosition())
local pt = Vector3(
self.inst
.Transform:GetWorldPosition())
local spawn_pt = self:GetSpawnPoint(pt)
local spawn_pt = self:GetSpawnPoint(pt)
if spawn_pt then
if spawn_pt then
local hassler = TheSim:FindFirstEntityWithTag(self.hasslerprefab)
local hassler = TheSim:FindFirstEntityWithTag(self.hasslerprefab)
if not hassler then
if not hassler then
hassler = SpawnPrefab(self.hasslerprefab)
hassler = SpawnPrefab(self.hasslerprefab)
end
end
if hassler then
if hassler then
hassler.Physics:Teleport(spawn_pt:Get())
hassler.Physics:Teleport(spawn_pt:Get())
Copia
Copiato
Copia
Copiato
local target = GetClosestInstWithTag("structure",
GetPlayer()
, 40)
local target = GetClosestInstWithTag("structure",
self.inst
, 40)
if target then
if target then
local targetPos = Vector3(target.Transform:GetWorldPosition() )
local targetPos = Vector3(target.Transform:GetWorldPosition() )
hassler.components.knownlocations:RememberLocation("targetbase", targetPos)
hassler.components.knownlocations:RememberLocation("targetbase", targetPos)
local wanderAwayPoint = self:GetWanderAwayPoint(targetPos)
local wanderAwayPoint = self:GetWanderAwayPoint(targetPos)
if wanderAwayPoint then
if wanderAwayPoint then
hassler.components.knownlocations:RememberLocation("home", wanderAwayPoint)
hassler.components.knownlocations:RememberLocation("home", wanderAwayPoint)
end
end
else
else
Copia
Copiato
Copia
Copiato
hassler.components.combat:SetTarget(
GetPlayer()
)
hassler.components.combat:SetTarget(
self.inst
)
end
end
end
end
end
end
end
end
return BaseHassler
return BaseHassler
Diff salvati
Testo originale
Apri file
local BaseHassler = Class(function(self, inst) self.inst = inst self.warning = false self.timetoattack = nil self.warnduration = 60 self.timetonextwarningsound = 0 self.announcewarningsoundinterval = 4 self.hasslerprefab = "deerclops" self.warningsound = "dontstarve/creatures/deerclops/distant" self.attacksperwinter = 1 self.attackduringsummer = false self.attackdelay = nil self.attackrandom = nil self.inst:ListenForEvent("snowcoverchange", function(inst) local snow_cover = GetSeasonManager() and GetSeasonManager():GetSnowPercent() or 0 if snow_cover >= 0.2 then if not self.timetoattack then self:StartAttacks() end elseif snow_cover <= 0 and self.attackduringsummer and not self.timetoattack then self:StartAttacks() else self:CeaseAttacks() end end, GetWorld() ) end) local HASSLER_SPAWN_DIST = 40 local WANDER_AWAY_DIST = 100 function BaseHassler:SetHasslerPrefab(prefab) self.hasslerprefab = prefab end function BaseHassler:SetWarningSound(sound) self.warningsound = sound end function BaseHassler:SetAttacksPerWinter(attacks) self.attacksperwinter = attacks end function BaseHassler:SetAttackDuringSummer(attack) self.attackduringsummer = attack end function BaseHassler:OnSave() if not self.noserial then return { warning = self.warning, timetoattack = self.timetoattack, attackdelay = self.attackdelay, attackrandom = self.attackrandom, } end self.noserial = false end function BaseHassler:OnLoad(data) self.warning = data.warning or false self.timetoattack = data.timetoattack self.attackdelay = data.attackdelay self.attackrandom = data.attackrandom if self.timetoattack then self.inst:StartUpdatingComponent(self) end end function BaseHassler:OnProgress() self.noserial = true end function BaseHassler:GetDebugString() if not self.timetoattack then return "DORMANT" elseif self.timetoattack > 0 then return string.format("%s Deerclops is coming in %2.2f", self.warning and "WARNING" or "WAITING", self.timetoattack) else return string.format("ATTACKING!!!") end end function BaseHassler:LongUpdate(dt) self:OnUpdate(dt) end function BaseHassler:OnUpdate(dt) if not self.timetoattack then self:CeaseAttacks() return end self.timetoattack = self.timetoattack - dt if self.timetoattack <= 0 then self.warning = false self:ReleaseHassler() self:CeaseAttacks() else if not self.warning and self.timetoattack < self.warnduration then self.warning = true self.timetonextwarningsound = 0 end end if self.warning then self.timetonextwarningsound = self.timetonextwarningsound - dt if self.timetonextwarningsound <= 0 then self.announcewarningsoundinterval = self.announcewarningsoundinterval - 1 if self.announcewarningsoundinterval <= 0 then self.announcewarningsoundinterval = 10 + math.random(5) GetPlayer().components.talker:Say(GetString(GetPlayer().prefab, "ANNOUNCE_DEERCLOPS")) end local inst = CreateEntity() inst.entity:AddTransform() inst.entity:AddSoundEmitter() inst.persists = false local theta = math.random() * 2 * PI local radius = 5 self.timetonextwarningsound = 15 + math.random(4) if self.timetoattack < 30 then self.timetonextwarningsound = 10 + math.random(1) radius = radius elseif self.timetoattack < 60 then radius = radius + 10 elseif self.timetoattack < 90 then radius = radius + 15 else radius = radius + 20 end local offset = Vector3(GetPlayer().Transform:GetWorldPosition()) + Vector3(radius * math.cos( theta ), 0, -radius * math.sin( theta )) inst.Transform:SetPosition(offset.x,offset.y,offset.z) inst.SoundEmitter:PlaySound(self.warningsound) inst:DoTaskInTime(1.5, function() inst:Remove() end) end end end function BaseHassler:StartAttacks() local timeLeftInSeason = GetSeasonManager():GetDaysLeftInSeason() * TUNING.TOTAL_DAY_TIME if self.attacksperwinter > 0 then if self.attacksperwinter < 1 then --special case: plan attack for NEXT season local summersToSkip = math.floor( (1 / self.attacksperwinter) - 1 ) local wintersToSkip = math.max(0, summersToSkip-1) self.attackdelay = 0.5*timeLeftInSeason + TUNING.TOTAL_DAY_TIME*(summersToSkip*GetSeasonManager().summerlength + wintersToSkip*GetSeasonManager().winterlength) self.attackrandom = 0.25*timeLeftInSeason else self.attackdelay = timeLeftInSeason / self.attacksperwinter self.attackrandom = 0.25*self.attackdelay end self:PlanNextAttack() self.inst:StartUpdatingComponent(self) end end function BaseHassler:PlanNextAttack() if (not GetSeasonManager():IsWinter() and not self.attackduringsummer) or not self.attackdelay then self:CeaseAttacks() return end self.timetoattack = GetRandomWithVariance(self.attackdelay, self.attackrandom or 0) end function BaseHassler:CeaseAttacks() self.timetoattack = nil self.warning = false self.inst:StopUpdatingComponent(self) end function BaseHassler:GetSpawnPoint(pt) local theta = math.random() * 2 * PI local radius = HASSLER_SPAWN_DIST local offset = FindWalkableOffset(pt, theta, radius, 12, true) if offset then return pt+offset end end function BaseHassler:GetWanderAwayPoint(pt) local theta = math.random() * 2 * PI local radius = WANDER_AWAY_DIST local ground = GetWorld() -- Walk the circle trying to find a valid spawn point local steps = 12 for i = 1, 12 do local offset = Vector3(radius * math.cos( theta ), 0, -radius * math.sin( theta )) local wander_point = pt + offset if ground.Map and ground.Map:GetTileAtPoint(wander_point.x, wander_point.y, wander_point.z) ~= GROUND.IMPASSABLE and ground.Pathfinder:IsClear(pt.x, pt.y, pt.z, wander_point.x, wander_point.y, wander_point.z, {ignorewalls = true} ) then return wander_point end theta = theta - (2 * PI / steps) end end function BaseHassler:ReleaseHassler() local pt = Vector3(GetPlayer().Transform:GetWorldPosition()) local spawn_pt = self:GetSpawnPoint(pt) if spawn_pt then local hassler = TheSim:FindFirstEntityWithTag(self.hasslerprefab) if not hassler then hassler = SpawnPrefab(self.hasslerprefab) end if hassler then hassler.Physics:Teleport(spawn_pt:Get()) local target = GetClosestInstWithTag("structure", GetPlayer(), 40) if target then local targetPos = Vector3(target.Transform:GetWorldPosition() ) hassler.components.knownlocations:RememberLocation("targetbase", targetPos) local wanderAwayPoint = self:GetWanderAwayPoint(targetPos) if wanderAwayPoint then hassler.components.knownlocations:RememberLocation("home", wanderAwayPoint) end else hassler.components.combat:SetTarget(GetPlayer()) end end end end return BaseHassler
Testo modificato
Apri file
local BaseHassler = Class(function(self, inst) self.inst = inst self.warning = false self.timetoattack = nil self.warnduration = 60 self.timetonextwarningsound = 0 self.announcewarningsoundinterval = 4 self.hasslerprefab = "deerclops" self.warningsound = "dontstarve/creatures/deerclops/distant" self.attacksperwinter = 1 self.attackduringsummer = false self.attackdelay = nil self.attackrandom = nil self.inst:ListenForEvent("snowcoverchange", function(inst, data) if data and data.snow >= 0.2 then if not self.timetoattack then self:StartAttacks() end elseif data and data.snow <= 0 and self.attackduringsummer and not self.timetoattack then self:StartAttacks() else self:CeaseAttacks() end end, GetWorld() ) end) local HASSLER_SPAWN_DIST = 40 local WANDER_AWAY_DIST = 100 function BaseHassler:SetHasslerPrefab(prefab) self.hasslerprefab = prefab end function BaseHassler:SetWarningSound(sound) self.warningsound = sound end function BaseHassler:SetAttacksPerWinter(attacks) self.attacksperwinter = attacks end function BaseHassler:SetAttackDuringSummer(attack) self.attackduringsummer = attack end function BaseHassler:OnSave() if not self.noserial then return { warning = self.warning, timetoattack = self.timetoattack, attackdelay = self.attackdelay, attackrandom = self.attackrandom, } end self.noserial = false end function BaseHassler:OnLoad(data) self.warning = data.warning or false self.timetoattack = data.timetoattack self.attackdelay = data.attackdelay self.attackrandom = data.attackrandom if self.timetoattack then self.inst:StartUpdatingComponent(self) end end function BaseHassler:OnProgress() self.noserial = true end function BaseHassler:GetDebugString() if not self.timetoattack then return "DORMANT" elseif self.timetoattack > 0 then return string.format("%s Deerclops is coming in %2.2f", self.warning and "WARNING" or "WAITING", self.timetoattack) else return string.format("ATTACKING!!!") end end function BaseHassler:OnUpdate(dt) if not self.timetoattack then self:CeaseAttacks() return end self.timetoattack = self.timetoattack - dt if self.timetoattack <= 0 then self.warning = false self:ReleaseHassler() self:CeaseAttacks() else if not self.warning and self.timetoattack < self.warnduration then self.warning = true self.timetonextwarningsound = 0 end end if self.warning then self.timetonextwarningsound = self.timetonextwarningsound - dt if self.timetonextwarningsound <= 0 then self.announcewarningsoundinterval = self.announcewarningsoundinterval - 1 if self.announcewarningsoundinterval <= 0 then self.announcewarningsoundinterval = 10 + math.random(5) self.inst.components.talker:Say(GetString(self.inst.prefab, "ANNOUNCE_DEERCLOPS")) end local inst = CreateEntity() inst.entity:AddTransform() inst.entity:AddSoundEmitter() inst.persists = false local theta = math.random() * 2 * PI local radius = 5 self.timetonextwarningsound = 15 + math.random(4) if self.timetoattack < 30 then self.timetonextwarningsound = 10 + math.random(1) radius = radius elseif self.timetoattack < 60 then radius = radius + 10 elseif self.timetoattack < 90 then radius = radius + 15 else radius = radius + 20 end local offset = Vector3(self.inst.Transform:GetWorldPosition()) + Vector3(radius * math.cos( theta ), 0, -radius * math.sin( theta )) inst.Transform:SetPosition(offset.x,offset.y,offset.z) inst.SoundEmitter:PlaySound(self.warningsound) inst:DoTaskInTime(1.5, function() inst:Remove() end) end end end function BaseHassler:StartAttacks() local timeLeftInSeason = GetSeasonManager():GetDaysLeftInSeason() * TUNING.TOTAL_DAY_TIME if self.attacksperwinter > 0 then if self.attacksperwinter < 1 then --special case: plan attack for NEXT season local summersToSkip = math.floor( (1 / self.attacksperwinter) - 1 ) local wintersToSkip = math.max(0, summersToSkip-1) self.attackdelay = 0.5*timeLeftInSeason + TUNING.TOTAL_DAY_TIME*(summersToSkip*GetSeasonManager().summerlength + wintersToSkip*GetSeasonManager().winterlength) self.attackrandom = 0.25*timeLeftInSeason else self.attackdelay = timeLeftInSeason / self.attacksperwinter self.attackrandom = 0.25*self.attackdelay end self:PlanNextAttack() self.inst:StartUpdatingComponent(self) end end function BaseHassler:PlanNextAttack() if (not GetSeasonManager():IsWinter() and not self.attackduringsummer) or not self.attackdelay then self:CeaseAttacks() return end self.timetoattack = GetRandomWithVariance(self.attackdelay, self.attackrandom or 0) end function BaseHassler:CeaseAttacks() self.timetoattack = nil self.warning = false self.inst:StopUpdatingComponent(self) end function BaseHassler:GetSpawnPoint(pt) local theta = math.random() * 2 * PI local radius = HASSLER_SPAWN_DIST local offset = FindWalkableOffset(pt, theta, radius, 12, true) if offset then return pt+offset end end function BaseHassler:GetWanderAwayPoint(pt) local theta = math.random() * 2 * PI local radius = WANDER_AWAY_DIST local ground = GetWorld() -- Walk the circle trying to find a valid spawn point local steps = 12 for i = 1, 12 do local offset = Vector3(radius * math.cos( theta ), 0, -radius * math.sin( theta )) local wander_point = pt + offset if ground.Map and ground.Map:GetTileAtPoint(wander_point.x, wander_point.y, wander_point.z) ~= GROUND.IMPASSABLE and ground.Pathfinder:IsClear(pt.x, pt.y, pt.z, wander_point.x, wander_point.y, wander_point.z, {ignorewalls = true} ) then return wander_point end theta = theta - (2 * PI / steps) end end function BaseHassler:ReleaseHassler() local pt = Vector3(self.inst.Transform:GetWorldPosition()) local spawn_pt = self:GetSpawnPoint(pt) if spawn_pt then local hassler = TheSim:FindFirstEntityWithTag(self.hasslerprefab) if not hassler then hassler = SpawnPrefab(self.hasslerprefab) end if hassler then hassler.Physics:Teleport(spawn_pt:Get()) local target = GetClosestInstWithTag("structure", self.inst, 40) if target then local targetPos = Vector3(target.Transform:GetWorldPosition() ) hassler.components.knownlocations:RememberLocation("targetbase", targetPos) local wanderAwayPoint = self:GetWanderAwayPoint(targetPos) if wanderAwayPoint then hassler.components.knownlocations:RememberLocation("home", wanderAwayPoint) end else hassler.components.combat:SetTarget(self.inst) end end end end return BaseHassler
Trovare la differenza