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 |
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 |
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 |
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) |