share/hedgewars/Data/Missions/Training/Basic_Training_-_Grenade.lua
changeset 13075 730db0a3eb43
parent 12224 d62d6f8ebef1
child 13165 89a6b862e692
equal deleted inserted replaced
13074:e69cb8d5512c 13075:730db0a3eb43
     1 -- Hedgewars Grenade Training
     1 --[[
     2 -- Scripting Example
     2 	Basic Grenade Training
     3 
     3 
     4 -- Lines such as this one are comments - they are ignored
     4 	This training mission teaches players how to use the grenade.
     5 -- by the game, no matter what kind of text is in there.
     5 	Lesson plan:
     6 -- It's also possible to place a comment after some real
     6 	- Selecting grenade
     7 -- instruction as you see below. In short, everything
     7 	- Aiming and shooting
     8 -- following "--" is ignored.
     8 	- Timer
     9 
     9 	- No wind
    10 ---------------------------------------------------------------
    10 	- Bounciness
    11 -- At first we implement the localization library using loadfile.
    11 ]]
    12 -- This allows us to localize strings without needing to think
       
    13 -- about translations.
       
    14 -- We can use the function loc(text) to localize a string.
       
    15 
    12 
    16 HedgewarsScriptLoad("/Scripts/Locale.lua")
    13 HedgewarsScriptLoad("/Scripts/Locale.lua")
    17 
    14 
    18 -- This variable will hold the number of destroyed targets.
    15 local hog			-- Hog gear
    19 local score = 0
    16 local weaponSelected = false	-- Player has selected the weapon
    20 -- This variable represents the number of targets to destroy.
    17 local gamePhase = 0		-- Used to track progress
    21 local score_goal = 5
    18 local targetsLeft = 0		-- # of targets left in this round
    22 -- This variable controls how many milliseconds/ticks we'd
    19 local targetGears = {}		-- list of target gears
    23 -- like to wait before we end the round once all targets
    20 local gameOver = false		-- If true, game has ended
    24 -- have been destroyed.
    21 local shotsFired = 0		-- Total # of grenades fired
    25 local end_timer = 4000 -- 5000 ms = 5 s
    22 local maxTargets = 0		-- Target counter, used together with flawless
    26 -- This variable is set to true if the game is lost (i.e.
    23 local flawless = true		-- track flawless victory (100% accuracy, no hurt, no death)
    27 -- time runs out).
    24 local missedTauntTimer = -1	-- Wait timer for playing sndMissed. -1 = no-op
    28 local game_lost = false
    25 
    29 -- This variable ensures that the death function isn't called
       
    30 -- repeatedly when game is over.
       
    31 local team_death = false
       
    32 -- This variable will point to the hog's gear
       
    33 local player = nil
       
    34 -- This variable will grab the time left at the end of the round
       
    35 local time_goal = 0
       
    36 
       
    37 -- This is a custom function to make it easier to
       
    38 -- spawn more targets with just one line of code
       
    39 -- You may define as many custom functions as you
       
    40 -- like.
       
    41 function spawnTarget()
       
    42 	-- add a new target gear
       
    43 	gear = AddGear(0, 0, gtTarget, 0, 0, 0, 0)
       
    44 	
       
    45 	-- move it to a random position within 0 and
       
    46 	-- LAND_WIDTH - the width of the map
       
    47 	FindPlace(gear, true, 0, LAND_WIDTH-326)
       
    48 	
       
    49 	-- move the target to a higher vertical position
       
    50 	-- to ensure it's not somewhere down below
       
    51 	x, y = GetGearPosition(gear)
       
    52 	SetGearPosition(gear, x, 0)
       
    53 end
       
    54 
       
    55 -- This function is called before the game loads its
       
    56 -- resources.
       
    57 -- It's one of the predefined function names that will
       
    58 -- be called by the game. They give you entry points
       
    59 -- where you're able to call your own code using either
       
    60 -- provided instructions or custom functions.
       
    61 function onGameInit()
    26 function onGameInit()
    62 	-- At first we have to overwrite/set some global variables
    27 
    63 	-- that define the map, the game has to load, as well as
    28 	ClearGameFlags()
    64 	-- other things such as the game rules to use, etc.
    29 	EnableGameFlags(gfDisableWind, gfOneClanMode, gfInfAttack, gfSolidLand, gfArtillery)
    65 	-- Things we don't modify here will use their default values.
    30 	Map = "Mushrooms"
    66 
    31 	Seed = 0
    67 	-- The base number for the random number generator
    32 	Theme = "Nature"
    68 	Seed = 1
    33 	TurnTime = 9999000
    69 	-- Game settings and rules
    34 	Explosives = 0
    70 	GameFlags = gfInfAttack + gfOneClanMode 
    35 	MinesNum = 0
    71 	-- The time the player has to move each round (in ms)
       
    72 	TurnTime = 60000
       
    73 	-- The frequency of crate drops
       
    74 	CaseFreq = 0
    36 	CaseFreq = 0
    75 	-- The number of mines being placed
    37 	WaterRise = 0
    76 	MinesNum = 0
    38 	HealthDecrease = 0
    77 	-- The number of explosives being placed
    39 
    78 	Explosives = 0
    40 	------ TEAM LIST ------
    79 	-- The delay between each round
    41 
    80 	Delay = 1
    42 	AddTeam(loc("Grenade Team"), 0xFF0204, "Flower", "Earth", "Default", "cm_grenade")
    81 	-- The map to be played
    43 	hog = AddHog(loc("Greenhorn"), 0, 1, "NoHat")
    82 	Map = "Battlefield"
    44 	SetGearPosition(hog, 570, 157)
    83 	-- The theme to be used
    45 	SetEffect(hog, heResurrectable, 1)
    84 	Theme = "Castle"
    46 
    85 	-- Setting these 2 values to 0 is the official way to disable Sudden Death cleanly
    47 	SendHealthStatsOff()
    86 	HealthDecrease = 0	-- Sudden Death damage
    48 end
    87 	WaterRise = 0		-- Water rise in Sudden Death
    49 
    88 
    50 function onGearResurrect(gear)
    89 	-- Create the player team
    51 	if gear == hog then
    90 	AddTeam(loc("Grenadiers"), 14483456, "Simple", "Island", "Default", "cm_grenade")
    52 		flawless = false
    91 	-- And add a hog to it
    53 		SetGearPosition(hog, 570, 157)
    92 	player = AddHog(loc("Nade Boy"), 0, 1, "war_grenadier1")
    54 		AddCaption(loc("Your hedgehog has been revived!"))
    93 	SetGearPosition(player, 506, 76)
    55 	end
    94 end
    56 end
    95 
    57 
    96 -- This function is called when the round starts
    58 local function placeGirders()
    97 -- it spawns the first target that has to be destroyed.
    59 	PlaceGirder(918, 248, 1)
    98 -- In addition it shows the scenario goal(s).
    60 	PlaceGirder(888, 129, 6)
       
    61 	PlaceGirder(844, 35, 1)
       
    62 	PlaceGirder(932, 37, 3)
       
    63 	PlaceGirder(926, 148, 6)
       
    64 	PlaceGirder(73, 812, 5)
       
    65 	PlaceGirder(189, 930, 5)
       
    66 	PlaceGirder(15, 669, 6)
       
    67 	PlaceGirder(15, 507, 6)
       
    68 	PlaceGirder(15, 344, 6)
       
    69 	PlaceGirder(62, 27, 0)
       
    70 	PlaceGirder(229, 115, 0)
       
    71 	PlaceGirder(1195, 250, 7)
       
    72 	PlaceGirder(1285, 205, 1)
       
    73 	PlaceGirder(1358, 201, 3)
       
    74 	PlaceGirder(1756, 415, 6)
       
    75 	PlaceGirder(1893, 95, 6)
       
    76 	PlaceGirder(1005, 333, 5)
       
    77 	PlaceGirder(1860, 187, 0)
       
    78 end
       
    79 
       
    80 local function spawnTargets()
       
    81 	-- Warm-up
       
    82 	if gamePhase == 0 then
       
    83 		AddGear(233, 97, gtTarget, 0, 0, 0, 0)
       
    84 		AddGear(333, 255, gtTarget, 0, 0, 0, 0)
       
    85 		AddGear(753, 225, gtTarget, 0, 0, 0, 0)
       
    86 	-- No Wind
       
    87 	elseif gamePhase == 2 then
       
    88 		AddGear(61, 9, gtTarget, 0, 0, 0, 0)
       
    89 		AddGear(882, 39, gtTarget, 0, 0, 0, 0)
       
    90 		AddGear(945, 498, gtTarget, 0, 0, 0, 0)
       
    91 	-- Bounciness
       
    92 	elseif gamePhase == 3 then
       
    93 		AddGear(323, 960, gtTarget, 0, 0, 0, 0)
       
    94 		AddGear(1318, 208, gtTarget, 0, 0, 0, 0)
       
    95 		AddGear(1697, 250, gtTarget, 0, 0, 0, 0)
       
    96 		AddGear(1852, 100, gtTarget, 0, 0, 0, 0)
       
    97 	-- Grand Final
       
    98 	elseif gamePhase == 4 then
       
    99 		AddGear(186, 473, gtTarget, 0, 0, 0, 0)
       
   100 		AddGear(950, 250, gtTarget, 0, 0, 0, 0)
       
   101 		AddGear(1102, 345, gtTarget, 0, 0, 0, 0)
       
   102 		AddGear(1556, 297, gtTarget, 0, 0, 0, 0)
       
   103 	end
       
   104 end
       
   105 
    99 function onGameStart()
   106 function onGameStart()
   100 	-- Spawn the first target.
   107 	placeGirders()
   101 	spawnTarget()
   108 	spawnTargets()
   102 	
   109 	ShowMission(loc("Basic Grenade Training"), loc("Basic Training"), loc("Destroy all the targets!"), -amGrenade, 0)
   103 	-- Show some nice mission goals.
   110 end
   104 	-- Parameters are: caption, sub caption, description,
   111 
   105 	-- extra text, icon and time to show.
   112 function newGamePhase()
   106 	-- A negative icon parameter (-n) represents the n-th weapon icon
   113 	-- Spawn targets, update wind and ammo, show instructions
   107 	-- A positive icon paramter (n) represents the (n+1)-th mission icon
   114 	if gamePhase == 0 then
   108 	-- A timeframe of 0 is replaced with the default time to show.
   115 		ShowMission(loc("Basic Grenade Training"), loc("Select Weapon"), loc("To begin with the training, select the grenade from the ammo menu!").."|"..
   109 	ShowMission(loc("Grenade Training"), loc("Aiming Practice"), loc("Eliminate all targets before your time runs out.|You have unlimited ammo for this mission."), -amGrenade, 0)
   116 		loc("Open ammo menu: [Right click]").."|"..
       
   117 		loc("Select weapon: [Left click]"), 2, 5000)
       
   118 	elseif gamePhase == 1 then
       
   119 		ShowMission(loc("Basic Grenade Training"), loc("Warming Up"),
       
   120 		loc("Throw some grenades to destroy the targets!").."|"..
       
   121 		loc("Hold the Attack key pressed for more power.").."|"..
       
   122 		loc("Grenades explode after 1 to 5 seconds (you decide).").."|"..
       
   123 		loc("Attack: [Space]").."|"..
       
   124 		loc("Aim: [Up]/[Down]").."|"..
       
   125 		loc("Set detonation timer: [1]-[5]").."|"..
       
   126 		loc("Change direction: [Left]/[Right]"), 2, 20000)
       
   127 		spawnTargets()
       
   128 	elseif gamePhase == 2 then
       
   129 		ShowMission(loc("Basic Grenade Training"), loc("No Wind Influcence"), loc("Unlike bazookas, grenades are not influenced by wind.").."|"..
       
   130 		loc("Destroy the targets!"), 2, 6000)
       
   131 		SetWind(50)
       
   132 		spawnTargets()
       
   133 	elseif gamePhase == 3 then
       
   134 		ShowMission(loc("Basic Grenade Training"), loc("Bounciness"),
       
   135 		loc("You can set the bounciness of grenades (and grenade-like weapons).").."|"..
       
   136 		loc("Grenades with high bounciness bounce a lot and behave chaotic.").."|"..
       
   137 		loc("With low bounciness, it barely bounces at all, but it is much more predictable.").."|"..
       
   138 		loc("Try out different bounciness levels to reach difficult targets.").."|"..
       
   139 		loc("Set bounciness: [Left Shift] + [1]-[5]"),
       
   140 		2, 20000)
       
   141 		spawnTargets()
       
   142 	elseif gamePhase == 4 then
       
   143 		ShowMission(loc("Basic Grenade Training"), loc("Final Targets"), loc("Good job! Now destroy the final targets to finish the training.").."|"..
       
   144 		loc("Precise Aim: [Left Shift] + [Up]/[Down]"),
       
   145 		2, 7000)
       
   146 		spawnTargets()
       
   147 	elseif gamePhase == 5 then
       
   148 		ShowMission(loc("Basic Grenade Training"), loc("Training complete!"), loc("Congratulations!"), 0, 0)
       
   149 		SetInputMask(0)
       
   150 		AddAmmo(CurrentHedgehog, amGrenade, 0)
       
   151 		if shotsFired > maxTargets then
       
   152 			flawless = false
       
   153 		end
       
   154 		if flawless then
       
   155 			PlaySound(sndFlawless, hog)
       
   156 		else
       
   157 			PlaySound(sndVictory, hog)
       
   158 		end
       
   159 		SendStat(siCustomAchievement, loc("Good job!"))
       
   160 		SendStat(siGameResult, loc("You have completed the Basic Grenade Training!"))
       
   161 		SendStat(siPlayerKills, "0", loc("Grenade Team"))
       
   162 		EndGame()
       
   163 		gameOver = true
       
   164 	end
       
   165 	gamePhase = gamePhase + 1
   110 end
   166 end
   111 
   167 
   112 function onNewTurn()
   168 function onNewTurn()
   113 	SetWeapon(amGrenade)
   169 	if gamePhase == 0 then
   114 end
   170 		newGamePhase()
   115 
   171 	end
   116 -- This function is called every game tick.
   172 end
   117 -- Note that there are 1000 ticks within one second.
   173 
   118 -- You shouldn't try to calculate too complicated
   174 function onSetWeapon(ammoType)
   119 -- code here as this might slow down your game.
   175 	if ammoType == amGrenade and not weaponSelected and gamePhase == 1 then
   120 function onGameTick20()
   176 		newGamePhase()
   121 	-- If time's up, set the game to be lost.
   177 		weaponSelected = true
   122 	-- We actually check the time to be "1 ms" as it
   178 	end
   123 	-- will be at "0 ms" right at the start of the game.
   179 end
   124 	if TurnTimeLeft < 40 and TurnTimeLeft > 0 and score < score_goal then
   180 
   125 		game_lost = true
   181 function onSlot(msgParam)
   126 		-- ... and show a short message.
   182 	if msgParam <= 1 and not weaponSelected and gamePhase == 1 then
   127 		ShowMission(loc("Grenade Training"), loc("Aiming Practice"), loc("Oh no! Time's up! Just try again."), -amSkip, 0)
   183 		newGamePhase()
   128 		-- How about killing our poor hog due to his poor performance?
   184 		weaponSelected = true
   129 		SetHealth(player, 0)
   185 	end
   130 		-- Just to be sure set the goal time to 1 ms
   186 end
   131 		time_goal = 1
   187 
   132 	end
   188 function onHogAttack(ammoType)
   133 	-- If the goal is reached or we've lost ...
   189 	if ammoType == amGrenade then
   134 	if score == score_goal or game_lost then
   190 		HideMission()
   135 		-- ... check to see if the time we'd like to
   191 	end
   136 		-- wait has passed and then ...
   192 end
   137 		if end_timer == 0 then
   193 
   138 			-- Override the 'Draw' message with the appropriate message.
   194 function onGearAdd(gear)
   139 			if game_lost then
   195 	if GetGearType(gear) == gtTarget then
   140 				AddCaption(loc("Mission lost!"), 0xffba00ff,capgrpGameState)
   196 		targetsLeft = targetsLeft + 1
   141 			else
   197 		maxTargets = maxTargets + 1
   142 				AddCaption(loc("Mission won!"), 0xffba00ff,capgrpGameState)
   198 		targetGears[gear] = true
   143 			end
   199 	elseif GetGearType(gear) == gtGrenade then
   144 			-- Remove the team to end the game. Only do this once.
   200 		shotsFired = shotsFired + 1
   145 			if team_death == false then
   201 	end
   146 				team_death = true
   202 end
   147 				DismissTeam(loc("Grenadiers"))
   203 
   148 			end
   204 function onGearDelete(gear)
   149 		else
   205 	if GetGearType(gear) == gtTarget then
   150 			-- ... or just lower the timer by 1.
   206 		targetsLeft = targetsLeft - 1
   151 			end_timer = end_timer - 20
   207 		targetGears[gear] = nil
   152 			-- Reset the time left to stop the timer
   208 		if targetsLeft <= 0 then
   153 			TurnTimeLeft = time_goal
   209 			newGamePhase()
   154 		end
   210 		end
   155 	end
   211 	end
   156 end
   212 end
   157 
   213 
   158 -- This function is called when the game is initialized
   214 function onGearDamage(gear)
   159 -- to request the available ammo and probabilities
   215 	if gear == hog then
       
   216 		flawless = false
       
   217 	end
       
   218 end
       
   219 
   160 function onAmmoStoreInit()
   220 function onAmmoStoreInit()
   161 	-- add an unlimited supply of bazooka ammo
       
   162 	SetAmmo(amGrenade, 9, 0, 0, 0)
   221 	SetAmmo(amGrenade, 9, 0, 0, 0)
   163 end
   222 end
   164 
       
   165 -- This function is called when a new gear is added.
       
   166 -- We don't need it for this training, so we can
       
   167 -- keep it empty.
       
   168 -- function onGearAdd(gear)
       
   169 -- end
       
   170 
       
   171 -- This function is called before a gear is destroyed.
       
   172 -- We use it to count the number of targets destroyed.
       
   173 function onGearDelete(gear)
       
   174 	-- We're only interested in target gears.
       
   175 	if GetGearType(gear) == gtTarget then
       
   176 		-- Add one point to our score/counter
       
   177 		score = score + 1
       
   178 		-- If we haven't reached the goal ...
       
   179 		if score < score_goal then
       
   180 			-- ... spawn another target.
       
   181 			spawnTarget()
       
   182 		else
       
   183 			if not game_lost then
       
   184 			-- Otherwise show that the goal was accomplished
       
   185 			ShowMission(loc("Grenade Training"), loc("Aiming Practice"), loc("Congratulations! You've eliminated all targets|within the allowed time frame."), 0, 0)
       
   186 			-- Also let the hogs shout "victory!"
       
   187 			PlaySound(sndVictory)
       
   188 			-- Save the time left so we may keep it.
       
   189 			time_goal = TurnTimeLeft
       
   190 			end
       
   191 		end
       
   192 	end
       
   193 end