1------------------- ABOUT ----------------------
2--
3-- Hero has get into an Red Strawberries ambush
4-- He has to eliminate the enemies by using limited
5-- ammo of sniper rifle and watermelon
6
7HedgewarsScriptLoad("/Scripts/Locale.lua")
8HedgewarsScriptLoad("/Scripts/Animate.lua")
9HedgewarsScriptLoad("/Missions/Campaign/A_Space_Adventure/global_functions.lua")
10
11----------------- VARIABLES --------------------
12-- globals
13local missionName = loc("Precise shooting")
14local timeLeft = 0
15local lastWeaponUsed = amNothing
16local firstTurn = true
17local battleStarted = false
18local challengeObjectives = loc("Use your available weapons in order to eliminate the enemies.").."|"..
19	loc("You can only use the sniper rifle or the watermelon bomb.").."|"..
20	loc("You'll have only 2 watermelon bombs during the game.").."|"..
21	loc("You'll get an extra sniper rifle every time you kill an enemy hog with a limit of max 4 rifles.").."|"..
22	loc("You'll get an extra teleport every time you kill an enemy hog with a limit of max 2 teleports.").."|"..
23	loc("The first turn will last 25 sec and every other turn 15 sec.").."|"..
24	loc("If you skip a turn then the turn time left will be added to your next turn.").."|"..
25	loc("Some parts of the land are indestructible.")
26-- dialogs
27local dialog01 = {}
28-- mission objectives
29local goals = {
30	["init"] = {missionName, loc("Challenge objectives"), challengeObjectives, 1, 35000},
31}
32-- hogs
33local hero = {
34	name = loc("Hog Solo"),
35	x = 1100,
36	y = 560
37}
38local heroTurns = 0
39local enemiesOdd = {
40	{name = loc("Hog 1"), x = 2000 , y = 175},
41	{name = loc("Hog III"), x = 1950 , y = 1110},
42	{name = loc("Hog 100"), x = 1270 , y = 1480},
43	{name = loc("Hog Saturn"), x = 240 , y = 790},
44	{name = loc("Hog nueve"), x = 620 , y = 1950},
45	{name = loc("Hog onze"), x = 720 , y = 1950},
46	{name = loc("Hog dertien"), x = 1620 , y = 1950},
47	{name = loc("Hog 3x5"), x = 1720 , y = 1950},
48}
49local enemiesEven = {
50	{name = loc("Hog two"), x = 660, y = 140},
51	{name = loc("Hog D"), x = 1120, y = 1250},
52	{name = loc("Hog exi"), x = 1290, y = 1250},
53	{name = loc("Hog octo"), x = 820, y = 1950},
54	{name = loc("Hog decar"), x = 920, y = 1950},
55	{name = loc("Hog Hephaestus"), x = 1820, y = 1950},
56	{name = loc("Hog 7+7"), x = 1920, y = 1950},
57	{name = loc("Hog EOF"), x = 1200, y = 560},
58}
59-- teams
60local teamA = {
61	name = loc("Hog Solo"),
62	color = -6
63}
64local teamB = {
65	-- Red Strawberries 1
66	name = loc("RS1"),
67	color = -1
68}
69local teamC = {
70	-- Red Strawberries 2
71	name = loc("RS2"),
72	color = -1
73}
74
75-------------- LuaAPI EVENT HANDLERS ------------------
76
77function onGameInit()
78	GameFlags = gfDisableWind + gfInfAttack
79	Seed = 1
80	TurnTime = 15000
81	CaseFreq = 0
82	MinesNum = 0
83	MinesTime = 1
84	Explosives = 0
85	Map = "fruit03_map"
86	Theme = "Fruit"
87	-- Disable Sudden Death
88	WaterRise = 0
89	HealthDecrease = 0
90
91	-- Hero
92	teamA.name = AddMissionTeam(teamA.color)
93	hero.gear = AddMissionHog(100)
94	hero.name = GetHogName(hero.gear)
95	AnimSetGearPosition(hero.gear, hero.x, hero.y)
96	-- enemies
97	local hats = { "Bandit", "fr_apple", "fr_banana", "fr_lemon", "fr_orange",
98					"fr_pumpkin", "Gasmask", "NinjaFull", "NinjaStraight", "NinjaTriangle" }
99	teamC.name = AddTeam(teamC.name, teamC.color, "bp2", "Island", "Default_qau", "cm_bars")
100	for i=1,table.getn(enemiesEven) do
101		enemiesEven[i].gear = AddHog(enemiesEven[i].name, 1, 100, hats[GetRandom(table.getn(hats))+1])
102		AnimSetGearPosition(enemiesEven[i].gear, enemiesEven[i].x, enemiesEven[i].y)
103	end
104	teamB.name = AddTeam(teamB.name, teamB.color, "bp2", "Island", "Default_qau", "cm_bars")
105	for i=1,table.getn(enemiesOdd) do
106		enemiesOdd[i].gear = AddHog(enemiesOdd[i].name, 1, 100, hats[GetRandom(table.getn(hats))+1])
107		AnimSetGearPosition(enemiesOdd[i].gear, enemiesOdd[i].x, enemiesOdd[i].y)
108	end
109
110	initCheckpoint("fruit03")
111
112	AnimInit()
113end
114
115function onGameStart()
116	FollowGear(hero.gear)
117	ShowMission(unpack(goals["init"]))
118
119	AddEvent(onHeroDeath, {hero.gear}, heroDeath, {hero.gear}, 0)
120	AddEvent(onHeroWin, {hero.gear}, heroWin, {hero.gear}, 0)
121
122	--hero ammo
123	AddAmmo(hero.gear, amTeleport, 2)
124	AddAmmo(hero.gear, amSniperRifle, 2)
125	AddAmmo(hero.gear, amWatermelon, 2)
126
127	AddAmmo(hero.gear, amSkip, 100)
128	timeLeft = 0
129
130	--enemies ammo
131	AddAmmo(enemiesOdd[1].gear, amDEagle, 100)
132	AddAmmo(enemiesOdd[1].gear, amSniperRifle, 100)
133	AddAmmo(enemiesOdd[1].gear, amWatermelon, 1)
134	AddAmmo(enemiesOdd[1].gear, amGrenade, 5)
135	AddAmmo(enemiesEven[1].gear, amDEagle, 100)
136	AddAmmo(enemiesEven[1].gear, amSniperRifle, 100)
137	AddAmmo(enemiesEven[1].gear, amWatermelon, 1)
138	AddAmmo(enemiesEven[1].gear, amGrenade, 5)
139
140	turnHogs()
141
142	SendHealthStatsOff()
143end
144
145function onNewTurn()
146	if CurrentHedgehog == hero.gear then
147		if firstTurn then
148			-- Unique game rule in this mission: First turn has more time
149			SetTurnTimeLeft(25000)
150			-- Generous ready time on first turn to give more time to read
151			SetReadyTimeLeft(35000)
152			battleStarted = true
153			firstTurn = false
154		end
155		if lastWeaponUsed == amSkip then
156			SetTurnTimeLeft(TurnTime + timeLeft)
157		end
158		timeLeft = 0
159		heroTurns = heroTurns + 1
160	end
161end
162
163function onGameTick()
164	AnimUnWait()
165	if ShowAnimation() == false then
166		return
167	end
168	ExecuteAfterAnimations()
169	CheckEvents()
170end
171
172function onGameTick20()
173	if CurrentHedgehog == hero.gear and TurnTimeLeft ~= 0 then
174		timeLeft = TurnTimeLeft
175	end
176end
177
178-- Display ammo icon above gear. i = offset (start at 1)
179local function displayAmmoIcon(gear, ammoType, i)
180	if not GetHealth(gear) then
181		return
182	end
183	local x = GetX(gear) + 2
184	local y = GetY(gear) + 32 * i
185	local vgear = AddVisualGear(x, y, vgtAmmo, 0, true)
186	if vgear ~= nil then
187		local vgtFrame = ammoType
188		SetVisualGearValues(vgear,nil,nil,nil,nil,nil,vgtFrame)
189	end
190end
191
192function onGearDelete(gear)
193	if (isEnemyHog(gear) and GetHealth(hero.gear)) then
194		local availableTeleports = GetAmmoCount(hero.gear,amTeleport)
195		local availableSniper = GetAmmoCount(hero.gear,amSniperRifle)
196		local ammolist = ""
197		local tele = false
198		if availableTeleports < 2 then
199			AddAmmo(hero.gear, amTeleport, availableTeleports + 1 )
200			displayAmmoIcon(hero.gear, amTeleport, 1)
201			tele = true
202			ammolist = ammolist .. string.format(loc("%s (+1)"), GetAmmoName(amTeleport))
203		end
204		if availableSniper < 4 then
205			AddAmmo(hero.gear, amSniperRifle, availableSniper + 1 )
206			displayAmmoIcon(hero.gear, amSniperRifle, 2)
207			if tele then
208				ammolist = ammolist .. " • "
209			end
210			ammolist = ammolist .. string.format(loc("%s (+1)"), GetAmmoName(amSniperRifle))
211		end
212		-- Show collected ammo
213		if ammolist ~= "" then
214			PlaySound(sndShotgunReload)
215			AddCaption(ammolist, GetClanColor(GetHogClan(hero.gear)), capgrpAmmoinfo)
216		end
217	end
218end
219
220-- Hide mission panel when player does anything
221function hideMissionOnAction()
222	if battleStarted then
223		HideMission()
224	end
225end
226
227onSlot = hideMissionOnAction
228onSetWeapon = hideMissionOnAction
229onAttack = hideMissionOnAction
230function onHogAttack(ammoType)
231	hideMissionOnAction()
232	if CurrentHedgehog == hero.gear then
233		lastWeaponUsed = ammoType
234	end
235end
236
237-------------- EVENTS ------------------
238
239function onHeroDeath(gear)
240	if not GetHealth(hero.gear) then
241		return true
242	end
243	return false
244end
245
246function onHeroWin(gear)
247	if (not IsHogAlive(hero.gear)) or (not StoppedGear(hero.gear)) then
248		return false
249	end
250	local enemies = enemiesOdd
251	for i=1,table.getn(enemiesEven) do
252		table.insert(enemies, enemiesEven[i])
253	end
254	local allDead = true
255	for i=1,table.getn(enemies) do
256		if GetHealth(enemies[i].gear) then
257			allDead = false
258			break
259		end
260	end
261	return allDead
262end
263
264-------------- ACTIONS ------------------
265
266function heroDeath(gear)
267	SendStat(siGameResult, string.format(loc("%s lost, try again!"), hero.name))
268	SendStat(siCustomAchievement, loc("You have to eliminate all the enemies."))
269	SendStat(siCustomAchievement, loc("Read the challenge objectives from within the mission for more details."))
270	sendSimpleTeamRankings({teamB.name, teamC.name, teamA.name})
271	EndGame()
272end
273
274function heroWin(gear)
275	saveBonus(2, 1)
276	SendStat(siGameResult, loc("Congratulations, you won!"))
277	SendStat(siCustomAchievement, string.format(loc("You completed the mission in %d rounds."), heroTurns))
278	local record = tonumber(GetCampaignVar("FastestPreciseShooting"))
279	if record ~= nil and heroTurns >= record then
280		SendStat(siCustomAchievement, string.format(loc("Your fastest victory so far: %d rounds"), record))
281	end
282	if record == nil or heroTurns < record then
283		SaveCampaignVar("FastestPreciseShooting", tostring(heroTurns))
284		if record ~= nil then
285			SendStat(siCustomAchievement, loc("This is a new personal best, congratulations!"))
286		end
287	end
288	SendStat(siCustomAchievement, loc("You will gain some extra ammo from the crates the next time you play the \"Getting to the device\" mission."))
289	sendSimpleTeamRankings({teamA.name, teamB.name, teamC.name})
290	SaveCampaignVar("Mission10Won", "true")
291	checkAllMissionsCompleted()
292	EndGame()
293end
294
295------------------ Other Functions -------------------
296
297function turnHogs()
298	if GetHealth(hero.gear) then
299		for i=1,table.getn(enemiesEven) do
300			if GetHealth(enemiesEven[i].gear) then
301				if GetX(enemiesEven[i].gear) < GetX(hero.gear) then
302					HogTurnLeft(enemiesEven[i].gear, false)
303				elseif GetX(enemiesEven[i].gear) > GetX(hero.gear) then
304					HogTurnLeft(enemiesEven[i].gear, true)
305				end
306			end
307		end
308		for i=1,table.getn(enemiesOdd) do
309			if GetHealth(enemiesOdd[i].gear) then
310				if GetX(enemiesOdd[i].gear) < GetX(hero.gear) then
311					HogTurnLeft(enemiesOdd[i].gear, false)
312				elseif GetX(enemiesOdd[i].gear) > GetX(hero.gear) then
313					HogTurnLeft(enemiesOdd[i].gear, true)
314				end
315			end
316		end
317	end
318end
319
320function isEnemyHog(gear)
321	for i=1, table.getn(enemiesOdd) do
322		if gear == enemiesOdd[i].gear then
323			return true
324		end
325	end
326	for i=1, table.getn(enemiesEven) do
327		if gear == enemiesEven then
328			return true
329		end
330	end
331	return false
332end
333