--ninjabomberman.lua --v0.0.2 --Created by Horikawa Otane, 2015 --Contact me at https://www.youtube.com/subscription_center?add_user=msotane local colliders = require("colliders") local savestate = require("savestate") local pm = require("playerManager") local ed = require("expandedDefines") --local graphx = require("graphX") local ninjabomberman = {} local startedAsBomberman = false local isInStartMenu = false local oldGravity = 12 local hitBoxArray = {} local frameCount = 0 local firstSave = false local hasJumped = true local hasTurnedHudOn = false local deathTimer = -1; local deathSoundChan = -1; ninjabomberman.usesavestate = true; ninjabomberman.deathDelay = lunatime.toTicks(0.5); local sfx_death = pm.registerSound(CHARACTER_NINJABOMBERMAN,"nbm_death.ogg"); local function freezePlayer(pauseMusic, pauseSound, playerX, playerY) pauseMusic = pauseMusic or false pauseSound = pauseSound or false playerX = playerX or player.x playerY = playerY or player.y mem(0x00B2C8B4, FIELD_WORD, -1) player.x = playerX player.y = playerY player:mem(0x04, FIELD_WORD, -1) --player:mem(0x11E, FIELD_WORD, 1) if pauseMusic then Audio.SeizeStream(-1) Audio.MusicPause() end if pauseSound then Audio.SfxPause(-1) end end local function unFreezePlayer(musicPaused, soundPaused) musicPaused = musicPaused or false soundPaused = soundPaused or false mem(0x00B2C8B4, FIELD_WORD, 0) player:mem(0x04, FIELD_WORD, 0) --player:mem(0x11E, FIELD_WORD, -1) || don't do this, it enables autojump if musicPaused then Audio.MusicResume() Audio.ReleaseStream(-1) end if soundPaused then Audio.SfxResume(-1) end end function ninjabomberman.onInitAPI() registerEvent(ninjabomberman, "onTick", "onTick", false) registerEvent(ninjabomberman, "onKeyDown", "onKeyDown", false) registerEvent(ninjabomberman, "onInputUpdate", "onInputUpdate", false) registerEvent(ninjabomberman, "onJump", "onJump", false) registerEvent(ninjabomberman, "onJumpEnd", "onJumpEnd", false) if (player.isValid) then if (player.character == CHARACTER_NINJABOMBERMAN) then player:mem(0x16, FIELD_WORD, 1) end end end --OnTick function ninjabomberman.onTick() if (player.character == CHARACTER_NINJABOMBERMAN) then if frameCount < 1 then frameCount = frameCount + 1 elseif frameCount == 1 and not firstSave then state = savestate.save(savestate.STATE_ALL) firstSave = true end if isInStartMenu then Defines.gravity = 0 freezePlayer(false, false, player.x, player.y) Text.printWP("Press run to Exit Level", 200, 200,-5) else unFreezePlayer(false, false) Defines.gravity = oldGravity end if not startedAsBomberman then state = savestate.save(savestate.STATE_ALL) startedAsBomberman = true end player:mem(0x1A, FIELD_WORD, 0) player:mem(0x18, FIELD_WORD, -1) for k, v in pairs(NPC.get()) do if (v.id == 192) then if (colliders.collide(player, v)) then state = savestate.save(savestate.STATE_ALL) end end end --[[ for _, v in pairs(NPC.get(291, player.section)) do graphx.boxLevel(v.x, v.y, v.width, v.height, 0xFF000066) for _, w in pairs(NPC.get(horikawaTools.hittableNPCs, player.section)) do Text.print(w.id, 100, 100) if (horikawaTools.npcList[w.id] or horikawaTools[w.id] == 2) then if (colliders.collide(v, w)) then canJump = true break end end end end ]] for _, npcLister in pairs(NPC.get(NPC.HITTABLE, player.section)) do if (npcLister:mem(0x64, FIELD_WORD) == 0) and (npcLister:mem(0x40, FIELD_WORD) == 0) then local thePnpc = npcLister npcHitBox = hitBoxArray[thePnpc.uid] -- If we already had this NPC in hitBoxArray, don't replace our old object, just update the hitbox if npcHitBox == nil then npcHitBox = {} npcHitBox.thePnpc = thePnpc npcHitBox.hasBeenHit = false hitBoxArray[npcHitBox.thePnpc.uid] = npcHitBox npcHitBox.timeout = 0 end npcHitBox.timeout = 0 npcHitBox.x = npcLister.x npcHitBox.x2 = npcLister.x + npcLister.width npcHitBox.y = npcLister.y npcHitBox.y2 = npcLister.y + npcLister.height --graphx.boxLevel(npcLister.x, npcLister.y, npcLister.width, npcLister.height, 0x00FF0066) end end for _, hitBox in pairs(hitBoxArray) do for _, hitAnimation in pairs(Animation.getIntersecting(hitBox.x, hitBox.y, hitBox.x2, hitBox.y2)) do if not hitBox.hasBeenHit and (hitAnimation.id == 148) then --graphx.boxLevel(hitAnimation.x, hitAnimation.y, hitAnimation.width, hitAnimation.height, 0xFF00FFFF) hitBox.hasBeenHit = true canJump = true end end -- If destroyed or marked as dead... if (not hitBox.thePnpc.isValid) or (hitBox.thePnpc.forcedState ~= 0) then hitBox.timeout = hitBox.timeout + 1 if hitBox.timeout > 5 then hitBoxArray[hitBox.thePnpc.uid] = nil end end end if player:mem(0x16, FIELD_WORD) > 1 then player:mem(0x16, FIELD_WORD, 1) end if player:mem(0x13C, FIELD_DWORD) ~= 0 or player.forcedState == 227 or player.forcedState == 2 then player:kill() Audio.SfxStop(-1) Audio.playSFX(pm.getSound(CHARACTER_NINJABOMBERMAN,sfx_death)) player:mem(0x13E, FIELD_WORD,1) Misc.pause(); deathTimer = ninjabomberman.deathDelay; end --Jumps if (not player:isGroundTouching() and player:mem(0x34, FIELD_WORD) ~= 2) and (player:mem(0x48, FIELD_WORD) == 0) then if player:mem(0x40, FIELD_WORD) ~= 3 then if not hasJumped then canJump = true hasJumped = true end else canJump = false hasJumped = false end if player.jumpKeyPressing or player.altJumpKeyPressing then if player.speedY > 0.2 then player.speedY = 0.2 end --Hover timer player:mem(0x1C, FIELD_WORD, -1) end else canJump = false hasJumped = false end --Quit level if player.keys.run == KEYS_PRESSED and isInStartMenu then unFreezePlayer(false, false) exitLevel() end end end --onkeydown function ninjabomberman.onKeyDown(keycode) if (player.character == CHARACTER_NINJABOMBERMAN) then if (keycode) == KEY_SEL and ninjabomberman.usesavestate then if not isInStartMenu then oldGravity = Defines.gravity end isInStartMenu = not isInStartMenu elseif (keycode == KEY_JUMP) or (keycode == KEY_SPINJUMP) then --prevent hover player:mem(0x1C, FIELD_WORD, -1) if (canJump) then player.speedY = -10 playSFX(1) NPC.spawn(291, player.x, player.y, player:mem(0x15A, FIELD_WORD)) canJump = false end end end end --onInputUpdate function ninjabomberman.onInputUpdate() if (player.character == CHARACTER_NINJABOMBERMAN) then pm.winStateCheck() if isInStartMenu then player.leftKeyPressing = false player.rightKeyPressing = false end if(Misc.isPaused()) then if(deathTimer > 0) then deathTimer = deathTimer - 1; elseif(deathTimer == 0) then if(ninjabomberman.usesavestate) then savestate.load(state, savestate.STATE_ALL) player.jumpKeyPressing = false player:mem(0x16, FIELD_WORD, 1) Misc.unpause(); deathTimer = -1; else Misc.unpause(); player:mem(0x13E,FIELD_WORD,198); deathTimer = -1; end end end end end --onjump function ninjabomberman.onJump() if (player.character == CHARACTER_NINJABOMBERMAN) then canJump = true hasJumped = true end end function ninjabomberman.onJumpEnd() if (player.character == CHARACTER_NINJABOMBERMAN) then canJump = false for _, j in pairs(hitBoxArray) do j.hasBeenHit = false end hasJumped = false end end --CLEANUP function ninjabomberman.initCharacter() -- CLEANUP NOTE: This is not safe if a level makes it's own use of gravity/jumpheight Defines.jumpheight = 10 Defines.jumpheight_bounce = 12 -- CLEANUP NOTE: This is not safe if a level makes it's own use of activateHud hasTurnedHudOn = false hud(false) end function ninjabomberman.cleanupCharacter() -- CLEANUP NOTE: This is not safe if a level makes it's own use of activateHud if not hasTurnedHudOn then hud(true) hasTurnedHudOn = true end isInStartMenu = false startedAsBomberman = false -- CLEANUP NOTE: This is not safe if a level makes it's own use of gravity/jumpheight Defines.jumpheight = nil Defines.jumpheight_bounce = nil Defines.gravity = 12 end function ninjabomberman.resetjump() canJump = true hasJumped = false end return ninjabomberman