share/hedgewars/Data/Missions/Training/Basic_Training_-_Rope.lua
changeset 14455 df366c5b8440
parent 14454 fd34b9037c69
child 14464 ead8928a59f8
equal deleted inserted replaced
14454:fd34b9037c69 14455:df366c5b8440
     7 	- Shoot rope, attach, detach
     7 	- Shoot rope, attach, detach
     8 	- Extend, retract, swing to reach easy target
     8 	- Extend, retract, swing to reach easy target
     9 	- Multiple shots / rope re-use to go over water hazard
     9 	- Multiple shots / rope re-use to go over water hazard
    10 	- Drop grenade from rope
    10 	- Drop grenade from rope
    11 	- Special rules when you only got 1 rope (i.e. when the rope is officially used up)
    11 	- Special rules when you only got 1 rope (i.e. when the rope is officially used up)
    12 	- Rope around obstacles and mines
    12 	- Rope around obstacles
    13 ]]
    13 ]]
    14 
    14 
    15 HedgewarsScriptLoad("/Scripts/Locale.lua")
    15 HedgewarsScriptLoad("/Scripts/Locale.lua")
    16 HedgewarsScriptLoad("/Scripts/Utils.lua")
    16 HedgewarsScriptLoad("/Scripts/Utils.lua")
    17 
    17 
    30 end
    30 end
    31 
    31 
    32 -- Gears
    32 -- Gears
    33 local hog
    33 local hog
    34 local ropeGear
    34 local ropeGear
    35 local mines = {}
       
    36 
    35 
    37 -- Status vars
    36 -- Status vars
    38 local ropeSelected = false	-- rope was selected the first time, used for msg
    37 local ropeSelected = false	-- rope was selected the first time, used for msg
    39 local ropeAttached = false	-- rope was attached, used for msg
    38 local ropeAttached = false	-- rope was attached, used for msg
    40 local target1Reached = false	-- hog near 1st first target
    39 local target1Reached = false	-- hog near 1st first target
    45 
    44 
    46 local cpX, cpY = 208, 1384	-- hog checkpoint, initialized with start coords
    45 local cpX, cpY = 208, 1384	-- hog checkpoint, initialized with start coords
    47 
    46 
    48 -- "Constants"
    47 -- "Constants"
    49 local initHogHealth = 50
    48 local initHogHealth = 50
       
    49 local initHogHealthFinal = 1
    50 local teamName = loc("Wannabe Ropers")
    50 local teamName = loc("Wannabe Ropers")
    51 
    51 
    52 local girderData = {
    52 local girderData = {
    53 	{2012, 1366, 6}, -- water gate
    53 	{2012, 1366, 6}, -- water gate
    54 	{1156, 678, 2}, -- post-barrel gate
    54 	{1156, 678, 2}, -- post-barrel gate
    57 	{1064, 455, 6}, -- top level gate
    57 	{1064, 455, 6}, -- top level gate
    58 	{1557, 1009, 0}, -- barrel pit protection
    58 	{1557, 1009, 0}, -- barrel pit protection
    59 	{1436, 1003, 4}, -- barrel pit protection
    59 	{1436, 1003, 4}, -- barrel pit protection
    60 	{3607, 1307, 4}, -- post-water gate
    60 	{3607, 1307, 4}, -- post-water gate
    61 	{3809, 1375, 0}, -- post-water gate
    61 	{3809, 1375, 0}, -- post-water gate
    62 }
       
    63 
       
    64 local mineData = {
       
    65 	{1261, 549},
       
    66 	{1395, 554},
       
    67 	{1719, 458},
       
    68 	{1489, 558},
       
    69 	{1686, 565},
       
    70 	{1581, 561},
       
    71 	{1904, 539},
       
    72 	{2047, 539},
       
    73 	{2226, 608},
       
    74 	{2387, 541},
       
    75 	{2523, 396},
       
    76 	{2899, 324},
       
    77 	{3428, 546},
       
    78 	{3373, 546},
       
    79 	{3271, 546},
       
    80 	{3123, 545},
       
    81 	{3012, 544},
       
    82 	{2907, 544},
       
    83 	{2793, 543},
       
    84 }
    62 }
    85 
    63 
    86 local targetData = {
    64 local targetData = {
    87 	-- 1: Start
    65 	-- 1: Start
    88 	{504, 1215},
    66 	{504, 1215},
   127 
   105 
   128 	SendHealthStatsOff()
   106 	SendHealthStatsOff()
   129 
   107 
   130 end
   108 end
   131 
   109 
   132 -- The final challenge is to rope through a mined obstacle course with only 1 rope.
   110 -- The final challenge is to rope through an obstacle course with only 1 rope.
   133 -- If the player screws up, this functinon will restart it.
   111 -- If the player screws up, this functinon will restart it.
   134 local function resetMineChallenge(setPos)
   112 local function resetFinalChallenge(setPos)
   135 	if setPos == nil then
   113 	if setPos == nil then
   136 		setPos = true
   114 		setPos = true
   137 	end
   115 	end
   138 	SetHealth(hog, initHogHealth)
   116 	SetHealth(hog, initHogHealthFinal)
   139 	AddAmmo(hog, amRope, 1)
   117 	AddAmmo(hog, amRope, 1)
   140 	for gear, _ in pairs(mines) do
   118 	SetGearVelocity(hog, 0, 0)
   141 		DeleteGear(gear)
   119 
   142 	end
       
   143 
       
   144 	for m=1, #mineData do
       
   145 		AddGear(mineData[m][1], mineData[m][2], gtMine, 0, 0, 0, 0)
       
   146 	end
       
   147 	if setPos then
   120 	if setPos then
       
   121 		PlaySound(sndWarp)
   148 		SetGearPosition(hog, cpX, cpY)
   122 		SetGearPosition(hog, cpX, cpY)
       
   123 		AddVisualGear(cpX, cpY, vgtExplosion, 0, false)
   149 		FollowGear(hog)
   124 		FollowGear(hog)
   150 	end
   125 	end
   151 end
   126 end
   152 
   127 
   153 -- Deletes girder with given girderData ID
   128 -- Deletes girder with given girderData ID
   161 local function loadGearData()
   136 local function loadGearData()
   162 	------ GIRDERS ------
   137 	------ GIRDERS ------
   163 	for g=1, #girderData do
   138 	for g=1, #girderData do
   164 		PlaceGirder(unpack(girderData[g]))
   139 		PlaceGirder(unpack(girderData[g]))
   165 	end
   140 	end
       
   141 
       
   142 	PlaceSprite(1678, 546, sprTargetBee, 0)
   166 
   143 
   167 	------ BARRELS ------
   144 	------ BARRELS ------
   168 	local barrels = {}
   145 	local barrels = {}
   169 	table.insert(barrels, AddGear(1370, 1223, gtExplosives, 0, 0, 0, 0))
   146 	table.insert(barrels, AddGear(1370, 1223, gtExplosives, 0, 0, 0, 0))
   170 	table.insert(barrels, AddGear(1430, 1226, gtExplosives, 0, 0, 0, 0))
   147 	table.insert(barrels, AddGear(1430, 1226, gtExplosives, 0, 0, 0, 0))
   173 	table.insert(barrels, AddGear(1578, 1206, gtExplosives, 0, 0, 0, 0))
   150 	table.insert(barrels, AddGear(1578, 1206, gtExplosives, 0, 0, 0, 0))
   174 	for b=1, #barrels do
   151 	for b=1, #barrels do
   175 		SetHealth(barrels[b], 1)
   152 		SetHealth(barrels[b], 1)
   176 	end
   153 	end
   177 
   154 
   178 	------ MINES ------
       
   179 	for m=1, #mineData do
       
   180 		AddGear(mineData[m][1], mineData[m][2], gtMine, 0, 0, 0, 0)
       
   181 	end
       
   182 
       
   183 	------ FIRST TARGET ------
   155 	------ FIRST TARGET ------
   184 	currentTarget = 1
   156 	currentTarget = 1
   185 	AddGear(targetData[currentTarget][1], targetData[currentTarget][2], gtTarget, 0, 0, 0, 0)
   157 	AddGear(targetData[currentTarget][1], targetData[currentTarget][2], gtTarget, 0, 0, 0, 0)
   186 end
   158 end
   187 
   159 
   203 		end
   175 		end
   204 		ShowMission(loc("Basic Rope Training"), loc("Select Rope"),
   176 		ShowMission(loc("Basic Rope Training"), loc("Select Rope"),
   205 		loc("Select the rope to begin!").."|"..
   177 		loc("Select the rope to begin!").."|"..
   206 		ctrl, 2, 7500)
   178 		ctrl, 2, 7500)
   207 		wasFirstTurn = true
   179 		wasFirstTurn = true
   208 	end
       
   209 	if isInMineChallenge then
       
   210 		resetMineChallenge()
       
   211 	end
   180 	end
   212 end
   181 end
   213 
   182 
   214 function onGameTick()
   183 function onGameTick()
   215 	if gameOver or (not CurrentHedgehog) then
   184 	if gameOver or (not CurrentHedgehog) then
   240 			loc("Use the rope to get to the target!").."|"..
   209 			loc("Use the rope to get to the target!").."|"..
   241 			loc("Retract/Extend rope: [Up]/[Down]").."|"..
   210 			loc("Retract/Extend rope: [Up]/[Down]").."|"..
   242 			loc("Swing: [Left]/[Right]").."|"..
   211 			loc("Swing: [Left]/[Right]").."|"..
   243 			loc("Release rope: [Attack]"), 2, 15000)
   212 			loc("Release rope: [Attack]"), 2, 15000)
   244 			ropeAttached = true
   213 			ropeAttached = true
   245 		elseif currentTarget > 1 and not (currentTarget == 6 and barrelsBoom) then
   214 		elseif currentTarget > 1 and (not (currentTarget == 6 and barrelsBoom)) then
   246 			HideMission()
   215 			HideMission()
   247 		end
   216 		end
   248 	end
   217 	end
   249 
   218 
   250 	-- Prevent grenade being thrown by hand (must use from rope instead)
   219 	-- Prevent grenade being thrown by hand (must use from rope instead)
   254 	end
   223 	end
   255 	if allowAttack then
   224 	if allowAttack then
   256 		SetInputMask(bor(GetInputMask(), gmAttack))
   225 		SetInputMask(bor(GetInputMask(), gmAttack))
   257 	else
   226 	else
   258 		SetInputMask(band(GetInputMask(), bnot(gmAttack)))
   227 		SetInputMask(band(GetInputMask(), bnot(gmAttack)))
       
   228 	end
       
   229 	if isInFinalChallenge then
       
   230 		local dX, dY = GetGearVelocity(CurrentHedgehog)
       
   231 		local x, y = GetGearPosition(CurrentHedgehog)
       
   232 		if band(GetState(CurrentHedgehog), gstHHDriven) ~= 0 and GetAmmoCount(CurrentHedgehog, amRope) == 0 and
       
   233 				GetFlightTime(CurrentHedgehog) == 0 and (not ropeGear) and
       
   234 				math.abs(dX) < 5 and math.abs(dY) < 5 and
       
   235 				(x < 3417 or y > 471) then
       
   236 			AddCaption(loc("Your rope is gone! Try again!"))
       
   237 			resetFinalChallenge()
       
   238 			PlaySound(sndWarp)
       
   239 		end
   259 	end
   240 	end
   260 end
   241 end
   261 
   242 
   262 function onGameTick20()
   243 function onGameTick20()
   263 	if not gameOver and not target1Reached and CurrentHedgehog and gearIsInCircle(CurrentHedgehog, targetData[1][1], targetData[1][2], 48, false) then
   244 	if not gameOver and not target1Reached and CurrentHedgehog and gearIsInCircle(CurrentHedgehog, targetData[1][1], targetData[1][2], 48, false) then
   269 end
   250 end
   270 
   251 
   271 function onGearAdd(gear)
   252 function onGearAdd(gear)
   272 	if GetGearType(gear) == gtRope then
   253 	if GetGearType(gear) == gtRope then
   273 		ropeGear = gear
   254 		ropeGear = gear
   274 	elseif GetGearType(gear) == gtMine then
       
   275 		mines[gear] = true
       
   276 	elseif GetGearType(gear) == gtGrenade then
   255 	elseif GetGearType(gear) == gtGrenade then
   277 		if not ropeGear then
   256 		if not ropeGear then
   278 			DeleteGear(gear)
   257 			DeleteGear(gear)
   279 		end
   258 		end
   280 	end
   259 	end
   287 		if vGear then
   266 		if vGear then
   288 			SetVisualGearValues(vGear, GetX(hog), GetY(hog))
   267 			SetVisualGearValues(vGear, GetX(hog), GetY(hog))
   289 		end
   268 		end
   290 		FollowGear(hog)
   269 		FollowGear(hog)
   291 		AddCaption(loc("Your hedgehog has been revived!"))
   270 		AddCaption(loc("Your hedgehog has been revived!"))
   292 		if isInMineChallenge then
   271 		if isInFinalChallenge then
   293 			resetMineChallenge(false)
   272 			resetFinalChallenge(false)
   294 		end
   273 		end
   295 	end
   274 	end
   296 end
   275 end
   297 
   276 
   298 function onGearDelete(gear)
   277 function onGearDelete(gear)
   330 			loc("Step 1: Start roping").."|"..
   309 			loc("Step 1: Start roping").."|"..
   331 			loc("Step 2: Select grenade").."|"..
   310 			loc("Step 2: Select grenade").."|"..
   332 			loc("Step 3: Drop the grenade").."| |"..
   311 			loc("Step 3: Drop the grenade").."| |"..
   333 			loc("Drop weapon (while on rope): [Long Jump]"), 2, 20000)
   312 			loc("Drop weapon (while on rope): [Long Jump]"), 2, 20000)
   334 			AddAmmo(hog, amBaseballBat, 0)
   313 			AddAmmo(hog, amBaseballBat, 0)
   335 			SpawnAmmoCrate(1849, 920, amGrenade, 100)
   314 			SpawnAmmoCrate(1849, 920, amGrenade, AMMO_INFINITE)
   336 		elseif currentTarget == 6 then
   315 		elseif currentTarget == 6 then
   337 			ShowMission(loc("Basic Rope Training"), loc("Finite Ropes"),
   316 			ShowMission(loc("Basic Rope Training"), loc("Finite Ropes"),
   338 			loc("So far, you had infinite ropes, but in the|real world, ropes are usually limited.").."|"..
   317 			loc("So far, you had infinite ropes, but in the|real world, ropes are usually limited.").."|"..
   339 			loc("Rules:").." |"..
   318 			loc("Rules:").." |"..
   340 			loc("As long you don't touch the ground, you can|re-use the same rope as often as you like.").."|"..
   319 			loc("As long you don't touch the ground, you can|re-use the same rope as often as you like.").."|"..
   341 			loc("If you miss a shot while trying to|re-attach, your rope is gone, too!").."| |"..
   320 			loc("If you miss a shot while trying to|re-attach, your rope is gone, too!").."| |"..
   342 			loc("Final Challenge:").." |"..
   321 			loc("Final Challenge:").." |"..
   343 			loc("Reach and destroy the final target to win.").."|"..
   322 			loc("Reach and destroy the final target to win.").."|"..
   344 			loc("You only get 1 rope this time, don't waste it!").."|"..
   323 			loc("You only get 1 rope this time, don't waste it!"),
   345 			loc("Avoid the mines!").."|"..
   324 			2, 25000)
   346 			loc("Skip your turn to try again."), 2, 25000)
       
   347 			eraseGirder(4)
   325 			eraseGirder(4)
   348 			eraseGirder(5)
   326 			eraseGirder(5)
   349 			AddAmmo(hog, amRope, 1)
   327 			AddAmmo(hog, amRope, 1)
   350 			AddAmmo(hog, amSkip, 100)
   328 			SetHealth(hog, initHogHealthFinal)
   351 			isInMineChallenge = true
   329 			isInFinalChallenge = true
   352 		elseif currentTarget == 7 then
   330 		elseif currentTarget == 7 then
   353 			ShowMission(loc("Basic Rope Training"), loc("Training complete!"),
   331 			ShowMission(loc("Basic Rope Training"), loc("Training complete!"),
   354 			loc("Congratulations!"), 0, 0)
   332 			loc("Congratulations!"), 0, 0)
   355 			PlaySound(sndVictory, hog)
   333 			PlaySound(sndVictory, hog)
   356 			AddAmmo(hog, amBaseballBat, 0)
   334 			AddAmmo(hog, amBaseballBat, 0)
   371 
   349 
   372 	elseif GetGearType(gear) == gtExplosives then
   350 	elseif GetGearType(gear) == gtExplosives then
   373 		if not barrelsBoom then
   351 		if not barrelsBoom then
   374 			barrelsBoom = true
   352 			barrelsBoom = true
   375 			AddAmmo(hog, amGrenade, 0)
   353 			AddAmmo(hog, amGrenade, 0)
   376 			AddAmmo(hog, amBaseballBat, 100)
   354 			AddAmmo(hog, amBaseballBat, AMMO_INFINITE)
   377 			eraseGirder(2)
   355 			eraseGirder(2)
   378 			eraseGirder(3)
   356 			eraseGirder(3)
   379 			ShowMission(loc("Basic Rope Training"),
   357 			ShowMission(loc("Basic Rope Training"),
   380 				loc("Kaboom!"),
   358 				loc("Kaboom!"),
   381 				loc("Follow the path and destroy the next target."),
   359 				loc("Follow the path and destroy the next target."),
   396 			loc("Go to the target.").."|"..
   374 			loc("Go to the target.").."|"..
   397 			loc("Hold [Attack] to attach the rope.").."|"..
   375 			loc("Hold [Attack] to attach the rope.").."|"..
   398 			ctrl, 2, 13000)
   376 			ctrl, 2, 13000)
   399 			ropeAttached = false
   377 			ropeAttached = false
   400 		end
   378 		end
   401 	elseif GetGearType(gear) == gtMine then
       
   402 		mines[gear] = nil
       
   403 	elseif GetGearType(gear) == gtCase then
   379 	elseif GetGearType(gear) == gtCase then
   404 		eraseGirder(6)
   380 		eraseGirder(6)
   405 		eraseGirder(7)
   381 		eraseGirder(7)
   406 	end
   382 	end
   407 end
   383 end
   408 
   384 
   409 function onAmmoStoreInit()
   385 function onAmmoStoreInit()
   410 	SetAmmo(amRope, 9, 0, 0, 1)
   386 	SetAmmo(amRope, 9, 0, 0, 1)
   411 	SetAmmo(amBaseballBat, 9, 0, 0, 1)
   387 	SetAmmo(amBaseballBat, 9, 0, 0, 1)
   412 end
       
   413 
       
   414 function onHogAttack(ammoType)
       
   415 	-- Allow to manually reset final challenge with skip
       
   416 	if ammoType == amSkip then
       
   417 		resetMineChallenge()
       
   418 	end
       
   419 end
   388 end
   420 
   389 
   421 function onAttack()
   390 function onAttack()
   422 	if GetCurAmmoType() == amGrenade and not ropeGear then
   391 	if GetCurAmmoType() == amGrenade and not ropeGear then
   423 		AddCaption(loc("You have to drop the grenade from rope!"), 0xFF4000FF, capgrpMessage)
   392 		AddCaption(loc("You have to drop the grenade from rope!"), 0xFF4000FF, capgrpMessage)