1--[[ 2 Basic Bazooka Training 3 4 This training missions teaches players how to use the bazooka. 5 Lesson plan: 6 - Selecting bazooka 7 - Aiming and shooting 8 - Wind 9 - Limited ammo 10 - “Bouncing bomb” / water skip 11 - Precise aiming 12]] 13 14HedgewarsScriptLoad("/Scripts/Locale.lua") 15HedgewarsScriptLoad("/Scripts/Achievements.lua") 16 17local hog -- Hog gear 18local weaponSelected = false -- Player has selected the weapon 19local gamePhase = 0 -- Used to track progress 20local targetsLeft = 0 -- # of targets left in this round 21local targetGears = {} -- list of target gears 22local bazookasInGame = 0 -- # of bazookas currently flying 23local bazookaGears = {} -- list of bazooka gears 24local limitedAmmo = 10 -- amount of ammo for the limited ammo challenge 25local limitedAmmoReset = -1 -- Timer for resetting ammo if player fails in 26 -- limited ammo challenge. -1 = no-op 27local gameOver = false -- If true, game has ended 28local shotsFired = 0 -- Total # of bazookas fired 29local maxTargets = 0 -- Target counter, used together with flawless 30local flawless = true -- track flawless victory (100% accuracy, no hurt, no death) 31local missedTauntTimer = -1 -- Wait timer for playing sndMissed. -1 = no-op 32 33function onGameInit() 34 35 ClearGameFlags() 36 EnableGameFlags(gfDisableWind, gfOneClanMode, gfInfAttack, gfSolidLand) 37 Map = "" 38 Seed = 0 39 Theme = "Nature" 40 MapGen = mgDrawn 41 TurnTime = MAX_TURN_TIME 42 Explosives = 0 43 MinesNum = 0 44 CaseFreq = 0 45 WaterRise = 0 46 HealthDecrease = 0 47 48 ------ TEAM LIST ------ 49 50 AddMissionTeam(-1) 51 hog = AddMissionHog(100) 52 SetGearPosition(hog, 1485, 2001) 53 SetEffect(hog, heResurrectable, 1) 54 55 SendHealthStatsOff() 56 SendRankingStatsOff() 57end 58 59function onGearResurrect(gear, vGear) 60 if gear == hog then 61 flawless = false 62 SetGearPosition(hog, 1485, 2001) 63 if vGear then 64 SetVisualGearValues(vGear, GetX(hog), GetY(hog)) 65 end 66 AddCaption(loc("Your hedgehog has been revived!")) 67 end 68end 69 70function placeGirders() 71 PlaceGirder(1520, 2018, 4) 72 PlaceGirder(1449, 1927, 6) 73 PlaceGirder(1341, 1989, 0) 74 PlaceGirder(1141, 1990, 0) 75 PlaceGirder(2031, 1907, 6) 76 PlaceGirder(2031, 1745, 6) 77 PlaceGirder(2398, 1985, 4) 78 PlaceGirder(2542, 1921, 7) 79 PlaceGirder(2617, 1954, 6) 80 PlaceGirder(2565, 2028, 0) 81 PlaceGirder(2082, 1979, 0) 82 PlaceGirder(2082, 1673, 0) 83 PlaceGirder(1980, 1836, 0) 84 PlaceGirder(1716, 1674, 0) 85 PlaceGirder(1812, 1832, 0) 86 PlaceGirder(1665, 1744, 6) 87 PlaceGirder(2326, 1895, 6) 88 PlaceGirder(2326, 1734, 6) 89 PlaceGirder(2326, 1572, 6) 90 PlaceGirder(2275, 1582, 0) 91 PlaceGirder(1738, 1714, 7) 92 PlaceGirder(1818, 1703, 0) 93 PlaceGirder(1939, 1703, 4) 94 PlaceGirder(2805, 1781, 3) 95 PlaceGirder(2905, 1621, 3) 96 PlaceGirder(3005, 1441, 3) 97 PlaceGirder(945, 1340, 5) 98end 99 100function spawnTargets(phase) 101 if not phase then 102 phase = gamePhase 103 end 104 if phase == 0 then 105 AddGear(1734, 1656, gtTarget, 0, 0, 0, 0) 106 AddGear(1812, 1814, gtTarget, 0, 0, 0, 0) 107 AddGear(1974, 1818, gtTarget, 0, 0, 0, 0) 108 elseif phase == 2 then 109 AddGear(2102, 1655, gtTarget, 0, 0, 0, 0) 110 AddGear(2278, 1564, gtTarget, 0, 0, 0, 0) 111 AddGear(2080, 1961, gtTarget, 0, 0, 0, 0) 112 elseif phase == 3 then 113 AddGear(1141, 1972, gtTarget, 0, 0, 0, 0) 114 AddGear(1345, 1971, gtTarget, 0, 0, 0, 0) 115 AddGear(1892, 1680, gtTarget, 0, 0, 0, 0) 116 elseif phase == 4 then 117 AddGear(2584, 2010, gtTarget, 0, 0, 0, 0) 118 elseif phase == 5 then 119 AddGear(955, 1320, gtTarget, 0, 0, 0, 0) 120 elseif phase == 6 then 121 AddGear(2794, 1759, gtTarget, 0, 0, 0, 0) 122 AddGear(2894, 1599, gtTarget, 0, 0, 0, 0) 123 AddGear(2994, 1419, gtTarget, 0, 0, 0, 0) 124 end 125end 126 127function onGameStart() 128 placeGirders() 129 spawnTargets() 130 ShowMission(loc("Basic Bazooka Training"), loc("Basic Training"), loc("Destroy all the targets!"), -amBazooka, 0) 131end 132 133function newGamePhase() 134 local ctrl = "" 135 -- Spawn targets, update wind and ammo, show instructions 136 if gamePhase == 0 then 137 if INTERFACE == "desktop" then 138 ctrl = loc("Open ammo menu: [Right click]").."|".. 139 loc("Select weapon: [Left click]") 140 elseif INTERFACE == "touch" then 141 ctrl = loc("Open ammo menu: Tap the [Suitcase]") 142 end 143 ShowMission(loc("Basic Bazooka Training"), loc("Select Weapon"), loc("To begin with the training, select the bazooka from the ammo menu!").."|".. 144 ctrl, 2, 5000) 145 elseif gamePhase == 1 then 146 if INTERFACE == "desktop" then 147 ctrl = loc("Attack: [Space]").."|".. 148 loc("Aim: [Up]/[Down]").."|".. 149 loc("Walk: [Left]/[Right]") 150 elseif INTERFACE == "touch" then 151 ctrl = loc("Attack: Tap the [Bomb]").."|".. 152 loc("Aim: [Up]/[Down]").."|".. 153 loc("Walk: [Left]/[Right]") 154 end 155 ShowMission(loc("Basic Bazooka Training"), loc("My First Bazooka"), 156 loc("Let's get started!").."|".. 157 loc("Launch some bazookas to destroy the targets!").."|".. 158 loc("Hold the Attack key pressed for more power.").."|".. 159 loc("Don't hit yourself!").."|".. 160 ctrl, 2, 10000) 161 spawnTargets() 162 elseif gamePhase == 2 then 163 if INTERFACE == "desktop" then 164 ctrl = loc("You see the wind strength at the bottom right corner.") 165 elseif INTERFACE == "touch" then 166 ctrl = loc("You see the wind strength at the top.") 167 end 168 ShowMission(loc("Basic Bazooka Training"), loc("Wind"), loc("Bazookas are influenced by wind.").."|".. 169 ctrl.."|".. 170 loc("Destroy the targets!"), 2, 5000) 171 SetWind(50) 172 spawnTargets() 173 elseif gamePhase == 3 then 174 -- Vaporize any bazookas still in the air 175 for gear, _ in pairs(bazookaGears) do 176 AddVisualGear(GetX(gear), GetY(gear), vgtSteam, 0, false) 177 DeleteGear(gear) 178 PlaySound(sndVaporize) 179 end 180 ShowMission(loc("Basic Bazooka Training"), loc("Limited Ammo"), loc("Your ammo is limited this time.").."|".. 181 loc("Destroy all targets with no more than 10 bazookas."), 182 2, 8000) 183 SetWind(-20) 184 AddAmmo(hog, amBazooka, limitedAmmo) 185 spawnTargets() 186 elseif gamePhase == 4 then 187 ShowMission(loc("Basic Bazooka Training"), loc("Bouncing Bomb"), loc("The next target can only be reached by something called “bouncing bomb”.").."|".. 188 loc("Hint: Launch the bazooka horizontally at full power."), 189 2, 8000) 190 SetWind(90) 191 spawnTargets() 192 AddAmmo(hog, amBazooka, 100) 193 if GetCurAmmoType() ~= amBazooka then 194 SetWeapon(amBazooka) 195 end 196 elseif gamePhase == 5 then 197 ShowMission(loc("Basic Bazooka Training"), loc("High Target"), 198 loc("By the way, not only bazookas will bounce on water, but also grenades and many other things.").."|".. 199 loc("The next target is high in the sky."), 200 2, 8000) 201 SetWind(-33) 202 spawnTargets() 203 elseif gamePhase == 6 then 204 if INTERFACE == "desktop" then 205 ctrl = loc("Precise Aim: [Left Shift] + [Up]/[Down]").."|" 206 end 207 ShowMission(loc("Basic Bazooka Training"), loc("Final Targets"), 208 loc("The final targets are quite tricky. You need to aim well.").."|".. 209 ctrl.. 210 loc("Hint: It might be easier if you vary the angle only slightly."), 211 2, 12000) 212 SetWind(75) 213 spawnTargets() 214 elseif gamePhase == 7 then 215 SaveMissionVar("Won", "true") 216 ShowMission(loc("Basic Bazooka Training"), loc("Training complete!"), loc("Congratulations!"), 4, 0) 217 SetInputMask(0) 218 AddAmmo(CurrentHedgehog, amBazooka, 0) 219 if shotsFired > maxTargets then 220 flawless = false 221 else 222 -- For 100% accuracy 223 awardAchievement(loc("Bazooka Master")) 224 end 225 if flawless then 226 PlaySound(sndFlawless, hog) 227 else 228 PlaySound(sndVictory, hog) 229 end 230 SendStat(siCustomAchievement, loc("Good job!")) 231 SendStat(siGameResult, loc("You have completed the Basic Bazooka Training!")) 232 EndGame() 233 SetState(hog, gstWinner) 234 gameOver = true 235 end 236 gamePhase = gamePhase + 1 237end 238 239function onNewTurn() 240 if gamePhase == 0 then 241 newGamePhase() 242 end 243end 244 245function onHogAttack(ammoType) 246 if ammoType == amBazooka then 247 HideMission() 248 end 249end 250 251function onAttack() 252 if GetCurAmmoType() == amBazooka then 253 HideMission() 254 end 255end 256 257function onGearAdd(gear) 258 if GetGearType(gear) == gtTarget then 259 targetsLeft = targetsLeft + 1 260 maxTargets = maxTargets + 1 261 targetGears[gear] = true 262 elseif GetGearType(gear) == gtShell then 263 bazookasInGame = bazookasInGame + 1 264 bazookaGears[gear] = true 265 shotsFired = shotsFired + 1 266 end 267end 268 269function onGearDelete(gear) 270 if GetGearType(gear) == gtTarget then 271 targetsLeft = targetsLeft - 1 272 targetGears[gear] = nil 273 if targetsLeft <= 0 then 274 newGamePhase() 275 end 276 elseif GetGearType(gear) == gtShell then 277 bazookasInGame = bazookasInGame - 1 278 bazookaGears[gear] = nil 279 if bazookasInGame == 0 and GetAmmoCount(hog, amBazooka) == 0 then 280 limitedAmmoReset = 20 281 flawless = false 282 end 283 end 284end 285 286function onGearDamage(gear) 287 if gear == hog then 288 flawless = false 289 end 290end 291 292function onGameTick20() 293 -- Reset targets and ammo if ammo depleted 294 if limitedAmmoReset > 0 then 295 limitedAmmoReset = limitedAmmoReset - 20 296 end 297 if limitedAmmoReset == 0 then 298 if not gameOver and bazookasInGame == 0 and GetAmmoCount(hog, amBazooka) == 0 then 299 for gear, _ in pairs(targetGears) do 300 DeleteGear(gear) 301 end 302 spawnTargets(3) 303 AddCaption(loc("Out of ammo! Try again!")) 304 AddAmmo(hog, amBazooka, limitedAmmo) 305 SetWeapon(amBazooka) 306 missedTauntTimer = 1000 307 end 308 limitedAmmoReset = -1 309 end 310 if missedTauntTimer > 0 then 311 missedTauntTimer = missedTauntTimer - 20 312 end 313 if missedTauntTimer == 0 then 314 PlaySound(sndMissed, hog) 315 missedTauntTimer = -1 316 end 317 318 if not weaponSelected and gamePhase == 1 and GetCurAmmoType() == amBazooka then 319 newGamePhase() 320 weaponSelected = true 321 end 322end 323 324function onAmmoStoreInit() 325 SetAmmo(amBazooka, 9, 0, 0, 0) 326end 327