Starbound/attic/npcs/tentaclecometspore/behavior.lua
2025-03-21 22:23:30 +11:00

124 lines
3.3 KiB
Lua

function init()
self.state = stateMachine.create({
"idleState",
"attackState",
})
self.state.leavingState = function(stateName)
entity.setAnimationState("movement", "idle")
end
self.initialPauseTimer = entity.configParameter("initialPauseTime")
entity.setDeathParticleBurst("deathPoof")
entity.setAggressive(true)
entity.setDamageOnTouch(true)
end
--------------------------------------------------------------------------------
function update(dt)
if self.initialPauseTimer > 0 then
self.initialPauseTimer = self.initialPauseTimer - dt
else
if util.trackTarget(entity.configParameter("targetNoticeDistance")) then
self.state.pickState(self.targetId)
end
self.state.update(dt)
end
end
--------------------------------------------------------------------------------
function boundingBox(offset)
local position = mcontroller.position()
if offset ~= nil then position = vec2.add(position, offset) end
local bounds = entity.configParameter("metaBoundBox")
return {
bounds[1] + position[1],
bounds[2] + position[2],
bounds[3] + position[1],
bounds[4] + position[2],
}
end
--------------------------------------------------------------------------------
function isClosed()
return entity.animationState("movement") == "closedIdle"
end
--------------------------------------------------------------------------------
function isOnPlatform()
local bounds = boundingBox({ 0, -1 })
return mcontroller.onGround() and
world.rectTileCollision(bounds, {"Platform"})
end
--------------------------------------------------------------------------------
function move(toTarget)
entity.setAnimationState("movement", "move")
if math.abs(toTarget[2]) < 4.0 and isOnPlatform() then
mcontroller.controlDown()
end
mcontroller.controlMove(toTarget[1], true)
end
--------------------------------------------------------------------------------
idleState = {}
function idleState.enter()
if isClosed() then return nil end
return { timer = entity.randomizeParameterRange("idleBlinkIntervalRange") }
end
function idleState.update(dt, stateData)
stateData.timer = stateData.timer - dt
if stateData.timer <= 0 then
entity.setAnimationState("movement", "blink")
stateData.timer = entity.randomizeParameterRange("idleBlinkIntervalRange")
end
return false
end
--------------------------------------------------------------------------------
attackState = {}
function attackState.enterWith(targetId)
if targetId == nil then return nil end
if isClosed() then
entity.setAnimationState("movement", "open")
end
return {
timer = entity.configParameter("attackTargetHoldTime"),
targetId = targetId,
targetPosition = world.entityPosition(targetId),
}
end
function attackState.update(dt, stateData)
if entity.animationState("movement") == "open" then
return false
end
local targetPosition = world.entityPosition(stateData.targetId)
if targetPosition == nil then return true end
if entity.entityInSight(stateData.targetId) then
stateData.targetPosition = targetPosition
stateData.timer = entity.configParameter("attackTargetHoldTime")
else
stateData.timer = stateData.timer - dt
end
local toTarget = world.distance(stateData.targetPosition, mcontroller.position())
move(toTarget)
return stateData.timer <= 0
end