Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --***************************************************************************************
- -- DIALOGUE/SUBTITLE VARIABLES *
- --***************************************************************************************
- -- Speaker NPC ID
- dialogSpeaker = 0
- -- _____
- dialogSpeakerFrame = 0
- -- Text display countdown
- dialogTextTime = 0
- -- Speaker animation countdown
- dialogSpeakerTime = 0
- -- Dialogue update rate (characters per frame)
- dialogTextSpeed = 1
- -- Check whether a line of dialogue or subtitle is being processed
- dialogOn = false
- -- Speaker name
- dialogName = ""
- -- Full line of dialogue being spoken with timing commands
- dialogTextFull = ""
- -- Currently-revealed dialogue string
- dialogText = ""
- -- Line of dialogue being spoken with timing commands
- dialogTextCommands = ""
- -- Individual lines of the line of dialogue being spoken
- dialogTextLine1 = ""
- dialogTextLine2 = ""
- dialogTextLine3 = ""
- dialogTextLine4 = ""
- -- Total number of characters in the dialogue string
- dialogNumCharsTotal = 0
- -- Number of characters revealed in the displayed dialogue
- dialogNumCharsCurrent = 0
- -- Number of characters revealed w/ bypassing commands
- dialogNumCharsCommands = 0
- -- Can the player press the key to skip the current line?
- dialogSkippable = true
- -- Does the dialogue halt the cutscene timing?
- dialogPause = true
- -- Does the player have to press a key to continue?
- dialogEndWithInput = true
- --***************************************************************************************
- -- CUTSCENE VARIABLES *
- --***************************************************************************************
- -- Is there a cutscene or boss in each section
- levelSectionHasCutscene = {true, false, false, false, false,
- false, false, false, false, false,
- false, false, false, false, false,
- false, false, false, false, false,
- false}
- -- Can the entire cutscene be skipped?
- cutsceneSkippable = true
- -- Player input currently active?
- playerInputActive = false
- -- Current cutscene/attack pattern time in frames
- cutsceneFrame = 0
- battleFrame = 0
- -- "Phase" of the full sequence; 0 = pre-battle, 1 = battle, 2 = post-battle
- cutscenePhase = 0
- -- "Phase" of the boss' attack pattern
- battlePhase = 0
- -- For looping attack patterns, this is the current step of the pattern
- bossAttackPattern = 0
- --***************************************************************************************
- -- CONSTANTS AND ENUMS *
- --***************************************************************************************
- -- Key terms
- KEYTERM_PLAYERNAME = ""
- -- NPC ID enums
- NPCID_BROADSWORD = 101
- NPCID_DONUTGEN = 211
- NPCID_SHOCKWAVEGEN = 206
- NPCID_COLLISIONA = 136
- NPCID_COLLISIONB = 137
- -- Sound IDs
- SOUNDID_DRAWSWORD = "sword1.wav"
- SOUNDID_SLICE = "sword2.wav"
- -- Animation states enum
- ANIMSTATE_NUMFRAMES = 0
- ANIMSTATE_IDLE = 1
- ANIMSTATE_TALK = 2
- ANIMSTATE_WALK = 3
- ANIMSTATE_JUMP = 4
- ANIMSTATE_FALL = 5
- ANIMSTATE_DEFEAT = 6
- ANIMSTATE_ATTACK1 = 7
- ANIMSTATE_ATTACK2 = 8
- ANIMSTATE_ATTACK3 = 9
- ANIMSTATE_ATTACK4 = 10
- ANIMSTATE_ATTACK5 = 11
- ANIMSTATE_ATTACK6 = 12
- ANIMSTATE_ATTACK7 = 13
- -- NPC animation state table
- npcAnimStates = {}
- npcAnimStates[NPCID_BROADSWORD] = ANIMSTATE_IDLE
- -- Individual NPC animation settings
- animData_Broadsword = {}
- animData_Broadsword[ANIMSTATE_NUMFRAMES] = 32
- animData_Broadsword[ANIMSTATE_IDLE] = "0-0"
- animData_Broadsword[ANIMSTATE_TALK] = "1-2"
- animData_Broadsword[ANIMSTATE_WALK] = "4-5"
- animData_Broadsword[ANIMSTATE_JUMP] = "7-7"
- animData_Broadsword[ANIMSTATE_FALL] = "9-9"
- animData_Broadsword[ANIMSTATE_DEFEAT] = "21-21"
- animData_Broadsword[ANIMSTATE_ATTACK1] = "11-11"
- animData_Broadsword[ANIMSTATE_ATTACK2] = "13-15"
- animData_Broadsword[ANIMSTATE_ATTACK3] = "17-17"
- animData_Broadsword[ANIMSTATE_ATTACK4] = "19-19"
- animData_Broadsword[ANIMSTATE_ATTACK5] = "23-23"
- animData_Broadsword[ANIMSTATE_ATTACK6] = "25-25"
- animData_Broadsword[ANIMSTATE_ATTACK7] = "27-30"
- -- PLEASE TAMPER WITH THIS FUNCTION, THANK YOU -----------------------------------------
- function onLoadVars ()
- end
- function preBattleEvents ()
- -- Disable the shockwave generators
- shockwaveGenLNPC:mem (0x6C, FIELD_FLOAT, 0)
- shockwaveGenRNPC:mem (0x6C, FIELD_FLOAT, 0)
- -- Make the boss invincible during the intro cutscene
- collisionANPC:mem (0x46, FIELD_WORD, 0xFFFF)
- -- Cutscene events
- if cutsceneFrame < 60 then
- forceNPCWalkRight (broadswordNPC, 0)
- player.speedX = 3
- elseif cutsceneFrame == 60 then
- --playSFX("voice_talk1.wav")
- npcAnimStates[NPCID_BROADSWORD] = ANIMSTATE_IDLE
- forceNPCWalkLeft (broadswordNPC, 0)
- elseif cutsceneFrame == 61 then
- startDialog (NPCID_BROADSWORD, "Uncle Broadsword", "A-ha! 'Twas a good show, "..KEYTERM_PLAYERNAME..", but I emerge the victor!", 30, 30, "voice_talk1.wav")
- elseif cutsceneFrame == 62 then
- startDialog (NPCID_IRIS, KEYTERM_PLAYERNAME, "B-but we really need that leek! Best two out of three?", 30, 30, "")
- elseif cutsceneFrame == 63 then
- startDialog (NPCID_BROADSWORD, "Uncle Broadsword", "Tsk, tsk, tsk! Nobody likes a sore loser, my dear!", 30, 30, "")
- elseif cutsceneFrame == 64 then
- setDialogRules (false, false, true, 1)
- startDialog (NPCID_BROADSWORD, "Uncle Broadsword", "But I am still feeling a tad sporting...", 160, 100, "")
- elseif cutsceneFrame < 120 then
- forceNPCWalkRight (broadswordNPC, 2)
- elseif cutsceneFrame == 120 then
- setDialogRules (true, true, true, 1)
- forceNPCWalkRight (broadswordNPC, 0)
- elseif cutsceneFrame == 121 then
- forceNPCWalkLeft (broadswordNPC, 0)
- startDialog (NPCID_BROADSWORD, "Uncle Broadsword", "Very well! If this preposterous produce means that much to you, then come and have a go!", 30, 30, "")
- elseif cutsceneFrame == 122 then
- startDialog (NPCID_BROADSWORD, "Uncle Broadsword", "Best moi in a duel and the colossal cabbage is yours!", 30, 30, "")
- elseif cutsceneFrame == 123 then
- --playSFX("voice_talk4.wav");
- elseif cutsceneFrame == 124 then
- startDialog (NPCID_BROADSWORD, "Uncle Broadsword", "But I shant take this challenge lightly, so don't hold back yourself!", 30, 30, "voice_talk4.wav")
- elseif cutsceneFrame == 125 then
- --playSFX("voice_talk5.wav");
- elseif cutsceneFrame == 126 then
- setDialogRules (false, false, false, 1)
- startDialog (NPCID_BROADSWORD, "Uncle Broadsword", "EN GARDE!", 160, 160, "voice_talk5.wav")
- elseif cutsceneFrame < 150 then
- npcAnimStates[NPCID_BROADSWORD] = ANIMSTATE_IDLE
- elseif cutsceneFrame == 150 then
- playSFX(SOUNDID_DRAWSWORD)
- broadswordNPC.x = broadswordNPC.x - 8
- elseif cutsceneFrame < 210 then
- npcAnimStates[NPCID_BROADSWORD] = ANIMSTATE_ATTACK1
- elseif cutsceneFrame == 210 then
- playSFX(SOUNDID_SLICE)
- broadswordNPC.x = broadswordNPC.x - 16
- elseif cutsceneFrame < 260 then
- npcAnimStates[NPCID_BROADSWORD] = ANIMSTATE_ATTACK2
- elseif cutsceneFrame == 260 then
- broadswordNPC.x = broadswordNPC.x + 32
- elseif cutsceneFrame < 320 then
- npcAnimStates[NPCID_BROADSWORD] = ANIMSTATE_IDLE
- elseif cutsceneFrame == 320 then
- triggerEvent("Begin Battle")
- cutscenePhase = 1
- cutsceneFrame = 0
- collisionANPC:mem (0x46, FIELD_WORD, 0)
- end
- end
- function bossBattleEvents ()
- -- Activate player input
- playerInputActive = true
- -- Disable the shockwave generators
- if battlePhase ~= 2 then
- shockwaveGenLNPC:mem (0x6C, FIELD_FLOAT, 0)
- shockwaveGenRNPC:mem (0x6C, FIELD_FLOAT, 0)
- end
- -- Determine where the boss is relative to the player
- local distToPlayerX = math.abs(getNPCRelativePosX (broadswordNPC))
- local dirToPlayerX = getNPCRelativeDirX (broadswordNPC)
- local distToWallX = getNPCWallDistance (broadswordNPC, getNPCWallClosest(broadswordNPC))
- -- Display boss HP
- if battlePhase ~= 30 then
- printCenteredText ("AUGUSTUS LEOPOLD BROADSWORD ESQ. III", 4, 400, 500)
- printCenteredText (string.rep("8", bossHP), 4, 400, 520)
- printCenteredText (string.rep("3", bossHP), 4, 400, 520)
- printCenteredText (string.rep("K", bossHP), 4, 400, 520)
- printCenteredText (string.rep("N", bossHP), 4, 400, 520)
- printCenteredText (string.rep("W", bossHP), 4, 400, 520)
- end
- -- PHASE 1: DEFEND & MOVE AROUND -------------------------------------------------------------------
- if battlePhase == 0 then
- battleFrame = battleFrame + 1
- -- After 160 frames, move on to the next phase of the attack pattern
- if battleFrame >= 240 and broadswordNPC.speedY == 0 then
- bossAttackPattern = bossAttackPattern + 1
- if (bossAttackPattern % 2 == 1) then
- playSFX ("voice_attack1.wav")
- battlePhase = 1
- else
- playSFX ("voice_attack2.wav")
- battlePhase = 2
- end
- battleFrame = 0
- elseif broadswordNPC.speedY == 0 then
- if npcAnimStates[NPCID_BROADSWORD] == ANIMSTATE_ATTACK7 then
- npcAnimStates[NPCID_BROADSWORD] = ANIMSTATE_IDLE
- end
- if distToWallX > 128 then
- if distToPlayerX > 160 then
- forceNPCWalkToPlayer (broadswordNPC, math.clamp(5, 12*(distToPlayerX/180 - 1), 8))
- elseif distToPlayerX < 160 then
- forceNPCJump (broadswordNPC, math.random(4,6))
- forceNPCWalkToPlayer (broadswordNPC, -6)
- end
- else
- if (donutGenNPC ~= nil) then
- donutGenNPC:mem (0x06, FIELD_WORD, 0)
- end
- forceNPCJump (broadswordNPC, 10)
- forceNPCWalkToPlayer (broadswordNPC, 8)
- npcAnimStates[NPCID_BROADSWORD] = ANIMSTATE_ATTACK7
- playSFX ("sword2.wav")
- end
- end
- -- PHASE 2: DASH ATTACK ------------------------------------------------------------------------------
- elseif battlePhase == 1 then
- battleFrame = battleFrame + 1
- -- Unsheath sword and hack away
- if battleFrame < 60 then
- broadswordNPC.speedY = math.max(0, broadswordNPC.speedY)
- npcAnimStates[NPCID_BROADSWORD] = ANIMSTATE_ATTACK1
- forceNPCWalkToPlayer (broadswordNPC, 0)
- elseif battleFrame == 60 then
- playSFX (SOUNDID_SLICE)
- elseif battleFrame < 100 then
- npcAnimStates[NPCID_BROADSWORD] = ANIMSTATE_ATTACK2
- forceNPCWalkForward (broadswordNPC, 8)
- if getNPCWallDistance (broadswordNPC, getNPCWallFacing(broadswordNPC)) < 100 then
- battleFrame = 100
- end
- else
- battlePhase = 3
- battleFrame = 0
- end
- -- PHASE 3: POGO ------------------------------------------------------------------------------
- elseif battlePhase == 2 then
- -- Disable the shockwave generators
- if battleFrame ~= 120 then
- shockwaveGenLNPC:mem (0x6C, FIELD_FLOAT, 0)
- shockwaveGenRNPC:mem (0x6C, FIELD_FLOAT, 0)
- end
- -- Jump high
- if battleFrame < 4 then
- npcAnimStates[NPCID_BROADSWORD] = ANIMSTATE_ATTACK5
- forceNPCWalkToPlayer (broadswordNPC, math.clamp(-8, 0.05*(distToPlayerX), 8))
- if broadswordNPC.speedY == 0 then
- forceNPCJump (broadswordNPC, 11)
- if (battleFrame > 0) then
- playSFX ("boing.wav")
- end
- battleFrame = battleFrame + 1
- end
- -- Hold in the air
- elseif battleFrame == 4 then
- playSFX (11)
- battleFrame = battleFrame + 1
- elseif battleFrame < 60 then
- battleFrame = battleFrame + 1
- forceNPCWalkToPlayer (broadswordNPC, 0)
- if broadswordNPC.speedY > 0 then
- broadswordNPC.speedY = 0
- end
- -- Stab down
- elseif battleFrame == 60 then
- playSFX (22)
- battleFrame = battleFrame + 1
- elseif battleFrame < 120 then
- if broadswordNPC.y + 200000 < -225 then
- npcAnimStates[NPCID_BROADSWORD] = ANIMSTATE_ATTACK6
- broadswordNPC.speedY = 64
- else
- shockwaveGenLNPC:mem (0x6C, FIELD_FLOAT, 100)
- shockwaveGenRNPC:mem (0x6C, FIELD_FLOAT, 100)
- battleFrame = 120
- end
- else
- battlePhase = 3
- battleFrame = 0
- end
- -- PHASE 4: VULNERABLE ---------------------------------------------------------------------
- elseif battlePhase == 3 then
- battleFrame = battleFrame + 1
- if battleFrame < 240 then
- npcAnimStates[NPCID_BROADSWORD] = ANIMSTATE_DEFEAT
- else
- npcAnimStates[NPCID_BROADSWORD] = ANIMSTATE_JUMP
- forceNPCJump (broadswordNPC, 4)
- forceNPCWalkToPlayer (broadswordNPC, -4)
- battlePhase = 0
- battleFrame = 0
- end
- -- PHASE 30: DEFEAT SEQUENCE ------------------------------------------------------------------------------
- elseif battlePhase == 30 then
- battleFrame = battleFrame + 1
- if battleFrame == 1 then
- npcAnimStates[NPCID_BROADSWORD] = ANIMSTATE_DEFEAT
- playSFX ("voice_defeat.wav")
- triggerEvent("End Battle")
- elseif battleFrame == 120 then
- cutscenePhase = 2
- battleFrame = 0
- cutsceneFrame = 0
- end
- end
- end
- function postBattleEvents ()
- -- Make the boss invincible during the cutscene
- collisionANPC:mem (0x46, FIELD_WORD, 0xFFFF)
- -- Disable the shockwave generators
- shockwaveGenLNPC:mem (0x6C, FIELD_FLOAT, 0)
- shockwaveGenRNPC:mem (0x6C, FIELD_FLOAT, 0)
- -- Cutscene events
- if cutsceneFrame <= 1 then
- playerInputActive = false
- elseif cutsceneFrame < 60 then
- setDialogRules (true, true, true, 1)
- npcAnimStates[NPCID_BROADSWORD] = ANIMSTATE_IDLE
- --forceNPCWalkToX (broadswordNPC, 600-200000, 2);
- --forceNPCWalkToX (player, 600-200000, 2);
- elseif cutsceneFrame == 60 then
- player.x = 200-200000
- broadswordNPC.x = 600-200000
- forceNPCWalkLeft (broadswordNPC, 0);
- --playSFX("voice_talk1.wav");
- elseif cutsceneFrame == 61 then
- startDialog (NPCID_BROADSWORD, "Uncle Broadsword", "I daresay, that was a most exhilarating scuffle! Bravo!", 30, 30, "voice_talk1.wav")
- elseif cutsceneFrame == 62 then
- startDialog (NPCID_BROADSWORD, "Uncle Broadsword", "As per our wager, the titanic tomato is now yours. Treasure it always!", 30, 30, "")
- elseif cutsceneFrame == 63 then
- forceNPCJump (broadswordNPC, 6);
- triggerEvent("Reveal Leek")
- elseif cutsceneFrame < 67 then
- -- EMPTY SPACE
- elseif cutsceneFrame == 67 then
- triggerEvent("Reveal Leek")
- elseif cutsceneFrame < 120 then
- -- EMPTY SPACE
- elseif cutsceneFrame == 120 then
- --playSFX("voice_talk3.wav");
- elseif cutsceneFrame == 121 then
- forceNPCWalkRight (broadswordNPC, 0)
- startDialog (NPCID_BROADSWORD, "Uncle Broadsword", "And with that, I must take my leave. There is still much adventuring to do! Cheerio!", 30, 30, "voice_talk3.wav")
- elseif cutsceneFrame < 180 then
- forceNPCWalkRight (broadswordNPC, 2)
- elseif cutsceneFrame < 240 then
- forceNPCWalkRight (broadswordNPC, 0)
- elseif cutsceneFrame == 240 then
- --playSFX("voice_talk4.wav");
- elseif cutsceneFrame == 241 then
- forceNPCWalkLeft (broadswordNPC, 0)
- startDialog (NPCID_BROADSWORD, "Uncle Broadsword", "Ah, one more thing.", 30, 30, "voice_talk4.wav")
- elseif cutsceneFrame == 242 then
- startDialog (NPCID_BROADSWORD, "Uncle Broadsword", "My brothers are...", 30, 30, "")
- elseif cutsceneFrame == 243 then
- startDialog (NPCID_BROADSWORD, "Uncle Broadsword", "...", 30, 30, "")
- elseif cutsceneFrame == 244 then
- forceNPCWalkRight (broadswordNPC, 0);
- startDialog (NPCID_BROADSWORD, "Uncle Broadsword", "Ah, what am I doing? Spoilers, Augustus! Spoilers!", 30, 30, "")
- elseif cutsceneFrame < 360 then
- forceNPCWalkRight (broadswordNPC, 4);
- elseif cutsceneFrame == 360 then
- playerInputActive = true
- end
- end
- -- PLEASE DO NOT TAMPER WITH THESE FUNCTIONS, THANK YOU ----------------------------
- function onLoad ()
- -- Filter the player to big
- player.powerup = math.max(player.powerup, 2)
- -- Set the boss' HP to 8
- bossHP = 8
- dialogSpeaker = 0
- dialogTextTime = 0
- dialogSpeakerTime = 0
- dialogName = ""
- dialogText = ""
- dialogTextLine1 = ""
- dialogTextLine2 = ""
- dialogTextLine3 = ""
- dialogTextLine4 = ""
- dialogTextFull = ""
- dialogSkippable = true
- dialogPause = true
- dialogEndWithInput = true
- cutsceneFrame = 0
- setDialogRules(true, true, true, 1)
- end
- function onLoop()
- -- Get references
- donutGenNPC = findnpcs(NPCID_DONUTGEN, -1)[0]
- shockwaveGenLNPC = findnpcs(NPCID_SHOCKWAVEGEN, -1)[0]
- shockwaveGenRNPC = findnpcs(NPCID_SHOCKWAVEGEN, -1)[1]
- broadswordNPC = findnpcs(NPCID_BROADSWORD, -1)[0]
- collisionANPC = findnpcs(NPCID_COLLISIONA, -1)[0]
- collisionBNPC = findnpcs(NPCID_COLLISIONB, -1)[0]
- -- player input during cutscenes
- freezePlayerInput ()
- -- Shockwave generators
- if (shockwaveGenLNPC ~= nil) then
- shockwaveGenLNPC.x = broadswordNPC.x-64
- shockwaveGenLNPC.y = broadswordNPC.y+32
- end
- if (shockwaveGenRNPC ~= nil) then
- shockwaveGenRNPC.x = broadswordNPC.x+64
- shockwaveGenRNPC.y = broadswordNPC.y+32
- end
- -- Snap the collision dummy A to Broadsword
- if (collisionANPC ~= nil) then
- collisionANPC.x = broadswordNPC.x
- collisionANPC.y = broadswordNPC.y
- -- If the boss is out of health, begin the win sequence and lead into the post-battle cutscene
- if (bossHP <= 0 and battlePhase ~= 30) then
- collisionANPC:mem (0x46, FIELD_WORD, 0xFFFF)
- battlePhase = 30
- battleFrame = 0
- end
- end
- -- Quickly reset the collision dummy B and reduce the boss HP counter
- if (collisionBNPC ~= nil) then
- bossHP = bossHP - 1
- playSFX ("voice_hurt1.wav")
- if battlePhase == 3 then
- battleFrame = battleFrame + 30
- end
- -- Speed up the music toward the end
- if (bossHP == 2) then
- triggerEvent("Ramp Up Music")
- end
- collisionBNPC:mem (0xE2, FIELD_WORD, NPCID_COLLISIONA)
- end
- -- Snap the donut generator to Broadsword
- if (donutGenNPC ~= nil) then
- donutGenNPC.x = broadswordNPC.x
- donutGenNPC.y = broadswordNPC.y
- end
- -- Turn all rinkas into _____
- allNPCs = findnpcs(210,player.section)
- for k,v in pairs(allNPCs) do
- v.speedY = -8
- v:mem (0xE2, FIELD_WORD, 30)
- if (v:mem (0x136, FIELD_WORD) == FFFF) then
- v.speedX = 4 * getNPCRelativeDirX (v)
- end
- end
- -- Test text
- --printText("SPEAKER="..tostring(dialogSpeaker), 10, 10)
- --printText("TIME="..tostring(cutsceneFrame), 10, 30)
- -- Trigger sequenced cutscene events
- processCutscene()
- -- Control specific NPC talking/idle animations
- controlNPCAnimation (NPCID_BROADSWORD, animData_Broadsword)
- -- Control dialogue display
- processDialog()
- defineKeyTerms()
- end
- function freezePlayerInput ()
- --[[
- if playerInputActive == false then
- player:mem(0x04, FIELD_WORD, 1)
- player:mem(0x06, FIELD_WORD, 0)
- player:mem(0xF2, FIELD_WORD, 0)
- player:mem(0xF4, FIELD_WORD, 0)
- player:mem(0xF6, FIELD_WORD, 0)
- player:mem(0xF8, FIELD_WORD, 0)
- player:mem(0xFA, FIELD_WORD, 0)
- player:mem(0xFC, FIELD_WORD, 0)
- player:mem(0x100, FIELD_WORD, 0)
- player:mem(0x118, FIELD_WORD, 0)
- player:mem(0x11E, FIELD_WORD, 0)
- player:mem(0x120, FIELD_WORD, 0)
- else
- player:mem(0x04, FIELD_WORD, 0)
- player:mem(0x06, FIELD_WORD, 1)
- end
- --]]
- end
- function onKeyDown (keycode)
- -- Skip dialog if allowed
- if(keycode == KEY_X and dialogEndWithInput == true and (dialogTextTime > 0 or dialogSpeakerTime > 0))then
- playSFX(23) -- 10 = skid, 14 = coin, 23 = shckwup
- endDialogLine()
- end
- end
- -- NPC COMMANDS ---------------------------------------------------------------------------------
- -- Jump --
- function forceNPCJump (myNPC, jumpStrength)
- myNPC.speedY = -1 * jumpStrength
- playSFX(1)
- end
- -- Walk --
- function forceNPCWalkToPlayer (myNPC, speed)
- local dirToPlayerX = getNPCRelativeDirX (myNPC)
- if dirToPlayerX == DIR_LEFT then
- forceNPCWalkLeft (myNPC, speed)
- else
- forceNPCWalkRight (myNPC, speed)
- end
- local tempSpeedX = myNPC.speedX
- myNPC.direction = dirToPlayerX
- myNPC.speedX = tempSpeedX
- end
- function forceNPCWalkToX (myNPC, destX, speed)
- local dirToX = DIR_LEFT
- if (myNPC.x - destX < 0) then
- dirToX = DIR_RIGHT
- end
- if dirToPlayerX == DIR_LEFT then
- forceNPCWalkLeft (myNPC, speed)
- else
- forceNPCWalkRight (myNPC, speed)
- end
- local tempSpeedX = myNPC.speedX
- myNPC.direction = dirToPlayerX
- myNPC.speedX = tempSpeedX
- end
- function forceNPCWalkForward (myNPC, speed)
- myNPC.speedX = myNPC.direction * speed
- end
- function forceNPCWalkLeft (myNPC, speed)
- myNPC.direction = DIR_LEFT
- myNPC.speedX = -1*speed
- setAnimStateByMovement (myNPC, myNPC.id)
- end
- function forceNPCWalkRight (myNPC, speed)
- myNPC.direction = DIR_RIGHT
- myNPC.speedX = speed
- setAnimStateByMovement (myNPC, myNPC.id)
- end
- function setAnimStateByMovement (myNPC, npcid)
- -- Don't disrupt unique animations
- if npcAnimStates[npcid] < ANIMSTATE_ATTACK1 then
- -- If on ground
- if myNPC.speedY == 0 then
- if math.abs(myNPC.speedX) < 1 then
- if dialogSpeaker == npcid then
- npcAnimStates[npcid] = ANIMSTATE_TALK
- else
- npcAnimStates[npcid] = ANIMSTATE_IDLE
- end
- else
- npcAnimStates[npcid] = ANIMSTATE_WALK
- end
- -- If jumping or falling
- elseif myNPC.speedY > 0 then
- npcAnimStates[npcid] = ANIMSTATE_FALL
- else
- npcAnimStates[npcid] = ANIMSTATE_JUMP
- end
- end
- end
- -- Accelerate --
- function accelNPCX (npcid, horzAccel)
- local myNPC = findnpcs(npcid, -1)[0]
- myNPC.speedX = myNPC.speedX + horzAccel
- end
- function accelNPCY (npcid, vertAccel)
- local myNPC = findnpcs(npcid, -1)[0]
- myNPC.speedY = myNPC.speedY + vertAccel
- end
- -- Set speed --
- function setNPCSpeedX (npcid, horzAmount)
- local myNPC = findnpcs(npcid, -1)[0]
- myNPC.speedX = horzAmount
- end
- function setNPCSpeedY (npcid, vertAmount)
- local myNPC = findnpcs(npcid, -1)[0]
- myNPC.speedY = vertAmount
- end
- function setNPCPosX (npcid, xPos)
- local myNPC = findnpcs(npcid, -1)[0]
- myNPC.x = xPos
- end
- function setNPCPosY (npcid, yPos)
- local myNPC = findnpcs(npcid, -1)[0]
- myNPC.y = yPos
- end
- function setNPCPos (npcid, xPos, yPos)
- setNPCPosX (npcid, xPos)
- setNPCPosY (npcid, yPos)
- end
- -- CUTSCENE CONTROL FUNCTIONS ---------------------------------------------------------------------------------
- function setDialogRules (pause, skippable, needInput, textSpeed)
- dialogPause = pause
- dialogSkippable = skippable
- dialogEndWithInput = needInput
- dialogTextSpeed = textSpeed
- end
- -- Character branching --
- function branchByCharacter(demoTime, irisTime, koodTime, sheathTime, raocowTime)
- local pID = getPlayerID()
- if pID == 1 then cutsceneFrame = demoTime
- elseif pID == 2 then cutsceneFrame = irisTime
- elseif pID == 3 then cutsceneFrame = koodTime
- elseif pID == 4 then cutsceneFrame = raocowTime
- elseif pID == 5 then cutsceneFrame = sheathTime
- else
- cutsceneFrame = triggerTime
- printText("LOOP ERROR", 3, 400, 300)
- end
- end
- function timedBranchByCharacter (triggerTime, demoTime, irisTime, koodTime, sheathTime, raocowTime)
- if (cutsceneFrame == triggerTime) then
- branchByCharacter (demoTime, irisTime, koodTime, sheathTime, raocowTime)
- end
- end
- -- Random chance branching --
- function branchRandom (percent, passFrame, failFrame)
- if (math.random(0, 100) <= percent) then
- cutsceneFrame = passFrame
- else
- cutsceneFrame = failFrame
- end
- end
- function timedBranchRandom (triggerTime, percent, passFrame, failFrame)
- if (cutsceneFrame == triggerTime) then
- branchRandom (percent, passFrame, failFrame)
- end
- end
- -- Time jumps --
- function timedCutsceneTimeJump (triggerFrame, jumpToFrame)
- if(cutsceneFrame == triggerFrame) then
- cutsceneTimeJump(jumpToFrame)
- end
- end
- function cutsceneTimeJump (jumpToFrame)
- cutsceneFrame = jumpToFrame
- end
- -- Triggering dialog --
- function startDialog (speakerid, name, text, textTime, speakTime, sound)
- if dialogOn == false and sound ~= "" then
- playSFX (sound)
- end
- triggerDialogSpeaker (speakerid, speakTime)
- triggerDialogText (name, text, textTime)
- dialogOn = true
- end
- function triggerDialogSpeaker (npcid, timeVal)
- dialogSpeaker = npcid
- dialogSpeakerTime = timeVal
- end
- function triggerDialogText (name,text,textTime)
- dialogName = name
- dialogTextFull = text
- dialogTextTime = textTime
- end
- -- CUTSCENE MANAGEMENT, DO NOT TOUCH ---------------------------------------------------------------------------------
- function defineKeyTerms()
- local pID = getPlayerID()
- if pID == 0 then KEYTERM_PLAYERNAME = "NOBODY"
- elseif pID == 1 then KEYTERM_PLAYERNAME = "Demo"
- elseif pID == 2 then KEYTERM_PLAYERNAME = "Iris"
- elseif pID == 3 then KEYTERM_PLAYERNAME = "Kood"
- elseif pID == 4 then KEYTERM_PLAYERNAME = "raocow"
- elseif pID == 5 then KEYTERM_PLAYERNAME = "Sheath"
- end
- end
- function processCutscene()
- if (dialogPause == false or dialogTextTime <= 0) then
- cutsceneFrame = cutsceneFrame + 1
- end
- -- Pre-battle cutscene
- if cutscenePhase == 0 then
- preBattleEvents ()
- -- Boss battle attack pattern
- elseif cutscenePhase == 1 then
- bossBattleEvents ()
- -- Post-battle cutscene
- elseif cutscenePhase == 2 then
- postBattleEvents ()
- end
- end
- function processDialog ()
- -- Display the text only revealed by the typewriter effect
- local currentCharNum = math.floor (dialogNumCharsCurrent)
- dialogText = string.sub (dialogTextFull, 0, currentCharNum)
- local currentChar = string.sub (dialogTextFull, currentCharNum-1, currentCharNum)
- -- Decrement the dialogue timer and increment the typewriter effect.
- if (dialogTextTime > 0) then
- dialogTextTime = dialogTextTime - 1
- if (dialogNumCharsCurrent < string.len (dialogTextFull)) then
- dialogNumCharsCurrent = dialogNumCharsCurrent + dialogTextSpeed
- --if (currentChar ~= " " and dialogNumCharsCurrent % 2 == 0) then
- --playSFX (35) -- 10 = skid, 14 = coin, 23 = shckwup, 24 = boing, 26 = skittish ticking, 29 = menu option, 33 = whoosh, 35 = blip
- --end
- end
- -- While the dialogue timer counts down, display the dialogue.
- printText(dialogName..":", 4, 5, 475)
- printText(string.sub(dialogText, 0, 43), 4, 15, 495)
- printText(string.sub(dialogText, 44, 87), 4, 15, 515)
- printText(string.sub(dialogText, 88, 131), 4, 15, 535)
- printText(string.sub(dialogText, 132, 175), 4, 15, 555)
- if(dialogEndWithInput == true)then
- printText("(PRESS X TO CONTINUE)", 4, 400, 580)
- end
- end
- -- When the speaker timer reaches zero, reset the speaker.
- dialogSpeakerTime = dialogSpeakerTime - 1
- if(dialogSpeakerTime == 0)then
- dialogSpeaker = 0
- end
- end
- function endDialogLine()
- dialogOn = false
- dialogTextTime = 0
- dialogNumCharsCurrent = 0
- dialogSpeakerTime = 0
- dialogSpeaker = 0
- end
- function controlNPCAnimation (npcid, animDataTable)
- local state = npcAnimStates[npcid]
- local boundsString = animDataTable[state]
- local dashCharPos = string.find(boundsString, "-")
- local minVal = tonumber(string.sub(boundsString, 0, dashCharPos-1))
- local maxVal = tonumber(string.sub(boundsString, dashCharPos+1))
- clampNPCAnim (npcid, minVal, maxVal, animDataTable[ANIMSTATE_NUMFRAMES])
- end
- function getNPCAnimFrame (myNPC)
- return myNPC:mem (0xE4, FIELD_WORD)
- end
- function setNPCAnimFrame(myNPC, frame)
- myNPC:mem(0xE4, FIELD_WORD, frame)
- end
- function clampNPCAnim(npcid, minVal, maxVal, dirOffsetFrames)
- local myNPC = findnpcs(npcid, -1)[0]
- -- Add an offset for flipped animations
- local dirOffset = dirOffsetFrames
- if(myNPC.direction == DIR_LEFT)then
- dirOffset = 0
- end
- -- Get the current animation frame
- animFrame = getNPCAnimFrame(myNPC)
- --printText(tostring(npcid).." ("..tostring(math.floor (myNPC.x+200000))..", "..tostring(math.floor (myNPC.y+200000))..")", 3, 10, 40+20*(npcid-100))
- --printText(tostring(npcid).." FRAMES > "..tostring(minVal)..", "..tostring(animFrame)..", "..tostring(maxVal), 3, 10, 10+80*(npcid-100))
- --printText("ANIMSTATE: "..tostring(npcAnimStates[npcid])..", X = "..tostring(myNPC.x), 3, 10, 30+80*(npcid-100))
- --printText("WALL "..tostring(getNPCWallDistance(npcid)), 3, 10, 50+80*(npcid-100))
- --printText("PLAYER "..tostring(getNPCRelativePosX(npcid)), 3, 10, 70+80*(npcid-100))
- if (animFrame < (minVal+dirOffset) or animFrame > (maxVal+dirOffset))then
- setNPCAnimFrame(myNPC, minVal+dirOffset)
- end
- end
- function printCenteredText (text, font, xPos, yPos)
- printText (text, font, xPos-9*string.len(text), yPos)
- end
- function getPlayerID()
- return player:mem(0xF0, FIELD_WORD)
- end
- function getNPCRelativePosX (myNPC)
- return (myNPC.x - player.x)
- end
- function getNPCRelativeDirX (myNPC)
- if (getNPCRelativePosX (myNPC) < 0) then
- return DIR_RIGHT
- else
- return DIR_LEFT
- end
- end
- function getNPCWallClosest (myNPC)
- local wallX = -200000
- if getNPCRelativeDirX(myNPC) == DIR_LEFT then
- wallX = 800 - 200000
- end
- return wallX
- end
- function getNPCWallFacing (myNPC)
- local wallX = -200000
- if myNPC.direction == DIR_RIGHT then
- wallX = 800 - 200000
- end
- return wallX
- end
- function getNPCWallDistance (myNPC, wallX)
- return math.abs(myNPC.x - wallX)
- end
- -- Clamps a number to within a certain range, with optional rounding
- function math.clamp (low, n, high)
- return math.min(math.max(n, low), high)
- end
- function getNPCAnimFrame (tarNPC)
- return tarNPC:mem(0xE4, FIELD_WORD)
- end
- function setNPCAnimFrame (tarNPC, val)
- tarNPC:mem(0xE4, FIELD_WORD, val)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement