Binary file share/hedgewars/Data/Graphics/Missions/Training/Target_Practice_-_Bazooka_easy@2x.png has changed
Binary file share/hedgewars/Data/Graphics/Missions/Training/Target_Practice_-_Bazooka_hard@2x.png has changed
Binary file share/hedgewars/Data/Graphics/Missions/Training/Target_Practice_-_Cluster_Bomb@2x.png has changed
Binary file share/hedgewars/Data/Graphics/Missions/Training/Target_Practice_-_Grenade_easy@2x.png has changed
Binary file share/hedgewars/Data/Graphics/Missions/Training/Target_Practice_-_Grenade_hard@2x.png has changed
Binary file share/hedgewars/Data/Graphics/Missions/Training/Target_Practice_-_Homing_Bee@2x.png has changed
Binary file share/hedgewars/Data/Graphics/Missions/Training/Target_Practice_-_Shotgun@2x.png has changed
--- a/share/hedgewars/Data/Locale/missions_en.txt Thu Dec 11 20:38:03 2014 +0900
+++ b/share/hedgewars/Data/Locale/missions_en.txt Thu Dec 11 21:00:42 2014 +0900
@@ -1,53 +1,74 @@
-Basic_Training_-_Bazooka.name=Basic Bazooka Training
-Basic_Training_-_Bazooka.desc="Using the wind to your advantage is key!"
-
-Basic_Training_-_Grenade.name=Basic Grenade Training
-Basic_Training_-_Grenade.desc="Remember, you pull the pin out AND throw!"
-
-Basic_Training_-_Cluster_Bomb.name=Basic Cluster Bomb Training
-Basic_Training_-_Cluster_Bomb.desc="Someone needs hot shower!"
-
-Basic_Training_-_Shotgun.name=Basic Shotgun Training
-Basic_Training_-_Shotgun.desc="Shoot first, ask questions later!"
-
-Basic_Training_-_Sniper_Rifle.name=Basic Sniper Rifle Training
-Basic_Training_-_Sniper_Rifle.desc="Boom, headshot!"
-
-Basic_Training_-_Rope.name=Basic Rope Training
-Basic_Training_-_Rope.desc="Get out there and swing!"
-
-User_Mission_-_Dangerous_Ducklings.name=Mission: Dangerous Ducklings
-User_Mission_-_Dangerous_Ducklings.desc="Alright, rookie! Time to put what we learned in Basic Training into practice!"
-
-User_Mission_-_Diver.name=Mission: Diver
-User_Mission_-_Diver.desc="This 'amphibious assault' thing is harder than it looks..."
-
-User_Mission_-_Teamwork.name=Mission: Teamwork
-User_Mission_-_Teamwork.desc="Sometimes, love hurts."
-
-User_Mission_-_Spooky_Tree.name=Mission: Spooky Tree
-User_Mission_-_Spooky_Tree.desc="Lots of crates out here. I sure hope that bird ain't feeling hungry."
-
-User_Mission_-_Bamboo_Thicket.name=Mission: Bamboo Thicket
-User_Mission_-_Bamboo_Thicket.desc="Death comes from above."
-
-User_Mission_-_That_Sinking_Feeling.name=Mission: That Sinking Feeling
-User_Mission_-_That_Sinking_Feeling.desc="The water is rising rapidly and time is limited. Many have tried and failed. Can you save them all?"
-
-User_Mission_-_Newton_and_the_Hammock.name=Mission: Newton and the Hammock
-User_Mission_-_Newton_and_the_Hammock.desc="Remember hoglets: The velocity of a body remains constant unless the body is acted upon by an external force!"
-
-User_Mission_-_The_Great_Escape.name=Mission: The Great Escape
-User_Mission_-_The_Great_Escape.desc="You think you can cage me!?"
-
-User_Mission_-_Rope_Knock_Challenge.name=Challenge: Rope Knocking
-User_Mission_-_Rope_Knock_Challenge.desc="Look behind you!"
-
-User_Mission_-_Nobody_Laugh.name=Mission: Nobody Laugh
-User_Mission_-_Nobody_Laugh.desc="This ain't no joke."
-
-User_Mission_-_RCPlane_Challenge.name=Challenge: RC Plane
-User_Mission_-_RCPlane_Challenge.desc="Feeling pretty confident, eh, flyboy?"
-
-portal.name=Mission: Portal Mind Challenge
-portal.desc="Use the portal to move fast and far, use it to kill, use it with caution!"
+Basic_Training_-_Bazooka.name=Basic Bazooka Training
+Basic_Training_-_Bazooka.desc="Using the wind to your advantage is key!"
+
+Basic_Training_-_Grenade.name=Basic Grenade Training
+Basic_Training_-_Grenade.desc="Remember, you pull the pin out AND throw!"
+
+Basic_Training_-_Cluster_Bomb.name=Basic Cluster Bomb Training
+Basic_Training_-_Cluster_Bomb.desc="Someone needs hot shower!"
+
+Basic_Training_-_Shotgun.name=Basic Shotgun Training
+Basic_Training_-_Shotgun.desc="Shoot first, ask questions later!"
+
+Basic_Training_-_Sniper_Rifle.name=Basic Sniper Rifle Training
+Basic_Training_-_Sniper_Rifle.desc="Boom, headshot!"
+
+Basic_Training_-_Rope.name=Basic Rope Training
+Basic_Training_-_Rope.desc="Get out there and swing!"
+
+User_Mission_-_Dangerous_Ducklings.name=Mission: Dangerous Ducklings
+User_Mission_-_Dangerous_Ducklings.desc="Alright, rookie! Time to put what we learned in Basic Training into practice!"
+
+User_Mission_-_Diver.name=Mission: Diver
+User_Mission_-_Diver.desc="This 'amphibious assault' thing is harder than it looks..."
+
+User_Mission_-_Teamwork.name=Mission: Teamwork
+User_Mission_-_Teamwork.desc="Sometimes, love hurts."
+
+User_Mission_-_Spooky_Tree.name=Mission: Spooky Tree
+User_Mission_-_Spooky_Tree.desc="Lots of crates out here. I sure hope that bird ain't feeling hungry."
+
+User_Mission_-_Bamboo_Thicket.name=Mission: Bamboo Thicket
+User_Mission_-_Bamboo_Thicket.desc="Death comes from above."
+
+User_Mission_-_That_Sinking_Feeling.name=Mission: That Sinking Feeling
+User_Mission_-_That_Sinking_Feeling.desc="The water is rising rapidly and time is limited. Many have tried and failed. Can you save them all?"
+
+User_Mission_-_Newton_and_the_Hammock.name=Mission: Newton and the Hammock
+User_Mission_-_Newton_and_the_Hammock.desc="Remember hoglets: The velocity of a body remains constant unless the body is acted upon by an external force!"
+
+User_Mission_-_The_Great_Escape.name=Mission: The Great Escape
+User_Mission_-_The_Great_Escape.desc="You think you can cage me!?"
+
+User_Mission_-_Rope_Knock_Challenge.name=Challenge: Rope Knocking
+User_Mission_-_Rope_Knock_Challenge.desc="Look behind you!"
+
+User_Mission_-_Nobody_Laugh.name=Mission: Nobody Laugh
+User_Mission_-_Nobody_Laugh.desc="This ain't no joke."
+
+User_Mission_-_RCPlane_Challenge.name=Challenge: RC Plane
+User_Mission_-_RCPlane_Challenge.desc="Feeling pretty confident, eh, flyboy?"
+
+portal.name=Mission: Portal Mind Challenge
+portal.desc="Use the portal to move fast and far, use it to kill, use it with caution!"
+
+Target_Practice_-_Bazooka_easy.name=Target Practice: Bazooka (easy)
+Target_Practice_-_Bazooka_easy.desc="Alright, soldier, blow those targets up as fast as you can!"
+
+Target_Practice_-_Bazooka_hard.name=Target Practice: Bazooka (hard)
+Target_Practice_-_Bazooka_hard.desc="Can you hit the targets even when they are very far away?"
+
+Target_Practice_-_Cluster_Bomb.name=Target Practice: Cluster Bomb
+Target_Practice_-_Cluster_Bomb.desc="Someone needs hot shower!"
+
+Target_Practice_-_Shotgun.name=Target Practice: Shotgun
+Target_Practice_-_Shotgun.desc="Shoot first, ask questions later!"
+
+Target_Practice_-_Homing_Bee.name=Target Practice: Homing Bee
+Target_Practice_-_Homing_Bee.desc="Using the homing bee is trickier than it seems."
+
+Target_Practice_-_Grenade_easy.name=Target Practice: Grenade (easy)
+Target_Practice_-_Grenade_easy.desc="A warm-up training for the aspiring grenadier."
+
+Target_Practice_-_Grenade_hard.name=Target Practice: Grenade (hard)
+Target_Practice_-_Grenade_hard.desc="This is nothing for greenhorns! We will place the targets at some really tricky positions."
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Training/Target_Practice_-_Bazooka_easy.lua Thu Dec 11 21:00:42 2014 +0900
@@ -0,0 +1,35 @@
+HedgewarsScriptLoad("/Scripts/TargetPractice.lua")
+
+local params = {
+ ammoType = amBazooka,
+ gearType = gtShell,
+ missionTitle = "Target Practice: Bazooka (easy)",
+ wind = 50,
+ solidLand = true,
+ map = "Lonely_Island",
+ theme = "Island",
+ hog_x = 1439,
+ hog_y = 482,
+ hogName = loc("Zook"),
+ hogHat = "war_americanww2helmet",
+ teamName = loc("Team Zook"),
+ targets = {
+ { x = 1310, y = 756 },
+ { x = 1281, y = 893 },
+ { x = 1376, y = 670 },
+ { x = 1725, y = 907 },
+ { x = 1971, y = 914 },
+ { x = 1098, y = 955 },
+ { x = 1009, y = 877 },
+ { x = 930, y = 711 },
+ { x = 771, y = 744 },
+ { x = 385, y = 405 },
+ { x = 442, y = 780 },
+ { x = 620, y = 639 },
+ { x = 311, y = 239 },
+ },
+ time = 80000,
+ shootText = loc("You have launched %d bazookas."),
+}
+
+TargetPracticeMission(params)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Training/Target_Practice_-_Bazooka_hard.lua Thu Dec 11 21:00:42 2014 +0900
@@ -0,0 +1,40 @@
+HedgewarsScriptLoad("/Scripts/TargetPractice.lua")
+
+local params = {
+ ammoType = amBazooka,
+ gearType = gtShell,
+ missionTitle = "Target Practice: Bazooka (hard)",
+ wind = 20,
+ solidLand = true,
+ artillery = true,
+ map = "SB_Grassy",
+ theme = "Castle",
+ hog_x = 2112,
+ hog_y = 913,
+ hogName = loc("Zook"),
+ hogHat = "war_americanww2helmet",
+ teamName = loc("Team Zook"),
+ targets = {
+ { x = 2660, y = 936 },
+ { x = 2857, y = 629 },
+ { x = 3044, y = 851 },
+ { x = 3200, y = 441 },
+ { x = 2931, y = 440 },
+ { x = 3264, y = 370 },
+ { x = 1880, y = 684 },
+ { x = 1392, y = 672 },
+ { x = 1587, y = 656 },
+ { x = 1300, y = 840 },
+ { x = 952, y = 814 },
+ { x = 862, y = 634 },
+ { x = 748, y = 794 },
+ { x = 639, y = 548 },
+ { x = 1730, y = 549 },
+ { x = 1466, y = 566 },
+ { x = 3716, y = 954 },
+ },
+ time = 180000,
+ shootText = loc("You have launched %d bazookas."),
+}
+
+TargetPracticeMission(params)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Training/Target_Practice_-_Cluster_Bomb.lua Thu Dec 11 21:00:42 2014 +0900
@@ -0,0 +1,33 @@
+HedgewarsScriptLoad("/Scripts/TargetPractice.lua")
+
+local params = {
+ ammoType = amClusterBomb,
+ gearType = gtClusterBomb,
+ missionTitle = "Cluster Bomb Training",
+ solidLand = false,
+ map = "Trash",
+ theme = "Golf",
+ hog_x = 756,
+ hog_y = 370,
+ hogName = loc("Private Nolak"),
+ hogHat = "war_desertgrenadier1",
+ teamName = loc("The Hogies"),
+ targets = {
+ { x = 628, y = 0 },
+ { x = 891, y = 0 },
+ { x = 1309, y = 0 },
+ { x = 1128, y = 0 },
+ { x = 410, y = 0 },
+ { x = 1564, y = 0 },
+ { x = 1248, y = 476 },
+ { x = 169, y = 0 },
+ { x = 1720, y = 0 },
+ { x = 1441, y = 0 },
+ { x = 599, y = 0 },
+ { x = 1638, y = 0 },
+ },
+ time = 180000,
+ shootText = loc("You have thrown %d cluster bombs."),
+}
+
+TargetPracticeMission(params)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Training/Target_Practice_-_Grenade_easy.lua Thu Dec 11 21:00:42 2014 +0900
@@ -0,0 +1,30 @@
+HedgewarsScriptLoad("/Scripts/TargetPractice.lua")
+
+local params = {
+ ammoType = amGrenade,
+ gearType = gtGrenade,
+ missionTitle = "Target Practice: Grenade (easy)",
+ solidLand = true,
+ artillery = true,
+ map = "SB_Crystal",
+ theme = "Cave",
+ hog_x = 2039,
+ hog_y = 684,
+ hogName = loc("Grenadier"),
+ hogHat = "war_desertgrenadier2",
+ teamName = loc("Grenade Group"),
+ targets = {
+ { x = 1834, y = 747 },
+ { x = 2308, y = 729 },
+ { x = 1659, y = 718 },
+ { x = 1196, y = 704 },
+ { x = 2650, y = 826 },
+ { x = 1450, y = 705 },
+ { x = 2774, y = 848 },
+ { x = 2970, y = 704 },
+ },
+ time = 80000,
+ shootText = loc("You have thrown %d grenades."),
+}
+
+TargetPracticeMission(params)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Training/Target_Practice_-_Grenade_hard.lua Thu Dec 11 21:00:42 2014 +0900
@@ -0,0 +1,41 @@
+HedgewarsScriptLoad("/Scripts/TargetPractice.lua")
+
+local params = {
+ ammoType = amGrenade,
+ gearType = gtGrenade,
+ missionTitle = "Target Practice: Grenade (hard)",
+ solidLand = true,
+ artillery = true,
+ map = "SB_Crystal",
+ theme = "Cave",
+ hog_x = 1456,
+ hog_y = 669,
+ hogName = loc("Grenadier"),
+ hogHat = "war_desertgrenadier2",
+ teamName = loc("Grenade Group"),
+ targets = {
+ { x = 1190, y = 694 },
+ { x = 962, y = 680 },
+ { x = 1090, y = 489 },
+ { x = 1664, y = 666 },
+ { x = 1584, y = 580 },
+ { x = 2160, y = 738 },
+ { x = 1836, y = 726 },
+ { x = 618, y = 753 },
+ { x = 837, y = 668 },
+ { x = 2424, y = 405 },
+ { x = 2310, y = 742 },
+ { x = 294, y = 897 },
+ { x = 472, y = 855 },
+ { x = 2949, y = 724},
+ { x = 3356, y = 926 },
+ { x = 3734, y = 918 },
+ { x = 170, y = 874 },
+
+
+ },
+ time = 180000,
+ shootText = loc("You have thrown %d grenades."),
+}
+
+TargetPracticeMission(params)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Training/Target_Practice_-_Homing_Bee.lua Thu Dec 11 21:00:42 2014 +0900
@@ -0,0 +1,35 @@
+HedgewarsScriptLoad("/Scripts/TargetPractice.lua")
+
+local params = {
+ ammoType = amBee,
+ gearType = gtBee,
+ missionTitle = "Target Practice: Homing Bee",
+ solidLand = true,
+ map = "Hedgewars",
+ theme = "Nature",
+ hog_x = 1990,
+ hog_y = 514,
+ hogHat = "NoHat",
+ teamGrave = "bp2",
+ targets = {
+ { x = 1949, y = 273 },
+ { x = 1734, y = 322 },
+ { x = 1574, y = 340 },
+ { x = 1642, y = 474 },
+ { x = 2006, y = 356 },
+ { x = 1104, y = 285 },
+ { x = 565, y = 440 },
+ { x = 732, y = 350 },
+ { x = 2022, y = 396 },
+ { x = 366, y = 360 },
+ { x = 556, y = 300 },
+ { x = 902, y = 306 },
+ { x = 924, y = 411 },
+ { x = 227, y = 510 },
+ { x = 150, y = 300 },
+ },
+ time = 120000,
+ shootText = loc("You have launched %d homing bees."),
+}
+
+TargetPracticeMission(params)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Missions/Training/Target_Practice_-_Shotgun.lua Thu Dec 11 21:00:42 2014 +0900
@@ -0,0 +1,38 @@
+HedgewarsScriptLoad("/Scripts/TargetPractice.lua")
+
+local params = {
+ ammoType = amShotgun,
+ gearType = gtShotgunShot,
+ missionTitle = "Target Practice: Shotgun",
+ solidLand = false,
+ map = "SB_Haunty",
+ theme = "Halloween",
+ hog_x = 320,
+ hog_y = 324,
+ hogHat = "NoHat",
+ hogGrave = "Bones",
+ targets = {
+ { x = 495, y = 501 },
+ { x = 227, y = 530 },
+ { x = 835, y = 934 },
+ { x = 1075, y = 889 },
+ { x = 887, y = 915 },
+ { x = 1148, y = 750 },
+ { x = 916, y = 915 },
+ { x = 1211, y = 700 },
+ { x = 443, y = 505 },
+ { x = 822, y = 964 },
+ { x = 1092, y = 819 },
+ { x = 1301, y = 683 },
+ { x = 1480, y = 661 },
+ { x = 1492, y = 786 },
+ { x = 1605, y = 562 },
+ { x = 1545, y = 466 },
+ { x = 1654, y = 392 },
+ { x = 1580, y = 334 },
+ { x = 1730, y = 222 },
+ },
+ time = 90000,
+}
+
+TargetPracticeMission(params)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Scripts/TargetPractice.lua Thu Dec 11 21:00:42 2014 +0900
@@ -0,0 +1,260 @@
+--[=[
+Target Practice Mission Framework for Hedgewars
+
+This is a simple library intended to make setting up simple training missions a trivial
+task requiring just. The library has been created to reduce redundancy in Lua scripts.
+
+The training framework generates complete and fully usable training missions by just
+one function call.
+
+The missions generated by this script are all the same:
+- The player will get a team with a single hedgehog.
+- The team gets a single predefined weapon infinitely times.
+- A fixed sequence of targets will spawn at predefined positions.
+- When a target has been destroyed, the next target of the target sequence appears
+- The mission ends successfully when all targets have been destroyed
+- The mission ends unsuccessfully when the time runs out or the hedgehog dies
+- When the mission ends, a score is awarded, based on the performance (hit targets,
+ accuracy and remaining time) of the hedgehog. When not all targets are hit, there
+ will be no accuracy and time bonuses.
+
+To use this library, you first have to load it and to call TrainingMission once with
+the appropriate parameters. Really, that’s all!
+See the comment of TrainingMission for a specification of all parameters.
+
+Below is a template for your convenience, you just have to fill in the fields and delete
+optional arguments you don’t want.
+----- snip -----
+HedgewarsScriptLoad("/Scripts/Training.lua")
+params = {
+ missionTitle = ,
+ map = ,
+ theme = ,
+ time = ,
+ ammoType = ,
+ gearType = ,
+ targets = {
+ { x = , y = },
+ { x = , y = },
+ -- etc.
+ },
+
+ wind = ,
+ solidLand = ,
+ artillery = ,
+ hogHat = ,
+ hogName = ,
+ teamName = ,
+ teamGrave = ,
+ clanColor = ,
+ goalText = ,
+ shootText =
+}
+TargetPracticeMission(params)
+----- snip -----
+]=]
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+
+local player = nil
+local scored = 0
+local shots = 0
+local end_timer = 1000
+local game_lost = false
+local time_goal = 0
+local total_targets
+local targets
+
+--[[
+TrainingMission(params)
+
+This function sets up the *entire* training mission and needs one argument: params.
+The argument “params” is a table containing fields which describe the training mission.
+ mandatory fields:
+ - missionTitle: the name of the mission
+ - map: the name map to be used
+ - theme: the name of the theme (does not need to be a standalone theme)
+ - time: the time limit in milliseconds
+ - ammoType: the ammo type of the weapon to be used
+ - gearType: the gear type of the gear which is fired (used to count shots)
+ - targets: The coordinates of where the targets will be spawned.
+ It is a table containing tables containing coordinates of format
+ { x=value, y=value }. The targets will be spawned in the same
+ order as specified the coordinate tables appear. Example:
+ targets = {
+ { x = 324, y = 43 },
+ { x = 123, y = 56 },
+ { x = 6, y = 0 },
+ }
+ There must be at least 1 target.
+
+ optional fields:
+ - wind: the initial wind (-100 to 100) (default: 0 (no wind))
+ - solidLand: weather the terrain is indestructible (default: false)
+ - artillery: if true, the hog can’t move (default: false)
+ - hogHat: hat of the hedgehog (default: "NoHat")
+ - hogName: name of the hedgehog (default: "Trainee")
+ - teamName: name of the hedgehog’s team (default: "Training Team")
+ - teamGrave: name of the hedgehog’s grave
+ - clanColor: color of the (only) clan (default: 0xFF0204, which is a red tone)
+ - goalText: A short string explaining the goal of the mission
+ (default: "Destroy all targets within the time!")
+ - shootText: A string which says how many times the player shot, “%d” is replaced
+ by the number of shots. (default: "You have shot %d times.")
+]]
+function TargetPracticeMission(params)
+ if params.hogHat == nil then params.hogHat = "NoHat" end
+ if params.hogName == nil then params.hogName = loc("Trainee") end
+ if params.teamName == nil then params.teamName = loc("Training Team") end
+ if params.goalText == nil then params.goalText = loc("Eliminate all targets before your time runs out.|You have unlimited ammo for this mission.") end
+ if params.shootText == nil then params.shootText = loc("You have shot %d times.") end
+ if params.clanColor == nil then params.clanColor = 0xFF0204 end
+ if params.teamGrave == nil then params.teamGrave= "Statue" end
+ if params.wind == nil then params.wind = 0 end
+
+ local solid, artillery
+ if params.solidLand == true then solid = gfSolidLand else solid = 0 end
+ if params.artillery == true then artillery = gfArtillery else artillery = 0 end
+
+ targets = params.targets
+
+ total_targets = #targets
+
+ _G.onAmmoStoreInit = function()
+ SetAmmo(params.ammoType, 9, 0, 0, 0)
+ end
+
+ _G.onGameInit = function()
+ Seed = 1
+ GameFlags = gfDisableWind + gfInfAttack + gfOneClanMode + solid + artillery
+ TurnTime = params.time
+ Map = params.map
+ Theme = params.theme
+ Goals = params.goalText
+ CaseFreq = 0
+ MinesNum = 0
+ Explosives = 0
+
+ SetWind(params.wind)
+
+ AddTeam(loc(params.teamName), params.clanColor, params.teamGrave, "Island", "Default", "Flowerhog")
+
+ player = AddHog(loc(params.hogName), 0, 1, params.hogHat)
+ SetGearPosition(player, params.hog_x, params.hog_y)
+ end
+
+ _G.onGameStart = function()
+ SendHealthStatsOff()
+ ShowMission(params.missionTitle, loc("Aiming practice"), params.goalText, -params.ammoType, 5000)
+ spawnTarget()
+ end
+
+ _G.onNewTurn = function()
+ -- TODO: Remove the else branch when 0.9.21 has been released
+ if SetWeapon ~= nil then
+ SetWeapon(params.ammoType)
+ else
+ ParseCommand("/setweap "..string.char(params.ammoType))
+ end
+ end
+
+ _G.spawnTarget = function()
+ gear = AddGear(0, 0, gtTarget, 0, 0, 0, 0)
+
+ x = targets[scored+1].x
+ y = targets[scored+1].y
+
+ SetGearPosition(gear, x, y)
+ end
+
+ _G.onGameTick20 = function()
+ if TurnTimeLeft < 40 and TurnTimeLeft > 0 and scored < total_targets and game_lost == false then
+ game_lost = true
+ AddCaption(loc("Time’s up!"), 0xFFFFFFFF, capgrpGameState)
+ ShowMission(params.missionTitle, loc("Aiming practice"), loc("Oh no! Time's up! Just try again."), -amSkip, 0)
+ SetHealth(player, 0)
+ time_goal = 1
+ end
+
+ if band(GetState(player), gstDrowning) == gstDrowning and game_lost == false and scored < total_targets then
+ game_lost = true
+ time_goal = 1
+ AddCaption(loc("You lose!"), 0xFFFFFFFF, capgrpGameState)
+ ShowMission(params.missionTitle, loc("Aiming practice"), loc("Oh no! You failed! Just try again."), -amSkip, 0)
+ end
+
+ if scored == total_targets or game_lost then
+ if end_timer == 0 then
+ generateStats()
+ EndGame()
+ else
+ TurnTimeLeft = time_goal
+ end
+ end_timer = end_timer - 20
+ end
+ end
+
+ _G.onGearAdd = function(gear)
+ if GetGearType(gear) == params.gearType then
+ shots = shots + 1
+ end
+ end
+
+ _G.onGearDamage = function(gear, damage)
+ if GetGearType(gear) == gtTarget then
+ scored = scored + 1
+ if scored < total_targets then
+ AddCaption(string.format(loc("Targets left: %d"), (total_targets-scored)), 0xFFFFFFFF, capgrpMessage)
+ spawnTarget()
+ else
+ if not game_lost then
+ AddCaption(loc("You have destroyed all targets!"), 0xFFFFFFFF, capgrpGameState)
+ ShowMission(params.missionTitle, loc("Aiming practice"), loc("Congratulations! You have destroyed all targets within the time."), 0, 0)
+ PlaySound(sndVictory, player)
+ SetState(player, bor(GetState(player), gstWinner))
+ time_goal = TurnTimeLeft
+ end
+ end
+ end
+
+ if GetGearType(gear) == gtHedgehog then
+ if not game_lost then
+ game_lost = true
+ AddCaption(loc("You lose!", 0xFFFFFFFF, capgrpGameState))
+ ShowMission(params.missionTitle, loc("Aiming practice"), loc("Oh no! You failed! Just try again."), -amSkip, 0)
+
+ SetHealth(player, 0)
+ time_goal = 1
+ end
+ end
+ end
+
+ _G.generateStats = function()
+ local accuracy = (scored/shots)*100
+ local end_score_targets = scored * math.ceil(6000/#targets)
+ local end_score_overall
+ if not game_lost then
+ local end_score_time = math.ceil(time_goal/(params.time/6000))
+ local end_score_accuracy = math.ceil(accuracy * 60)
+ end_score_overall = end_score_time + end_score_targets + end_score_accuracy
+
+ SendStat(siGameResult, loc("You have finished the target practice!"))
+
+ SendStat(siCustomAchievement, string.format(loc("You have destroyed %d of %d targets (+%d points)."), scored, total_targets, end_score_targets))
+ SendStat(siCustomAchievement, string.format(params.shootText, shots))
+ SendStat(siCustomAchievement, string.format(loc("Your accuracy was %.1f%% (+%d points)."), accuracy, end_score_accuracy))
+ SendStat(siCustomAchievement, string.format(loc("You had %.1fs remaining on the clock (+%d points)."), (time_goal/1000), end_score_time))
+ else
+ SendStat(siGameResult, loc("You lose!"))
+
+ SendStat(siCustomAchievement, string.format(loc("You have destroyed %d of %d targets (+%d points)."), scored, total_targets, end_score_targets))
+ SendStat(siCustomAchievement, string.format(params.shootText, shots))
+ if(shots > 0) then
+ SendStat(siCustomAchievement, string.format(loc("Your accuracy was %.1f%%."), accuracy))
+ end
+ end_score_overall = end_score_targets
+ end
+ SendStat(siPlayerKills, tostring(end_score_overall), loc(params.teamName))
+ SendStat(siPointType, loc("points"))
+ end
+end