ASA moon02: Disable hog input after victory
Player could briefly move Crazy Runner when skipping final cutscene.
------------------- ABOUT ----------------------
--
-- The hero has to catch the other hog in order
-- to get informations about the origin of Pr. Hogevil
HedgewarsScriptLoad("/Scripts/Locale.lua")
HedgewarsScriptLoad("/Scripts/Animate.lua")
HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua")
----------------- VARIABLES --------------------
-- globals
local missionName = loc("Chasing the blue hog")
local challengeObjectives = loc("Use the rope in order to catch the blue hedgehog").."|"..
loc("You have to stand very close to him")
local currentPosition = 1
local raceSectionStarted = false
local runnerCaught = false
local previousTimeLeft = 0
local startChallenge = false
local winningTime = nil
local currentTime = 0
local runnerTime = 0
local record
local lostGame = false
local heroHurt = false
-- dialogs
local dialog01 = {}
local dialog02 = {}
-- mission objectives
local goals = {
[dialog01] = {missionName, loc("Challenge objectives"), challengeObjectives, 1, 0},
}
-- hogs
local hero = {
name = loc("Hog Solo"),
x = 1300,
y = 948
}
local runner = {
name = loc("Crazy Runner"),
places = {
{x = 1400,y = 904, turnTime = 0},
{x = 3880,y = 33, turnTime = 30000},
{x = 250,y = 1780, turnTime = 25000},
{x = 3850,y = 1940, turnTime = 20000},
}
}
local runnerTimeTotal = 0
for i=1, #runner.places do
runnerTimeTotal = runnerTimeTotal + runner.places[i].turnTime
end
-- teams
local teamA = {
name = loc("Hog Solo"),
color = -6
}
local teamB = {
name = loc("Crazy Runner"),
color = -2
}
-------------- LuaAPI EVENT HANDLERS ------------------
function onGameInit()
GameFlags = gfDisableWind
Seed = 1
TurnTime = 25000
CaseFreq = 0
MinesNum = 0
Explosives = 0
Map = "moon02_map"
Theme = "Cheese"
-- Disable Sudden Death
WaterRise = 0
HealthDecrease = 0
-- Hero
teamA.name = AddMissionTeam(teamA.color)
hero.gear = AddMissionHog(1)
hero.name = GetHogName(hero.gear)
AnimSetGearPosition(hero.gear, hero.x, hero.y)
-- Crazy Runner
teamB.name = AddTeam(teamB.name, teamB.color, "ring", "Island", "Default_qau", "cm_sonic")
runner.gear = AddHog(runner.name, 0, 100, "sth_Sonic")
AnimSetGearPosition(runner.gear, runner.places[1].x, runner.places[1].y)
HogTurnLeft(runner.gear, true)
record = tonumber(GetCampaignVar("FastestBlueHogCatch"))
initCheckpoint("moon02")
AnimInit(true)
AnimationSetup()
end
function onGameStart()
AnimWait(hero.gear, 3000)
FollowGear(hero.gear)
AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0)
AddEvent(onRunnerDeath, {runner.gear}, runnerDeath, {runner.gear}, 0)
if record ~= nil then
goals[dialog01][3] = goals[dialog01][3] .. "|" .. string.format(loc("Personal best: %.3f seconds"), record/1000)
end
AddAmmo(hero.gear, amRope, 1)
SendHealthStatsOff()
hogTurn = runner.gear
AddAnim(dialog01)
end
-- Hide mission panel when jumping or shooting rope
function onGearAdd(gear)
if GetGearType(gear) == gtRope then
HideMission()
end
end
function onLJump()
if startChallenge then
HideMission()
end
end
onHJump = onLJump
function onNewTurn()
if startChallenge and currentPosition < 5 then
if CurrentHedgehog ~= hero.gear then
EndTurn(true)
runnerTime = runnerTime + runner.places[currentPosition].turnTime
SetTeamLabel(teamB.name, string.format(loc("%.1fs"), runnerTime/1000))
else
SetWeapon(amRope)
SetTurnTimeLeft(runner.places[currentPosition].turnTime + previousTimeLeft)
previousTimeLeft = 0
if currentPosition > 1 then
raceSectionStarted = true
end
runnerCaught = false
end
end
end
function onEndTurn()
if raceSectionStarted and currentPosition > 1 and currentPosition < 5 then
if CurrentHedgehog == hero.gear and (not runnerCaught) and (not heroHurt) then
-- sndBoring played manually because lose calls EndGame, which suppresses
-- the taunt.
PlaySound(sndBoring, hero.gear)
lose()
end
end
raceSectionStarted = false
end
function onGameTick()
AnimUnWait()
if ShowAnimation() == false then
return
end
ExecuteAfterAnimations()
CheckEvents()
if GetHealth(hero.gear) and CurrentHedgehog == hero.gear and startChallenge and currentPosition < 5 and currentPosition > 1 and ReadyTimeLeft == 0 and band(GetState(CurrentHedgehog), gstHHDriven) ~= 0 then
currentTime = currentTime + 1
end
end
function onGameTick20()
if startChallenge and currentPosition < 5 and currentPosition > 1 and CurrentHedgehog == hero.gear and ReadyTimeLeft == 0 and band(GetState(CurrentHedgehog), gstHHDriven) ~= 0 then
SetTeamLabel(teamA.name, string.format(loc("%.1fs"), currentTime/1000))
end
if GetHealth(hero.gear) and startChallenge and isHeroNextToRunner() and currentPosition < 5 then
moveRunner()
end
end
function onPrecise()
if GameTime > 3000 then
SetAnimSkip(true)
end
end
function onGearDamage(gear)
if gear == hero.gear then
heroHurt = true
end
end
-------------- EVENTS ------------------
function onHeroDeath(gear)
if not GetHealth(hero.gear) then
return true
end
return false
end
function onRunnerDeath(gear)
if not GetHealth(runner.gear) then
return true
end
return false
end
-------------- ACTIONS ------------------
function heroDeath(gear)
lose()
end
function runnerDeath(gear)
loseRunnerDeath()
end
-------------- ANIMATIONS ------------------
function Skipanim(anim)
if goals[anim] ~= nil then
ShowMission(unpack(goals[anim]))
end
if anim == dialog01 then
moveRunner()
elseif anim == dialog02 then
win()
end
end
function AnimationSetup()
-- DIALOG 01 - Start, game instructions
AddSkipFunction(dialog01, Skipanim, {dialog01})
table.insert(dialog01, {func = AnimWait, args = {hero.gear, 3200}})
table.insert(dialog01, {func = AnimCaption, args = {hero.gear, loc("On the other side of the moon ..."), 5000}})
table.insert(dialog01, {func = AnimSay, args = {runner.gear, loc("So you are interested in Professor Hogevil, huh?"), SAY_SAY, 3000}})
table.insert(dialog01, {func = AnimSay, args = {runner.gear, loc("We'll play a game first."), SAY_SAY, 3000}})
table.insert(dialog01, {func = AnimSay, args = {runner.gear, loc("I'll let you know whatever I know about him if you manage to catch me 3 times."), SAY_SAY, 4000}})
table.insert(dialog01, {func = AnimSay, args = {runner.gear, loc("Let's go!"), SAY_SAY, 2000}})
table.insert(dialog01, {func = ShowMission, args = goals[dialog01]})
table.insert(dialog01, {func = moveRunner, args = {}})
-- DIALOG 02 - Professor Hogevil story
AddSkipFunction(dialog02, Skipanim, {dialog02})
table.insert(dialog02, {func = AnimWait, args = {hero.gear, 3200}})
table.insert(dialog02, {func = AnimCaption, args = {hero.gear, loc("The truth about Professor Hogevil"), 5000}})
table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("Amazing! I was never beaten in a race before!"), SAY_SAY, 4000}})
table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("So, let me tell you what I know about Professor Hogevil."), SAY_SAY, 4000}})
table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("Professor Hogevil, then known as James Hogus, worked for PAotH back in my time."), SAY_SAY, 4000}})
table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("He was the lab assistant of Dr. Goodhogan, the inventor of the anti-gravity device."), SAY_SAY, 5000}})
table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("During the final testing of the device an accident happened."), SAY_SAY, 5000}})
table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("In this accident, Professor Hogevil lost all his spines on his head!"), SAY_SAY, 5000}})
table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("That's why he always wears a hat since then."), SAY_SAY, 4000}})
table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("After that incident he went underground and started working on his plan to steal the device."), SAY_SAY, 5000}})
table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("He is a very tough and very determined hedgehog. I would be extremely careful if I were you."), SAY_SAY, 5000}})
table.insert(dialog02, {func = AnimSay, args = {runner.gear, loc("I should go now, goodbye!"), SAY_SAY, 3000}})
table.insert(dialog02, {func = win, args = {}})
end
------------- other functions ---------------
function isHeroNextToRunner()
if IsHogAlive(hero.gear) and IsHogAlive(runner.gear) and
math.abs(GetX(hero.gear) - GetX(runner.gear)) < 75 and
math.abs(GetY(hero.gear) - GetY(runner.gear)) < 75 and
StoppedGear(hero.gear) and StoppedGear(runner.gear) then
return true
end
return false
end
function moveRunner()
if currentPosition == 4 then
currentPosition = currentPosition + 1
if GetX(hero.gear) > GetX(runner.gear) then
HogTurnLeft(runner.gear, false)
end
AddAnim(dialog02)
-- Update time record
winningTime = runnerTimeTotal - TurnTimeLeft
SetTeamLabel(teamA.name, string.format(loc("%.3fs"), winningTime/1000))
SendStat(siCustomAchievement, string.format(loc("You have managed to catch the blue hedgehog in %.3f seconds."), winningTime/1000))
if record ~= nil and winningTime >= record then
SendStat(siCustomAchievement, string.format(loc("Your personal best time so far: %.3f seconds"), record/1000))
end
if record == nil or winningTime < record then
SaveCampaignVar("FastestBlueHogCatch", tostring(winningTime))
if record ~= nil then
SendStat(siCustomAchievement, loc("This is a new personal best time, congratulations!"))
end
end
EndTurn(true)
elseif currentPosition < 4 then
if not startChallenge then
startChallenge = true
end
AddAmmo(hero.gear, amRope, 1)
if currentPosition ~= 1 then
if currentPosition > 1 and currentPosition < 4 then
AnimCaption(hero.gear, loc("Go, get him again!"), 3000)
AnimSay(runner.gear, loc("You got me!"), SAY_SAY, 3000)
end
runnerCaught = true
previousTimeLeft = TurnTimeLeft
end
currentPosition = currentPosition + 1
AddVisualGear(GetX(runner.gear), GetY(runner.gear), vgtExplosion, 0, false)
SetGearPosition(runner.gear, runner.places[currentPosition].x, runner.places[currentPosition].y)
EndTurn(true)
end
end
function lose()
if lostGame then
return
end
lostGame = true
SendStat(siGameResult, loc("Too slow! Try again ..."))
SendStat(siCustomAchievement, loc("You have to catch the other hog 3 times."))
SendStat(siCustomAchievement, loc("The time that you have left when you reach the blue hedgehog will be added to the next turn."))
SendStat(siCustomAchievement, loc("Each turn you'll have only one rope to use."))
SendStat(siCustomAchievement, loc("You'll lose if you die or if your time is up."))
SendStat(siPointType, "!TIME")
SendStat(siPlayerKills, tostring(runnerTimeTotal), teamB.name)
SendStat(siPointType, "!EMPTY")
SendStat(siPlayerKills, "0", teamA.name)
EndGame()
end
function loseRunnerDeath()
if lostGame then
return
end
lostGame = true
SendStat(siGameResult, loc("Race failed!"))
SendStat(siCustomAchievement, loc("The other hog has died, he should have survived!"))
SendStat(siCustomAchievement, loc("You have to catch the other hog 3 times."))
SendStat(siTeamRank, "1")
SendStat(siPlayerKills, tostring(GetTeamStats(teamB.name).Kills), teamB.name)
SendStat(siTeamRank, "1")
SendStat(siPlayerKills, tostring(GetTeamStats(teamA.name).Kills), teamA.name)
EndGame()
end
function win()
AnimSetInputMask(0)
SendStat(siGameResult, loc("Congratulations, you are the fastest!"))
-- siCustomAchievements were added earlier
SendStat(siPointType, "!TIME")
SendStat(siPlayerKills, tostring(winningTime), teamA.name)
SendStat(siPointType, "!TIME")
SendStat(siPlayerKills, tostring(runnerTimeTotal), teamB.name)
SaveCampaignVar("Mission13Won", "true")
checkAllMissionsCompleted()
EndGame()
end