|
1 --[[ |
|
2 Flying Saucer Training |
|
3 This is a training mission which teaches many basic (and not-so-basic) moves |
|
4 with the flying saucer. |
|
5 |
|
6 Lesson plan: |
|
7 - Taking off |
|
8 - Basic flight |
|
9 - Landing safely |
|
10 - Managing fuel |
|
11 - Changing saucers in mid-flight |
|
12 - Diving |
|
13 - Dropping weapons from flying saucer |
|
14 - Firing from flying saucer with [Precise] + [Attack] |
|
15 - Aiming in flying saucer with [Precise] + [Up]/[Down] |
|
16 - Underwater attack |
|
17 - Free flight with inf. fuel and some weapons at end of training |
|
18 |
|
19 FIXME: |
|
20 - Bad respawn animation ("explosion" just happens randomly because of the way the resurrection effect works) |
|
21 - Hide fuel if infinite (probably needs engine support) |
|
22 ]] |
|
23 |
|
24 HedgewarsScriptLoad("/Scripts/Locale.lua") |
|
25 HedgewarsScriptLoad("/Scripts/Tracker.lua") |
|
26 |
|
27 local Player = nil -- Pointer to hog created in: onGameInit |
|
28 local Target = nil -- Pointer to target hog |
|
29 local Objective = false -- Get to the target |
|
30 |
|
31 local TargetNumber = 0 -- The current target number |
|
32 local GrenadeThrown = false -- Used for the Boom Target |
|
33 local BazookasLeft = 0 -- Used by the Launch Target and the Unterwater Attack Target |
|
34 |
|
35 local InfFuel = false -- If true, flying saucer has infinite fuel |
|
36 local SaucerGear = nil -- Store flying saucer gear here (if one exists) |
|
37 local TargetGears = {} -- List of remaining gears to collect or destroy in the current round |
|
38 local TargetsRemaining = 0 |
|
39 local Barrels = {} -- Table contraining the explosive barrel gears |
|
40 |
|
41 local CheckTimer = 500 -- Time to wait at least before checking safe landing |
|
42 local Check = false -- The last target has recently been collected/destroyed and the CheckTimer is running |
|
43 local GrenadeTimer = 0 -- Time after a grenade has been thrown |
|
44 |
|
45 local TargetPos = {} -- Table of targets |
|
46 |
|
47 local StartPos = { X = 742, Y = 290 } |
|
48 |
|
49 --[[ |
|
50 List of all targets (or "objectives"). The player has to complete them one-by-one and must always land safely afterwards. |
|
51 Some target numbers have names for easier reference. |
|
52 ]] |
|
53 TargetPos[1] = { |
|
54 Targets = {{ X = 1027, Y = 217 }}, |
|
55 Ammo = { }, |
|
56 Message = loc("Here you will learn how to fly the flying saucer|and get so learn some cool tricks.") .. "|" .. |
|
57 loc("Collect the first crate to begin!"), |
|
58 MessageIcon = -amJetpack, } |
|
59 TargetPos[2] = { |
|
60 Targets = {{ X = 1369, Y = 265 }}, |
|
61 Ammo = { [amJetpack] = 100 }, |
|
62 InfFuel = true, |
|
63 MessageTime = 10000, |
|
64 Message = loc("Get to the crate using your flying saucer!") .. "|" .. |
|
65 loc("Press [Attack] (space bar by default) to start,|repeadedly tap the up, left and right movement keys to accelerate.") .. "|" .. |
|
66 loc("Try to land softly, as you can still take fall damage!"), } |
|
67 TargetPos[3] = { |
|
68 Targets = {{ X = 689, Y = 58 }}, |
|
69 Ammo = { [amJetpack] = 100 }, |
|
70 MessageTime = 5000, |
|
71 Message = loc("Now collect the next crate!") .. "|" .. loc("Be careful, your fuel is limited from now on!") .."|" .. |
|
72 loc("Tip: If you get stuck in this training, use \"Skip turn\" to restart the current objective.") } |
|
73 |
|
74 -- The Double Target |
|
75 local DoubleTarget = 4 |
|
76 TargetPos[4] = { |
|
77 Targets = { { X = 84, Y = -20 }, { X = 1980 , Y = -20 } }, |
|
78 Ammo = { [amJetpack] = 2 }, |
|
79 MessageTime = 9000, |
|
80 Message = loc("Now collect the 2 crates to the far left and right.") .. "|" .. |
|
81 loc("You only have 2 flying saucers this time.") .. "|" .. |
|
82 loc("Tip: You can change your flying saucer|in mid-flight by hitting the [Attack] key twice."), } |
|
83 TargetPos[5] = { |
|
84 Targets = {{ X = 47, Y = 804 }}, |
|
85 Ammo = { [amJetpack] = 100 }, |
|
86 MessageTime = 5000, |
|
87 Message = loc("Time for a more interesting stunt, but first just collect the next crate!"), } |
|
88 TargetPos[6] = { |
|
89 Targets = {{ X = 604, Y = 871}}, |
|
90 MessageTime = 15000, |
|
91 Message = loc("You can dive with your flying saucer!") .. "|" .. |
|
92 loc("Try it now and dive here to collect the crate on the right girder.") .. "|" .. |
|
93 loc("You only have one flying saucer this time.") .. "|" .. |
|
94 loc("Beware, though, you will only be able to move slowly through the water.") .. "|" .. |
|
95 loc("Warning: Never ever leave the flying saucer while in water!"), |
|
96 Ammo = { [amJetpack] = 1 }, } |
|
97 |
|
98 TargetPos[7] = { |
|
99 Targets = {{ X = 1884, Y = 704 }}, |
|
100 MessageTime = 6500, |
|
101 Message = loc("Now dive just one more time and collect the next crate." .. "|" .. |
|
102 loc("Tip: Don't remain for too long in the water, or you won't make it.")), |
|
103 Ammo = { [amJetpack] = 1}, } |
|
104 |
|
105 -- The Boom Target |
|
106 local BoomTarget = 8 |
|
107 TargetPos[8] = { |
|
108 Modifier = true, Func = function() |
|
109 Info(loc("Instructions"), |
|
110 loc("Now let's try to drop weapons while flying!") .. "|" .. |
|
111 loc("You have to destroy the target above by dropping a grenade on it from your flying saucer.") .. "|" .. |
|
112 loc("It's not that easy, so listen carefully:") .. "|" .. |
|
113 loc("Step 1: Activate your flying saucer but do NOT move yet!") .. "|" .. |
|
114 loc("Step 2: Select your grenade.") .. "|" .. |
|
115 loc("Step 3: Start flying and get yourself right above the target.") .. "|" .. |
|
116 loc("Step 4: Drop your grenade by pressing the [Long jump] key.") .. "|" .. |
|
117 loc("Step 5: Get away quickly and land safely anywhere." .. "| |" .. |
|
118 loc("Note: We only give you grenades if you stay in your flying saucer.")), nil, 20000) |
|
119 |
|
120 SpawnBoomTarget() |
|
121 |
|
122 if SaucerGear ~= nil then |
|
123 AddAmmo(Player, amGrenade, 1) |
|
124 else |
|
125 AddAmmo(Player, amGrenade, 0) |
|
126 end |
|
127 GrenadeThrown = false |
|
128 |
|
129 end, |
|
130 Ammo = { [amJetpack] = 100 }, |
|
131 Respawn = { X = 2000, Y = 742 }, } |
|
132 |
|
133 -- The Launch Target |
|
134 local LaunchTarget = 9 |
|
135 TargetPos[9] = { |
|
136 Targets = {{ X = 1700, Y = 640, Type = gtTarget }, { X = 1460, Y = 775, Type = gtTarget }}, |
|
137 MessageTime = 20000, |
|
138 Message = loc("Only the best pilots can master the following stunts.") .. "|" .. |
|
139 loc("As you've seen, the dropped grenade roughly fell into your flying direction.") .. "|" .. |
|
140 loc("You have to destroy two targets, but the previous technique would be very difficult or dangerous to use.") .. "|" .. |
|
141 loc("So you are able to launch projectiles into your aiming direction, always at full power.") .."|".. |
|
142 loc("To launch a projectile in mid-flight, hold [Precise] and press [Long jump].") .. "|" .. |
|
143 loc("You can even change your aiming direction in mid-flight if you first hold [Precice] and then press [Up] or [Down].") .. "|" .. |
|
144 loc("Tip: Changing your aim while flying is very difficult, so adjust it before you take off."), |
|
145 Ammo = { [amJetpack] = 1, }, |
|
146 Respawn = { X = 1764, Y = 916 }, |
|
147 ExtraFunc = function() |
|
148 HogTurnLeft(Player, true) |
|
149 if SaucerGear ~= nil then |
|
150 AddAmmo(Player, amBazooka, 2) |
|
151 else |
|
152 AddAmmo(Player, amBazooka, 0) |
|
153 end |
|
154 BazookasLeft = 2 |
|
155 |
|
156 end } |
|
157 |
|
158 -- The Underwater Attack Target |
|
159 local UnderwaterAttackTarget = 10 |
|
160 TargetPos[10] = { |
|
161 MessageTime = 17000, |
|
162 Message = loc("Now for the supreme discipline of saucer flying, the underwater attack.") .. "|" .. |
|
163 loc("Basically this is a combination of diving and launching.") .. "|" .. |
|
164 loc("Dropping a weapon while in water would just drown it, but launching one would work.") .."|" .. |
|
165 loc("Based on what you've learned, destroy the target on the girder and as always, land safely!"), |
|
166 Targets = {{ X = 1200, Y = 930, Type = gtTarget }}, |
|
167 Ammo = { [amJetpack] = 1, }, |
|
168 Respawn = { X = 1027, Y = 217 }, |
|
169 ExtraFunc = function() |
|
170 if SaucerGear ~= nil then |
|
171 AddAmmo(Player, amBazooka, 1) |
|
172 else |
|
173 AddAmmo(Player, amBazooka, 0) |
|
174 end |
|
175 BazookasLeft = 1 |
|
176 end } |
|
177 TargetPos[11] = { |
|
178 Targets = {{ X = 742, Y = 290 }}, |
|
179 MessageTime = 5000, |
|
180 Message = loc("This almost concludes our tutorial.") .. "|" .. |
|
181 loc("You now have infinite fuel, grenades and bazookas for fun.") .. "|" .. |
|
182 loc("Collect or destroy the final crate to finish the training."), |
|
183 Ammo = { [amJetpack] = 100, [amGrenade] = 100, [amBazooka] = 100 }, |
|
184 InfFuel = true, } |
|
185 TargetPos[12] = { Modifier = true, Func = function() |
|
186 Objective = true |
|
187 AddCaption(loc("Training complete!"), 0xFFFFFFFF, capgrpGameState) |
|
188 Info(loc("Training complete!"), loc("Good bye!"), 4, 5000) |
|
189 |
|
190 if SaucerGear ~= nil then |
|
191 DeleteGear(SaucerGear) |
|
192 end |
|
193 SetState(Player, band(GetState(Player), bnot(gstHHDriven))) |
|
194 SetState(Player, bor(GetState(Player), gstWinner)) |
|
195 PlaySound(sndVictory, Player) |
|
196 |
|
197 SendStat(siGameResult, loc("You have finished the Flying Saucer Training!")) |
|
198 SendStat(siCustomAchievement, loc("Good job!")) |
|
199 SendStat(siPlayerKills, "0", loc("Hogonauts")) |
|
200 |
|
201 TurnTimeLeft = 0 |
|
202 EndGame() |
|
203 end, |
|
204 } |
|
205 |
|
206 -- Just a wrapper for ShowMission |
|
207 function Info(Title, Text, Icon, Time) |
|
208 if Time == nil then Time = 0 end |
|
209 if Icon == nil then Icon = 2 end |
|
210 ShowMission(loc("Flying Saucer Training"), Title, Text, Icon, Time) |
|
211 end |
|
212 |
|
213 -- Spawn all the gears for the Boom Target |
|
214 function SpawnBoomTarget() |
|
215 if TargetsRemaining < 1 then |
|
216 TargetGears[1] = AddGear(1602, 507, gtTarget, 0, 0, 0, 0) |
|
217 TargetsRemaining = TargetsRemaining + 1 |
|
218 end |
|
219 |
|
220 if Barrels[1] == nil then |
|
221 Barrels[1] = AddGear(1563, 532, gtExplosives, 0, 0, 0, 0) |
|
222 end |
|
223 if Barrels[2] == nil then |
|
224 Barrels[2] = AddGear(1648, 463, gtExplosives, 0, 0, 0, 0) |
|
225 end |
|
226 |
|
227 for i=1,#Barrels do |
|
228 SetHealth(Barrels[i], 1) |
|
229 end |
|
230 end |
|
231 |
|
232 -- Generic target spawning for the current target |
|
233 function SpawnTargets() |
|
234 for i=1,#TargetPos[TargetNumber].Targets do |
|
235 if TargetGears[i] == nil then |
|
236 SpawnTarget(TargetPos[TargetNumber].Targets[i].X, TargetPos[TargetNumber].Targets[i].Y, |
|
237 TargetPos[TargetNumber].Targets[i].Type, i) |
|
238 end |
|
239 end |
|
240 end |
|
241 |
|
242 function SpawnTarget( PosX, PosY, Type, ID ) |
|
243 if Type ~= nil and Type ~= gtCase then |
|
244 if Type == gtTarget then |
|
245 TargetGears[ID] = AddGear(PosX, PosY, gtTarget, 0, 0, 0, 0) |
|
246 end |
|
247 else |
|
248 TargetGears[ID] = SpawnFakeUtilityCrate(PosX, PosY, false, false) |
|
249 end |
|
250 TargetsRemaining = TargetsRemaining + 1 |
|
251 end |
|
252 |
|
253 function AutoSpawn() -- Auto-spawn the next target after you've obtained the current target! |
|
254 TargetNumber = TargetNumber + 1 |
|
255 TargetsRemaining = 0 |
|
256 |
|
257 if TargetPos[TargetNumber].Ammo then |
|
258 for ammoType, count in pairs(TargetPos[TargetNumber].Ammo) do |
|
259 AddAmmo(Player, ammoType, count) |
|
260 end |
|
261 if GetCurAmmoType() ~= amJetpack then |
|
262 SetWeapon(amJetpack) |
|
263 end |
|
264 end |
|
265 if TargetPos[TargetNumber].InfFuel then |
|
266 InfFuel = true |
|
267 else |
|
268 InfFuel = false |
|
269 end |
|
270 |
|
271 -- Func (if present) will be run instead of the ordinary spawning handling |
|
272 if TargetPos[TargetNumber].Modifier then -- If there is a modifier, run the function |
|
273 TargetPos[TargetNumber].Func() |
|
274 return true |
|
275 end |
|
276 |
|
277 -- ExtraFunc is for additional events for a target |
|
278 if TargetPos[TargetNumber].ExtraFunc ~= nil then |
|
279 TargetPos[TargetNumber].ExtraFunc() |
|
280 end |
|
281 |
|
282 local subcap |
|
283 if TargetNumber == 1 then |
|
284 subcap = loc("Training") |
|
285 else |
|
286 subcap = loc("Instructions") |
|
287 end |
|
288 Info(subcap, TargetPos[TargetNumber].Message, TargetPos[TargetNumber].MessageIcon, TargetPos[TargetNumber].MessageTime) |
|
289 |
|
290 -- Spawn targets on the next position |
|
291 SpawnTargets() |
|
292 |
|
293 if TargetNumber > 1 then |
|
294 AddCaption(loc("Next target is ready!"), 0xFFFFFFFF, capgrpMessage2) |
|
295 end |
|
296 end |
|
297 |
|
298 -- Returns true if the hedgehog has safely "landed" (alive, no flying saucer gear and not moving) |
|
299 -- This is to ensure the training only continues when the player didn't screw up and to restart the current target |
|
300 function HasHedgehogLandedYet() |
|
301 if band(GetState(Player), gstMoving) == 0 and SaucerGear == nil and GetHealth(Player) > 0 then |
|
302 return true |
|
303 else |
|
304 return false |
|
305 end |
|
306 end |
|
307 |
|
308 -- Clean up the gear mess left behind when the player failed to get a clean state after restarting |
|
309 function CleanUpGears() |
|
310 -- (We track flames, grenades, bazooka shells) |
|
311 runOnGears(DeleteGear) |
|
312 end |
|
313 |
|
314 -- Completely restarts the current target/objective; the hedgehog is spawned at the last "checkpoint" |
|
315 -- Called when hedgeghog is resurrected or skips turn |
|
316 function ResetCurrentTarget() |
|
317 GrenadeThrown = false |
|
318 GrenadeTimer = 0 |
|
319 if TargetNumber == LaunchTarget then |
|
320 BazookasLeft = 2 |
|
321 elseif TargetNumber == UnderwaterAttackTarget then |
|
322 BazookasLeft = 1 |
|
323 else |
|
324 BazookasLeft = 0 |
|
325 end |
|
326 Check = false |
|
327 |
|
328 CleanUpGears() |
|
329 |
|
330 local X, Y |
|
331 if TargetNumber == 1 then |
|
332 X, Y = StartPos.X, StartPos.Y |
|
333 else |
|
334 if TargetPos[TargetNumber-1].Modifier or TargetPos[TargetNumber-1].Respawn ~= nil then |
|
335 X, Y = TargetPos[TargetNumber-1].Respawn.X, TargetPos[TargetNumber-1].Respawn.Y |
|
336 else |
|
337 X, Y = TargetPos[TargetNumber-1].Targets[1].X, TargetPos[TargetNumber-1].Targets[1].Y |
|
338 end |
|
339 end |
|
340 if TargetNumber == BoomTarget then |
|
341 SpawnBoomTarget() |
|
342 end |
|
343 if TargetPos[TargetNumber].Modifier ~= true then |
|
344 SpawnTargets() |
|
345 end |
|
346 if TargetPos[TargetNumber].Ammo then |
|
347 for ammoType, count in pairs(TargetPos[TargetNumber].Ammo) do |
|
348 AddAmmo(Player, ammoType, count) |
|
349 end |
|
350 if GetCurAmmoType() ~= amJetpack then |
|
351 SetWeapon(amJetpack) |
|
352 end |
|
353 end |
|
354 if TargetPos[TargetNumber].InfFuel then |
|
355 InfFuel = true |
|
356 else |
|
357 InfFuel = false |
|
358 end |
|
359 |
|
360 SetGearPosition(Player, X, Y) |
|
361 end |
|
362 |
|
363 function onGameInit() |
|
364 Seed = 1 |
|
365 GameFlags = gfInfAttack + gfOneClanMode + gfSolidLand + gfDisableWind |
|
366 TurnTime = 2000000 --[[ This rffectively hides the turn time; a turn time above 1000s is not displayed. |
|
367 We will also ensure this timer always stays above 999s later ]] |
|
368 CaseFreq = 0 |
|
369 MinesNum = 0 |
|
370 Explosives = 0 |
|
371 Map = "Eyes" |
|
372 Theme = "EarthRise" |
|
373 SuddenDeathTurns = 50 |
|
374 WaterRise = 0 |
|
375 HealthDecrease = 0 |
|
376 |
|
377 -- Team name is a pun on “hedgehog” and “astronauts” |
|
378 AddTeam( loc( "Hogonauts" ), 0xDDDD00, "earth", "Earth", "Default", "cm_galaxy" ) |
|
379 |
|
380 -- Hedgehog name is a pun on “Neil Armstrong” |
|
381 Player = AddHog( loc( "Neil Hogstrong" ), 0, 1, "NoHat" ) |
|
382 SetGearPosition( Player, StartPos.X, StartPos.Y) |
|
383 SetEffect( Player, heResurrectable, 1 ) |
|
384 end |
|
385 |
|
386 function onGameStart() |
|
387 SendHealthStatsOff() |
|
388 |
|
389 -- Girder near first crate |
|
390 PlaceGirder(1257, 204, 6) |
|
391 |
|
392 -- The upper girders |
|
393 PlaceGirder(84, 16, 0) |
|
394 PlaceGirder(1980, 16, 0) |
|
395 |
|
396 -- The lower girder platform at the water pit |
|
397 PlaceGirder(509, 896, 4) |
|
398 PlaceGirder(668, 896, 4) |
|
399 PlaceGirder(421, 896, 2) |
|
400 PlaceGirder(758, 896, 2) |
|
401 |
|
402 -- Girders for the Launch Target and the Underwater Attack Target |
|
403 PlaceGirder(1191, 960, 4) |
|
404 PlaceGirder(1311, 960, 0) |
|
405 PlaceGirder(1460, 827, 3) |
|
406 PlaceGirder(1509, 763, 2) |
|
407 PlaceGirder(1605, 672, 4) |
|
408 PlaceGirder(1764, 672, 4) |
|
409 PlaceGirder(1803, 577, 6) |
|
410 |
|
411 -- Spawn our 1st target using the wrapper function |
|
412 AutoSpawn() |
|
413 end |
|
414 |
|
415 function onAmmoStoreInit() |
|
416 SetAmmo(amJetpack, 0, 0, 0, 0) |
|
417 SetAmmo(amGrenade, 0, 0, 0, 0) |
|
418 SetAmmo(amBazooka, 0, 0, 0, 0) |
|
419 |
|
420 -- Added for resetting current target/objective when player is stuck somehow |
|
421 SetAmmo(amSkip, 9, 0, 0, 0) |
|
422 end |
|
423 |
|
424 function onGearAdd(Gear) |
|
425 if GetGearType(Gear) == gtJetpack then |
|
426 SaucerGear = Gear |
|
427 if TargetNumber == BoomTarget and GrenadeThrown == false then |
|
428 AddAmmo(Player, amGrenade, 1) |
|
429 end |
|
430 if (TargetNumber == LaunchTarget or TargetNumber == UnderwaterAttackTarget) and BazookasLeft > 0 then |
|
431 AddAmmo(Player, amBazooka, BazookasLeft) |
|
432 end |
|
433 end |
|
434 if GetGearType(Gear) == gtGrenade then |
|
435 GrenadeThrown = true |
|
436 GrenadeTimer = 0 |
|
437 end |
|
438 if GetGearType(Gear) == gtShell then |
|
439 BazookasLeft = BazookasLeft - 1 |
|
440 end |
|
441 if GetGearType(Gear) == gtFlame or GetGearType(Gear) == gtGrenade or GetGearType(Gear) == gtShell then |
|
442 trackGear(Gear) |
|
443 end |
|
444 end |
|
445 |
|
446 function onGearDelete(Gear) |
|
447 if GetGearType(Player) ~= nil and (GetGearType(Gear) == gtTarget or GetGearType(Gear) == gtCase) then |
|
448 for i=1, #TargetGears do |
|
449 if Gear == TargetGears[i] then |
|
450 TargetGears[i] = nil |
|
451 TargetsRemaining = TargetsRemaining - 1 |
|
452 end |
|
453 end |
|
454 if TargetsRemaining <= 0 then |
|
455 if TargetNumber == BoomTarget or not HasHedgehogLandedYet() then |
|
456 if SaucerGear then |
|
457 AddCaption(loc("Objective completed! Now land safely."), 0xFFFFFFFF, capgrpMessage2) |
|
458 end |
|
459 Check = true |
|
460 CheckTimer = 500 |
|
461 else |
|
462 AutoSpawn() |
|
463 end |
|
464 end |
|
465 end |
|
466 if GetGearType(Gear) == gtGrenade then |
|
467 GrenadeTimer = 0 |
|
468 GrenadeExploded = true |
|
469 end |
|
470 if GetGearType(Gear) == gtJetpack then |
|
471 SaucerGear = nil |
|
472 if TargetNumber == BoomTarget then |
|
473 AddAmmo(Player, amGrenade, 0) |
|
474 end |
|
475 if TargetNumber == LaunchTarget or TargetNumber == UnderwaterAttackTarget then |
|
476 AddAmmo(Player, amBazooka, 0) |
|
477 end |
|
478 end |
|
479 if GetGearType(Gear) == gtCase and GetGearType(Player) ~= nil then |
|
480 PlaySound(sndShotgunReload) |
|
481 end |
|
482 if Gear == Barrels[1] then |
|
483 Barrels[1] = nil |
|
484 end |
|
485 if Gear == Barrels[2] then |
|
486 Barrels[2] = nil |
|
487 AddCaption(loc("Kaboom!"), 0xFFFFFFFF, capgrpMessage) |
|
488 end |
|
489 end |
|
490 |
|
491 |
|
492 |
|
493 function onNewTurn() |
|
494 SetWeapon(amJetpack) |
|
495 end |
|
496 |
|
497 function onGameTick20() |
|
498 if (TurnTimeLeft < 1500000 and not Objective) then |
|
499 TurnTimeLeft = TurnTime |
|
500 end |
|
501 if Check then |
|
502 CheckTimer = CheckTimer - 20 |
|
503 if CheckTimer <= 0 then |
|
504 if HasHedgehogLandedYet() then |
|
505 AutoSpawn() |
|
506 Check = false |
|
507 GrenadeThrown = false |
|
508 end |
|
509 end |
|
510 end |
|
511 if GrenadeExploded and TargetNumber == BoomTarget then |
|
512 GrenadeTimer = GrenadeTimer + 20 |
|
513 if GrenadeTimer > 1500 then |
|
514 GrenadeTimer = 0 |
|
515 GrenadeThrown = false |
|
516 GrenadeExploded = false |
|
517 if SaucerGear and TargetNumber == BoomTarget and TargetsRemaining > 0 then |
|
518 PlaySound(sndShotgunReload) |
|
519 AddCaption(loc("+1 Grenade"), 0xDDDD00FF, capgrpAmmoinfo) |
|
520 AddAmmo(Player, amGrenade, 1) |
|
521 end |
|
522 end |
|
523 end |
|
524 ResetFuel() |
|
525 end |
|
526 |
|
527 -- Used to ensure infinite fuel |
|
528 function ResetFuel() |
|
529 if SaucerGear and InfFuel then |
|
530 SetHealth(SaucerGear, 2000) |
|
531 end |
|
532 end |
|
533 |
|
534 onUp = ResetFuel |
|
535 onLeft = ResetFuel |
|
536 onRight = ResetFuel |
|
537 |
|
538 function onGearDamage(Gear) |
|
539 if Gear == Player then |
|
540 CleanUpGears() |
|
541 GrenadeThrown = false |
|
542 Check = false |
|
543 end |
|
544 end |
|
545 |
|
546 function onGearResurrect(Gear) |
|
547 if Gear == Player then |
|
548 AddCaption(loc("Oh no! You have died. Try again!"), 0xFFFFFFFF, capgrpMessage2) |
|
549 ResetCurrentTarget() |
|
550 end |
|
551 end |
|
552 |
|
553 function onHogAttack(ammoType) |
|
554 if ammoType == amSkip then |
|
555 AddCaption(loc("Try again!"), 0xFFFFFFFF, capgrpMessage2) |
|
556 ResetCurrentTarget() |
|
557 end |
|
558 end |