1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2024-12-27 23:35:51 +00:00
Aquaria/game_scripts/scripts/entities/energyboss.lua
fgenesis 7ff0caaed8 Script interface improvements & extensions.
- Pointer typechecks are now enabled by default.

- enabled all script warnings for non-FULL or DEMO builds by default

- Added generic obj_* functions that operate on any type of RenderObject.
  These give quite low-level control about the renderer, and are quite
  dangerous too.
  Subsequently, many functions sharing the same code (*_setPosition, for example)
  could be removed, and simply call the generic functions after a type check.

- Added interface function deathNotify(). The original logic of death
  notifiers was never used, so i thought i'd make use of it.
  This is useful in scripts to safely drop dangling pointers.

- removed sendEntityMessage, entity_setCollideWithAvatar, entity_setTouchDamage,
  which were essentially no-ops.

- Replaced all unnecessary luaReturnNum(0) and luaReturnInt(0),
  now it does only push a return value on the stack if the function
  is actually supposed to have a retun value.

- Allow variadic calling of entity_msg(). Now any parameters can be passed
  to the function, and the target entity will receive all of them.
  Any values returned from the entity's msg() callback will be returned
  by entity_msg() to the original caller. This allows nice RPC-like
  entity communication.

- fixed possible crash in debugLog, bone_update, entity_debugText

- added an override function for loadfile() that is case-insensitive like dofile()

- entity_createEntity returns the created entity now

- spawnParticleEffect returns the associated RenderObject

- Added some text rendering functions

- Added beam_setFirer()

- removed the underflow check in avatar_decrLeaches() I added earlier

- added a panic function for Lua.

- added the Lua debug library

- fixed a stupid typo in ScriptObject::isType() that made the type checks a lot less accurate

- misc stuff I forgot
2012-02-05 20:22:54 +01:00

586 lines
16 KiB
Lua

