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