diff -r dce9f0b84a18 -r aa9e871f9685 share/hedgewars/Data/Missions/Training/Basic_Training_-_Rope.lua --- a/share/hedgewars/Data/Missions/Training/Basic_Training_-_Rope.lua Mon Mar 05 19:26:46 2018 +0100 +++ b/share/hedgewars/Data/Missions/Training/Basic_Training_-_Rope.lua Tue Mar 06 03:48:03 2018 +0100 @@ -1,205 +1,399 @@ ---Created by Patrick Nielsen ---It's been so fun to create this, your welcome to contact me at Trivkz@gmail.com --- ---I've tried to keep the code as clear as possible and with comments. ---But as English is not my first language there may be spelling / grammar mistakes. --- ---I know there need to be more "tutorial" specefic messages, but I had a hard timer figuring out what to type / what would be the best technical description. +--[[ + Basic Rope Training + Teaches the player how to rope! No advanced tricks, just the basics. But fun! (I hope) + Lesson plan: + - Select rope + - Shoot rope, attach, detach + - Extend, retract, swing to reach easy target + - Multiple shots / rope re-use to go over water hazard + - Drop grenade from rope + - Special rules when you only got 1 rope (i.e. when the rope is officially used up) + - Rope around obstacles and mines +]] HedgewarsScriptLoad("/Scripts/Locale.lua") -HedgewarsScriptLoad("/Scripts/Utils.lua") -- For the gearIsInBox function, wrote my own, but decided it was a waste to include it +HedgewarsScriptLoad("/Scripts/Utils.lua") + +-- Map definition automatically converted from HWMAP file by hwmap2lua.sh +local map = +{'\2\30\7\126\135\2\28\5\52\0\1\211\6\203\135\3\207\6\189\0\3\1\5\205\135\4\120\5\203\0\2\30\5\31\135\2\35\4\173\0\1\170\4\216\135\4\150\4\248\0\3\230\4\138\135\4\54\6\22\0\3\205\6\189\135\4\154\7\91\0\4\154\7\91\135\6\57\7\41\0\4\79\6\38\135\4\221\6\112\0\4\221\6\112\135\6\27\6\70\0\3\175\6\196\135\4\51\5\235\0\3\17\6\178\135\3\161\5\226\0\4\33\7\4\135\4\191\6\93\0\4\200\7\75\135\5\45\6\137\0\6\29\6\66\135\6\98\5\123\0\6\107\7\32\135\6\237\5\249\0\6\102\5\95\135\7\169\5\6\0\7\0\5\237\135\7\235\6\20\0\7\233\6\13\135\7\226\8\43\0\13\66\6\47\135\13\100\8\57\0\7\167\5\15\135\7\164\4\51\0\7\71\4\109\135\13\235\4\132\0\13\4\6\75\135\14\242\6\57\0\14\169\6\166\135\15\183\4\86\0', +'\15\208\5\13\135\15\96\2\248\0\15\206\3\104\135\13\175\2\88\0\14\171\5\17\140\14\219\4\77\138\14\166\3\136\136\13\219\3\31\136\13\184\4\228\136\13\173\3\250\0\14\2\4\19\136\7\36\3\211\0\14\52\2\85\137\7\57\2\76\0\12\196\2\245\137\11\195\3\127\137\10\174\2\223\137\9\174\3\113\137\8\160\2\211\137\8\11\3\111\137\6\249\3\218\131\6\66\3\209\0\5\88\3\202\131\4\38\3\193\0\5\33\3\207\131\5\31\5\31\0\4\235\4\228\131\6\125\4\251\0\6\98\3\214\131\6\80\5\1\0\7\41\2\104\136\3\253\2\72\0\4\31\3\207\133\1\149\3\166\0\2\243\4\15\133\1\117\2\202\0\1\149\3\60\133\1\211\1\87\0\1\138\1\138\133\3\42\0\71\0\2\131\0\96\133\4\168\0\149\0\5\116\1\124\141\7\41\0\204\141\8\252\2\42\141\10\39\0\135\141\11\40\1\124\141\10\17\1\186\141', +'\12\104\0\151\141\4\29\0\156\137\14\160\0\69\0\13\182\1\133\137\13\171\2\78\0\13\201\0\78\137\13\189\0\197\0\13\194\1\195\137\15\148\2\147\0\14\189\0\59\137\15\222\0\217\0\15\226\0\215\137\15\164\2\145\0\13\217\1\211\137\15\167\1\220\0\14\208\2\37\164\8\89\1\92\139\6\146\1\211\139\8\174\2\39\203\10\19\2\7\203\11\56\1\167\203\12\106\0\217\203\7\36\1\12\203\5\182\1\163\203\6\141\1\165\203\8\71\1\135\203\8\151\3\19\203\8\7\3\70\203\9\227\3\118\203\13\66\3\113\133\13\54\4\104\0\11\200\3\26\133\11\191\4\84\0\9\160\2\255\133\9\160\4\84\0\8\16\3\163\133\8\18\4\109\0\9\108\3\53\197\10\19\3\70\0\14\25\5\228\132\14\43\4\253\130\13\237\3\241\210\13\217\3\225\210\13\95\4\74\140\7\137\4\40\0\2\209\6\75\207\3\255\6\102\0\4\1\6\107\207', +'\4\182\6\228\0\4\182\6\226\207\6\36\6\189\0\6\36\6\201\207\6\166\5\191\0\4\138\4\100\158\1\183\4\68\0\4\145\5\8\158\4\203\5\201\0\5\141\5\198\158\5\180\5\139\0\7\116\4\230\142\5\49\5\52\0\6\185\4\47\148\6\182\4\186\0\7\64\4\88\153\4\216\4\10\143\13\255\2\42\146\15\100\2\216\0\4\1\6\20\199\2\142\6\29\0\3\255\6\22\199\5\22\6\224\0\7\231\5\198\133\7\235\6\31\0\13\70\6\68\133\13\54\5\237\0\14\36\4\253\197\4\90\2\223\133\4\239\3\97\0\2\181\2\252\133\3\95\2\156\0\2\216\1\90\133\3\113\1\218\0\4\200\1\32\133\4\122\1\167\0\7\169\1\106\133\4\10\4\106\213\1\30\4\86\0\4\58\5\54\219\1\119\5\6\139\1\119\5\157\0\1\238\5\189\139\0\85\5\164\0\0\105\6\63\139\0\119\3\182\0\0\37\3\188\134\1\231\3\195\0', +'\1\142\5\13\145\1\188\5\102\0\1\199\5\59\145\3\209\5\198\134\5\59\5\102\0\4\63\5\111\134\0\121\3\225\134\4\111\3\234\0\2\255\4\106\134\3\12\4\228\0\2\58\4\120\132\13\148\2\60\132\13\146\1\106\0'} -local Player = nil -- Pointer to hog created in: onGameInit -local Target = nil -- Pointer to target hog -local GameLost = false -- You lost the game -local Objective = false -- Get to the target -local RopeMaster = false -- Achievement -local StatsSent = false -- Remember whether the stats have been sent already +local function drawMap() + for m=1, #map do + ParseCommand("draw "..map[m]) + end +end + +-- Gears +local hog +local ropeGear +local mines = {} -local WaitTime = 1000 -- Wait 1sec before quit -local FollowTime = 1500 -- For use with FollowGear -local FollowingGear = false -local BaseballIntro = false -- Fail safe for ticker -local TargetNumber = 0 -- The current target number +-- Status vars +local ropeSelected = false -- rope was selected the first time, used for msg +local ropeAttached = false -- rope was attached, used for msg +local target1Reached = false -- hog near 1st first target +local barrelsBoom = false -- barrels exploded +local wasFirstTurn = false -- first turn msg was displayed +local gameOver = false -- game over (only victory possible) +local currentTarget = 0 -- current target ID. First target = 1 + +local cpX, cpY = 208, 1384 -- hog checkpoint, initialized with start coords -local TargetPos = {} -- Tabel of targets -local Timers = {} -local GetTime = 0 +-- "Constants" +local initHogHealth = 50 +local teamName = loc("Wannabe Ropers") + +local girderData = { + {2012, 1366, 6}, -- water gate + {1156, 678, 2}, -- post-barrel gate + {1206, 905, 2}, -- post-barrel gate + {1064, 288, 6}, -- top level gate + {1064, 455, 6}, -- top level gate + {1557, 1009, 0}, -- barrel pit protection + {1436, 1003, 4}, -- barrel pit protection + {3607, 1307, 4}, -- post-water gate + {3809, 1375, 0}, -- post-water gate +} -TargetPos[ 1 ] = { X = 1100, Y = 1100, Message = loc("Now find the next target! |Tip: Normally you lose health by falling down, so be careful!") } -TargetPos[ 2 ] = { X = 1500, Y = 1490, Message = loc("You're getting pretty good! |Tip: When you shorten you rope, you move faster!|And when you lengthen it, you move slower.") } -TargetPos[ 3 ] = { X = 2200, Y = 800, Message = loc("The next one is pretty hard! |Tip: You have to do multiple swings!") } -TargetPos[ 4 ] = { X = 2870, Y = 400, Message = loc("I don't know how you did that. But good work!|The next one should be easy as cake for you!") } -TargetPos[ 5 ] = { X = 4000, Y = 1750, Message = "" } -TargetPos[ 6 ] = { Modifier = true, Func = function() -- Last target is ALWAYS the "winning" target! - Info( loc("Congratulations"), loc("Congratulations! You've completed the Basic Rope Training!"), 0 ) -- Congrats - PlaySound( sndVictory, Player ) +local mineData = { + {1261, 549}, + {1395, 554}, + {1719, 458}, + {1489, 558}, + {1686, 565}, + {1581, 561}, + {1904, 539}, + {2047, 539}, + {2226, 608}, + {2387, 541}, + {2523, 396}, + {2899, 324}, + {3428, 546}, + {3373, 546}, + {3271, 546}, + {3123, 545}, + {3012, 544}, + {2907, 544}, + {2793, 543}, +} - AddCaption( loc( "Victory!" ), 0xFFFFFFFF, capgrpGameState) - if TurnTimeLeft >= 250000 then -- If you very fast, unlock the ahievement "Rope Master!" - RopeMaster = true - AddCaption( string.format(loc("Achievement gotten: %s"), loc("Rope Master") ), 0xffba00ff, capgrpMessage2) - PlaySound( sndHomerun ) - end - Objective = true -end } +local targetData = { + -- 1: Start + {504, 1215}, + -- 2: Start 2 + {1082, 1348}, + -- 3: Before the water + {1941, 1490}, + -- 4: After the water + {3504, 1557}, + -- 5: Barrel pit + {2060, 885}, + -- 6: Grand Finale + {757, 679}, + -- 7: Goal + {3802, 356}, +} + +function onGameInit() -function Info( Title, Text, Icon ) -- I made a small wrapper to ease the process - ShowMission( loc("Rope Training"), Title, Text, Icon, 0 ) + ClearGameFlags() + EnableGameFlags(gfDisableGirders, gfDisableLandObjects, gfOneClanMode, gfInfAttack, gfSolidLand, gfDisableWind) + Seed = "{386439b4-748a-48b1-945a-eba6a817ca83}" + Theme = "Bamboo" + MapGen = mgDrawn + MapFeatureSize = 12 + TemplateFilter = 0 + TemplateNumber = 0 + TurnTime = 9999000 + Explosives = 0 + MinesNum = 0 + CaseFreq = 0 + MinesTime = 0 + WaterRise = 0 + HealthDecrease = 0 + + AddTeam(teamName, 0xFF0204, "Plinko", "Snail", "Default", "cm_yinyang") + hog = AddHog(loc("Roper"), 0, initHogHealth, "StrawHat") + SetGearPosition(hog, cpX, cpY) + SetEffect(hog, heResurrectable, 1) + + drawMap() + + SendHealthStatsOff() + end -function NewFollowGear( Gear ) - FollowingGear = true - FollowGear( Gear ) +-- The final challenge is to rope through a mined obstacle course with only 1 rope. +-- If the player screws up, this functinon will restart it. +local function resetMineChallenge(setPos) + if setPos == nil then + setPos = true + end + SetHealth(hog, initHogHealth) + AddAmmo(hog, amRope, 1) + for gear, _ in pairs(mines) do + DeleteGear(gear) + end + + for m=1, #mineData do + AddGear(mineData[m][1], mineData[m][2], gtMine, 0, 0, 0, 0) + end + if setPos then + SetGearPosition(hog, cpX, cpY) + FollowGear(hog) + end end -function SpawnTarget( PosX, PosY ) - Target = AddGear( 0, 0, gtTarget, 0, 0, 0, 0 ) -- Create a new target - SetGearPosition( Target, PosX, PosY ) -- Set the position of the target - NewFollowGear( Target ) +-- Deletes girder with given girderData ID +local function eraseGirder(id) + EraseSprite(girderData[id][1], girderData[id][2], sprAmGirder, girderData[id][3], false, false, false, false) + PlaySound(sndVaporize) + AddVisualGear(girderData[id][1], girderData[id][2], vgtSteam, false, 0) + AddCaption(loc("Barrier unlocked!")) end -function AutoSpawn() -- Auto spawn the next target after you've killed the current target! - TargetNumber = TargetNumber + 1 +local function loadGearData() + ------ GIRDERS ------ + for g=1, #girderData do + PlaceGirder(unpack(girderData[g])) + end - if TargetPos[ TargetNumber ].Modifier then -- If there is a modifier, run the function, only used in the winning target! - TargetPos[ TargetNumber ].Func() - return true + ------ BARRELS ------ + local barrels = {} + table.insert(barrels, AddGear(1370, 1223, gtExplosives, 0, 0, 0, 0)) + table.insert(barrels, AddGear(1430, 1226, gtExplosives, 0, 0, 0, 0)) + table.insert(barrels, AddGear(1489, 1218, gtExplosives, 0, 0, 0, 0)) + table.insert(barrels, AddGear(1537, 1211, gtExplosives, 0, 0, 0, 0)) + table.insert(barrels, AddGear(1578, 1206, gtExplosives, 0, 0, 0, 0)) + for b=1, #barrels do + SetHealth(barrels[b], 1) + end + + ------ MINES ------ + for m=1, #mineData do + AddGear(mineData[m][1], mineData[m][2], gtMine, 0, 0, 0, 0) end - if TargetNumber > 1 then - Info(loc("Training"), TargetPos[ TargetNumber - 1 ].Message, -amRope ) + ------ FIRST TARGET ------ + currentTarget = 1 + AddGear(targetData[currentTarget][1], targetData[currentTarget][2], gtTarget, 0, 0, 0, 0) +end + +function onGameStart() + loadGearData() + + ShowMission(loc("Basic Rope Training"), loc("Basic Training"), + loc("Use the rope to complete the obstacle course!"), -amRope, 0) + FollowGear(hog) +end + +function onNewTurn() + if not wasFirstTurn then + ShowMission(loc("Basic Rope Training"), loc("Select Rope"), + loc("Select the rope to begin!").."|".. + loc("Open ammo menu: [Right click]"), 2, 7500) + wasFirstTurn = true end - - SpawnTarget( TargetPos[ TargetNumber ].X, TargetPos[ TargetNumber ].Y ) -- Spawn target on the next position + if isInMineChallenge then + resetMineChallenge() + end end -function InRange( Gear, PosX, PosY, Distance ) -- Fix as the default function didn't do quite what I needed - GearX, GearY = GetGearPosition( Gear ) +function onGameTick() + if gameOver or (not CurrentHedgehog) then + return + end - return GearX >= PosX - Distance and GearX <= PosX + Distance and GearY >= PosY and GearY - Distance <= PosY + Distance + -- First rope selection + if not ropeSelected and GetCurAmmoType() == amRope then + ShowMission(loc("Basic Rope Training"), loc("Getting Started"), + loc("You can use the rope to reach new places.").."|".. + loc("Aim at the ceiling and hold [Attack] pressed until the rope attaches.").."|".. + loc("Aim: [Up]/[Down]").."|".. + loc("Attack: [Space]"), 2, 15000) + ropeSelected = true + -- Rope attach + elseif ropeGear and band(GetState(ropeGear), gstCollision) ~= 0 then + -- First rope attach + if not ropeAttached and not target1Reached then + ShowMission(loc("Basic Rope Training"), loc("How to Rope"), + loc("Great!").."|".. + loc("Use the rope to get to the target!").."|".. + loc("Extend/Retract rope: [Up]/[Down]").."|".. + loc("Swing: [Left]/[Right]").."|".. + loc("Release rope: [Attack]"), 2, 15000) + ropeAttached = true + elseif currentTarget > 1 then + HideMission() + end + end + + -- Prevent grenade being thrown by hand (must use from rope instead) + local allowAttack = true + if GetCurAmmoType() == amGrenade and ropeGear == nil then + allowAttack = false + end + if allowAttack then + SetInputMask(bor(GetInputMask(), gmAttack)) + else + SetInputMask(band(GetInputMask(), bnot(gmAttack))) + end end -function CheckPosition( Hog, Distance ) -- Show a message when you get close to the current target! - if (not BaseballIntro and not Objective) and (CurrentHedgehog ~= nil) then --Fail safe check - if InRange( Hog, 1100, 1100, Distance ) then -- Check if the player is within predefined position of the first target - BaseballIntro = true - Info(loc("Training"), loc("Great work! Now hit it with your Baseball Bat! |Tip: You can change weapon with 'Right Click'!"), -amRope ) -- Guide them - Timer( 10000, loc("Remember: The rope only bend around objects, |if it doesn't hit anything it's always stright!")) +function onGameTick20() + if not gameOver and not target1Reached and CurrentHedgehog and gearIsInCircle(CurrentHedgehog, targetData[1][1], targetData[1][2], 48, false) then + ShowMission(loc("Basic Rope Training"), loc("Target Puncher"), + loc("Okay, now destroy the target|using the baseball bat.").."|".. + loc("Release rope: [Attack]"), 2, 9000) + target1Reached = true + end +end + +function onGearAdd(gear) + if GetGearType(gear) == gtRope then + ropeGear = gear + elseif GetGearType(gear) == gtMine then + mines[gear] = true + elseif GetGearType(gear) == gtGrenade then + if not ropeGear then + DeleteGear(gear) end end end -function Timer( Delay, Message ) - local Timer = {} - Timer.End = GetTime + Delay - Timer.Message = Message - - table.insert( Timers, Timer ) -end - -function onGameInit() -- Called when the game loads - Seed = 1 -- The base number for the random number generator - GameFlags = gfInfAttack + gfOneClanMode + gfSolidLand + gfInvulnerable + gfBorder -- Game settings and rules, going with a border to make it easier - TurnTime = 300000 -- Player can move for 5min each round - CaseFreq = 0 -- No random crate drops - MinesNum = 0 -- Never place any mines on the map - Explosives = 0 -- Never place any explosives - Delay = 1 -- We don't wont to wait between each round ( as the only is one ) - Map = "Ropes" -- Map name - Theme = "Nature" -- Map theme - -- Disable Sudden Death - SuddenDeathTurns = 50 - WaterRise = 0 - HealthDecrease = 0 - - AddTeam( loc( "Rope Team" ), 14483456, "Simple", "Island", "Default", "cm_shoppa" ) -- Lets make the team - Player = AddHog( loc( "Hunter" ), 0, 1, "StrawHat" ) -- Add a hog for it, and name it "Hunter" - SetGearPosition( Player, 420, 1750 ) -- Set player position - - SetEffect( Player, heResurrectable, 1 ) -- By Suggestion :) -end - -function onGameStart() -- Called when the game starts - SendHealthStatsOff() - AutoSpawn() -- Spawn our 1st target using the wrapper function - - SetHealth( Player, 100 ) -- Give the player 100 Health points - - PlaceGirder(46,1783, 0) -- Place a girder to prevent the player falling into the water - - local message = loc("Get to the target using your rope!") .. "|" .. loc("Controls: Hold the Attack key (space by default) to|fire the rope, then, once attached use:|Left and Right to swing the rope;|Up and Down to contract and expand.") - Info(loc("Training"), message, -amRope ) -- Short intro to tell the player what to do - Timer( 10000, message .. "|" .. loc("Tip: The rope physics are different than in the real world, |use it to your advantage!") ) -- After 15 sec, give them more help -end - -function onNewTurn() - SetWeapon(amRope) -- Set the default weapon to Rope +function onGearResurrect(gear) + -- Teleport hog to previous checkpoint + if gear == hog then + SetGearPosition(hog, cpX, cpY) + FollowGear(hog) + AddCaption(loc("Your hedgehog has been revived!")) + if isInMineChallenge then + resetMineChallenge(false) + end + end end -function onGameTick20() - if TurnTimeLeft < 40 and TurnTimeLeft > 0 then -- Round starts at 0, so we check if the round is finished by using 1 - GameLost = true -- You lost the game - Info(loc("Training"), loc("You did not make it in time, try again!"), -amSkip ) - if not StatsSent then - SendStat(siGameResult, loc("You failed!")) - SendStat(siCustomAchievement, loc("You did not make it in time, try again!")) - StatsSent = true - end - SetHealth( Player, 0 ) -- Kill the player so he can't keep moving! +function onGearDelete(gear) + if GetGearType(gear) == gtTarget then + -- Update checkpoint + cpX, cpY = GetGearPosition(gear) - SetEffect( Player, heResurrectable, 0 ) - - end - - -- If the player gets to the last target, they win OR - -- If round is finished and your not at the target you lose - -- in either case, end the game - if (Objective == true) or (GameLost == true) then - if (WaitTime == 0 and not StatsSent) then + -- New message + if currentTarget == 1 then + ShowMission(loc("Basic Rope Training"), loc("Obstacle"), + loc("Well done! Let's destroy the next target!").."|".. + loc("The targets will guide you through the training.").."|".. + loc("Use your rope to get to the next target, then destroy it!"), 2, 8000) + elseif currentTarget == 2 then + ShowMission(loc("Basic Rope Training"), loc("Speed Roping"), + loc("Try to reach and destroy the next target quickly.").."|".. + loc("Hint: When you shorten the rope, you move faster!|And when you lengthen it, you move slower."), 2, 15000) + elseif currentTarget == 3 then + ShowMission(loc("Basic Rope Training"), loc("Over the Water"), + loc("When you're in mid-air, you can continue to aim|and fire another rope if you're not attached.").."|".. + loc("To get over the water, you have to do multiple|rope shots and swings.").."|".. + loc("It needs some practice, but you have infinite lives.").."|".. + loc("Good luck!"), 2, 22500) + eraseGirder(1) + elseif currentTarget == 4 then + ShowMission(loc("Basic Rope Training"), loc("Little Obstacle Course"), + loc("Well done! The next target awaits.").."|".. + loc("Hint: The rope only bends around objects.|When it doesn't hit anything, it's always straight."), 2, 7000) + eraseGirder(8) + eraseGirder(9) + elseif currentTarget == 5 then + ShowMission(loc("Basic Rope Training"), loc("Rope Weapons"), + loc("Some weapons can be dropped from the rope.").."|".. + loc("Collect the weapon crate and drop|a grenade from rope to destroy the barrels.").."|".. + loc("Step 1: Start roping").."|".. + loc("Step 2: Select grenade").."|".. + loc("Step 3: Drop the grenade").."| |".. + loc("Drop weapon (while on rope): [Long Jump]"), 2, 20000) + AddAmmo(hog, amBaseballBat, 0) + SpawnAmmoCrate(1849, 920, amGrenade, 100) + elseif currentTarget == 6 then + ShowMission(loc("Basic Rope Training"), loc("Finite Ropes"), + loc("So far, you had infinite ropes, but in the|real world, ropes are usually limited.").."|".. + loc("Rules:").." |".. + loc("As long you don't touch the ground, you can|re-use the same rope as often as you like.").."|".. + loc("If you miss a shot while trying to|re-attach, your rope is gone, too!").."| |".. + loc("Final Challenge:").." |".. + loc("Reach and destroy the final target to win.").."|".. + loc("You only get 1 rope this time, don't waste it!").."|".. + loc("Avoid the mines!").."|".. + loc("Skip your turn to try again."), 2, 25000) + eraseGirder(4) + eraseGirder(5) + AddAmmo(hog, amRope, 1) + AddAmmo(hog, amSkip, 100) + isInMineChallenge = true + elseif currentTarget == 7 then + ShowMission(loc("Basic Rope Training"), loc("Training complete!"), + loc("Congratulations!"), 0, 0) + PlaySound(sndVictory, hog) + AddAmmo(hog, amBaseballBat, 0) + AddAmmo(hog, amGrenade, 0) + AddAmmo(hog, amRope, 0) + SendStat(siCustomAchievement, loc("Oh yeah! You sure know how to rope!")) SendStat(siGameResult, loc("You have finished the Basic Rope Training!")) - SendStat(siCustomAchievement, loc("Good job!")) - SendStat(siPlayerKills, "0", loc("Rope Team")) - if RopeMaster then - SendStat(siCustomAchievement, loc("You earned the \"Rope Master\" achievement for finishing in under 50 seconds.")) - end - StatsSent = true + SendStat(siPlayerKills, "0", teamName) EndGame() - else - WaitTime = WaitTime - 20 + gameOver = true + SetInputMask(0) end - end + currentTarget = currentTarget + 1 + + if currentTarget <= #targetData then + AddGear(targetData[currentTarget][1], targetData[currentTarget][2], gtTarget, 0, 0, 0, 0) + end - if FollowingGear == true then - if FollowTime == 0 then - FollowingGear = false - FollowTime = 1500 - FollowGear( Player ) - else - FollowTime = FollowTime - 20 + elseif GetGearType(gear) == gtExplosives then + if not barrelsBoom then + barrelsBoom = true + AddAmmo(hog, amGrenade, 0) + AddAmmo(hog, amBaseballBat, 100) + eraseGirder(2) + eraseGirder(3) end + elseif GetGearType(gear) == gtRope then + ropeGear = nil + if ropeAttached and not target1Reached then + ShowMission(loc("Basic Rope Training"), loc("How to Rope"), + loc("Go to the target.").."|".. + loc("Hold [Attack] to attach the rope.").."|".. + loc("Aim: [Up]/[Down]").."|".. + loc("Attack: [Space]"), 2, 13000) + ropeAttached = false + end + elseif GetGearType(gear) == gtMine then + mines[gear] = nil + elseif GetGearType(gear) == gtCase then + eraseGirder(6) + eraseGirder(7) end - - for k, v in pairs( Timers ) do - if v.End <= GetTime then - Info(loc("Training"), v.Message, -amRope ) - Timers[ k ] = nil - end - end - - GetTime = GetTime + 20 - - CheckPosition( Player, 70 ) -- Run the CheckPosition function to check if the player is close to a target end function onAmmoStoreInit() - SetAmmo( amRope, 9, 2, 0, 0 ) -- Player ammo, Rope - SetAmmo( amBaseballBat, 9, 2, 0, 0 ) --Baseball bat + SetAmmo(amRope, 9, 0, 0, 1) + SetAmmo(amBaseballBat, 9, 0, 0, 1) end -function onGearDelete( Gear ) - if GetGearType( Gear ) == gtTarget then - AutoSpawn() -- When a target is deleted / destroyed, spawn a new one! +function onHogAttack(ammoType) + -- Allow to manually reset final challenge with skip + if ammoType == amSkip then + resetMineChallenge() end end + +function onAttack() + if GetCurAmmoType() == amGrenade and not ropeGear then + AddCaption(loc("You have to drop the grenade from rope!"), 0xFF4000FF, capgrpMessage) + PlaySound(sndDenied) + end +end