1--[[ 2 Basic Grenade Training 3 4 This training mission teaches players how to use the grenade. 5 Lesson plan: 6 - Selecting grenade 7 - Aiming and shooting 8 - Timer 9 - No wind 10 - Bounciness 11]] 12 13HedgewarsScriptLoad("/Scripts/Locale.lua") 14 15local hog -- Hog gear 16local weaponSelected = false -- Player has selected the weapon 17local gamePhase = 0 -- Used to track progress 18local targetsLeft = 0 -- # of targets left in this round 19local targetGears = {} -- list of target gears 20local gameOver = false -- If true, game has ended 21local shotsFired = 0 -- Total # of grenades fired 22local maxTargets = 0 -- Target counter, used together with flawless 23local flawless = true -- track flawless victory (100% accuracy, no hurt, no death) 24local missedTauntTimer = -1 -- Wait timer for playing sndMissed. -1 = no-op 25 26function onGameInit() 27 28 ClearGameFlags() 29 EnableGameFlags(gfDisableWind, gfOneClanMode, gfInfAttack, gfSolidLand, gfArtillery) 30 Map = "Mushrooms" 31 Seed = 0 32 Theme = "Nature" 33 TurnTime = MAX_TURN_TIME 34 Explosives = 0 35 MinesNum = 0 36 CaseFreq = 0 37 WaterRise = 0 38 HealthDecrease = 0 39 40 ------ TEAM LIST ------ 41 42 AddMissionTeam(-1) 43 hog = AddMissionHog(1) 44 SetGearPosition(hog, 570, 157) 45 SetEffect(hog, heResurrectable, 1) 46 47 SendHealthStatsOff() 48 SendRankingStatsOff() 49end 50 51function onGearResurrect(gear, vGear) 52 if gear == hog then 53 flawless = false 54 SetGearPosition(hog, 570, 157) 55 if vGear then 56 SetVisualGearValues(vGear, GetX(hog), GetY(hog)) 57 end 58 AddCaption(loc("Your hedgehog has been revived!")) 59 end 60end 61 62local function placeGirders() 63 PlaceGirder(918, 248, 1) 64 PlaceGirder(888, 129, 6) 65 PlaceGirder(844, 35, 1) 66 PlaceGirder(932, 37, 3) 67 PlaceGirder(926, 148, 6) 68 PlaceGirder(73, 812, 5) 69 PlaceGirder(189, 930, 5) 70 PlaceGirder(15, 669, 6) 71 PlaceGirder(15, 507, 6) 72 PlaceGirder(15, 344, 6) 73 PlaceGirder(62, 27, 0) 74 PlaceGirder(229, 115, 0) 75 PlaceGirder(1195, 250, 7) 76 PlaceGirder(1285, 205, 1) 77 PlaceGirder(1358, 201, 3) 78 PlaceGirder(1756, 415, 6) 79 PlaceGirder(1893, 95, 6) 80 PlaceGirder(1005, 333, 5) 81 PlaceGirder(1860, 187, 0) 82end 83 84local function spawnTargets() 85 -- Warm-up 86 if gamePhase == 0 then 87 AddGear(945, 498, gtTarget, 0, 0, 0, 0) 88 -- Timer 89 elseif gamePhase == 2 then 90 AddGear(233, 97, gtTarget, 0, 0, 0, 0) 91 AddGear(333, 255, gtTarget, 0, 0, 0, 0) 92 AddGear(753, 225, gtTarget, 0, 0, 0, 0) 93 -- No Wind 94 elseif gamePhase == 3 then 95 AddGear(15, 240, gtTarget, 0, 0, 0, 0) 96 AddGear(61, 9, gtTarget, 0, 0, 0, 0) 97 AddGear(882, 39, gtTarget, 0, 0, 0, 0) 98 -- Bounciness 99 elseif gamePhase == 4 then 100 AddGear(1318, 208, gtTarget, 0, 0, 0, 0) 101 AddGear(1697, 250, gtTarget, 0, 0, 0, 0) 102 AddGear(323, 960, gtTarget, 0, 0, 0, 0) 103 AddGear(1852, 100, gtTarget, 0, 0, 0, 0) 104 -- Grand Final 105 elseif gamePhase == 5 then 106 AddGear(186, 473, gtTarget, 0, 0, 0, 0) 107 AddGear(950, 250, gtTarget, 0, 0, 0, 0) 108 AddGear(1102, 345, gtTarget, 0, 0, 0, 0) 109 AddGear(1556, 297, gtTarget, 0, 0, 0, 0) 110 end 111end 112 113function onGameStart() 114 placeGirders() 115 spawnTargets() 116 ShowMission(loc("Basic Grenade Training"), loc("Basic Training"), loc("Destroy all the targets!"), -amGrenade, 0) 117end 118 119function newGamePhase() 120 -- Spawn targets, update wind and ammo, show instructions 121 local ctrl = "" 122 if gamePhase == 0 then 123 if INTERFACE == "desktop" then 124 ctrl = loc("Open ammo menu: [Right click]").."|".. 125 loc("Select weapon: [Left click]") 126 else 127 ctrl = loc("Open ammo menu: Tap the [Suitcase]") 128 end 129 ShowMission(loc("Basic Grenade Training"), loc("Select Weapon"), loc("To begin with the training, select the grenade from the ammo menu!").."|".. 130 ctrl, 2, 5000) 131 elseif gamePhase == 1 then 132 if INTERFACE == "desktop" then 133 ctrl = loc("Attack: [Space]").."|".. 134 loc("Aim: [Up]/[Down]").."|".. 135 loc("Change direction: [Left]/[Right]") 136 elseif INTERFACE == "touch" then 137 ctrl = loc("Attack: Tap the [Bomb]").."|".. 138 loc("Aim: [Up]/[Down]").."|".. 139 loc("Change direction: [Left]/[Right]") 140 end 141 ShowMission(loc("Basic Grenade Training"), loc("Warming Up"), 142 loc("Throw a grenade to destroy the target!").."|".. 143 loc("Hold the Attack key pressed for more power.").."|".. 144 ctrl.."|".. 145 loc("Note: Walking is disabled in this mission."), 2, 20000) 146 spawnTargets() 147 elseif gamePhase == 2 then 148 if INTERFACE == "desktop" then 149 ctrl = loc("Set detonation timer: [1]-[5]") 150 elseif INTERFACE == "touch" then 151 ctrl = loc("Change detonation timer: Tap the [Clock]") 152 end 153 ShowMission(loc("Basic Grenade Training"), loc("Timer"), 154 loc("You can change the detonation timer of grenades.").."|".. 155 loc("Grenades explode after 1 to 5 seconds (you decide).").."|".. 156 ctrl, 2, 15000) 157 spawnTargets() 158 elseif gamePhase == 3 then 159 ShowMission(loc("Basic Grenade Training"), loc("No Wind Influence"), loc("Unlike bazookas, grenades are not influenced by wind.").."|".. 160 loc("Destroy the targets!"), 2, 6000) 161 SetWind(50) 162 spawnTargets() 163 elseif gamePhase == 4 then 164 local caption = loc("Bounciness") 165 ctrl = loc("You can set the bounciness of grenades (and grenade-like weapons).").."|".. 166 loc("Grenades with high bounciness bounce a lot and behave chaotic.").."|".. 167 loc("With low bounciness, it barely bounces at all, but it is much more predictable.").."|".. 168 loc("Try out different bounciness levels to reach difficult targets.").."|" 169 if INTERFACE == "desktop" then 170 ctrl = ctrl .. loc("Set bounciness: [Left Shift] + [1]-[5]") 171 elseif INTERFACE == "touch" then 172 ctrl = ctrl .. loc("Change bounciness: Tap [B]") 173 end 174 175 ShowMission(loc("Basic Grenade Training"), caption, ctrl, 2, 20000) 176 spawnTargets() 177 elseif gamePhase == 5 then 178 if INTERFACE == "desktop" then 179 ctrl = loc("Precise Aim: [Left Shift] + [Up]/[Down]") 180 -- FIXME: No precise aim in touch interface yet :( 181 end 182 ShowMission(loc("Basic Grenade Training"), loc("Final Targets"), loc("Good job! Now destroy the final targets to finish the training.").."|".. 183 ctrl, 184 2, 7000) 185 spawnTargets() 186 elseif gamePhase == 6 then 187 SaveMissionVar("Won", "true") 188 ShowMission(loc("Basic Grenade Training"), loc("Training complete!"), loc("Congratulations!"), 4, 0) 189 SetInputMask(0) 190 AddAmmo(CurrentHedgehog, amGrenade, 0) 191 if shotsFired > maxTargets then 192 flawless = false 193 end 194 if flawless then 195 PlaySound(sndFlawless, hog) 196 else 197 PlaySound(sndVictory, hog) 198 end 199 SendStat(siCustomAchievement, loc("Good job!")) 200 SendStat(siGameResult, loc("You have completed the Basic Grenade Training!")) 201 EndGame() 202 gameOver = true 203 SetState(hog, gstWinner) 204 end 205 gamePhase = gamePhase + 1 206end 207 208function onNewTurn() 209 if gamePhase == 0 then 210 newGamePhase() 211 end 212end 213 214function onGameTick20() 215 if not weaponSelected and gamePhase == 1 and GetCurAmmoType() == amGrenade then 216 newGamePhase() 217 weaponSelected = true 218 end 219end 220 221function onHogAttack(ammoType) 222 if ammoType == amGrenade then 223 HideMission() 224 end 225end 226 227function onAttack() 228 if GetCurAmmoType() == amGrenade then 229 HideMission() 230 end 231end 232 233function onGearAdd(gear) 234 if GetGearType(gear) == gtTarget then 235 targetsLeft = targetsLeft + 1 236 maxTargets = maxTargets + 1 237 targetGears[gear] = true 238 elseif GetGearType(gear) == gtGrenade then 239 shotsFired = shotsFired + 1 240 end 241end 242 243function onGearDelete(gear) 244 if GetGearType(gear) == gtTarget then 245 targetsLeft = targetsLeft - 1 246 targetGears[gear] = nil 247 if targetsLeft <= 0 then 248 newGamePhase() 249 end 250 end 251end 252 253function onGearDamage(gear) 254 if gear == hog then 255 flawless = false 256 end 257end 258 259function onAmmoStoreInit() 260 SetAmmo(amGrenade, 9, 0, 0, 0) 261end 262