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