|
1 --[=[ |
|
2 Speed Shoppa Mission Framework for Hedgewars |
|
3 |
|
4 This is a simple library intended to make setting up simple training missions a trivial |
|
5 task. The library has been created to reduce redundancy in Lua scripts. |
|
6 |
|
7 The framework generates complete and fully Speed Shoppa missions by just |
|
8 one function call. |
|
9 |
|
10 The missions generated by this script are all the same: |
|
11 - The player will get a team with a single hedgehog. |
|
12 - The team gets infinite ropes. |
|
13 - A fixed set of crates will spawn at predefined positions. |
|
14 - The mission ends successfully when all crates have been collected |
|
15 - The mission ends unsuccessfully when the time runs out or the hedgehog dies |
|
16 - When the mission ends, the time it took to finish the mission is shown |
|
17 |
|
18 To use this library, you first have to load it and to call SpeedShoppaMission once with |
|
19 the appropriate parameters. Really, that’s all! |
|
20 See the comment of SpeedShoppaMission for a specification of all parameters. |
|
21 |
|
22 ]=] |
|
23 |
|
24 HedgewarsScriptLoad("/Scripts/Locale.lua") |
|
25 |
|
26 --[[ |
|
27 SpeedShoppaMission(params) |
|
28 |
|
29 This function sets up the *entire* mission and needs one argument: params. |
|
30 The argument “params” is a table containing fields which describe the training mission. |
|
31 mandatory fields: |
|
32 - map: the name of the map to be used |
|
33 - theme: the name of the theme (does not need to be a standalone theme) |
|
34 - time: the time limit in milliseconds |
|
35 - crates: The coordinates of where the crates will be spawned. |
|
36 It is a table containing tables containing coordinates of format |
|
37 { x=value, y=value }. Example: |
|
38 crates = { |
|
39 { x = 324, y = 43 }, |
|
40 { x = 123, y = 56 }, |
|
41 { x = 6, y = 0 }, |
|
42 } |
|
43 There must be at least 1 crate. |
|
44 |
|
45 optional fields: |
|
46 - missionTitle: the name of the mission (optional but highly recommended) (default: "Speed Shoppa") |
|
47 - hogHat: hat of the hedgehog (default: "NoHat") |
|
48 - hogName: name of the hedgehog (default: "Roper") |
|
49 - teamName: name of the hedgehog’s team (default: "Shoppers") |
|
50 - teamGrave: name of the hedgehog’s grave (default: "Statue") |
|
51 - teamFlag: name of the team’s flag (default: "cm_shoppa") |
|
52 - clanColor: color of the (only) clan (default: 0xFF0204, which is a red tone) |
|
53 - goalText: A short string explaining the goal of the mission |
|
54 (default: "Use your rope to collect all crates as fast as possible.") |
|
55 - faceLeft: If true, the hog faces to the left initially, if false, it faces to the right. |
|
56 (default: false (=right)) |
|
57 - crateType Specify the type of crate (this has no gameplay effect), pick one of |
|
58 "ammo", "utility", "health". Default: "ammo" |
|
59 - extra_onGameStart: A function which is called at the end of this script's onGameStart. It takes no parameters. |
|
60 You could use this to spawn additional gears like girders or mines. |
|
61 - extra_onGameInit: A function which is called at the end of this script's onGameInit. |
|
62 ]] |
|
63 |
|
64 |
|
65 local playerHog |
|
66 local gameStarted = false |
|
67 local cratesCollected = 0 |
|
68 local gameEnded = false |
|
69 local timeOut = false |
|
70 local hogHurt = false |
|
71 local endTime |
|
72 |
|
73 local crates |
|
74 |
|
75 function SpeedShoppaMission(params) |
|
76 if params.hogHat == nil then params.hogHat = "NoHat" end |
|
77 if params.hogName == nil then params.hogName = loc("Roper") end |
|
78 if params.teamName == nil then params.teamName = loc("Shoppers") end |
|
79 if params.goalText == nil then params.goalText = loc("Use your rope to collect all crates as fast as possible.") end |
|
80 if params.missionTitle == nil then params.missionTitle = loc("Speed Shoppa") end |
|
81 if params.clanColor == nil then params.clanColor = 0xFF0204 end |
|
82 if params.teamGrave == nil then params.teamGrave = "Statue" end |
|
83 if params.teamFlag == nil then params.teamFlag = "cm_shoppa" end |
|
84 if params.extra_onGameInit == nil then params.extra_onGameInit = function() end end |
|
85 if params.extra_onGameStart == nil then params.extra_onGameStart = function() end end |
|
86 if params.faceLeft == nil then params.faceLeft = false end |
|
87 |
|
88 crates = params.crates |
|
89 startTime = params.time |
|
90 |
|
91 _G.onGameInit = function() |
|
92 GameFlags = gfDisableWind + gfOneClanMode + gfBorder + gfSolidLand |
|
93 TurnTime = startTime |
|
94 CaseFreq = 0 |
|
95 MinesNum = 0 |
|
96 Explosives = 0 |
|
97 Delay = 10 |
|
98 Theme = params.theme |
|
99 Map = params.map |
|
100 |
|
101 AddTeam(params.teamName, params.clanColor, params.teamGrave, "Castle", "Default", params.teamFlag) |
|
102 playerHog = AddHog(params.hogName, 0, 1, params.hogHat) |
|
103 HogTurnLeft(playerHog, params.faceLeft) |
|
104 |
|
105 SetGearPosition(playerHog, params.hog_x, params.hog_y) |
|
106 |
|
107 params.extra_onGameInit() |
|
108 end |
|
109 |
|
110 _G.onAmmoStoreInit = function() |
|
111 SetAmmo(amRope, 9, 0, 0, 1) |
|
112 end |
|
113 |
|
114 _G.onGameStart = function() |
|
115 SendHealthStatsOff() |
|
116 ShowMission(params.missionTitle, loc("Challenge"), params.goalText, -amRope, 5000) |
|
117 for i=1,#crates do |
|
118 spawnCrate(crates[i].x, crates[i].y) |
|
119 end |
|
120 params.extra_onGameStart() |
|
121 end |
|
122 |
|
123 _G.onNewTurn = function() |
|
124 SetWeapon(amRope) |
|
125 gameStarted = true |
|
126 end |
|
127 _G.onGearDelete = function(gear) |
|
128 if GetGearType(gear) == gtCase and not hogHurt and not timeOut then |
|
129 cratesCollected = cratesCollected + 1 |
|
130 PlaySound(sndShotgunReload) |
|
131 if cratesCollected == #crates then |
|
132 endTime = TurnTimeLeft |
|
133 finalize() |
|
134 else |
|
135 AddCaption(string.format(loc("%d crate(s) remaining"), #crates - cratesCollected)) |
|
136 end |
|
137 elseif gear == playerHog then |
|
138 finalize() |
|
139 end |
|
140 end |
|
141 |
|
142 _G.onGearDamage = function(gear) |
|
143 if gear == playerHog then |
|
144 hogHurt = true |
|
145 end |
|
146 end |
|
147 |
|
148 |
|
149 _G.onGameTick20 = function() |
|
150 if TurnTimeLeft < 40 and TurnTimeLeft > 0 and gameStarted and not timeOut and not gameEnded then |
|
151 timeOut = true |
|
152 AddCaption(loc("Time's up!")) |
|
153 SetHealth(playerHog, 0) |
|
154 hogHurt = true |
|
155 end |
|
156 end |
|
157 |
|
158 _G.finalize = function() |
|
159 if not gameEnded then |
|
160 if cratesCollected == #crates then |
|
161 PlaySound(sndVictory, playerHog) |
|
162 SetState(playerHog, bor(GetState(playerHog), gstWinner)) |
|
163 SetState(playerHog, band(GetState(playerHog), bnot(gstHHDriven))) |
|
164 AddCaption(loc("Challenge completed!")) |
|
165 SendStat(siGameResult, loc("Challenge completed!")) |
|
166 SendStat(siPointType, loc("milliseconds")) |
|
167 local time = startTime - endTime |
|
168 SendStat(siPlayerKills, tostring(time), params.teamName) |
|
169 SendStat(siCustomAchievement, string.format(loc("You have finished the challenge in %.3f s."), (time/1000))) |
|
170 TurnTimeLeft = 0 |
|
171 else |
|
172 SendStat(siGameResult, loc("Challenge failed!")) |
|
173 SendStat(siPointType, loc("crate(s)")) |
|
174 SendStat(siPlayerKills, tostring(cratesCollected), params.teamName) |
|
175 SendStat(siCustomAchievement, string.format(loc("You have collected %d out of %d crate(s)."), cratesCollected, #crates)) |
|
176 end |
|
177 gameEnded = true |
|
178 EndGame() |
|
179 end |
|
180 end |
|
181 |
|
182 _G.spawnCrate = function(x, y) |
|
183 if params.crateType == "utility" then |
|
184 SpawnFakeUtilityCrate(x, y, false, false) |
|
185 elseif params.crateType == "ammo" then |
|
186 SpawnFakeAmmoCrate(x, y, false, false) |
|
187 elseif params.crateType == "health" then |
|
188 SpawnFakeHealthCrate(x, y, false, false) |
|
189 else |
|
190 SpawnFakeAmmoCrate(x, y, false, false) |
|
191 end |
|
192 end |
|
193 |
|
194 end |