--[[ A Classic Fairytale: The Shadow Falls = SUMMARY = Dense Cloud and Leaks a Lot fight against waves of cannibals. Then a cyborg shows up and offers one of the natives goodies in exchange for betraying his tribe. The decision affects the rest of the story. The survival of Dense Cloud is important for the gameplay of the next mission. = GOALS = Kill Weaklings and Stronglings. = FLOW CHART = == Linear events == - Initial hog spawns: Dense Cloud, Leaks a Lot and Brainiac (Weaklings) - Cut scene: startDialogue - TBS - Brainiac dead - Cut scene: weaklingsAnim - The remaining Weaklings spawn - TBS - All Weaklings dead - Cut scene: stronglingsAnim: Stronglings spawn, hero walks to forest, meets cyborg, cyborg makes offer - The cyborg offer is an IMPORTANT decision, it completely changes the next mission, and the rest of the story | Accept: Player walks to cyborg - Cut scene: acceptAnim - Hero needs to walk all the way back (infinite turn time) - Hero reached tree - Turn time starts - TBS - Stronglings defeated | Stronglings defeated with both hogs survived - Cut scene: acceptedSurvivedFinalAnim | Stronglings deafeated with Dense Cloud dead - Cut scene: acceptedDiedFinalAnim > Victory | Reject: Player walks away - Cut scene: refusedAnim - Leaks a Lot teleports back to tree at the start (automatically) - Spiky Cheese and Ramon appear together with crates - Spiky Cheese gains control - TBS - Stronglings defeated - Cut scene: refusedFinalAnim > Victory | Attack: Player attacks cyborg - Cut scene: attackAnim - Cyborg kills hero - Other native's turn to defeat Stronglings - TBS - Stronglings defeated - Cut scene: attackedFinalAnim > Victory == Non-linear events == | Dense Cloud or Leaks A Lot dead (exceptions: killed by cyborg; or Leaks A Lot died in the battle against the Stronglings): > Game over ]] HedgewarsScriptLoad("/Scripts/Locale.lua") HedgewarsScriptLoad("/Scripts/Animate.lua") -----------------------------Constants--------------------------------- startStage = 0 spyStage = 1 wave1Stage = 2 wave2Stage = 3 cyborgStage = 4 ramonStage = 5 aloneStage = 6 duoStage = 7 interSpyStage = 8 interWeakStage = 9 acceptedReturnStage = 10 refusedReturnStage = 11 attackedReturnStage = 12 loseStage = 13 ourTeam = 0 weakTeam = 1 strongTeam = 2 cyborgTeam = 3 leaksNr = 0 denseNr = 1 choiceAccept = 1 choiceRefuse = 2 choiceAttack = 3 HogNames = {loc("Brainiac"), loc("Corpsemonger"), loc("Femur Lover"), loc("Glark"), loc("Bonely"), loc("Rot Molester"), loc("Bloodrocutor"), loc("Muscle Dissolver"), loc("Bloodsucker")} nativesTeamName = nil weaklingsTeamName = nil ---POSITIONS--- cannibalPos = {{3108, 1127}, {2559, 1080}, {3598, 1270}, {3293, 1177}, {2623, 1336}, {3418, 1336}, {3447, 1335}, {3481, 1340}, {3507, 1324}} densePos = {2776, 1177} leaksPos = {2941, 1172} cyborgPos = {1113, 1818} ---Animations startDialogue = {} weaklingsAnim = {} stronglingsAnim = {} acceptedAnim = {} acceptedSurvivedFinalAnim = {} acceptedDiedFinalAnim = {} refusedAnim = {} refusedFinalAnim = {} attackedAnim = {} attackedFinalAnim = {} -----------------------------Variables--------------------------------- lastHogTeam = ourTeam lastOurHog = leaksNr lastEnemyHog = 0 stage = 0 choice = 0 brainiacDead = false cyborgHidden = false leaksHidden = false denseHidden = false cyborgAttacked = false shotgunTaken = false grenadeTaken = false spikyDead = false ramonDead = false denseDead = false leaksDead = false ramonHidden = false spikyHidden = false grenadeUsed = false shotgunUsed = false hogNr = {} cannibalDead = {} isHidden = {} local grenadeHint = loc("Grenade hint: Set timer with the [Timer] controls, aim with [Up]/[Down].") .. "|" .. loc("Hold [Attack] pressed to throw with more power.") if INTERFACE == "touch" then grenadeHint = grenadeHint .. "|" .. loc("Change detonation timer: Tap the [Clock]") .. "|" .. loc("Attack: Tap the [Bomb]") else grenadeHint = grenadeHint .. "|" .. loc("Set detonation timer: [1]-[5]") .. "|" .. loc("Attack: [Space]") end --------------------------Anim skip functions-------------------------- function AfterRefusedAnim() if stage == loseStage then return end SpawnSupplyCrate(2045, 1575, amSwitch) SpawnSupplyCrate(2365, 1495, amShotgun) SpawnSupplyCrate(2495, 1519, amGrenade) SpawnSupplyCrate(2620, 1524, amRope) ShowMission(loc("The Shadow Falls"), loc("The Showdown"), loc("Save Leaks A Lot!|Hint: The switch hedgehog utility might be of help to you."), 1, 6000) RemoveEventFunc(CheckDenseDead) AddEvent(CheckStronglingsDead, {}, DoStronglingsDeadRefused, {}, 0) AddAmmo(cannibals[6], amGrenade, 1) AddAmmo(cannibals[7], amGrenade, 1) AddAmmo(cannibals[8], amGrenade, 1) AddAmmo(cannibals[9], amGrenade, 1) AddAmmo(dense, amSkip, 100) AddAmmo(leaks, amSkip, 100) stage = ramonStage SwitchHog(cannibals[9]) FollowGear(ramon) EndTurn(true) SetGearMessage(ramon, 0) SetGearMessage(leaks, 0) AnimWait(ramon, 1) AddFunction({func = HideHog, args = {cyborg}}) end function SkipRefusedAnim() if stage == loseStage then return end RefusedStart() AnimSetGearPosition(dense, 2645, 1146) AnimSetGearPosition(ramon, 2218, 1675) AnimSetGearPosition(spiky, 2400, 1675) end function AfterStartDialogue() if stage == loseStage then return end stage = spyStage ShowMission(loc("The Shadow Falls"), loc("Play with me!"), loc("Kill the cannibal!").."|"..loc("Both your hedgehogs must survive."), 1, 6000) SetTurnTimeLeft(TurnTime) end function StartSkipFunc() if stage == loseStage then return end SetState(cannibals[1], 0) AnimTurn(leaks, "Right") AnimSwitchHog(leaks) end function AfterWeaklingsAnim() if stage == loseStage then return end AddAmmo(cannibals[2], amShotgun, 1) AddAmmo(cannibals[2], amGrenade, 1) AddAmmo(cannibals[3], amShotgun, 1) AddAmmo(cannibals[3], amGrenade, 1) AddAmmo(cannibals[4], amShotgun, 1) AddAmmo(cannibals[4], amGrenade, 1) AddAmmo(cannibals[5], amShotgun, 1) AddAmmo(cannibals[5], amGrenade, 1) AddAmmo(leaks, amSkip, 100) AddAmmo(dense, amSkip, 100) AddEvent(CheckWeaklingsKilled, {}, DoWeaklingsKilled, {}, 0) SetHealth(SpawnHealthCrate(2757, 1030), 50) SetHealth(SpawnHealthCrate(2899, 1009), 50) stage = wave1Stage SwitchHog(dense) SetGearMessage(dense, 0) SetGearMessage(leaks, 0) SetTurnTimeLeft(TurnTime) ShowMission(loc("The Shadow Falls"), loc("Why do you not like me?"), loc("Obliterate them!|Hint: You might want to take cover...").."|"..loc("Both your hedgehogs must survive."), 1, 6000) end function SkipWeaklingsAnim() if stage == loseStage then return end for i = 2, 5 do if isHidden[cannibals[i]] == true then RestoreHog(cannibals[i]) isHidden[cannibals[i]] = false end AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i])) SetState(cannibals[i], 0) end end function AfterStronglingsAnim() if stage == loseStage then return end stage = cyborgStage ShowMission(loc("The Shadow Falls"), loc("The Dilemma"), loc("Choose your side! If you want to join the strange man, walk up to him.|Otherwise, walk away from him. If you decide to att...nevermind..."), 1, 8000) AddEvent(CheckChoice, {}, DoChoice, {}, 0) AddEvent(CheckRefuse, {}, DoRefuse, {}, 0) AddEvent(CheckAccept, {}, DoAccept, {}, 0) AddEvent(CheckConfront, {}, DoConfront, {}, 0) AddAmmo(dense, amSwitch, 0) AddAmmo(dense, amSkip, 0) AddAmmo(leaks, amSwitch, 0) AddAmmo(leaks, amSkip, 0) SetHealth(SpawnHealthCrate(2557, 1030), 50) SetHealth(SpawnHealthCrate(3599, 1009), 50) EndTurn(true) end function SkipStronglingsAnim() if stage == loseStage then return end for i = 6, 9 do if isHidden[cannibals[i]] == true then RestoreHog(cannibals[i]) isHidden[cannibals[i]] = false end AnimSetGearPosition(cannibals[i], unpack(cannibalPos[i])) SetState(cannibals[i], 0) end if cyborgHidden == true then RestoreHog(cyborg) cyborgHidden = false end SetState(cyborg, 0) SetState(dense, 0) AnimSetGearPosition(dense, 1350, 1315) FollowGear(dense) HogTurnLeft(dense, true) AnimSetGearPosition(cyborg, 1250, 1315) SwitchHog(dense) end function AfterAcceptedAnim() if stage == loseStage then return end stage = acceptedReturnStage SpawnSupplyCrate(1370, 810, amGirder) SpawnSupplyCrate(1300, 810, amParachute) ShowMission(loc("The Shadow Falls"), loc("The walk of Fame"), loc("Return to Leaks A Lot!"), 1, 6000) AddEvent(CheckReadyForStronglings, {}, DoReadyForStronglings, {}, 0) AddEvent(CheckNeedGirder, {}, DoNeedGirder, {}, 0) AddEvent(CheckNeedWeapons, {}, DoNeedWeapons, {}, 0) RemoveEventFunc(CheckDenseDead) SwitchHog(dense) AnimWait(dense, 1) AddFunction({func = HideHog, args = {cyborg}}) end function SkipAcceptedAnim() if stage == loseStage then return end AnimSetGearPosition(cyborg, unpack(cyborgPos)) SetState(cyborg, gstInvisible) AnimSwitchHog(dense) end function AfterAttackedAnim() if stage == loseStage then return end stage = aloneStage ShowMission(loc("The Shadow Falls"), loc("The Individualist"), loc("Defeat the cannibals!") .. "|" .. grenadeHint, 1, 12000) AddAmmo(cannibals[6], amGrenade, 1) AddAmmo(cannibals[6], amFirePunch, 0) AddAmmo(cannibals[6], amBaseballBat, 0) AddAmmo(cannibals[7], amGrenade, 1) AddAmmo(cannibals[7], amFirePunch, 0) AddAmmo(cannibals[7], amBaseballBat, 0) AddAmmo(cannibals[8], amGrenade, 1) AddAmmo(cannibals[8], amFirePunch, 0) AddAmmo(cannibals[8], amBaseballBat, 0) AddAmmo(cannibals[9], amGrenade, 1) AddAmmo(cannibals[9], amFirePunch, 0) AddAmmo(cannibals[9], amBaseballBat, 0) SetGearMessage(leaks, 0) SetTurnTimeLeft(TurnTime) AddEvent(CheckStronglingsDead, {}, DoStronglingsDeadAttacked, {}, 0) SwitchHog(leaks) AnimWait(dense, 1) AddFunction({func = HideHog, args = {cyborg}}) end function SkipAttackedAnim() if stage == loseStage then return end if denseDead == false then DeleteGear(dense) end SpawnSupplyCrate(2551, 994, amGrenade) SpawnSupplyCrate(3551, 994, amGrenade) SpawnSupplyCrate(3392, 1101, amShotgun) SpawnSupplyCrate(3192, 1101, amShotgun) AnimSetGearPosition(cyborg, unpack(cyborgPos)) SetState(cyborg, gstInvisible) AnimSwitchHog(leaks) end -----------------------------Animations-------------------------------- function SpawnCrates() SpawnSupplyCrate(2551, 994, amGrenade) SpawnSupplyCrate(3551, 994, amGrenade) SpawnSupplyCrate(3392, 1101, amShotgun) SpawnSupplyCrate(3192, 1101, amShotgun) return true end function EmitDenseClouds(anim, dir) if stage == loseStage then return end local dif if dir == "Left" then dif = 10 else dif = -10 end AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false}) AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false}) AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false}) AnimInsertStepNext({func = AnimWait, args = {dense, 800}}) AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false}) AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false}) AnimInsertStepNext({func = AnimWait, args = {dense, 800}}) AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + dif, GetY(dense) + dif, vgtSteam, 0, true}, swh = false}) end function BlowDenseCloud() if stage == loseStage then return end AnimInsertStepNext({func = DeleteGear, args = {dense}, swh = false}) AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense), GetY(dense), vgtBigExplosion, 0, true}, swh = false}) AnimInsertStepNext({func = AnimWait, args = {dense, 1200}}) AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + 20, GetY(dense), vgtExplosion, 0, true}, swh = false}) AnimInsertStepNext({func = AnimWait, args = {dense, 100}}) AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) + 10, GetY(dense), vgtExplosion, 0, true}, swh = false}) AnimInsertStepNext({func = AnimWait, args = {dense, 100}}) AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) - 10, GetY(dense), vgtExplosion, 0, true}, swh = false}) AnimInsertStepNext({func = AnimWait, args = {dense, 100}}) AnimInsertStepNext({func = AnimVisualGear, args = {dense, GetX(dense) - 20, GetY(dense), vgtExplosion, 0, true}, swh = false}) end function SetupAcceptedSurvivedFinalAnim() table.insert(acceptedSurvivedFinalAnim, {func = AnimCustomFunction, args = {dense, CondNeedToTurn, {leaks, dense}}}) table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {leaks, loc("Pfew! That was close!"), SAY_SAY, 3000}}) if grenadeUsed and shotgunUsed then table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {leaks, loc("Where did you get the exploding apples and the magic bow that shoots many arrows?"), SAY_SAY, 9000}}) elseif grenadeUsed then table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {leaks, loc("Where did you get the exploding apples?"), SAY_SAY, 6000}}) elseif shotgunUsed then table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {leaks, loc("Where did you get the magic bow that shoots many arrows?"), SAY_SAY, 8000}}) else table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {leaks, loc("Did you warn the village?"), SAY_SAY, 4000}}) table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {dense, loc("No, I came back to help you out..."), SAY_SAY, 5000}}) end if grenadeUsed or shotgunUsed then table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {dense, loc("Uhm...I met one of them and took his weapons."), SAY_SAY, 5000}}) end table.insert(acceptedSurvivedFinalAnim, {func = AnimSay, args = {dense, loc("We should head back to the village now."), SAY_SAY, 5000}}) end function AnimationSetup() table.insert(startDialogue, {func = AnimWait, args = {dense, 4000}}) table.insert(startDialogue, {func = AnimCaption, args = {leaks, loc("After the shock caused by the enemy spy, Leaks A Lot and Dense Cloud went hunting to relax."), 6000}}) table.insert(startDialogue, {func = AnimCaption, args = {leaks, loc("Little did they know that this hunt will mark them forever..."), 4000}}) table.insert(startDialogue, {func = AnimSay, args = {leaks, loc("I have no idea where that mole disappeared...Can you see it?"), SAY_SAY, 9000}}) table.insert(startDialogue, {func = AnimSay, args = {dense, loc("Nope. It was one fast mole, that's for sure."), SAY_SAY, 5000}}) table.insert(startDialogue, {func = AnimCustomFunction, args = {dense, EmitDenseClouds, {startDialogue, "Right"}}}) table.insert(startDialogue, {func = AnimWait, args = {dense, 2000}}) table.insert(startDialogue, {func = AnimSay, args = {leaks, loc("Please, stop releasing your \"smoke signals\"!"), SAY_SAY, 5000}}) table.insert(startDialogue, {func = AnimSay, args = {leaks, loc("You're terrorizing the forest...We won't catch anything like this!"), SAY_SAY, 6000}}) table.insert(startDialogue, {func = AnimSay, args = {leaks, loc("..."), SAY_THINK, 1000}}) table.insert(startDialogue, {func = AnimGiveState, args = {cannibals[1], 0}, swh = false}) table.insert(startDialogue, {func = AnimOutOfNowhere, args = {cannibals[1], unpack(cannibalPos[1])}, swh = false}) table.insert(startDialogue, {func = AnimTurn, args = {leaks, "Right"}}) table.insert(startDialogue, {func = AnimTurn, args = {cannibals[1], "Right"}}) table.insert(startDialogue, {func = AnimWait, args = {cannibals[1], 1000}}) table.insert(startDialogue, {func = AnimTurn, args = {cannibals[1], "Left"}}) table.insert(startDialogue, {func = AnimWait, args = {cannibals[1], 1000}}) table.insert(startDialogue, {func = AnimTurn, args = {cannibals[1], "Right"}}) table.insert(startDialogue, {func = AnimSay, args = {cannibals[1], loc("I can't believe it worked!"), SAY_THINK, 3500}}) table.insert(startDialogue, {func = AnimSay, args = {cannibals[1], loc("That shaman sure knows what he's doing!"), SAY_THINK, 6000}}) table.insert(startDialogue, {func = AnimSay, args = {cannibals[1], loc("Yeah...I think it's a 'he', lol."), SAY_THINK, 5000}}) table.insert(startDialogue, {func = AnimSay, args = {leaks, loc("It wants our brains!"), SAY_SHOUT, 3000}}) table.insert(startDialogue, {func = AnimTurn, args = {cannibals[1], "Left"}}) table.insert(startDialogue, {func = AnimSay, args = {cannibals[1], loc("Not you again! My head still hurts from last time!"), SAY_SHOUT, 6000}}) table.insert(startDialogue, {func = AnimSwitchHog, args = {leaks}}) AddSkipFunction(startDialogue, StartSkipFunc, {}) table.insert(weaklingsAnim, {func = AnimGearWait, args = {leaks, 1000}}) table.insert(weaklingsAnim, {func = AnimCustomFunction, args = {leaks, CondNeedToTurn, {leaks, dense}}}) table.insert(weaklingsAnim, {func = AnimSay, args = {leaks, loc("Did you see him coming?"), SAY_SAY, 3500}}) table.insert(weaklingsAnim, {func = AnimSay, args = {dense, loc("No. Where did he come from?"), SAY_SAY, 3500}}) table.insert(weaklingsAnim, {func = AnimCustomFunction, args = {leaks, UnHideWeaklings, {}}}) table.insert(weaklingsAnim, {func = AnimOutOfNowhere, args = {cannibals[2], unpack(cannibalPos[2])}}) table.insert(weaklingsAnim, {func = AnimGiveState, args = {cannibals[2], 0}}) table.insert(weaklingsAnim, {func = AnimWait, args = {leaks, 400}}) table.insert(weaklingsAnim, {func = AnimGiveState, args = {cannibals[3], 0}}) table.insert(weaklingsAnim, {func = AnimOutOfNowhere, args = {cannibals[3], unpack(cannibalPos[3])}}) table.insert(weaklingsAnim, {func = AnimWait, args = {leaks, 400}}) table.insert(weaklingsAnim, {func = AnimGiveState, args = {cannibals[4], 0}}) table.insert(weaklingsAnim, {func = AnimOutOfNowhere, args = {cannibals[4], unpack(cannibalPos[4])}}) table.insert(weaklingsAnim, {func = AnimWait, args = {leaks, 400}}) table.insert(weaklingsAnim, {func = AnimGiveState, args = {cannibals[5], 0}}) table.insert(weaklingsAnim, {func = AnimOutOfNowhere, args = {cannibals[5], unpack(cannibalPos[5])}}) table.insert(weaklingsAnim, {func = AnimWait, args = {leaks, 400}}) table.insert(weaklingsAnim, {func = AnimSay, args = {cannibals[3], loc("Are we there yet?"), SAY_SAY, 4000}}) table.insert(weaklingsAnim, {func = AnimSay, args = {dense, loc("This must be some kind of sorcery!"), SAY_SHOUT, 3500}}) table.insert(weaklingsAnim, {func = AnimSwitchHog, args = {leaks}}) AddSkipFunction(weaklingsAnim, SkipWeaklingsAnim, {}) table.insert(stronglingsAnim, {func = AnimGearWait, args = {leaks, 1000}}) table.insert(stronglingsAnim, {func = AnimCustomFunction, args = {leaks, UnHideStronglings, {}}}) table.insert(stronglingsAnim, {func = AnimCustomFunction, args = {leaks, CondNeedToTurn, {leaks, dense}}}) table.insert(stronglingsAnim, {func = AnimGiveState, args = {leaks, 0}}) table.insert(stronglingsAnim, {func = AnimGiveState, args = {dense, 0}}) table.insert(stronglingsAnim, {func = AnimSay, args = {leaks, loc("I thought their shaman died when he tried our medicine!"), SAY_SAY, 7000}}) table.insert(stronglingsAnim, {func = AnimSay, args = {dense, loc("I saw it with my own eyes!"), SAY_SAY, 4000}}) table.insert(stronglingsAnim, {func = AnimSay, args = {leaks, loc("Then how do they keep appearing?"), SAY_SAY, 4000}}) table.insert(stronglingsAnim, {func = AnimSay, args = {leaks, loc("It's impossible to communicate with the spirits without a shaman."), SAY_SAY, 7000}}) table.insert(stronglingsAnim, {func = AnimSay, args = {dense, loc("We need to warn the village."), SAY_SAY, 3500}}) table.insert(stronglingsAnim, {func = AnimGiveState, args = {cannibals[6], 0}}) table.insert(stronglingsAnim, {func = AnimOutOfNowhere, args = {cannibals[6], unpack(cannibalPos[6])}}) table.insert(stronglingsAnim, {func = AnimWait, args = {leaks, 400}}) table.insert(stronglingsAnim, {func = AnimGiveState, args = {cannibals[7], 0}}) table.insert(stronglingsAnim, {func = AnimOutOfNowhere, args = {cannibals[7], unpack(cannibalPos[7])}}) table.insert(stronglingsAnim, {func = AnimWait, args = {leaks, 400}}) table.insert(stronglingsAnim, {func = AnimGiveState, args = {cannibals[8], 0}}) table.insert(stronglingsAnim, {func = AnimOutOfNowhere, args = {cannibals[8], unpack(cannibalPos[8])}}) table.insert(stronglingsAnim, {func = AnimWait, args = {leaks, 400}}) table.insert(stronglingsAnim, {func = AnimGiveState, args = {cannibals[9], 0}}) table.insert(stronglingsAnim, {func = AnimOutOfNowhere, args = {cannibals[9], unpack(cannibalPos[9])}}) table.insert(stronglingsAnim, {func = AnimWait, args = {leaks, 400}}) table.insert(stronglingsAnim, {func = AnimSay, args = {cannibals[7], loc("What a ride!"), SAY_SHOUT, 2000}}) table.insert(stronglingsAnim, {func = AnimTurn, args = {leaks, "Right"}}) table.insert(stronglingsAnim, {func = AnimWait, args = {leaks, 700}}) table.insert(stronglingsAnim, {func = AnimTurn, args = {leaks, "Left"}}) table.insert(stronglingsAnim, {func = AnimSay, args = {leaks, loc("We can't defeat them!"), SAY_THINK, 3000}}) table.insert(stronglingsAnim, {func = AnimSay, args = {leaks, loc("I'll hold them off while you return to the village!"), SAY_SAY, 6000}}) table.insert(stronglingsAnim, {func = AnimFollowGear, args = {cyborg}, swh = false}) table.insert(stronglingsAnim, {func = AnimCaption, args = {cyborg, loc("30 minutes later...")}, swh = false}) table.insert(stronglingsAnim, {func = AnimWait, args = {cyborg, 2000}}) table.insert(stronglingsAnim, {func = AnimSetGearPosition, args = {dense, 1420, 1315}}) table.insert(stronglingsAnim, {func = AnimMove, args = {dense, "Left", 1400, 0}}) table.insert(stronglingsAnim, {func = AnimCustomFunction, args = {dense, EmitDenseClouds, {stronglingsAnim, "Left"}}}) table.insert(stronglingsAnim, {func = AnimMove, args = {dense, "Left", 1350, 0}}) table.insert(stronglingsAnim, {func = AnimOutOfNowhere, args = {cyborg, 1250, 1320}}) table.insert(stronglingsAnim, {func = AnimRemoveState, args = {cyborg, gstInvisible}}) table.insert(stronglingsAnim, {func = AnimGearWait, args = {cyborg, 2000}}) table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("Greetings, cloudy one!"), SAY_SAY, 3000}}) table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("I have come to make you an offering..."), SAY_SAY, 6000}}) table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("You are given the chance to turn your life around..."), SAY_SAY, 6000}}) table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("If you agree to provide the information we need, you will be spared!"), SAY_SAY, 7000}}) table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("Have no illusions, your tribe is dead, indifferent of your choice."), SAY_SAY, 7000}}) table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("If you decide to help us, though, we will no longer need to find a new governor for the island."), SAY_SAY, 8000}}) table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("If you know what I mean..."), SAY_SAY, 3000}}) table.insert(stronglingsAnim, {func = AnimSay, args = {cyborg, loc("So? What will it be?"), SAY_SAY, 3000}}) table.insert(stronglingsAnim, {func = AnimSwitchHog, args = {dense}}) AddSkipFunction(stronglingsAnim, SkipStronglingsAnim, {}) table.insert(acceptedAnim, {func = AnimSay, args = {cyborg, loc("Great choice, Steve! Mind if I call you that?"), SAY_SAY, 7000}}) table.insert(acceptedAnim, {func = AnimSay, args = {dense, loc("Whatever floats your boat..."), SAY_SAY, 4500}}) table.insert(acceptedAnim, {func = AnimSay, args = {cyborg, loc("Great! You will be contacted soon for assistance."), SAY_SAY, 6000}}) table.insert(acceptedAnim, {func = AnimSay, args = {cyborg, loc("In the meantime, take these and return to your \"friend\"!"), SAY_SAY, 6000}}) table.insert(acceptedAnim, {func = AnimGiveState, args = {cyborg, gstInvisible}}) table.insert(acceptedAnim, {func = AnimDisappear, args = {cyborg, unpack(cyborgPos)}}) table.insert(acceptedAnim, {func = AnimSwitchHog, args = {dense}}) AddSkipFunction(acceptedAnim, SkipAcceptedAnim, {}) table.insert(acceptedDiedFinalAnim, {func = AnimSay, args = {leaks, loc("Pfew! That was close!"), SAY_THINK, 3000}}) table.insert(acceptedDiedFinalAnim, {func = AnimSay, args = {leaks, loc("Your death will not be in vain, Dense Cloud!"), SAY_THINK, 5000}}) table.insert(acceptedDiedFinalAnim, {func = AnimSay, args = {dense, loc("You will be avenged!"), SAY_SAY, 3000}}) table.insert(refusedAnim, {func = AnimSay, args = {cyborg, loc("I see..."), SAY_SAY, 2000}}) table.insert(refusedAnim, {func = AnimSay, args = {cyborg, loc("Remember this, pathetic animal: When the day comes, you will regret your blind loyalty!"), SAY_SAY, 8000}}) table.insert(refusedAnim, {func = AnimSay, args = {cyborg, loc("You just committed suicide..."), SAY_SAY, 5000}}) table.insert(refusedAnim, {func = AnimDisappear, args = {cyborg, unpack(cyborgPos)}}) table.insert(refusedAnim, {func = AnimGiveState, args = {cyborg, gstInvisible}}) table.insert(refusedAnim, {func = AnimSay, args = {dense, loc("If you say so..."), SAY_THINK, 3000}}) table.insert(refusedAnim, {func = AnimFollowGear, args = {cyborg}, swh = false}) table.insert(refusedAnim, {func = AnimWait, args = {cyborg, 700}}) table.insert(refusedAnim, {func = AnimCustomFunction, args = {dense, RefusedStart, {}}}) table.insert(refusedAnim, {func = AnimOutOfNowhere, args = {dense, 2645, 1146}}) table.insert(refusedAnim, {func = AnimOutOfNowhere, args = {ramon, 2218, 1675}}) table.insert(refusedAnim, {func = AnimOutOfNowhere, args = {spiky, 2400, 1675}}) table.insert(refusedAnim, {func = AnimTurn, args = {spiky, "Left"}}) table.insert(refusedAnim, {func = AnimWait, args = {cyborg, 1700}}) table.insert(refusedAnim, {func = AnimTurn, args = {spiky, "Right"}}) table.insert(refusedAnim, {func = AnimWait, args = {cyborg, 1700}}) table.insert(refusedAnim, {func = AnimTurn, args = {spiky, "Left"}}) table.insert(refusedAnim, {func = AnimSay, args = {spiky, loc("Dude, we really need a new shaman..."), SAY_SAY, 4000}}) AddSkipFunction(refusedAnim, SkipRefusedAnim, {}) table.insert(refusedFinalAnim, {func = AnimSay, args = {leaks, loc("It's over..."), SAY_SAY, 2000}}) table.insert(refusedFinalAnim, {func = AnimSay, args = {leaks, loc("Let's head back to the village!"), SAY_SAY, 4000}}) table.insert(attackedAnim, {func = AnimCustomFunction, args = {dense, CondNeedToTurn, {cyborg, dense}}}) table.insert(attackedAnim, {func = AnimCustomFunction, args = {cyborg, SetHealth, {cyborg, 200}}}) table.insert(attackedAnim, {func = AnimWait, args = {cyborg, 2000}}) table.insert(attackedAnim, {func = AnimSay, args = {cyborg, loc("Really?! You thought you could harm me with your little toys?"), SAY_SAY, 7000}}) table.insert(attackedAnim, {func = AnimSay, args = {cyborg, loc("You're pathetic! You are not worthy of my attention..."), SAY_SAY, 6000}}) table.insert(attackedAnim, {func = AnimSay, args = {cyborg, loc("Actually, you aren't worthy of life! Take this..."), SAY_SAY, 5000}}) table.insert(attackedAnim, {func = AnimCustomFunction, args = {dense, BlowDenseCloud, {}}, swh = false}) table.insert(attackedAnim, {func = AnimWait, args = {cyborg, 2000}}) table.insert(attackedAnim, {func = AnimSay, args = {cyborg, loc("Incredible..."), SAY_SAY, 3000}}) table.insert(attackedAnim, {func = AnimDisappear, args = {cyborg, unpack(cyborgPos)}}) table.insert(attackedAnim, {func = AnimGiveState, args = {cyborg, gstInvisible}}) table.insert(attackedAnim, {func = AnimSwitchHog, args = {leaks}}) table.insert(attackedAnim, {func = AnimSay, args = {leaks, loc("I wonder where Dense Cloud is..."), SAY_THINK, 4000}}) table.insert(attackedAnim, {func = AnimSay, args = {leaks, loc("I can't wait any more, I have to save myself!"), SAY_THINK, 5000}}) table.insert(attackedAnim, {func = AnimCustomFunction, args = {leaks, SpawnCrates, {}}}) table.insert(attackedAnim, {func = AnimWait, args = {leaks, 1500}}) table.insert(attackedAnim, {func = AnimSay, args = {leaks, loc("Where are all these crates coming from?!"), SAY_THINK, 5500}}) AddSkipFunction(attackedAnim, SkipAttackedAnim, {}) table.insert(attackedFinalAnim, {func = AnimWait, args = {leaks, 2000}}) table.insert(attackedFinalAnim, {func = AnimSay, args = {leaks, loc("I have to get back to the village!"), SAY_THINK, 5000}}) table.insert(attackedFinalAnim, {func = AnimSay, args = {leaks, loc("Dense Cloud must have already told them everything..."), SAY_THINK, 7000}}) end -----------------------------Misc-------------------------------------- function RefusedStart() if stage == loseStage then return end if ramonHidden == true then RestoreHog(ramon) ramonHidden = false end if spikyHidden == true then RestoreHog(spiky) spikyHidden = false end SetState(ramon, 0) SetState(spiky, 0) SetGearMessage(dense, 0) SetGearMessage(ramon, 0) SetGearMessage(spiky, 0) end function AddHogs() nativesTeamName = AddMissionTeam(-2) ramon = AddHog(loc("Ramon"), 0, 100, "rasta") leaks = AddHog(loc("Leaks A Lot"), 0, 100, "Rambo") dense = AddHog(loc("Dense Cloud"), 0, 100, "RobinHood") spiky = AddHog(loc("Spiky Cheese"), 0, 100, "hair_yellow") weaklingsTeamName = AddTeam(loc("Weaklings"), -1, "skull", "Island", "Pirate","cm_vampire") cannibals = {} cannibals[1] = AddHog(loc("Brainiac"), 5, 20, "Zombi") for i = 2, 5 do cannibals[i] = AddHog(HogNames[i], 5, 20, "Zombi") hogNr[cannibals[i]] = i - 2 end AddTeam(loc("Stronglings"), -1, "skull", "Island", "Pirate","cm_vampire") for i = 6, 9 do cannibals[i] = AddHog(HogNames[i], 4, 30, "vampirichog") hogNr[cannibals[i]] = i - 2 end AddTeam(loc("011101001"), -1, "ring", "UFO", "Robot", "cm_binary") cyborg = AddHog(loc("Y3K1337"), 0, 200, "cyborg1") end function PlaceHogs() HogTurnLeft(leaks, true) for i = 2, 9 do AnimSetGearPosition(cannibals[i], unpack(cyborgPos)) AnimTurn(cannibals[i], "Left") cannibalDead[i] = false end AnimSetGearPosition(cannibals[1], cannibalPos[1][1], cannibalPos[1][2]) AnimTurn(cannibals[1], "Left") AnimSetGearPosition(cyborg, cyborgPos[1], cyborgPos[2]) AnimSetGearPosition(ramon, 2218, 1675) AnimSetGearPosition(skiky, 2400, 1675) AnimSetGearPosition(dense, densePos[1], densePos[2]) AnimSetGearPosition(leaks, leaksPos[1], leaksPos[2]) end function VisiblizeHogs() for i = 1, 9 do SetState(cannibals[i], gstInvisible) end SetState(cyborg, gstInvisible) SetState(ramon, gstInvisible) SetState(spiky, gstInvisible) end function CondNeedToTurn(hog1, hog2) if stage == loseStage then return end xl, xd = GetX(hog1), GetX(hog2) if xl and xd then if xl > xd then AnimInsertStepNext({func = AnimTurn, args = {hog1, "Left"}}) AnimInsertStepNext({func = AnimTurn, args = {hog2, "Right"}}) elseif xl < xd then AnimInsertStepNext({func = AnimTurn, args = {hog2, "Left"}}) AnimInsertStepNext({func = AnimTurn, args = {hog1, "Right"}}) end end end function HideHogs() for i = 2, 9 do HideHog(cannibals[i]) isHidden[cannibals[i]] = true end HideHog(cyborg) cyborgHidden = true HideHog(ramon) HideHog(spiky) ramonHidden = true spikyHidden = true end function HideStronglings() if stage == loseStage then return end for i = 6, 9 do HideHog(cannibals[i]) isHidden[cannibals[i]] = true end end function UnHideWeaklings() if stage == loseStage then return end for i = 2, 5 do RestoreHog(cannibals[i]) isHidden[cannibals[i]] = false SetState(cannibals[i], gstInvisible) end end function UnHideStronglings() if stage == loseStage then return end for i = 6, 9 do RestoreHog(cannibals[i]) isHidden[cannibals[i]] = false SetState(cannibals[i], gstInvisible) end RestoreHog(cyborg) cyborgHidden = false SetState(cyborg, gstInvisible) end function ChoiceTaken() if stage == loseStage then return end SetGearMessage(CurrentHedgehog, 0) if choice == choiceAccept then AddAnim(acceptedAnim) AddFunction({func = AfterAcceptedAnim, args = {}}) elseif choice == choiceRefuse then AddAnim(refusedAnim) AddFunction({func = AfterRefusedAnim, args = {}}) else AddAnim(attackedAnim) AddFunction({func = AfterAttackedAnim, args = {}}) end end function KillCyborg() if stage == loseStage then return end RestoreHog(cyborg) DeleteGear(cyborg) EndTurn(true) end -----------------------------Events------------------------------------ function CheckBrainiacDead() return brainiacDead end function DoBrainiacDead() if stage == loseStage then return end EndTurn(true) SetGearMessage(CurrentHedgehog, 0) AddAnim(weaklingsAnim) AddFunction({func = AfterWeaklingsAnim, args = {}}) stage = interSpyStage end function CheckWeaklingsKilled() for i = 2, 5 do if cannibalDead[i] == false then return false end end return true end function DoWeaklingsKilled() if stage == loseStage then return end if denseDead or GetHealth(dense) == 0 or leaksDead or GetHealth(leaks) == 0 then return end SetGearMessage(CurrentHedgehog, 0) AddAnim(stronglingsAnim) AddFunction({func = AfterStronglingsAnim, args = {}}) stage = interWeakStage DismissTeam(weaklingsTeamName) end function CheckRefuse() return GetX(dense) > 1400 and StoppedGear(dense) end function DoRefuse() if stage == loseStage then return end choice = choiceRefuse end function CheckAccept() return GetX(dense) < 1300 and StoppedGear(dense) end function DoAccept() if stage == loseStage then return end choice = choiceAccept end function CheckConfront() return cyborgAttacked and StoppedGear(dense) end function DoConfront() if stage == loseStage then return end choice = choiceAttack end function CheckChoice() return choice ~= 0 end function DoChoice() if stage == loseStage then return end RemoveEventFunc(CheckConfront) RemoveEventFunc(CheckAccept) RemoveEventFunc(CheckRefuse) ChoiceTaken() end function CheckNeedGirder() if stage == loseStage then return false end return GetX(dense) > 1640 and StoppedGear(dense) end function DoNeedGirder() if stage == loseStage then return end local ctrl = loc("Hint: To place a girder, select it,|then use [Left] and [Right] to select angle and length,|then choose a location for the girder.") if INTERFACE == "touch" then ctrl = ctrl .. "|" .. loc("Choose location: Tap the [Target] button, then tap on the spot you want to choose") else ctrl = ctrl .. "|" .. loc("Choose location: Left click") end ShowMission(loc("The Shadow Falls"), loc("Under Construction"), loc("Return to Leaks A Lot!") .. "|" .. ctrl, 1, 6000) end function CheckNeedWeapons() if stage == loseStage then return false end return GetX(dense) > 2522 and StoppedGear(dense) end function DoNeedWeapons() if stage == loseStage then return end grenadeCrate = SpawnSupplyCrate(2550, 800, amGrenade) shotgunCrate = SpawnSupplyCrate(2610, 850, amShotgun) AddCaption(loc("A little gift from the cyborgs")) end function CheckReadyForStronglings() if stage == loseStage then return false end return (shotgunTaken and grenadeTaken) or GetX(dense) > 2700 end function DoReadyForStronglings() if stage == loseStage then return end ShowMission(loc("The Shadow Falls"), loc("The guardian"), loc("Defeat the cannibals!") .."|".. loc("Leaks A Lot must survive!") .. "|" .. grenadeHint, 1, 12000) AddAmmo(dense, amSkip, 100) AddAmmo(dense, amSwitch, 100) AddAmmo(leaks, amSkip, 100) AddAmmo(leaks, amSwitch, 100) stage = duoStage RemoveEventFunc(CheckNeedGirder) RemoveEventFunc(CheckNeedWeapons) AddEvent(CheckStronglingsDead, {}, DoStronglingsDead, {}, 0) AddAmmo(cannibals[6], amGrenade, 2) AddAmmo(cannibals[6], amShotgun, 2) AddAmmo(cannibals[7], amGrenade, 2) AddAmmo(cannibals[7], amShotgun, 2) AddAmmo(cannibals[8], amGrenade, 2) AddAmmo(cannibals[8], amShotgun, 2) AddAmmo(cannibals[9], amGrenade, 2) AddAmmo(cannibals[9], amShotgun, 2) SetGearMessage(leaks, 0) SetGearMessage(dense, 0) SetTurnTimeLeft(TurnTime) end function DoStronglingsDead() if stage == loseStage then return end if leaksDead or GetHealth(leaks) == 0 then return end SetGearMessage(CurrentHedgehog, 0) if denseDead == true then AddAnim(acceptedDiedFinalAnim) SaveCampaignVar("M2DenseDead", "1") else SetupAcceptedSurvivedFinalAnim() AddAnim(acceptedSurvivedFinalAnim) SaveCampaignVar("M2DenseDead", "0") end SaveCampaignVar("M2RamonDead", "0") SaveCampaignVar("M2SpikyDead", "0") AddFunction({func = KillCyborg, args = {}}) if progress and progress<2 then SaveCampaignVar("Progress", "2") end SaveCampaignVar("M2Choice", "" .. choice) end function DoStronglingsDeadRefused() if stage == loseStage then return end if denseDead == true then SaveCampaignVar("M2DenseDead", "1") else SaveCampaignVar("M2DenseDead", "0") end if ramonDead == true then SaveCampaignVar("M2RamonDead", "1") else SaveCampaignVar("M2RamonDead", "0") end if spikyDead == true then SaveCampaignVar("M2SpikyDead", "1") else SaveCampaignVar("M2SpikyDead", "0") end AddAnim(refusedFinalAnim) AddFunction({func = KillCyborg, args = {}}) if progress and progress<2 then SaveCampaignVar("Progress", "2") end SaveCampaignVar("M2Choice", "" .. choice) end function DoStronglingsDeadAttacked() if stage == loseStage then return end SaveCampaignVar("M2DenseDead", "1") SaveCampaignVar("M2RamonDead", "0") SaveCampaignVar("M2SpikyDead", "0") if progress and progress<2 then SaveCampaignVar("Progress", "2") end SaveCampaignVar("M2Choice", "" .. choice) AddAnim(attackedFinalAnim) AddFunction({func = KillCyborg, args = {}}) end function CheckStronglingsDead() if leaksDead == true then return false end for i = 6, 9 do if cannibalDead[i] == false then return false end end return true end function CheckLeaksDead() return leaksDead end function DoDead() if stage == loseStage then return end AddCaption(loc("...and so the cyborgs took over the world...")) stage = loseStage DismissTeam(nativesTeamName) end function CheckDenseDead() return denseDead and choice ~= choiceAttack end -----------------------------Main Functions---------------------------- function onGameInit() Seed = 334 GameFlags = gfSolidLand + gfDisableWind + gfPerHogAmmo TurnTime = 50000 CaseFreq = 0 MinesNum = 0 MinesTime = 3000 Explosives = 0 Map = "A_Classic_Fairytale_shadow" Theme = "Nature" -- Disable Sudden Death HealthDecrease = 0 WaterRise = 0 AddHogs() PlaceHogs() VisiblizeHogs() AnimInit() AnimationSetup() end function onGameStart() progress = tonumber(GetCampaignVar("Progress")) HideHogs() AddAmmo(leaks, amSwitch, 100) AddAmmo(dense, amSwitch, 100) AddEvent(CheckLeaksDead, {}, DoDead, {}, 0) AddEvent(CheckDenseDead, {}, DoDead, {}, 0) AddAnim(startDialogue) AddFunction({func = AfterStartDialogue, args = {}}) AddEvent(CheckBrainiacDead, {}, DoBrainiacDead, {}, 0) local hint if INTERFACE == "touch" then -- FIXME: No precise key available in Touch yet. hint = "" else hint = "|" .. loc("Hint: Cinematics can be skipped with the [Precise] key.") end ShowMission(loc("The Shadow Falls"), loc("The First Encounter"), loc("Survive!") .. hint, 1, 0) end function onGameTick() AnimUnWait() if ShowAnimation() == false then return end ExecuteAfterAnimations() CheckEvents() end function onGearDelete(gear) if gear == cannibals[1] then brainiacDead = true elseif gear == grenadeCrate then grenadeTaken = true elseif gear == shotgunCrate then shotgunTaken = true elseif gear == dense then denseDead = true elseif gear == leaks then leaksDead = true elseif gear == ramon then ramonDead = true elseif gear == spiky then spikyDead = true else for i = 2, 9 do if gear == cannibals[i] then cannibalDead[i] = true end end end end function onGearAdd(gear) if GetGearType(gear) == gtGrenade and GetHogTeamName(CurrentHedgehog) == nativesTeamName then grenadeUsed = true elseif GetGearType(gear) == gtShotgunShot and GetHogTeamName(CurrentHedgehog) == nativesTeamName then shotgunUsed = true end end function onAmmoStoreInit() SetAmmo(amDEagle, 9, 0, 0, 0) SetAmmo(amSniperRifle, 6, 0, 0, 0) SetAmmo(amFirePunch, 3, 0, 0, 0) SetAmmo(amWhip, 4, 0, 0, 0) SetAmmo(amBaseballBat, 4, 0, 0, 0) SetAmmo(amHammer, 2, 0, 0, 0) SetAmmo(amLandGun, 1, 0, 0, 0) SetAmmo(amSnowball, 7, 0, 0, 0) SetAmmo(amGirder, 0, 0, 0, 2) SetAmmo(amParachute, 0, 0, 0, 2) SetAmmo(amGrenade, 0, 0, 0, 3) SetAmmo(amShotgun, 0, 0, 0, 3) SetAmmo(amSwitch, 0, 0, 0, 8) SetAmmo(amRope, 0, 0, 0, 6) SetAmmo(amSkip, 9, 0, 0, 0) end function onNewTurn() if AnimInProgress() then SetTurnTimeLeft(MAX_TURN_TIME) elseif stage == cyborgStage then if CurrentHedgehog ~= dense then EndTurn(true) else SetTurnTimeLeft(MAX_TURN_TIME) end elseif stage == acceptedReturnStage then SwitchHog(dense) FollowGear(dense) SetTurnTimeLeft(MAX_TURN_TIME) end end function onGearDamage(gear, damage) if gear == cyborg and stage == cyborgStage then cyborgAttacked = true end end function onPrecise() if GameTime > 2500 and AnimInProgress() then SetAnimSkip(true) return end end