Diff
checker
Texte
Texte
Images
Documents
Excel
Dossiers
Legal
Enterprise
Application de bureau
Prix
Se connecter
Télécharger Diffchecker Desktop
Comparer le texte
Trouver la différence entre deux fichiers texte
Outils
Historique
Éditeur live
Cacher identiques
Sans retour à la ligne
Vue
Divisé
Unifié
Niveau de précision
Intelligent
Mot
Caractère
Coloration syntaxique
Choisir la syntaxe
Ignorer
Transformer le texte
Aller au premier écart
Modifier l'entrée
Diffchecker Desktop
La façon la plus sécurisée d'utiliser Diffchecker. Obtenez l'application Diffchecker Desktop : vos diffs ne quittent jamais votre ordinateur !
Obtenir Desktop
Untitled diff
Créé
il y a 11 ans
Le diff n'expire jamais
Effacer
Exporter
Partager
Expliquer
16 suppressions
Lignes
Total
Supprimé
Caractères
Total
Supprimé
Pour continuer à utiliser cette fonctionnalité, passez à
Diff
checker
Pro
Voir les prix
246 lignes
Copier tout
9 ajouts
Lignes
Total
Ajouté
Caractères
Total
Ajouté
Pour continuer à utiliser cette fonctionnalité, passez à
Diff
checker
Pro
Voir les prix
239 lignes
Copier tout
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
Copier
Copié
Copier
Copié
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
Copier
Copié
Copier
Copié
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
Copier
Copié
Copier
Copié
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)
Copier
Copié
Copier
Copié
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
Copier
Copié
Copier
Copié
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()
Copier
Copié
Copier
Copié
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())
Copier
Copié
Copier
Copié
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
Copier
Copié
Copier
Copié
hassler.components.combat:SetTarget(
GetPlayer()
)
hassler.components.combat:SetTarget(
self.inst
)
end
end
end
end
end
end
end
end
return BaseHassler
return BaseHassler
Différences enregistrées
Texte d'origine
Ouvrir un fichier
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
Texte modifié
Ouvrir un fichier
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
Trouver la différence