205 lines
5.4 KiB
Lua
205 lines
5.4 KiB
Lua
function init()
|
|
self.dead = false
|
|
|
|
self.state = stateMachine.create({
|
|
"aggroState",
|
|
"spinAttack",
|
|
"bombAttack",
|
|
"spawnAttack",
|
|
"explodeState"
|
|
})
|
|
self.state.shuffleStates()
|
|
|
|
entity.setDeathParticleBurst("deathPoof")
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
function update(dt)
|
|
if util.trackTarget(entity.configParameter("noticeDistance")) then
|
|
attack(self.targetId)
|
|
end
|
|
entity.setAggressive(self.targetId ~= nil)
|
|
entity.setDamageOnTouch(self.targetId ~= nil)
|
|
|
|
if not self.state.update(dt) then
|
|
entity.setAnimationState("movement", "idle")
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
function damage(args)
|
|
if self.targetId == nil then
|
|
attack(args.sourceId)
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
function shouldDie()
|
|
return entity.health() <= 0 or self.dead
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
function attack(targetId)
|
|
local stateName = self.state.stateDesc()
|
|
if not string.find(stateName, 'Attack$') and stateName ~= "explodeState" then
|
|
if self.state.pickState({ targetId = targetId }) then
|
|
self.targetId = targetId
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
aggroState = {}
|
|
|
|
function aggroState.enterWith(params)
|
|
if params.targetId == nil then return nil end
|
|
|
|
entity.setAnimationState("movement", "aggro")
|
|
|
|
return { timer = entity.configParameter("aggroTime") }
|
|
end
|
|
|
|
function aggroState.update(dt, stateData)
|
|
mcontroller.controlFly({ 0, entity.configParameter("aggroMoveSpeed") })
|
|
|
|
stateData.timer = stateData.timer - dt
|
|
return stateData.timer <= 0
|
|
end
|
|
|
|
function aggroState.leavingState(stateData)
|
|
self.state.pickState({ attack = true })
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
spinAttack = {}
|
|
|
|
function spinAttack.enterWith(params)
|
|
if self.targetId == nil then return true end
|
|
if not params.attack then return nil end
|
|
|
|
entity.setAnimationState("movement", "spin")
|
|
return {}
|
|
end
|
|
|
|
function spinAttack.update(dt, stateData)
|
|
if self.targetId == nil then return true end
|
|
|
|
if stateData.targetPosition == nil then
|
|
stateData.targetPosition = self.targetPosition
|
|
end
|
|
|
|
local toTarget = world.distance(stateData.targetPosition, mcontroller.position())
|
|
if world.magnitude(toTarget) <= 1.0 then
|
|
return true
|
|
else
|
|
mcontroller.controlFly(vec2.mul(vec2.norm(toTarget), mcontroller.baseParameters().flySpeed))
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
function spinAttack.leavingState(stateData)
|
|
self.state.pickState({ explode = true })
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
bombAttack = {}
|
|
|
|
function bombAttack.enterWith(params)
|
|
if self.targetId == nil then return true end
|
|
if not params.attack then return nil end
|
|
|
|
return {
|
|
timer = 0,
|
|
totalTime = entity.randomizeParameterRange("bombAttackTimeRange"),
|
|
direction = util.randomDirection()
|
|
}
|
|
end
|
|
|
|
function bombAttack.enteringState(stateData)
|
|
entity.setFireDirection({0, 0}, {1, 0})
|
|
-- entity.startFiring("bomb")
|
|
end
|
|
|
|
function bombAttack.update(dt, stateData)
|
|
if self.targetId == nil then return true end
|
|
|
|
mcontroller.controlFly({ 0, 0 })
|
|
|
|
local ratio = stateData.timer / stateData.totalTime
|
|
local angle = ratio * math.pi
|
|
local direction = {
|
|
math.cos(angle) * stateData.direction,
|
|
math.sin(angle)
|
|
}
|
|
direction = vec2.mul(direction, 2.0)
|
|
|
|
-- entity.setFireDirection(direction, direction)
|
|
|
|
stateData.timer = stateData.timer + dt
|
|
return stateData.timer >= stateData.totalTime
|
|
end
|
|
|
|
function bombAttack.leavingState(stateData)
|
|
-- entity.stopFiring()
|
|
self.state.pickState({ explode = true })
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
spawnAttack = {}
|
|
|
|
function spawnAttack.enterWith(params)
|
|
if self.targetId == nil then return true end
|
|
if not params.attack then return nil end
|
|
|
|
return { timer = entity.configParameter("spawnAttackWaitTime") }
|
|
end
|
|
|
|
function spawnAttack.enteringState(stateData)
|
|
entity.burstParticleEmitter("deathPoof")
|
|
|
|
local initialSpeed = entity.configParameter("spawnAttackInitialSpeed")
|
|
for _, offset in pairs(entity.configParameter("spawnAttackOffsets")) do
|
|
local entityId = world.spawnMonster("glitchspider", entity.toAbsolutePosition(offset))
|
|
world.callScriptedEntity(entityId, "setSpawnVelocity", vec2.mul(offset, initialSpeed))
|
|
end
|
|
end
|
|
|
|
function spawnAttack.update(dt, stateData)
|
|
if self.targetId == nil then return nil end
|
|
|
|
mcontroller.controlFly({ 0, 0 })
|
|
|
|
stateData.timer = stateData.timer - dt
|
|
return stateData.timer <= 0
|
|
end
|
|
|
|
function spawnAttack.leavingState(stateData)
|
|
self.state.pickState({ explode = true })
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
explodeState = {}
|
|
|
|
function explodeState.enterWith(params)
|
|
if not params.explode or self.dead then return nil end
|
|
|
|
return { timer = entity.configParameter("explodeTime") }
|
|
end
|
|
|
|
function explodeState.enteringState(stateData)
|
|
-- entity.startFiring("deathexplosion")
|
|
-- entity.setFireDirection({0, 0}, {1, 0})
|
|
end
|
|
|
|
function explodeState.update(dt, stateData)
|
|
mcontroller.controlFly({ 0, 0 })
|
|
|
|
stateData.timer = stateData.timer - dt
|
|
return stateData.timer <= 0
|
|
end
|
|
|
|
function explodeState.leavingState(stateData)
|
|
-- entity.stopFiring()
|
|
self.dead = true
|
|
end
|