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