-- Copyright (C) 2007, 2010 - Bit-Blot
--
-- This file is part of Aquaria.
--
-- Aquaria is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; either version 2
-- of the License, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
-- See the GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
if not v then v = {} end
if not AQUARIA_VERSION then dofile("scripts/entities/entityinclude.lua") end
-- ================================================================================================
-- Energy Boss
-- ================================================================================================
local STATE_MOVING = 1001
local STATE_MOVEBACK = 1002
local STATE_SHOCKED = 1003
local STATE_FIRE = 1004
local STATE_HITBARRIER = 1005
local STATE_MOVEBACKFROMBARRIER = 1006
local STATE_COLLAPSE = 1007
local STATE_COLLAPSED = 1100
local ATTACK_UP = 1
local ATTACK_DOWN = 2
local ATTACK_BITE = 3
v.attacks = 0
v.attack = 0
v.awoken = false
v.attackDelay = 0
v.naija = 0
v.maxMove = 0
v.maxMove2 = 0
v.minMove = 0
v.pushBackHits = 0
v.maxPushBackHits = 6
v.moveDelay = 0
v.fireDelay = 0
v.fireBit = 0
v.shotsFired = 0
v.barrier = 0
v.maxHits = 3
v.hits = v.maxHits
v.endTextDelay = 0
v.playedMusic = false
v.dead = false
v.orb = 0
v.bone_jaw = 0
v.bone_claw = 0
v.bone_head = 0
v.bone_body = 0
function damage(me, attacker, bone, damageType, dmg)
bone_damageFlash(bone, 1)
if entity_x(me) > node_x(v.minMove)+50 and not entity_isState(me, STATE_MOVEBACK) and not entity_isState(me, STATE_HITBARRIER) and not entity_isState(me, STATE_MOVEBACKFROMBARRIER) and not entity_isState(me, STATE_COLLAPSE) then
v.pushBackHits = v.pushBackHits + dmg
if v.pushBackHits >= v.maxPushBackHits then
v.pushBackHits = 0
entity_setState(me, STATE_MOVEBACK)
end
end
return false
end
function init(me)
setupBasicEntity(
me,
"", -- texture
30, -- health
1, -- manaballamount
1, -- exp
1, -- money
0, -- collideRadius (only used if hit entities is on)
STATE_IDLE, -- initState
90, -- sprite width
90, -- sprite height
1, -- particle "explosion" type, maps to particleEffects.txt -1 = none
0, -- 0/1 hit other entities off/on (uses collideRadius)
6000, -- updateCull -1: disabled, default: 4000
0
)
entity_initSkeletal(me, "EnergyBoss")
entity_setState(me, STATE_IDLE)
entity_setCull(me, false)
entity_setName(me, "EnergyBoss")
--entity_flipHorizontal(me)
entity_scale(me, 1.5, 1.5)
entity_setWeight(me, 800)
entity_setMaxSpeed(me, 2000)
entity_generateCollisionMask(me)
v.bone_jaw = entity_getBoneByName(me, "Jaw")
v.bone_claw = entity_getBoneByName(me, "Claw")
v.bone_head = entity_getBoneByName(me, "Head")
v.bone_body = entity_getBoneByName(me, "Body")
v.maxMove = getNode("ENERGYBOSSMAXMOVE")
v.maxMove2 = getNode("ENERGYBOSSMAXMOVE2")
v.minMove = getNode("ENERGYBOSSMINMOVE")
entity_setDamageTarget(me, DT_AVATAR_LIZAP, false)
entity_setDamageTarget(me, DT_AVATAR_PET, false)
v.naija = getNaija()
loadSound("EnergyBoss-Attack")
loadSound("EnergyBoss-Die")
loadSound("EnergyBoss-Hurt")
loadSound("BossDieSmall")
end
function postInit(me)
if not entity_isState(me, STATE_COLLAPSE) then
if getFlag(FLAG_ENERGYBOSSDEAD)>0 and not entity_isState(me, STATE_COLLAPSED) then
entity_setPosition(me, node_x(v.maxMove2), entity_y(me))
entity_setState(me, STATE_COLLAPSED)
v.dead = true
return
end
end
v.orb = getEntityByID(4)
v.holder = getEntityByID(3)
v.barrier = getEntityByID(5)
end
function update(me, dt)
--[[
if entity_isState(me, STATE_COLLAPSED) then
if getFlag(FLAG_ENERGYBOSSDEAD)>0 then
fadeOutMusic(0.5)
end
end
]]--
if entity_isState(me, STATE_COLLAPSE) then
if v.endTextDelay > 0 then
v.endTextDelay = v.endTextDelay - dt
if v.endTextDelay < 0 then
v.endTextDelay = 0
cam_toEntity(v.naija)
changeForm(FORM_NORMAL)
setInvincible(true)
entity_idle(v.naija)
entity_animate(v.naija, "agony", -1)
entity_flipToEntity(v.naija, me)
--voiceOnce("Naija_EnergyBossOver")
voice("Naija_Vision_EnergyBoss1")
--entity_idle(v.naija)
entity_idle(v.naija)
entity_animate(v.naija, "agony", -1)
fade2(0.5, 8, 1, 1, 1)
watchForVoice()
fade2(1, 1, 1, 1, 1)
watch(1)
local collectibleNode = getNode("COLLECTIBLE")
local ent = createEntity("CollectibleEnergyBoss", "", node_x(collectibleNode), node_y(collectibleNode))
entity_alpha(ent, 0)
entity_alpha(ent, 1, 2)
watch(0.5)
setInvincible(false)
if entity_getHealth(v.naija) < 1 then
entity_heal(v.naija, 1)
end
loadMap("EnergyTempleVision")
--entity_idle(v.naija)
--watch(6.5)
--[[
showImage("Visions/EnergyBoss/00")
voice("Naija_Vision_EnergyBoss2")
watchForVoice()
entity_idle(v.naija)
hideImage()
watch(1)
voice("Naija_Vision_EnergyBoss3")
]]--
end
end
return
end
if entity_isState(me, STATE_COLLAPSED) then
return
end
if not v.awoken and not v.playedMusic and getFlag(FLAG_ENERGYBOSSDEAD)==0 then
if not isFlag(FLAG_OMPO, 4) then
if entity_isEntityInRange(me, v.naija, 1220) then
emote(EMOTE_NAIJAUGH)
v.playedMusic = true
playMusic("BigBoss")
--setNaijaHeadTexture("shock", 4)
entity_setState(me, STATE_INTRO)
end
end
end
if not v.awoken then return end
if entity_isState(me, STATE_COLLAPSED) then
return
end
--[[
if v.barrier == 0 then
v.barrier = getEntityByID(5)
end
]]--
local bone = entity_collideSkeletalVsCircle(me, getNaija())
if bone ~= 0 or entity_x(v.naija) < entity_x(me) then
entity_damage(getNaija(), me, 1)
if entity_y(v.naija) > entity_y(me)+50 then
entity_push(getNaija(), 1200, -600, 0.5)
elseif entity_y(v.naija) < entity_y(me) then
entity_push(getNaija(), 1200, 600, 0.5)
else
entity_push(getNaija(), 1200, 0, 0.5)
end
end
if entity_isState(me, STATE_ATTACK) or entity_isState(me, STATE_INTRO) then
if not entity_isAnimating(me) then
if entity_isState(me, STATE_ATTACK) then
v.attacks = v.attacks + 1
if v.attacks >= 1 then
v.attacks = 0
entity_setState(me, STATE_MOVING)
else
entity_setState(me, STATE_IDLE)
end
else
entity_setState(me, STATE_IDLE)
end
end
end
--[[
if entity_isState(me, STATE_HITBARRIER) and not entity_isAnimating(me) then
entity_setState(me, STATE_MOVEBACKFROMBARRIER)
end
]]--
if not entity_isState(me, STATE_MOVEBACK) and not entity_isState(me, STATE_MOVEBACKFROMBARRIER) then
if entity_x(v.orb) < entity_x(v.barrier) then
if v.moveDelay > 0 then
v.moveDelay = v.moveDelay - dt
if v.moveDelay < 0 then
v.moveDelay = 0
end
end
end
end
if v.barrier ~= 0 then
--debugLog("ENERGYBOSS: has Barrier")
if entity_isState(v.barrier, STATE_PULSE) then
--debugLog("ENERGYBOSS: barrier pulse")
if not entity_isState(me, STATE_HITBARRIER) and not entity_isState(me, STATE_MOVEBACKFROMBARRIER) then
local lineBone = entity_collideSkeletalVsLine(me, entity_x(v.barrier), entity_y(v.barrier)+500, entity_x(v.barrier), entity_y(v.barrier)-500, 8)
if lineBone ~= 0 then
--debugLog("ENERGYBOSS: hit barrier!")
local bx,by = bone_getPosition(lineBone)
spawnParticleEffect("HitEnergyBarrierBig", entity_x(v.barrier), by)
bone_damageFlash(v.bone_head)
bone_damageFlash(v.bone_body)
v.hits = v.hits - 1
if v.hits <= 0 then
entity_setState(me, STATE_COLLAPSE)
else
entity_setState(me, STATE_HITBARRIER, 1)
end
end
end
else
--debugLog("ENERGYBOSS: barrier off")
end
else
--debugLog("ENERGYBOSS: Did not find barrier")
end
if entity_isState(me, STATE_FIRE) then
v.fireBit = v.fireBit - dt
if v.fireBit < 0 then
entity_setTarget(me, v.naija)
local offx, offy = 0
while v.shotsFired < 3 do
local velx, vely = 0, 0
if v.shotsFired == 3 then
velx = 100
vely = 50
elseif v.shotsFired == 0 then
velx = 100
vely = 25
elseif v.shotsFired == 1 then
velx = 100
vely = 0
elseif v.shotsFired == 2 then
velx = 100
vely = -25
end
--entity_fireAtTarget(me, "Purple", 1, 500, 100, 0, 0, offx, offy, velx, vely)
local s = createShot("EnergyBoss", me, entity_getTarget(me), entity_getPosition(me))
shot_setAimVector(s, velx, vely)
v.shotsFired = v.shotsFired + 1
end
entity_setState(me, STATE_IDLE)
end
end
if entity_isState(me, STATE_IDLE) then
if v.moveDelay <= 0 and entity_x(me) < node_x(v.maxMove)
and entity_x(v.naija) < entity_x(me)+1200 then
entity_setState(me, STATE_MOVING)
else
if v.awoken then
v.fireDelay = v.fireDelay - dt
if v.fireDelay <= 0 then
v.fireDelay = 0
entity_setState(me, STATE_FIRE)
end
end
if entity_isState(me, STATE_IDLE) then
v.attackDelay = v.attackDelay - dt
if v.attackDelay <= 0 and entity_x(v.naija) < entity_x(me)+800 then
v.attackDelay = 1
entity_setState(me, STATE_ATTACK)
end
end
end
end
if entity_isState(me, STATE_MOVING) and entity_x(me) >= node_x(v.maxMove) then
if entity_isInterpolating() then
entity_animate(me, "idle")
end
entity_stopInterpolating(me)
entity_setPosition(me, node_x(v.maxMove), entity_y(me))
end
if (entity_isState(me, STATE_MOVEBACK) or entity_isState(me, STATE_MOVEBACKFROMBARRIER)) and entity_x(me) <= node_x(v.minMove) then
entity_stopInterpolating(me)
entity_setPosition(me, node_x(v.minMove), entity_y(me))
end
if entity_isState(me, STATE_MOVING) or entity_isState(me, STATE_MOVEBACK) or entity_isState(me, STATE_MOVEBACKFROMBARRIER) then
if not entity_isInterpolating(me) then
entity_setState(me, STATE_IDLE)
end
end
entity_handleShotCollisionsSkeletal(me)
entity_clearTargetPoints(me)
entity_addTargetPoint(me, bone_getWorldPosition(v.bone_head))
if entity_isState(me, STATE_ATTACK) then
entity_setLookAtPoint(me, bone_getWorldPosition(v.bone_claw))
entity_setNaijaReaction(me, "shock")
else
entity_setLookAtPoint(me, bone_getWorldPosition(v.bone_jaw))
entity_setNaijaReaction(me, "")
end
--entity_setEnergyShotTargetPosition(me, bone_getWorldPosition(v.bone_head))
end
function enterState(me)
if entity_isState(me, STATE_IDLE) then
entity_stopInterpolating(me)
entity_animate(me, "idle", LOOP_INF)
elseif entity_isState(me, STATE_ATTACK) then
playSfx("EnergyBoss-Attack", 900+math.random(200))
local x, y = bone_getPosition(v.bone_jaw)
if entity_isPositionInRange(v.naija, x, y, 600)
and entity_y(v.naija) < y+64
and entity_y(v.naija) > y-64
then
entity_animate(me, "bite")
v.attack = ATTACK_BITE
else
if entity_y(v.naija) < entity_y(me)-200 then
entity_animate(me, "attackUp")
v.attack = ATTACK_UP
else
entity_animate(me, "lungeBite")
v.attack = ATTACK_DOWN
end
end
elseif entity_isState(me, STATE_FIRE) then
v.shotsFired = 0
entity_animate(me, "firing")
v.fireDelay = 4
elseif entity_isState(me, STATE_MOVING) then
if v.hits <= 1 then
v.maxMove = v.maxMove2
end
entity_animate(me, "moveForward", LOOP_INF)
if entity_x(v.orb) > entity_x(v.barrier) then
entity_setPosition(me, entity_x(me)+(800/2), entity_y(me), 3.5/2)
else
entity_setPosition(me, entity_x(me)+800, entity_y(me), 3.5)
end
elseif entity_isState(me, STATE_MOVEBACK) then
entity_animate(me, "moveBackward", LOOP_INF)
if entity_x(v.orb) > entity_x(v.barrier) then
v.moveDelay = 999
else
v.moveDelay = v.moveDelay + 10
end
v.attackDelay = 0
v.fireDelay = 0
playSfx("EnergyBoss-Hurt", 900+math.random(200))
entity_animate(me, "hurt")
entity_setPosition(me, entity_x(me)-500, entity_y(me), 1.6)
elseif entity_isState(me, STATE_HITBARRIER) then
entity_stopInterpolating(me)
playSfx("EnergyBoss-Die", 1100+math.random(200))
entity_animate(me, "hitBarrier")
entity_spawnParticlesFromCollisionMask(me, "energyboss-hit", 4)
elseif entity_isState(me, STATE_MOVEBACKFROMBARRIER) then
--entity_animate(me, "idle", LOOP_INF)
--entity_setPosition(me, entity_x(me)-(1500*0.80), entity_y(me), 2)
local nodeName = string.format("bossbackloc%d", v.hits)
debugLog(string.format("nodeName: %s", nodeName))
local backNode = getNode(nodeName)
entity_setPosition(me, node_x(backNode), entity_y(me), -800)
elseif entity_isState(me, STATE_COLLAPSE) then
clearShots()
playSfx("EnergyBoss-Die", 1000)
setFlag(FLAG_ENERGYBOSSDEAD, 1)
entity_setDamageTarget(me, DT_AVATAR_ENERGYBLAST, false)
entity_setDamageTarget(me, DT_AVATAR_SHOCK, false)
v.endTextDelay = 6.5
entity_spawnParticlesFromCollisionMask(me, "energyboss-hit", 4)
fadeOutMusic(2)
entity_animate(me, "die")
cam_toEntity(me)
disableInput()
--[[
cam_toEntity(me)
watch(4)
voiceOnce("Naija_EnergyBossOver")
cam_toEntity(getNaija())
]]--
elseif entity_isState(me, STATE_COLLAPSED) then
v.orb = getEntityByID(4)
v.holder = getEntityByID(3)
if v.orb and v.holder then
entity_setPosition(v.orb, entity_x(v.holder), entity_y(v.holder))
end
local collectibleNode = getNode("COLLECTIBLE")
createEntity("CollectibleEnergyBoss", "", node_x(collectibleNode), node_y(collectibleNode))
--debugLog("animating dead")
entity_setDamageTarget(me, DT_AVATAR_ENERGYBLAST, false)
entity_setDamageTarget(me, DT_AVATAR_SHOCK, false)
entity_animate(me, "dead")
--if entity_isFlag(me, 0) then
-- you can't beat the game without dual form
-- and we don't want to stop the music when we're panning near the boss at the end of the game
-- therefore: DO THIS:
if not hasSong(SONG_DUALFORM) then
fadeOutMusic(0.1)
end
--entity_setFlag(me, 1)
--end
elseif entity_isState(me, STATE_INTRO) then
v.awoken = true
playSfx("EnergyBoss-Die", 800)
shakeCamera(10, 3)
entity_stopInterpolating(me)
entity_animate(me, "roar")
overrideZoom(0.5, 1)
elseif entity_isState(me, STATE_APPEAR) then
entity_animate(me, "eatOmpo")
end
end
function animationKey(me, key)
if entity_isState(me, STATE_APPEAR) then
if key == 5 then
local x, y = bone_getWorldPosition(v.bone_claw)
spawnParticleEffect("Dirt", x,y)
playSfx("RockHit-Big")
elseif key == 7 then
playSfx("Bite")
elseif key == 9 then
playSfx("Bite")
elseif key == 15 then
local x, y = bone_getWorldPosition(v.bone_claw)
spawnParticleEffect("Dirt", x,y)
--playSfx("RockHit-Big")
elseif key == 16 then
playSfx("Gulp")
elseif key == 17 then
local x, y = bone_getWorldPosition(v.bone_claw)
spawnParticleEffect("Dirt", x,y)
playSfx("RockHit-Big")
end
return
end
if entity_isState(me, STATE_COLLAPSE) then
if key == 9 then
playSfx("BossDieSmall")
fade2(0.5, 0, 1, 1, 1)
fade2(0, 1, 1, 1, 1)
end
if key == 11 then
playSfx("BossDieSmall")
fade2(0.2, 0, 1, 1, 1)
fade2(0, 1, 1, 1, 1)
entity_spawnParticlesFromCollisionMask(me, "energyboss-hit", 4)
end
else
if v.attack == ATTACK_DOWN then
if entity_isState(me, STATE_ATTACK) and key == 4 then
local x, y = bone_getWorldPosition(v.bone_claw)
spawnParticleEffect("Dirt", x,y)
playSfx("RockHit-Big")
shakeCamera(15, 0.5)
end
elseif v.attack == ATTACK_UP then
if entity_isState(me, STATE_ATTACK) and key == 4 then
local x, y = bone_getWorldPosition(v.bone_claw)
spawnParticleEffect("Dirt", x,y)
playSfx("RockHit-Big")
shakeCamera(15, 0.5)
end
end
end
end
function exitState(me)
if entity_isState(me, STATE_HITBARRIER) then
entity_setState(me, STATE_MOVEBACKFROMBARRIER)
elseif entity_isState(me, STATE_MOVING) then
v.moveDelay = 4
end
end
function activate(me)
end
function hitSurface(me)
end