86 d := r - hwRound(Distance(gi^.X - x, gi^.Y - y)); |
87 d := r - hwRound(Distance(gi^.X - x, gi^.Y - y)); |
87 if (d > 1) and (not gi^.Invulnerable) and (GetRandom(2) = 0) then |
88 if (d > 1) and (not gi^.Invulnerable) and (GetRandom(2) = 0) then |
88 begin |
89 begin |
89 if (CurrentHedgehog^.Gear = gi) then |
90 if (CurrentHedgehog^.Gear = gi) then |
90 PlaySound(sndOops, gi^.Hedgehog^.Team^.voicepack) |
91 PlaySound(sndOops, gi^.Hedgehog^.Team^.voicepack) |
|
92 |
91 else |
93 else |
92 begin |
94 begin |
93 if (gi^.State and gstMoving) = 0 then |
95 if (gi^.State and gstMoving) = 0 then |
94 gi^.State := gi^.State or gstLoser; |
96 gi^.State := gi^.State or gstLoser; |
|
97 |
95 if d > r div 2 then |
98 if d > r div 2 then |
96 PlaySound(sndNooo, gi^.Hedgehog^.Team^.voicepack) |
99 PlaySound(sndNooo, gi^.Hedgehog^.Team^.voicepack) |
97 else |
100 else |
98 PlaySound(sndUhOh, gi^.Hedgehog^.Team^.voicepack); |
101 PlaySound(sndUhOh, gi^.Hedgehog^.Team^.voicepack); |
99 end; |
102 end; |
100 end; |
103 end; |
101 end; |
104 end; |
|
105 |
102 gi := gi^.NextGear |
106 gi := gi^.NextGear |
103 end; |
107 end; |
104 end; |
108 end; |
105 |
109 |
106 procedure HideHog(HH: PHedgehog); |
110 procedure HideHog(HH: PHedgehog); |
107 begin |
111 begin |
108 ScriptCall('onHogHide', HH^.Gear^.Uid); |
112 ScriptCall('onHogHide', HH^.Gear^.Uid); |
109 DeleteCI(HH^.Gear); |
113 DeleteCI(HH^.Gear); |
110 if FollowGear = HH^.Gear then FollowGear:= nil; |
114 if FollowGear = HH^.Gear then |
111 if lastGearByUID = HH^.Gear then lastGearByUID := nil; |
115 FollowGear:= nil; |
112 RemoveGearFromList(HH^.Gear); |
116 |
113 with HH^.Gear^ do |
117 if lastGearByUID = HH^.Gear then |
|
118 lastGearByUID := nil; |
|
119 |
|
120 RemoveGearFromList(HH^.Gear); |
|
121 with HH^.Gear^ do |
|
122 begin |
|
123 Z := cHHZ; |
|
124 Active := false; |
|
125 State:= State and (not (gstHHDriven or gstAttacking or gstAttacked)); |
|
126 Message := Message and (not gmAttack); |
|
127 end; |
|
128 HH^.GearHidden:= HH^.Gear; |
|
129 HH^.Gear:= nil |
|
130 end; |
|
131 |
|
132 procedure RestoreHog(HH: PHedgehog); |
|
133 begin |
|
134 HH^.Gear:=HH^.GearHidden; |
|
135 HH^.GearHidden:= nil; |
|
136 InsertGearToList(HH^.Gear); |
|
137 HH^.Gear^.State:= (HH^.Gear^.State and (not (gstHHDriven or gstInvisible or gstAttacking))) or gstAttacked; |
|
138 AddGearCI(HH^.Gear); |
|
139 HH^.Gear^.Active:= true; |
|
140 ScriptCall('onHogRestore', HH^.Gear^.Uid) |
|
141 end; |
|
142 |
|
143 //////////////////////////////////////////////////////////////////////////////// |
|
144 procedure CheckCollision(Gear: PGear); inline; |
|
145 begin |
|
146 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) |
|
147 or (TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) <> 0) then |
|
148 Gear^.State := Gear^.State or gstCollision |
|
149 else |
|
150 Gear^.State := Gear^.State and (not gstCollision) |
|
151 end; |
|
152 |
|
153 procedure CheckCollisionWithLand(Gear: PGear); inline; |
|
154 begin |
|
155 if TestCollisionX(Gear, hwSign(Gear^.dX)) |
|
156 or TestCollisionY(Gear, hwSign(Gear^.dY)) then |
|
157 Gear^.State := Gear^.State or gstCollision |
|
158 else |
|
159 Gear^.State := Gear^.State and (not gstCollision) |
|
160 end; |
|
161 |
|
162 |
|
163 //////////////////////////////////////////////////////////////////////////////// |
|
164 |
|
165 |
|
166 //////////////////////////////////////////////////////////////////////////////// |
|
167 procedure doStepDrowningGear(Gear: PGear); |
114 begin |
168 begin |
115 Z := cHHZ; |
|
116 Active := false; |
|
117 State:= State and (not (gstHHDriven or gstAttacking or gstAttacked)); |
|
118 Message := Message and (not gmAttack); |
|
119 end; |
|
120 HH^.GearHidden:= HH^.Gear; |
|
121 HH^.Gear:= nil |
|
122 end; |
|
123 |
|
124 procedure RestoreHog(HH: PHedgehog); |
|
125 begin |
|
126 HH^.Gear:=HH^.GearHidden; |
|
127 HH^.GearHidden:= nil; |
|
128 InsertGearToList(HH^.Gear); |
|
129 HH^.Gear^.State:= (HH^.Gear^.State and (not (gstHHDriven or gstInvisible or gstAttacking))) or gstAttacked; |
|
130 AddGearCI(HH^.Gear); |
|
131 HH^.Gear^.Active:= true; |
|
132 ScriptCall('onHogRestore', HH^.Gear^.Uid) |
|
133 end; |
|
134 |
|
135 //////////////////////////////////////////////////////////////////////////////// |
|
136 procedure CheckCollision(Gear: PGear); inline; |
|
137 begin |
|
138 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) or (TestCollisionYwithGear(Gear, hwSign(Gear^.dY)) <> 0) then |
|
139 Gear^.State := Gear^.State or gstCollision |
|
140 else Gear^.State := Gear^.State and (not gstCollision) |
|
141 end; |
|
142 |
|
143 procedure CheckCollisionWithLand(Gear: PGear); inline; |
|
144 begin |
|
145 if TestCollisionX(Gear, hwSign(Gear^.dX)) or TestCollisionY(Gear, hwSign(Gear^.dY) |
|
146 ) |
|
147 then Gear^.State := Gear^.State or gstCollision |
|
148 else Gear^.State := Gear^.State and (not gstCollision) |
|
149 end; |
|
150 |
|
151 |
|
152 //////////////////////////////////////////////////////////////////////////////// |
|
153 |
|
154 |
|
155 //////////////////////////////////////////////////////////////////////////////// |
|
156 procedure doStepDrowningGear(Gear: PGear); |
|
157 begin |
|
158 AllInactive := false; |
169 AllInactive := false; |
159 Gear^.Y := Gear^.Y + cDrownSpeed; |
170 Gear^.Y := Gear^.Y + cDrownSpeed; |
160 Gear^.X := Gear^.X + Gear^.dX * cDrownSpeed; |
171 Gear^.X := Gear^.X + Gear^.dX * cDrownSpeed; |
161 // Create some bubbles (0.5% might be better but causes too few bubbles sometimes) |
172 // Create some bubbles (0.5% might be better but causes too few bubbles sometimes) |
162 if ((not SuddenDeathDmg and (cWaterOpacity < $FF)) or (SuddenDeathDmg and (cSDWaterOpacity < $FF))) and ((GameTicks and $1F) = 0) then |
173 if ((not SuddenDeathDmg and (cWaterOpacity < $FF)) |
|
174 or (SuddenDeathDmg and (cSDWaterOpacity < $FF))) and ((GameTicks and $1F) = 0) then |
163 if (Gear^.Kind = gtHedgehog) and (Random(4) = 0) then |
175 if (Gear^.Kind = gtHedgehog) and (Random(4) = 0) then |
164 AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble) |
176 AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble) |
165 else if Random(12) = 0 then |
177 else if Random(12) = 0 then |
166 AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble); |
178 AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble); |
167 if (not SuddenDeathDmg and (cWaterOpacity > $FE)) or (SuddenDeathDmg and (cSDWaterOpacity > $FE)) or (hwRound(Gear^.Y) > Gear^.Radius + cWaterLine + cVisibleWater) then |
179 if (not SuddenDeathDmg and (cWaterOpacity > $FE)) |
|
180 or (SuddenDeathDmg and (cSDWaterOpacity > $FE)) |
|
181 or (hwRound(Gear^.Y) > Gear^.Radius + cWaterLine + cVisibleWater) then |
168 DeleteGear(Gear); |
182 DeleteGear(Gear); |
169 end; |
183 end; |
170 |
184 |
171 //////////////////////////////////////////////////////////////////////////////// |
185 //////////////////////////////////////////////////////////////////////////////// |
172 procedure doStepFallingGear(Gear: PGear); |
186 procedure doStepFallingGear(Gear: PGear); |
173 var |
187 var |
174 isFalling: boolean; |
188 isFalling: boolean; |
176 tdX, tdY: hwFloat; |
190 tdX, tdY: hwFloat; |
177 collV, collH: LongInt; |
191 collV, collH: LongInt; |
178 land: word; |
192 land: word; |
179 begin |
193 begin |
180 // clip velocity at 1.9 - over 1 per pixel, but really shouldn't cause many actual problems. |
194 // clip velocity at 1.9 - over 1 per pixel, but really shouldn't cause many actual problems. |
181 if Gear^.dX.QWordValue > 8160437862 then Gear^.dX.QWordValue:= 8160437862; |
195 if Gear^.dX.QWordValue > 8160437862 then |
182 if Gear^.dY.QWordValue > 8160437862 then Gear^.dY.QWordValue:= 8160437862; |
196 Gear^.dX.QWordValue:= 8160437862; |
|
197 if Gear^.dY.QWordValue > 8160437862 then |
|
198 Gear^.dY.QWordValue:= 8160437862; |
183 Gear^.State := Gear^.State and (not gstCollision); |
199 Gear^.State := Gear^.State and (not gstCollision); |
184 collV := 0; |
200 collV := 0; |
185 collH := 0; |
201 collH := 0; |
186 tdX := Gear^.dX; |
202 tdX := Gear^.dX; |
187 tdY := Gear^.dY; |
203 tdY := Gear^.dY; |
188 |
204 |
189 |
205 |
190 // might need some testing/adjustments - just to avoid projectiles to fly forever (accelerated by wind/skips) |
206 // might need some testing/adjustments - just to avoid projectiles to fly forever (accelerated by wind/skips) |
191 if (hwRound(Gear^.X) < LAND_WIDTH div -2) or (hwRound(Gear^.X) > LAND_WIDTH * 3 div 2) then Gear^.State := Gear^.State or gstCollision; |
207 if (hwRound(Gear^.X) < LAND_WIDTH div -2) |
|
208 or (hwRound(Gear^.X) > LAND_WIDTH * 3 div 2) then |
|
209 Gear^.State := Gear^.State or gstCollision; |
192 |
210 |
193 if Gear^.dY.isNegative then |
211 if Gear^.dY.isNegative then |
194 begin |
212 begin |
195 isFalling := true; |
213 isFalling := true; |
196 land:= TestCollisionYwithGear(Gear, -1); |
214 land:= TestCollisionYwithGear(Gear, -1); |
197 if land <> 0 then |
215 if land <> 0 then |
198 begin |
216 begin |
199 collV := -1; |
217 collV := -1; |
200 if land and lfIce <> 0 then Gear^.dX := Gear^.dX * (_0_9 + Gear^.Friction * _0_1) |
218 if land and lfIce <> 0 then |
201 else Gear^.dX := Gear^.dX * Gear^.Friction; |
219 Gear^.dX := Gear^.dX * (_0_9 + Gear^.Friction * _0_1) |
|
220 else |
|
221 Gear^.dX := Gear^.dX * Gear^.Friction; |
202 |
222 |
203 Gear^.dY := - Gear^.dY * Gear^.Elasticity; |
223 Gear^.dY := - Gear^.dY * Gear^.Elasticity; |
204 Gear^.State := Gear^.State or gstCollision |
224 Gear^.State := Gear^.State or gstCollision |
205 end |
225 end |
206 else if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, 1) <> 0) then collV := 1; |
226 else if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, 1) <> 0) then |
|
227 collV := 1; |
207 end |
228 end |
208 else |
229 else |
209 begin // Gear^.dY.isNegative is false |
230 begin // Gear^.dY.isNegative is false |
210 land:= TestCollisionYwithGear(Gear, 1); |
231 land:= TestCollisionYwithGear(Gear, 1); |
211 if land <> 0 then |
232 if land <> 0 then |
237 Gear^.State := Gear^.State or gstCollision |
258 Gear^.State := Gear^.State or gstCollision |
238 end |
259 end |
239 else if (Gear^.AdvBounce=1) and TestCollisionXwithGear(Gear, -hwSign(Gear^.dX)) then |
260 else if (Gear^.AdvBounce=1) and TestCollisionXwithGear(Gear, -hwSign(Gear^.dX)) then |
240 collH := -hwSign(Gear^.dX); |
261 collH := -hwSign(Gear^.dX); |
241 //if Gear^.AdvBounce and (collV <>0) and (collH <> 0) and (hwSqr(tdX) + hwSqr(tdY) > _0_08) then |
262 //if Gear^.AdvBounce and (collV <>0) and (collH <> 0) and (hwSqr(tdX) + hwSqr(tdY) > _0_08) then |
242 if (Gear^.AdvBounce=1) and (collV <>0) and (collH <> 0) and ((collV=-1) or ((tdX.QWordValue + |
263 if (Gear^.AdvBounce=1) and (collV <>0) and (collH <> 0) and ((collV=-1) |
243 tdY.QWordValue) > _0_2.QWordValue)) then |
264 or ((tdX.QWordValue + tdY.QWordValue) > _0_2.QWordValue)) then |
244 begin |
265 begin |
245 Gear^.dX := tdY*Gear^.Elasticity*Gear^.Friction; |
266 Gear^.dX := tdY*Gear^.Elasticity*Gear^.Friction; |
246 Gear^.dY := tdX*Gear^.Elasticity; |
267 Gear^.dY := tdX*Gear^.Elasticity; |
247 //*Gear^.Friction; |
268 //*Gear^.Friction; |
248 Gear^.dY.isNegative := not tdY.isNegative; |
269 Gear^.dY.isNegative := not tdY.isNegative; |
249 isFalling := false; |
270 isFalling := false; |
250 Gear^.AdvBounce := 10; |
271 Gear^.AdvBounce := 10; |
251 end; |
272 end; |
252 |
273 |
253 if Gear^.AdvBounce > 1 then dec(Gear^.AdvBounce); |
274 if Gear^.AdvBounce > 1 then |
|
275 dec(Gear^.AdvBounce); |
254 |
276 |
255 if isFalling then |
277 if isFalling then |
256 begin |
278 begin |
257 Gear^.dY := Gear^.dY + cGravity; |
279 Gear^.dY := Gear^.dY + cGravity; |
258 if (GameFlags and gfMoreWind) <> 0 then Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density |
280 if (GameFlags and gfMoreWind) <> 0 then |
259 end; |
281 Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density |
|
282 end; |
260 |
283 |
261 Gear^.X := Gear^.X + Gear^.dX; |
284 Gear^.X := Gear^.X + Gear^.dX; |
262 Gear^.Y := Gear^.Y + Gear^.dY; |
285 Gear^.Y := Gear^.Y + Gear^.dY; |
263 if Gear^.Kind <> gtBee then |
286 if Gear^.Kind <> gtBee then |
264 CheckGearDrowning(Gear); |
287 CheckGearDrowning(Gear); |
265 //if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_0002) and |
288 //if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_0002) and |
266 if (not isFalling) and ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_02.QWordValue) then |
289 if (not isFalling) and ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_02.QWordValue) then |
267 Gear^.State := Gear^.State and (not gstMoving) |
290 Gear^.State := Gear^.State and (not gstMoving) |
268 else |
291 else |
269 Gear^.State := Gear^.State or gstMoving; |
292 Gear^.State := Gear^.State or gstMoving; |
270 |
293 |
271 if (Gear^.nImpactSounds > 0) and |
294 if (Gear^.nImpactSounds > 0) and (((Gear^.Kind <> gtMine) and (Gear^.Damage <> 0)) |
272 (((Gear^.Kind <> gtMine) and (Gear^.Damage <> 0)) or |
295 or ((Gear^.State and (gstCollision or gstMoving)) = (gstCollision or gstMoving))) and(((Gear^.Radius < 3) and (Gear^.dY < -_0_1)) |
273 ((Gear^.State and (gstCollision or gstMoving)) = (gstCollision or gstMoving))) and |
296 or ((Gear^.Radius >= 3) and ((Gear^.dX.QWordValue > _0_1.QWordValue) |
274 (((Gear^.Radius < 3) and (Gear^.dY < -_0_1)) or |
297 or (Gear^.dY.QWordValue > _0_1.QWordValue)))) then |
275 ((Gear^.Radius >= 3) and ((Gear^.dX.QWordValue > _0_1.QWordValue) or |
|
276 (Gear^.dY.QWordValue > _0_1.QWordValue)))) then |
|
277 PlaySound(TSound(ord(Gear^.ImpactSound) + LongInt(GetRandom(Gear^.nImpactSounds))), true); |
298 PlaySound(TSound(ord(Gear^.ImpactSound) + LongInt(GetRandom(Gear^.nImpactSounds))), true); |
278 end; |
299 end; |
279 |
300 |
280 //////////////////////////////////////////////////////////////////////////////// |
301 //////////////////////////////////////////////////////////////////////////////// |
281 procedure doStepBomb(Gear: PGear); |
302 procedure doStepBomb(Gear: PGear); |
297 gtHellishBomb: makeHogsWorry(Gear^.X, Gear^.Y, 90); |
318 gtHellishBomb: makeHogsWorry(Gear^.X, Gear^.Y, 90); |
298 gtGasBomb: makeHogsWorry(Gear^.X, Gear^.Y, 50); |
319 gtGasBomb: makeHogsWorry(Gear^.X, Gear^.Y, 50); |
299 end; |
320 end; |
300 |
321 |
301 if (Gear^.Kind = gtBall) and ((Gear^.State and gstTmpFlag) <> 0) then |
322 if (Gear^.Kind = gtBall) and ((Gear^.State and gstTmpFlag) <> 0) then |
302 begin |
323 begin |
303 CheckCollision(Gear); |
324 CheckCollision(Gear); |
304 if (Gear^.State and gstCollision) <> 0 then |
325 if (Gear^.State and gstCollision) <> 0 then |
305 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLDontDraw or EXPLNoGfx); |
326 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLDontDraw or EXPLNoGfx); |
306 end; |
327 end; |
307 |
328 |
308 if (Gear^.Kind = gtGasBomb) and ((GameTicks mod 200) = 0) then |
329 if (Gear^.Kind = gtGasBomb) and ((GameTicks mod 200) = 0) then |
309 begin |
330 begin |
310 vg:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeWhite); |
331 vg:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeWhite); |
311 if vg <> nil then |
332 if vg <> nil then |
312 vg^.Tint:= $FFC0C000; |
333 vg^.Tint:= $FFC0C000; |
313 end; |
334 end; |
314 |
335 |
315 if Gear^.Timer = 0 then |
336 if Gear^.Timer = 0 then |
316 begin |
337 begin |
317 case Gear^.Kind of |
338 case Gear^.Kind of |
318 gtGrenade: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); |
339 gtGrenade: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); |
319 gtBall: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 40, Gear^.Hedgehog, EXPLAutoSound); |
340 gtBall: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 40, Gear^.Hedgehog, EXPLAutoSound); |
320 gtClusterBomb: |
341 gtClusterBomb: |
321 begin |
342 begin |
322 x := hwRound(Gear^.X); |
343 x := hwRound(Gear^.X); |
323 y := hwRound(Gear^.Y); |
344 y := hwRound(Gear^.Y); |
324 doMakeExplosion(x, y, 20, Gear^.Hedgehog, EXPLAutoSound); |
345 doMakeExplosion(x, y, 20, Gear^.Hedgehog, EXPLAutoSound); |
325 for i:= 0 to 4 do |
346 for i:= 0 to 4 do |
326 begin |
347 begin |
327 dX := rndSign(GetRandom * _0_1) + Gear^.dX / 5; |
348 dX := rndSign(GetRandom * _0_1) + Gear^.dX / 5; |
328 dY := (GetRandom - _3) * _0_08; |
349 dY := (GetRandom - _3) * _0_08; |
329 FollowGear := AddGear(x, y, gtCluster, 0, dX, dY, 25) |
350 FollowGear := AddGear(x, y, gtCluster, 0, dX, dY, 25) |
330 end |
351 end |
331 end; |
352 end; |
332 gtWatermelon: |
353 gtWatermelon: |
333 begin |
354 begin |
334 x := hwRound(Gear^.X); |
355 x := hwRound(Gear^.X); |
335 y := hwRound(Gear^.Y); |
356 y := hwRound(Gear^.Y); |
457 AddGear(gX, gY, gtFlame, gstTmpFlag,-dX, dY, 0); |
484 AddGear(gX, gY, gtFlame, gstTmpFlag,-dX, dY, 0); |
458 AddGear(gX, gY, gtFlame, gstTmpFlag,-dX,-dY, 0); |
485 AddGear(gX, gY, gtFlame, gstTmpFlag,-dX,-dY, 0); |
459 end; |
486 end; |
460 DeleteGear(Gear); |
487 DeleteGear(Gear); |
461 exit |
488 exit |
462 end; |
489 end; |
463 end; |
490 end; |
464 |
491 |
465 //////////////////////////////////////////////////////////////////////////////// |
492 //////////////////////////////////////////////////////////////////////////////// |
466 |
493 |
467 procedure doStepCluster(Gear: PGear); |
494 procedure doStepCluster(Gear: PGear); |
468 begin |
495 begin |
469 AllInactive := false; |
496 AllInactive := false; |
470 doStepFallingGear(Gear); |
497 doStepFallingGear(Gear); |
471 if (Gear^.State and gstCollision) <> 0 then |
498 if (Gear^.State and gstCollision) <> 0 then |
472 begin |
499 begin |
473 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Timer, Gear^.Hedgehog, EXPLAutoSound); |
500 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Timer, Gear^.Hedgehog, EXPLAutoSound); |
474 DeleteGear(Gear); |
501 DeleteGear(Gear); |
475 exit |
502 exit |
476 end; |
503 end; |
477 |
504 |
478 if (Gear^.Kind = gtMelonPiece) or (Gear^.Kind = gtBall) then |
505 if (Gear^.Kind = gtMelonPiece) |
|
506 or (Gear^.Kind = gtBall) then |
479 CalcRotationDirAngle(Gear) |
507 CalcRotationDirAngle(Gear) |
480 else if (GameTicks and $1F) = 0 then |
508 else if (GameTicks and $1F) = 0 then |
481 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) |
509 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) |
482 end; |
510 end; |
483 |
511 |
484 //////////////////////////////////////////////////////////////////////////////// |
512 //////////////////////////////////////////////////////////////////////////////// |
485 procedure doStepShell(Gear: PGear); |
513 procedure doStepShell(Gear: PGear); |
486 begin |
514 begin |
487 AllInactive := false; |
515 AllInactive := false; |
488 if (GameFlags and gfMoreWind) = 0 then Gear^.dX := Gear^.dX + cWindSpeed; |
516 if (GameFlags and gfMoreWind) = 0 then |
|
517 Gear^.dX := Gear^.dX + cWindSpeed; |
489 doStepFallingGear(Gear); |
518 doStepFallingGear(Gear); |
490 if (Gear^.State and gstCollision) <> 0 then |
519 if (Gear^.State and gstCollision) <> 0 then |
491 begin |
520 begin |
492 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); |
521 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); |
493 DeleteGear(Gear); |
522 DeleteGear(Gear); |
513 Gear^.dX.isNegative:= not Gear^.dX.isNegative; |
543 Gear^.dX.isNegative:= not Gear^.dX.isNegative; |
514 AmmoShove(Gear, 1, kick); |
544 AmmoShove(Gear, 1, kick); |
515 for i:= 15 + kick div 10 downto 0 do |
545 for i:= 15 + kick div 10 downto 0 do |
516 begin |
546 begin |
517 particle := AddVisualGear(hwRound(Gear^.X) + Random(25), hwRound(Gear^.Y) + Random(25), vgtDust); |
547 particle := AddVisualGear(hwRound(Gear^.X) + Random(25), hwRound(Gear^.Y) + Random(25), vgtDust); |
518 if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480) |
548 if particle <> nil then |
|
549 particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480) |
519 end; |
550 end; |
520 DeleteGear(Gear); |
551 DeleteGear(Gear); |
521 exit |
552 exit |
522 end; |
553 end; |
523 if ((GameTicks and $1F) = 0) and (Random(3) = 0) then |
554 if ((GameTicks and $1F) = 0) and (Random(3) = 0) then |
524 begin |
555 begin |
525 particle:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtDust); |
556 particle:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtDust); |
526 if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480) |
557 if particle <> nil then |
|
558 particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480) |
527 end |
559 end |
528 end; |
560 end; |
529 |
561 |
530 //////////////////////////////////////////////////////////////////////////////// |
562 //////////////////////////////////////////////////////////////////////////////// |
531 procedure doStepSnowflake(Gear: PGear); |
563 procedure doStepSnowflake(Gear: PGear); |
558 xx:= hwRound(X); |
591 xx:= hwRound(X); |
559 yy:= hwRound(Y); |
592 yy:= hwRound(Y); |
560 if vobVelocity <> 0 then |
593 if vobVelocity <> 0 then |
561 begin |
594 begin |
562 DirAngle := DirAngle + (Angle / 1250000000); |
595 DirAngle := DirAngle + (Angle / 1250000000); |
563 if DirAngle < 0 then DirAngle := DirAngle + 360 |
596 if DirAngle < 0 then |
564 else if 360 < DirAngle then DirAngle := DirAngle - 360; |
597 DirAngle := DirAngle + 360 |
|
598 else if 360 < DirAngle then |
|
599 DirAngle := DirAngle - 360; |
565 end; |
600 end; |
566 |
601 |
567 inc(Health, 8); |
602 inc(Health, 8); |
568 if longword(Health) > vobFrameTicks then |
603 if longword(Health) > vobFrameTicks then |
569 begin |
604 begin |
570 dec(Health, vobFrameTicks); |
605 dec(Health, vobFrameTicks); |
571 inc(Timer); |
606 inc(Timer); |
572 if Timer = vobFramesCount then Timer:= 0 |
607 if Timer = vobFramesCount then |
|
608 Timer:= 0 |
573 end; |
609 end; |
574 // move back to cloud layer |
610 // move back to cloud layer |
575 if yy > cWaterLine then move:= true |
611 if yy > cWaterLine then |
576 else if ((yy and LAND_HEIGHT_MASK) <> 0) or (xx > LAND_WIDTH + 512) or (xx < -512) then move:=true |
612 move:= true |
|
613 else if ((yy and LAND_HEIGHT_MASK) <> 0) |
|
614 or (xx > LAND_WIDTH + 512) or (xx < -512) then |
|
615 move:=true |
577 // Solid pixel encountered |
616 // Solid pixel encountered |
578 else if ((xx and LAND_WIDTH_MASK) = 0) and (Land[yy, xx] <> 0) then |
617 else if ((xx and LAND_WIDTH_MASK) = 0) and (Land[yy, xx] <> 0) then |
579 begin |
618 begin |
580 lf:= Land[yy, xx] and (lfObject or lfBasic); |
619 lf:= Land[yy, xx] and (lfObject or lfBasic); |
581 // If there's room below keep falling |
620 // If there's room below keep falling |
691 //////////////////////////////////////////////////////////////////////////////// |
733 //////////////////////////////////////////////////////////////////////////////// |
692 procedure doStepGrave(Gear: PGear); |
734 procedure doStepGrave(Gear: PGear); |
693 begin |
735 begin |
694 AllInactive := false; |
736 AllInactive := false; |
695 if Gear^.dY.isNegative then |
737 if Gear^.dY.isNegative then |
696 if TestCollisionY(Gear, -1) then Gear^.dY := _0; |
738 if TestCollisionY(Gear, -1) then |
|
739 Gear^.dY := _0; |
697 |
740 |
698 if not Gear^.dY.isNegative then |
741 if not Gear^.dY.isNegative then |
699 if TestCollisionY(Gear, 1) then |
742 if TestCollisionY(Gear, 1) then |
700 begin |
743 begin |
701 Gear^.dY := - Gear^.dY * Gear^.Elasticity; |
744 Gear^.dY := - Gear^.dY * Gear^.Elasticity; |
702 if Gear^.dY > - _1div1024 then |
745 if Gear^.dY > - _1div1024 then |
703 begin |
746 begin |
704 Gear^.Active := false; |
747 Gear^.Active := false; |
705 exit |
748 exit |
706 end |
749 end |
707 else if Gear^.dY < - _0_03 then PlaySound(Gear^.ImpactSound) |
750 else if Gear^.dY < - _0_03 then |
|
751 PlaySound(Gear^.ImpactSound) |
708 end; |
752 end; |
709 |
753 |
710 Gear^.Y := Gear^.Y + Gear^.dY; |
754 Gear^.Y := Gear^.Y + Gear^.dY; |
711 CheckGearDrowning(Gear); |
755 CheckGearDrowning(Gear); |
712 Gear^.dY := Gear^.dY + cGravity |
756 Gear^.dY := Gear^.dY + cGravity |
727 uw := (Gear^.Tag <> 0); // was bee underwater last tick? |
771 uw := (Gear^.Tag <> 0); // was bee underwater last tick? |
728 nuw := (cWaterLine < gy + Gear^.Radius); // is bee underwater now? |
772 nuw := (cWaterLine < gy + Gear^.Radius); // is bee underwater now? |
729 |
773 |
730 // if water entered or left |
774 // if water entered or left |
731 if nuw <> uw then |
775 if nuw <> uw then |
732 begin |
776 begin |
733 AddVisualGear(gX, cWaterLine, vgtSplash); |
777 AddVisualGear(gX, cWaterLine, vgtSplash); |
734 AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); |
778 AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); |
735 AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); |
779 AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); |
736 AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); |
780 AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); |
737 AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); |
781 AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet); |
738 StopSound(Gear^.SoundChannel); |
782 StopSound(Gear^.SoundChannel); |
739 if nuw then |
783 if nuw then |
740 begin |
784 begin |
741 Gear^.SoundChannel := LoopSound(sndBeeWater); |
785 Gear^.SoundChannel := LoopSound(sndBeeWater); |
742 Gear^.Tag := 1; |
786 Gear^.Tag := 1; |
743 end |
787 end |
744 else |
788 else |
745 begin |
789 begin |
746 Gear^.SoundChannel := LoopSound(sndBee); |
790 Gear^.SoundChannel := LoopSound(sndBee); |
747 Gear^.Tag := 0; |
791 Gear^.Tag := 0; |
748 end; |
792 end; |
749 end; |
793 end; |
750 |
794 |
751 |
795 |
752 if Gear^.Timer = 0 then |
796 if Gear^.Timer = 0 then |
753 Gear^.RenderTimer:= false |
797 Gear^.RenderTimer:= false |
754 else |
798 else |
755 begin |
799 begin |
756 if (GameTicks and $F) = 0 then |
800 if (GameTicks and $F) = 0 then |
757 begin |
801 begin |
758 if (GameTicks and $30) = 0 then |
802 if (GameTicks and $30) = 0 then |
759 AddVisualGear(gX, gY, vgtBeeTrace); |
803 AddVisualGear(gX, gY, vgtBeeTrace); |
760 Gear^.dX := Gear^.Elasticity * (Gear^.dX + _0_000064 * (Gear^.Target.X - gX)); |
804 Gear^.dX := Gear^.Elasticity * (Gear^.dX + _0_000064 * (Gear^.Target.X - gX)); |
761 Gear^.dY := Gear^.Elasticity * (Gear^.dY + _0_000064 * (Gear^.Target.Y - gY)); |
805 Gear^.dY := Gear^.Elasticity * (Gear^.dY + _0_000064 * (Gear^.Target.Y - gY)); |
762 // make sure new speed isn't higher than original one (which we stored in Friction variable) |
806 // make sure new speed isn't higher than original one (which we stored in Friction variable) |
763 t := Gear^.Friction / Distance(Gear^.dX, Gear^.dY); |
807 t := Gear^.Friction / Distance(Gear^.dX, Gear^.dY); |
764 Gear^.dX := Gear^.dX * t; |
808 Gear^.dX := Gear^.dX * t; |
765 Gear^.dY := Gear^.dY * t; |
809 Gear^.dY := Gear^.dY * t; |
766 end; |
810 end; |
767 |
811 |
768 Gear^.X := Gear^.X + Gear^.dX; |
812 Gear^.X := Gear^.X + Gear^.dX; |
769 Gear^.Y := Gear^.Y + Gear^.dY; |
813 Gear^.Y := Gear^.Y + Gear^.dY; |
770 |
814 |
771 end; |
815 end; |
772 |
816 |
773 |
817 |
774 CheckCollision(Gear); |
818 CheckCollision(Gear); |
775 if ((Gear^.State and gstCollision) <> 0) then |
819 if ((Gear^.State and gstCollision) <> 0) then |
776 begin |
820 begin |
777 StopSound(Gear^.SoundChannel); |
821 StopSound(Gear^.SoundChannel); |
778 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); |
822 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); |
779 for i:= 0 to 31 do |
823 for i:= 0 to 31 do |
780 begin |
824 begin |
781 flower:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtStraightShot); |
825 flower:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtStraightShot); |
783 with flower^ do |
827 with flower^ do |
784 begin |
828 begin |
785 Scale:= 0.75; |
829 Scale:= 0.75; |
786 dx:= 0.001 * (random(200)); |
830 dx:= 0.001 * (random(200)); |
787 dy:= 0.001 * (random(200)); |
831 dy:= 0.001 * (random(200)); |
788 if random(2) = 0 then dx := -dx; |
832 if random(2) = 0 then |
789 if random(2) = 0 then dy := -dy; |
833 dx := -dx; |
|
834 if random(2) = 0 then |
|
835 dy := -dy; |
790 FrameTicks:= random(250) + 250; |
836 FrameTicks:= random(250) + 250; |
791 State:= ord(sprTargetBee); |
837 State:= ord(sprTargetBee); |
792 end; |
838 end; |
793 end; |
839 end; |
794 DeleteGear(Gear); |
840 DeleteGear(Gear); |
795 end; |
841 end; |
796 |
842 |
797 if (Gear^.Timer > 0) then |
843 if (Gear^.Timer > 0) then |
798 dec(Gear^.Timer) |
844 dec(Gear^.Timer) |
799 else |
845 else |
800 begin |
846 begin |
801 if nuw then |
847 if nuw then |
802 begin |
848 begin |
803 StopSound(Gear^.SoundChannel); |
849 StopSound(Gear^.SoundChannel); |
804 CheckGearDrowning(Gear); |
850 CheckGearDrowning(Gear); |
805 end |
851 end |
806 else |
852 else |
807 doStepFallingGear(Gear); |
853 doStepFallingGear(Gear); |
808 end; |
854 end; |
809 end; |
855 end; |
810 |
856 |
811 procedure doStepBee(Gear: PGear); |
857 procedure doStepBee(Gear: PGear); |
812 begin |
858 begin |
813 AllInactive := false; |
859 AllInactive := false; |
814 Gear^.X := Gear^.X + Gear^.dX; |
860 Gear^.X := Gear^.X + Gear^.dX; |
815 Gear^.Y := Gear^.Y + Gear^.dY; |
861 Gear^.Y := Gear^.Y + Gear^.dY; |
816 Gear^.dY := Gear^.dY + cGravity; |
862 Gear^.dY := Gear^.dY + cGravity; |
817 CheckCollision(Gear); |
863 CheckCollision(Gear); |
818 if (Gear^.State and gstCollision) <> 0 then |
864 if (Gear^.State and gstCollision) <> 0 then |
819 begin |
865 begin |
820 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); |
866 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); |
821 DeleteGear(Gear); |
867 DeleteGear(Gear); |
822 exit |
868 exit |
823 end; |
869 end; |
824 dec(Gear^.Timer); |
870 dec(Gear^.Timer); |
825 if Gear^.Timer = 0 then |
871 if Gear^.Timer = 0 then |
826 begin |
872 begin |
827 Gear^.Hedgehog^.Gear^.Message:= Gear^.Hedgehog^.Gear^.Message and (not gmAttack); |
873 Gear^.Hedgehog^.Gear^.Message:= Gear^.Hedgehog^.Gear^.Message and (not gmAttack); |
828 Gear^.Hedgehog^.Gear^.State:= Gear^.Hedgehog^.Gear^.State and (not gstAttacking); |
874 Gear^.Hedgehog^.Gear^.State:= Gear^.Hedgehog^.Gear^.State and (not gstAttacking); |
829 AttackBar:= 0; |
875 AttackBar:= 0; |
830 |
876 |
831 Gear^.SoundChannel := LoopSound(sndBee); |
877 Gear^.SoundChannel := LoopSound(sndBee); |
832 Gear^.Timer := 5000; |
878 Gear^.Timer := 5000; |
833 // save initial speed in otherwise unused Friction variable |
879 // save initial speed in otherwise unused Friction variable |
834 Gear^.Friction := Distance(Gear^.dX, Gear^.dY); |
880 Gear^.Friction := Distance(Gear^.dX, Gear^.dY); |
835 Gear^.doStep := @doStepBeeWork |
881 Gear^.doStep := @doStepBeeWork |
836 end; |
882 end; |
837 end; |
883 end; |
838 |
884 |
839 //////////////////////////////////////////////////////////////////////////////// |
885 //////////////////////////////////////////////////////////////////////////////// |
840 procedure doStepShotIdle(Gear: PGear); |
886 procedure doStepShotIdle(Gear: PGear); |
841 begin |
887 begin |
842 AllInactive := false; |
888 AllInactive := false; |
843 inc(Gear^.Timer); |
889 inc(Gear^.Timer); |
844 if Gear^.Timer > 75 then |
890 if Gear^.Timer > 75 then |
845 begin |
891 begin |
846 DeleteGear(Gear); |
892 DeleteGear(Gear); |
847 AfterAttack |
893 AfterAttack |
848 end |
894 end |
849 end; |
895 end; |
850 |
896 |
851 procedure doStepShotgunShot(Gear: PGear); |
897 procedure doStepShotgunShot(Gear: PGear); |
852 var |
898 var |
853 i: LongWord; |
899 i: LongWord; |
854 shell: PVisualGear; |
900 shell: PVisualGear; |
855 begin |
901 begin |
856 AllInactive := false; |
902 AllInactive := false; |
857 |
903 |
858 if ((Gear^.State and gstAnimation) = 0) then |
904 if ((Gear^.State and gstAnimation) = 0) then |
859 begin |
905 begin |
860 dec(Gear^.Timer); |
906 dec(Gear^.Timer); |
861 if Gear^.Timer = 0 then |
907 if Gear^.Timer = 0 then |
862 begin |
908 begin |
863 PlaySound(sndShotgunFire); |
909 PlaySound(sndShotgunFire); |
864 shell := AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell); |
910 shell := AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell); |
865 if shell <> nil then |
911 if shell <> nil then |
866 begin |
912 begin |
867 shell^.dX := gear^.dX.QWordValue / -17179869184; |
913 shell^.dX := gear^.dX.QWordValue / -17179869184; |
868 shell^.dY := gear^.dY.QWordValue / -17179869184; |
914 shell^.dY := gear^.dY.QWordValue / -17179869184; |
869 shell^.Frame := 0 |
915 shell^.Frame := 0 |
870 end; |
916 end; |
871 Gear^.State := Gear^.State or gstAnimation |
917 Gear^.State := Gear^.State or gstAnimation |
872 end; |
918 end; |
873 exit |
919 exit |
874 end |
920 end |
875 else inc(Gear^.Timer); |
921 else |
876 |
922 inc(Gear^.Timer); |
877 i := 200; |
923 |
|
924 i := 200; |
878 repeat |
925 repeat |
879 Gear^.X := Gear^.X + Gear^.dX; |
926 Gear^.X := Gear^.X + Gear^.dX; |
880 Gear^.Y := Gear^.Y + Gear^.dY; |
927 Gear^.Y := Gear^.Y + Gear^.dY; |
881 CheckCollision(Gear); |
928 CheckCollision(Gear); |
882 if (Gear^.State and gstCollision) <> 0 then |
929 if (Gear^.State and gstCollision) <> 0 then |
883 begin |
930 begin |
884 Gear^.X := Gear^.X + Gear^.dX * 8; |
931 Gear^.X := Gear^.X + Gear^.dX * 8; |
885 Gear^.Y := Gear^.Y + Gear^.dY * 8; |
932 Gear^.Y := Gear^.Y + Gear^.dY * 8; |
886 ShotgunShot(Gear); |
933 ShotgunShot(Gear); |
887 Gear^.doStep := @doStepShotIdle; |
934 Gear^.doStep := @doStepShotIdle; |
888 exit |
935 exit |
889 end; |
936 end; |
890 |
937 |
891 CheckGearDrowning(Gear); |
938 CheckGearDrowning(Gear); |
892 if (Gear^.State and gstDrowning) <> 0 then |
939 if (Gear^.State and gstDrowning) <> 0 then |
893 begin |
940 begin |
894 Gear^.doStep := @doStepShotIdle; |
941 Gear^.doStep := @doStepShotIdle; |
895 exit |
942 exit |
896 end; |
943 end; |
897 dec(i) |
944 dec(i) |
898 until i = 0; |
945 until i = 0; |
899 if (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) |
946 if (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then |
900 then |
|
901 Gear^.doStep := @doStepShotIdle |
947 Gear^.doStep := @doStepShotIdle |
902 end; |
948 end; |
903 |
949 |
904 //////////////////////////////////////////////////////////////////////////////// |
950 //////////////////////////////////////////////////////////////////////////////// |
905 procedure spawnBulletTrail(Bullet: PGear); |
951 procedure spawnBulletTrail(Bullet: PGear); |
917 oy:= Bullet^.Friction; |
963 oy:= Bullet^.Friction; |
918 end; |
964 end; |
919 |
965 |
920 // Bullet trail |
966 // Bullet trail |
921 VGear := AddVisualGear(hwRound(ox), hwRound(oy), vgtLineTrail); |
967 VGear := AddVisualGear(hwRound(ox), hwRound(oy), vgtLineTrail); |
|
968 |
922 if VGear <> nil then |
969 if VGear <> nil then |
923 begin |
970 begin |
924 VGear^.X:= hwFloat2Float(ox); |
971 VGear^.X:= hwFloat2Float(ox); |
925 VGear^.Y:= hwFloat2Float(oy); |
972 VGear^.Y:= hwFloat2Float(oy); |
926 VGear^.dX:= hwFloat2Float(Bullet^.X); |
973 VGear^.dX:= hwFloat2Float(Bullet^.X); |
927 VGear^.dY:= hwFloat2Float(Bullet^.Y); |
974 VGear^.dY:= hwFloat2Float(Bullet^.Y); |
928 |
975 |
929 // reached edge of land. assume infinite beam. Extend it way out past camera |
976 // reached edge of land. assume infinite beam. Extend it way out past camera |
930 if (hwRound(Bullet^.X) and LAND_WIDTH_MASK <> 0) |
977 if (hwRound(Bullet^.X) and LAND_WIDTH_MASK <> 0) |
931 or (hwRound(Bullet^.Y) and LAND_HEIGHT_MASK <> 0) then |
978 or (hwRound(Bullet^.Y) and LAND_HEIGHT_MASK <> 0) then |
932 // only extend if not under water |
979 // only extend if not under water |
933 if hwRound(Bullet^.Y) < cWaterLine then |
980 if hwRound(Bullet^.Y) < cWaterLine then |
934 begin |
981 begin |
935 VGear^.dX := VGear^.dX + LAND_WIDTH * (VGear^.dX - VGear^.X); |
982 VGear^.dX := VGear^.dX + LAND_WIDTH * (VGear^.dX - VGear^.X); |
936 VGear^.dY := VGear^.dY + LAND_WIDTH * (VGear^.dY - VGear^.Y); |
983 VGear^.dY := VGear^.dY + LAND_WIDTH * (VGear^.dY - VGear^.Y); |
954 repeat |
1001 repeat |
955 Gear^.X := Gear^.X + Gear^.dX; |
1002 Gear^.X := Gear^.X + Gear^.dX; |
956 Gear^.Y := Gear^.Y + Gear^.dY; |
1003 Gear^.Y := Gear^.Y + Gear^.dY; |
957 x := hwRound(Gear^.X); |
1004 x := hwRound(Gear^.X); |
958 y := hwRound(Gear^.Y); |
1005 y := hwRound(Gear^.Y); |
959 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) |
1006 |
960 and (Land[y, x] <> 0) then inc(Gear^.Damage); |
1007 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] <> 0) then |
|
1008 inc(Gear^.Damage); |
961 // let's interrupt before a collision to give portals a chance to catch the bullet |
1009 // let's interrupt before a collision to give portals a chance to catch the bullet |
962 if (Gear^.Damage = 1) and (Gear^.Tag = 0) and (Land[y, x] > 255) then |
1010 if (Gear^.Damage = 1) and (Gear^.Tag = 0) and (Land[y, x] > 255) then |
963 begin |
1011 begin |
964 Gear^.Tag := 1; |
1012 Gear^.Tag := 1; |
965 Gear^.Damage := 0; |
1013 Gear^.Damage := 0; |
966 Gear^.X := Gear^.X - Gear^.dX; |
1014 Gear^.X := Gear^.X - Gear^.dX; |
967 Gear^.Y := Gear^.Y - Gear^.dY; |
1015 Gear^.Y := Gear^.Y - Gear^.dY; |
968 CheckGearDrowning(Gear); |
1016 CheckGearDrowning(Gear); |
969 break; |
1017 break; |
970 end |
1018 end |
971 else |
1019 else |
972 Gear^.Tag := 0; |
1020 Gear^.Tag := 0; |
973 |
1021 |
974 if Gear^.Damage > 5 then |
1022 if Gear^.Damage > 5 then |
975 if Gear^.AmmoType = amDEagle then |
1023 if Gear^.AmmoType = amDEagle then |
976 AmmoShove(Gear, 7, 20) |
1024 AmmoShove(Gear, 7, 20) |
977 else |
1025 else |
978 AmmoShove(Gear, Gear^.Timer, 20); |
1026 AmmoShove(Gear, Gear^.Timer, 20); |
979 CheckGearDrowning(Gear); |
1027 CheckGearDrowning(Gear); |
980 dec(i) |
1028 dec(i) until (i = 0) or (Gear^.Damage > Gear^.Health) or ((Gear^.State and gstDrowning) <> 0); |
981 until (i = 0) or (Gear^.Damage > Gear^.Health) or ((Gear^.State and gstDrowning) <> 0); |
|
982 if Gear^.Damage > 0 then |
1029 if Gear^.Damage > 0 then |
983 begin |
1030 begin |
984 DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 82 - i, 1); |
1031 DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 82 - i, 1); |
985 dec(Gear^.Health, Gear^.Damage); |
1032 dec(Gear^.Health, Gear^.Damage); |
986 Gear^.Damage := 0 |
1033 Gear^.Damage := 0 |
987 end; |
1034 end; |
988 if ((Gear^.State and gstDrowning) <> 0) and (Gear^.Damage < Gear^.Health) and ((not SuddenDeathDmg and (cWaterOpacity < $FF)) or (SuddenDeathDmg and (cSDWaterOpacity < $FF))) then |
1035 if ((Gear^.State and gstDrowning) <> 0) and (Gear^.Damage < Gear^.Health) and ((not SuddenDeathDmg and (cWaterOpacity < $FF)) or (SuddenDeathDmg and (cSDWaterOpacity < $FF))) then |
989 begin |
1036 begin |
990 for i:=(Gear^.Health - Gear^.Damage) * 4 downto 0 do |
1037 for i:=(Gear^.Health - Gear^.Damage) * 4 downto 0 do |
991 begin |
1038 begin |
992 if Random(6) = 0 then |
1039 if Random(6) = 0 then |
993 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble); |
1040 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble); |
994 Gear^.X := Gear^.X + Gear^.dX; |
1041 Gear^.X := Gear^.X + Gear^.dX; |
995 Gear^.Y := Gear^.Y + Gear^.dY; |
1042 Gear^.Y := Gear^.Y + Gear^.dY; |
996 end; |
1043 end; |
997 end; |
1044 end; |
998 |
1045 |
999 if (Gear^.Health <= 0) |
1046 if (Gear^.Health <= 0) |
1000 or (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) |
1047 or (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) |
1001 or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then |
1048 or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then |
1002 begin |
1049 begin |
1003 if (Gear^.Kind = gtSniperRifleShot) and ((GameFlags and gfLaserSight) = 0) then |
1050 if (Gear^.Kind = gtSniperRifleShot) and ((GameFlags and gfLaserSight) = 0) then |
1004 cLaserSighting := false; |
1051 cLaserSighting := false; |
1005 if (Ammoz[Gear^.AmmoType].Ammo.NumPerTurn <= CurrentHedgehog^.MultiShootAttacks) and |
1052 if (Ammoz[Gear^.AmmoType].Ammo.NumPerTurn <= CurrentHedgehog^.MultiShootAttacks) and ((GameFlags and gfArtillery) = 0) then |
1006 ((GameFlags and gfArtillery) = 0) then cArtillery := false; |
1053 cArtillery := false; |
1007 |
1054 |
1008 // Bullet Hit |
1055 // Bullet Hit |
1009 if (hwRound(Gear^.X) and LAND_WIDTH_MASK = 0) |
1056 if (hwRound(Gear^.X) and LAND_WIDTH_MASK = 0) and (hwRound(Gear^.Y) and LAND_HEIGHT_MASK = 0) then |
1010 and (hwRound(Gear^.Y) and LAND_HEIGHT_MASK = 0) then |
1057 begin |
1011 begin |
1058 VGear := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBulletHit); |
1012 VGear := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBulletHit); |
1059 if VGear <> nil then |
1013 if VGear <> nil then |
1060 begin |
1014 begin |
1061 VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY); |
1015 VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY); |
1062 end; |
1016 end; |
1063 end; |
1017 end; |
|
1018 |
1064 |
1019 spawnBulletTrail(Gear); |
1065 spawnBulletTrail(Gear); |
1020 Gear^.doStep := @doStepShotIdle |
1066 Gear^.doStep := @doStepShotIdle |
1021 end; |
1067 end; |
1022 end; |
1068 end; |
1023 |
1069 |
1024 procedure doStepDEagleShot(Gear: PGear); |
1070 procedure doStepDEagleShot(Gear: PGear); |
1025 begin |
1071 begin |
1026 PlaySound(sndGun); |
1072 PlaySound(sndGun); |
1039 HHGear := Gear^.Hedgehog^.Gear; |
1085 HHGear := Gear^.Hedgehog^.Gear; |
1040 HHGear^.State := HHGear^.State or gstNotKickable; |
1086 HHGear^.State := HHGear^.State or gstNotKickable; |
1041 HedgehogChAngle(HHGear); |
1087 HedgehogChAngle(HHGear); |
1042 if not cLaserSighting then |
1088 if not cLaserSighting then |
1043 // game does not have default laser sight. turn it on and give them a chance to aim |
1089 // game does not have default laser sight. turn it on and give them a chance to aim |
1044 begin |
1090 begin |
1045 cLaserSighting := true; |
1091 cLaserSighting := true; |
1046 HHGear^.Message := 0; |
1092 HHGear^.Message := 0; |
1047 if (HHGear^.Angle - 32 >= 0) then dec(HHGear^.Angle,32) |
1093 if (HHGear^.Angle - 32 >= 0) then |
1048 end; |
1094 dec(HHGear^.Angle,32) |
|
1095 end; |
1049 |
1096 |
1050 if (HHGear^.Message and gmAttack) <> 0 then |
1097 if (HHGear^.Message and gmAttack) <> 0 then |
1051 begin |
1098 begin |
1052 shell := AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell); |
1099 shell := AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell); |
1053 if shell <> nil then |
1100 if shell <> nil then |
1054 begin |
1101 begin |
1055 shell^.dX := gear^.dX.QWordValue / -8589934592; |
1102 shell^.dX := gear^.dX.QWordValue / -8589934592; |
1056 shell^.dY := gear^.dY.QWordValue / -8589934592; |
1103 shell^.dY := gear^.dY.QWordValue / -8589934592; |
1057 shell^.Frame := 1 |
1104 shell^.Frame := 1 |
1058 end; |
1105 end; |
1059 Gear^.State := Gear^.State or gstAnimation; |
1106 Gear^.State := Gear^.State or gstAnimation; |
1060 Gear^.dX := SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _0_5; |
1107 Gear^.dX := SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _0_5; |
1061 Gear^.dY := -AngleCos(HHGear^.Angle) * _0_5; |
1108 Gear^.dY := -AngleCos(HHGear^.Angle) * _0_5; |
1062 PlaySound(sndGun); |
1109 PlaySound(sndGun); |
1063 // add 3 initial steps to avoid problem with ammoshove related to calculation of radius + 1 radius as gear widths, and also just weird angles |
1110 // add 3 initial steps to avoid problem with ammoshove related to calculation of radius + 1 radius as gear widths, and also just weird angles |
1064 Gear^.X := Gear^.X + Gear^.dX * 3; |
1111 Gear^.X := Gear^.X + Gear^.dX * 3; |
1065 Gear^.Y := Gear^.Y + Gear^.dY * 3; |
1112 Gear^.Y := Gear^.Y + Gear^.dY * 3; |
1066 Gear^.doStep := @doStepBulletWork; |
1113 Gear^.doStep := @doStepBulletWork; |
1067 end |
1114 end |
1068 else |
1115 else |
1069 if (GameTicks mod 32) = 0 then |
1116 if (GameTicks mod 32) = 0 then |
1070 if (GameTicks mod 4096) < 2048 then |
1117 if (GameTicks mod 4096) < 2048 then |
1071 begin |
1118 begin |
1072 if (HHGear^.Angle + 1 <= cMaxAngle) then inc(HHGear^.Angle) |
1119 if (HHGear^.Angle + 1 <= cMaxAngle) then |
1073 end |
1120 inc(HHGear^.Angle) |
|
1121 end |
1074 else |
1122 else |
1075 if (HHGear^.Angle - 1 >= 0) then dec(HHGear^.Angle); |
1123 if (HHGear^.Angle - 1 >= 0) then |
|
1124 dec(HHGear^.Angle); |
1076 |
1125 |
1077 if (TurnTimeLeft > 0) then |
1126 if (TurnTimeLeft > 0) then |
1078 dec(TurnTimeLeft) |
1127 dec(TurnTimeLeft) |
1079 else |
1128 else |
1080 begin |
1129 begin |
1081 DeleteGear(Gear); |
1130 DeleteGear(Gear); |
1082 AfterAttack |
1131 AfterAttack |
1083 end; |
1132 end; |
1084 end; |
1133 end; |
1085 |
1134 |
1086 //////////////////////////////////////////////////////////////////////////////// |
1135 //////////////////////////////////////////////////////////////////////////////// |
1087 procedure doStepActionTimer(Gear: PGear); |
1136 procedure doStepActionTimer(Gear: PGear); |
1088 begin |
1137 begin |
1089 dec(Gear^.Timer); |
1138 dec(Gear^.Timer); |
1090 case Gear^.Kind of |
1139 case Gear^.Kind of |
1091 gtATStartGame: |
1140 gtATStartGame: |
1092 begin |
1141 begin |
1093 AllInactive := false; |
1142 AllInactive := false; |
1094 if Gear^.Timer = 0 then |
1143 if Gear^.Timer = 0 then |
1095 begin |
1144 begin |
1096 AddCaption(trmsg[sidStartFight], cWhiteColor, capgrpGameState); |
1145 AddCaption(trmsg[sidStartFight], cWhiteColor, capgrpGameState); |
1097 end |
1146 end |
1098 end; |
1147 end; |
1099 gtATFinishGame: |
1148 gtATFinishGame: |
1100 begin |
1149 begin |
1101 AllInactive := false; |
1150 AllInactive := false; |
1102 if Gear^.Timer = 1000 then |
1151 if Gear^.Timer = 1000 then |
1103 begin |
1152 begin |
1104 ScreenFade := sfToBlack; |
1153 ScreenFade := sfToBlack; |
1105 ScreenFadeValue := 0; |
1154 ScreenFadeValue := 0; |
1106 ScreenFadeSpeed := 1; |
1155 ScreenFadeSpeed := 1; |
1107 end; |
1156 end; |
1108 if Gear^.Timer = 0 then |
1157 if Gear^.Timer = 0 then |
1109 begin |
1158 begin |
1110 SendIPC('N'); |
1159 SendIPC('N'); |
1111 SendIPC('q'); |
1160 SendIPC('q'); |
1112 GameState := gsExit |
1161 GameState := gsExit |
1113 end |
1162 end |
1114 end; |
1163 end; |
1115 end; |
1164 end; |
1116 if Gear^.Timer = 0 then DeleteGear(Gear) |
1165 if Gear^.Timer = 0 then |
|
1166 DeleteGear(Gear) |
1117 end; |
1167 end; |
1118 |
1168 |
1119 //////////////////////////////////////////////////////////////////////////////// |
1169 //////////////////////////////////////////////////////////////////////////////// |
1120 procedure doStepPickHammerWork(Gear: PGear); |
1170 procedure doStepPickHammerWork(Gear: PGear); |
1121 var |
1171 var |
1178 if CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y + Gear^.dY + cGravity), $FF00) then |
1230 if CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y + Gear^.dY + cGravity), $FF00) then |
1179 begin |
1231 begin |
1180 Gear^.dY := Gear^.dY + cGravity; |
1232 Gear^.dY := Gear^.dY + cGravity; |
1181 Gear^.Y := Gear^.Y + Gear^.dY |
1233 Gear^.Y := Gear^.Y + Gear^.dY |
1182 end; |
1234 end; |
1183 if hwRound(Gear^.Y) > cWaterLine then Gear^.Timer := 1 |
1235 if hwRound(Gear^.Y) > cWaterLine then |
|
1236 Gear^.Timer := 1 |
1184 end; |
1237 end; |
1185 |
1238 |
1186 Gear^.X := Gear^.X + HHGear^.dX; |
1239 Gear^.X := Gear^.X + HHGear^.dX; |
1187 if CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y)-cHHRadius, $FF00) then |
1240 if CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y)-cHHRadius, $FF00) then |
1188 begin |
1241 begin |
1189 HHGear^.X := Gear^.X; |
1242 HHGear^.X := Gear^.X; |
1190 HHGear^.Y := Gear^.Y - int2hwFloat(cHHRadius) |
1243 HHGear^.Y := Gear^.Y - int2hwFloat(cHHRadius) |
1191 end; |
1244 end; |
1192 |
1245 |
1193 if (Gear^.Message and gmAttack) <> 0 then |
1246 if (Gear^.Message and gmAttack) <> 0 then |
1194 if (Gear^.State and gsttmpFlag) <> 0 then Gear^.Timer := 1 |
1247 if (Gear^.State and gsttmpFlag) <> 0 then |
|
1248 Gear^.Timer := 1 |
|
1249 else //there would be a mistake. |
1195 else |
1250 else |
|
1251 if (Gear^.State and gsttmpFlag) = 0 then |
|
1252 Gear^.State := Gear^.State or gsttmpFlag; |
|
1253 if ((Gear^.Message and gmLeft) <> 0) then |
|
1254 Gear^.dX := - _0_3 |
1196 else |
1255 else |
1197 if (Gear^.State and gsttmpFlag) = 0 then Gear^.State := Gear^.State or gsttmpFlag; |
1256 if ((Gear^.Message and gmRight) <> 0) then |
1198 if ((Gear^.Message and gmLeft) <> 0) then Gear^.dX := - _0_3 |
1257 Gear^.dX := _0_3 |
1199 else |
|
1200 if ((Gear^.Message and gmRight) <> 0) then Gear^.dX := _0_3 |
|
1201 else Gear^.dX := _0; |
1258 else Gear^.dX := _0; |
1202 end; |
1259 end; |
1203 |
1260 |
1204 procedure doStepPickHammer(Gear: PGear); |
1261 procedure doStepPickHammer(Gear: PGear); |
1205 var |
1262 var |
1342 var |
1400 var |
1343 HHGear: PGear; |
1401 HHGear: PGear; |
1344 begin |
1402 begin |
1345 HHGear := Gear^.Hedgehog^.Gear; |
1403 HHGear := Gear^.Hedgehog^.Gear; |
1346 if ((HHGear^.State and gstHHDriven) = 0) |
1404 if ((HHGear^.State and gstHHDriven) = 0) |
1347 or (CheckGearDrowning(HHGear)) |
1405 or (CheckGearDrowning(HHGear)) |
1348 or (TestCollisionYwithGear(HHGear, 1) <> 0) then |
1406 or (TestCollisionYwithGear(HHGear, 1) <> 0) then |
1349 begin |
1407 begin |
1350 DeleteGear(Gear); |
1408 DeleteGear(Gear); |
1351 isCursorVisible := false; |
1409 isCursorVisible := false; |
1352 ApplyAmmoChanges(HHGear^.Hedgehog^); |
1410 ApplyAmmoChanges(HHGear^.Hedgehog^); |
1353 exit |
1411 exit |
1354 end; |
1412 end; |
1355 |
1413 |
1356 HedgehogChAngle(HHGear); |
1414 HedgehogChAngle(HHGear); |
1357 |
1415 |
1358 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX); |
1416 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then |
1359 |
1417 SetLittle(HHGear^.dX); |
1360 if HHGear^.dY.isNegative and (TestCollisionYwithGear(HHGear, -1) <> 0) then HHGear^.dY := _0; |
1418 |
|
1419 if HHGear^.dY.isNegative and (TestCollisionYwithGear(HHGear, -1) <> 0) then |
|
1420 HHGear^.dY := _0; |
1361 HHGear^.X := HHGear^.X + HHGear^.dX; |
1421 HHGear^.X := HHGear^.X + HHGear^.dX; |
1362 HHGear^.Y := HHGear^.Y + HHGear^.dY; |
1422 HHGear^.Y := HHGear^.Y + HHGear^.dY; |
1363 HHGear^.dY := HHGear^.dY + cGravity; |
1423 HHGear^.dY := HHGear^.dY + cGravity; |
1364 if (GameFlags and gfMoreWind) <> 0 then HHGear^.dX := HHGear^.dX + cWindSpeed / HHGear^.Density; |
1424 |
|
1425 if (GameFlags and gfMoreWind) <> 0 then |
|
1426 HHGear^.dX := HHGear^.dX + cWindSpeed / HHGear^.Density; |
1365 |
1427 |
1366 if (Gear^.Message and gmAttack) <> 0 then |
1428 if (Gear^.Message and gmAttack) <> 0 then |
1367 begin |
1429 begin |
1368 Gear^.X := HHGear^.X; |
1430 Gear^.X := HHGear^.X; |
1369 Gear^.Y := HHGear^.Y; |
1431 Gear^.Y := HHGear^.Y; |
1758 //////////////////////////////////////////////////////////////////////////////// |
1823 //////////////////////////////////////////////////////////////////////////////// |
1759 procedure doStepMine(Gear: PGear); |
1824 procedure doStepMine(Gear: PGear); |
1760 var vg: PVisualGear; |
1825 var vg: PVisualGear; |
1761 begin |
1826 begin |
1762 if (Gear^.State and gstMoving) <> 0 then |
1827 if (Gear^.State and gstMoving) <> 0 then |
1763 begin |
1828 begin |
1764 DeleteCI(Gear); |
1829 DeleteCI(Gear); |
1765 doStepFallingGear(Gear); |
1830 doStepFallingGear(Gear); |
1766 if (Gear^.State and gstMoving) = 0 then |
1831 if (Gear^.State and gstMoving) = 0 then |
1767 begin |
1832 begin |
1768 AddGearCI(Gear); |
1833 AddGearCI(Gear); |
1769 Gear^.dX := _0; |
1834 Gear^.dX := _0; |
1770 Gear^.dY := _0 |
1835 Gear^.dY := _0 |
1771 end; |
1836 end; |
1772 CalcRotationDirAngle(Gear); |
1837 CalcRotationDirAngle(Gear); |
1773 AllInactive := false |
1838 AllInactive := false |
1774 end |
1839 end |
1775 else |
1840 else |
1776 if ((GameTicks and $3F) = 25) then |
1841 if ((GameTicks and $3F) = 25) then |
1777 doStepFallingGear(Gear); |
1842 doStepFallingGear(Gear); |
1778 if (Gear^.Health = 0) then |
1843 if (Gear^.Health = 0) then |
1779 begin |
1844 begin |
1780 if not Gear^.dY.isNegative and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then |
1845 if not Gear^.dY.isNegative and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then |
1781 inc(Gear^.Damage, hwRound(Gear^.dY * _70)) |
1846 inc(Gear^.Damage, hwRound(Gear^.dY * _70)) |
|
1847 |
1782 else if not Gear^.dX.isNegative and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then |
1848 else if not Gear^.dX.isNegative and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then |
1783 inc(Gear^.Damage, hwRound(Gear^.dX * _70)) |
1849 inc(Gear^.Damage, hwRound(Gear^.dX * _70)) |
|
1850 |
1784 else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then |
1851 else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then |
1785 inc(Gear^.Damage, hwRound(Gear^.dY * -_70)) |
1852 inc(Gear^.Damage, hwRound(Gear^.dY * -_70)) |
|
1853 |
1786 else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then |
1854 else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then |
1787 inc(Gear^.Damage, hwRound(Gear^.dX * -_70)); |
1855 inc(Gear^.Damage, hwRound(Gear^.dX * -_70)); |
1788 |
1856 |
1789 if ((GameTicks and $FF) = 0) and (Gear^.Damage > random(30)) then |
1857 if ((GameTicks and $FF) = 0) and (Gear^.Damage > random(30)) then |
1790 begin |
1858 begin |
1791 vg:= AddVisualGear(hwRound(Gear^.X) - 4 + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke); |
1859 vg:= AddVisualGear(hwRound(Gear^.X) - 4 + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke); |
1792 if vg <> nil then vg^.Scale:= 0.5 |
1860 if vg <> nil then |
1793 end; |
1861 vg^.Scale:= 0.5 |
|
1862 end; |
1794 |
1863 |
1795 if (Gear^.Damage > 35) then |
1864 if (Gear^.Damage > 35) then |
1796 begin |
1865 begin |
1797 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); |
1866 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); |
1798 DeleteGear(Gear); |
1867 DeleteGear(Gear); |
1802 |
1871 |
1803 if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Health <> 0) then |
1872 if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Health <> 0) then |
1804 if ((Gear^.State and gstAttacking) = 0) then |
1873 if ((Gear^.State and gstAttacking) = 0) then |
1805 begin |
1874 begin |
1806 if ((GameTicks and $1F) = 0) then |
1875 if ((GameTicks and $1F) = 0) then |
1807 if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then Gear^.State := Gear^.State or |
1876 if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then |
1808 gstAttacking |
1877 Gear^.State := Gear^.State or gstAttacking |
1809 end |
1878 end |
1810 else // gstAttacking <> 0 |
1879 else // gstAttacking <> 0 |
1811 begin |
1880 begin |
1812 AllInactive := false; |
1881 AllInactive := false; |
1813 if (Gear^.Timer and $FF) = 0 then PlaySound(sndMineTick); |
1882 if (Gear^.Timer and $FF) = 0 then |
|
1883 PlaySound(sndMineTick); |
1814 if Gear^.Timer = 0 then |
1884 if Gear^.Timer = 0 then |
1815 begin |
1885 begin |
1816 if ((Gear^.State and gstWait) <> 0) or |
1886 if ((Gear^.State and gstWait) <> 0) |
1817 (cMineDudPercent = 0) or |
1887 or (cMineDudPercent = 0) |
1818 (getRandom(100) > cMineDudPercent) then |
1888 or (getRandom(100) > cMineDudPercent) then |
1819 begin |
1889 begin |
1820 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); |
1890 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); |
1821 DeleteGear(Gear) |
1891 DeleteGear(Gear) |
1822 end |
1892 end |
1823 else |
1893 else |
1824 begin |
1894 begin |
1825 vg:= AddVisualGear(hwRound(Gear^.X) - 4 + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke); |
1895 vg:= AddVisualGear(hwRound(Gear^.X) - 4 + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke); |
1826 if vg <> nil then vg^.Scale:= 0.5; |
1896 if vg <> nil then |
|
1897 vg^.Scale:= 0.5; |
1827 PlaySound(sndVaporize); |
1898 PlaySound(sndVaporize); |
1828 Gear^.Health := 0; |
1899 Gear^.Health := 0; |
1829 Gear^.Damage := 0; |
1900 Gear^.Damage := 0; |
1830 Gear^.State := Gear^.State and (not gstAttacking) |
1901 Gear^.State := Gear^.State and (not gstAttacking) |
1831 end; |
1902 end; |
1832 exit |
1903 exit |
1833 end; |
1904 end; |
1834 dec(Gear^.Timer); |
1905 dec(Gear^.Timer); |
1835 end |
1906 end |
1836 else // gsttmpFlag = 0 |
1907 else // gsttmpFlag = 0 |
1837 if (TurnTimeLeft = 0) or ((GameFlags and gfInfAttack <> 0) and (GameTicks > Gear^.FlightTime)) or (Gear^.Hedgehog^.Gear = nil) then Gear^.State := Gear^.State or gsttmpFlag; |
1908 if (TurnTimeLeft = 0) |
|
1909 or ((GameFlags and gfInfAttack <> 0) and (GameTicks > Gear^.FlightTime)) |
|
1910 or (Gear^.Hedgehog^.Gear = nil) then |
|
1911 Gear^.State := Gear^.State or gsttmpFlag; |
1838 end; |
1912 end; |
1839 |
1913 |
1840 //////////////////////////////////////////////////////////////////////////////// |
1914 //////////////////////////////////////////////////////////////////////////////// |
1841 procedure doStepSMine(Gear: PGear); |
1915 procedure doStepSMine(Gear: PGear); |
1842 begin |
1916 begin |
1843 // TODO: do real calculation? |
1917 // TODO: do real calculation? |
1844 if TestCollisionXwithGear(Gear, 2) |
1918 if TestCollisionXwithGear(Gear, 2) |
1845 or (TestCollisionYwithGear(Gear, -2) <> 0) |
1919 or (TestCollisionYwithGear(Gear, -2) <> 0) |
1846 or TestCollisionXwithGear(Gear, -2) |
1920 or TestCollisionXwithGear(Gear, -2) |
1847 or (TestCollisionYwithGear(Gear, 2) <> 0) then |
1921 or (TestCollisionYwithGear(Gear, 2) <> 0) then |
1848 begin |
1922 begin |
1849 if (hwAbs(Gear^.dX) > _0) or (hwAbs(Gear^.dY) > _0) then |
1923 if (hwAbs(Gear^.dX) > _0) or (hwAbs(Gear^.dY) > _0) then |
1850 begin |
1924 begin |
1851 PlaySound(sndRopeAttach); |
1925 PlaySound(sndRopeAttach); |
1852 Gear^.dX:= _0; |
1926 Gear^.dX:= _0; |
1853 Gear^.dY:= _0; |
1927 Gear^.dY:= _0; |
1854 AddGearCI(Gear); |
1928 AddGearCI(Gear); |
1855 end; |
1929 end; |
1856 end |
1930 end |
1857 else |
1931 else |
1858 begin |
1932 begin |
1859 DeleteCI(Gear); |
1933 DeleteCI(Gear); |
1860 doStepFallingGear(Gear); |
1934 doStepFallingGear(Gear); |
1861 AllInactive := false; |
1935 AllInactive := false; |
1862 CalcRotationDirAngle(Gear); |
1936 CalcRotationDirAngle(Gear); |
1863 end; |
1937 end; |
1864 |
1938 |
1865 if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Health <> 0) then |
1939 if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Health <> 0) then |
1866 begin |
1940 begin |
1867 if ((Gear^.State and gstAttacking) = 0) then |
1941 if ((Gear^.State and gstAttacking) = 0) then |
1868 begin |
1942 begin |
1869 if ((GameTicks and $1F) = 0) then |
1943 if ((GameTicks and $1F) = 0) then |
1870 if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then Gear^.State := Gear^.State or |
1944 if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then |
1871 gstAttacking |
1945 Gear^.State := Gear^.State or gstAttacking |
1872 end |
1946 end |
1873 else // gstAttacking <> 0 |
1947 else // gstAttacking <> 0 |
1874 begin |
1948 begin |
1875 AllInactive := false; |
1949 AllInactive := false; |
1876 if Gear^.Timer = 0 then |
1950 if Gear^.Timer = 0 then |
1877 begin |
1951 begin |
1878 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound); |
1952 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound); |
1879 DeleteGear(Gear); |
1953 DeleteGear(Gear); |
1880 exit |
1954 exit |
1881 end else |
1955 end else |
1882 if (Gear^.Timer and $FF) = 0 then PlaySound(sndMineTick); |
1956 if (Gear^.Timer and $FF) = 0 then |
|
1957 PlaySound(sndMineTick); |
1883 |
1958 |
1884 dec(Gear^.Timer); |
1959 dec(Gear^.Timer); |
|
1960 end |
1885 end |
1961 end |
1886 end |
|
1887 else // gsttmpFlag = 0 |
1962 else // gsttmpFlag = 0 |
1888 if (TurnTimeLeft = 0) or ((GameFlags and gfInfAttack <> 0) and (GameTicks > Gear^.FlightTime)) or (Gear^.Hedgehog^.Gear = nil) then Gear^.State := Gear^.State or gsttmpFlag; |
1963 if (TurnTimeLeft = 0) |
|
1964 or ((GameFlags and gfInfAttack <> 0) and (GameTicks > Gear^.FlightTime)) |
|
1965 or (Gear^.Hedgehog^.Gear = nil) then |
|
1966 Gear^.State := Gear^.State or gsttmpFlag; |
1889 end; |
1967 end; |
1890 |
1968 |
1891 //////////////////////////////////////////////////////////////////////////////// |
1969 //////////////////////////////////////////////////////////////////////////////// |
1892 procedure doStepDynamite(Gear: PGear); |
1970 procedure doStepDynamite(Gear: PGear); |
1893 begin |
1971 begin |
1894 doStepFallingGear(Gear); |
1972 doStepFallingGear(Gear); |
1895 AllInactive := false; |
1973 AllInactive := false; |
1896 if Gear^.Timer mod 166 = 0 then inc(Gear^.Tag); |
1974 if Gear^.Timer mod 166 = 0 then |
|
1975 inc(Gear^.Tag); |
1897 if Gear^.Timer = 1000 then // might need better timing |
1976 if Gear^.Timer = 1000 then // might need better timing |
1898 makeHogsWorry(Gear^.X, Gear^.Y, 75); |
1977 makeHogsWorry(Gear^.X, Gear^.Y, 75); |
1899 if Gear^.Timer = 0 then |
1978 if Gear^.Timer = 0 then |
1900 begin |
1979 begin |
1901 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, Gear^.Hedgehog, EXPLAutoSound); |
1980 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, Gear^.Hedgehog, EXPLAutoSound); |
1902 DeleteGear(Gear); |
1981 DeleteGear(Gear); |
1903 exit |
1982 exit |
1904 end; |
1983 end; |
1905 dec(Gear^.Timer); |
1984 dec(Gear^.Timer); |
1906 end; |
1985 end; |
1907 |
1986 |
1908 /////////////////////////////////////////////////////////////////////////////// |
1987 /////////////////////////////////////////////////////////////////////////////// |
1909 |
1988 |
1915 procedure doStepRollingBarrel(Gear: PGear); |
1994 procedure doStepRollingBarrel(Gear: PGear); |
1916 var |
1995 var |
1917 i: LongInt; |
1996 i: LongInt; |
1918 particle: PVisualGear; |
1997 particle: PVisualGear; |
1919 begin |
1998 begin |
1920 if (Gear^.dY.QWordValue = 0) and (Gear^.dY.QWordValue = 0) and (TestCollisionYwithGear(Gear, 1) = 0) then SetLittle(Gear^.dY); |
1999 if (Gear^.dY.QWordValue = 0) and (Gear^.dY.QWordValue = 0) and (TestCollisionYwithGear(Gear, 1) = 0) then |
|
2000 SetLittle(Gear^.dY); |
1921 Gear^.State := Gear^.State or gstAnimation; |
2001 Gear^.State := Gear^.State or gstAnimation; |
1922 if ((Gear^.dX.QWordValue <> 0) or (Gear^.dY.QWordValue <> 0)) then |
2002 |
1923 begin |
2003 if ((Gear^.dX.QWordValue <> 0) |
|
2004 or (Gear^.dY.QWordValue <> 0)) then |
|
2005 begin |
1924 DeleteCI(Gear); |
2006 DeleteCI(Gear); |
1925 AllInactive := false; |
2007 AllInactive := false; |
1926 if not Gear^.dY.isNegative and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then |
2008 if not Gear^.dY.isNegative and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then |
1927 begin |
2009 begin |
1928 Gear^.State := Gear^.State or gsttmpFlag; |
2010 Gear^.State := Gear^.State or gsttmpFlag; |
1929 inc(Gear^.Damage, hwRound(Gear^.dY * _70)); |
2011 inc(Gear^.Damage, hwRound(Gear^.dY * _70)); |
1930 for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do |
2012 for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do |
1931 begin |
2013 begin |
1932 particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, |
2014 particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12,vgtDust); |
1933 vgtDust); |
2015 if particle <> nil then |
1934 if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480) |
2016 particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480) |
|
2017 end |
1935 end |
2018 end |
1936 end |
2019 else if not Gear^.dX.isNegative and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then |
1937 else if not Gear^.dX.isNegative and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) |
2020 inc(Gear^.Damage, hwRound(Gear^.dX * _70)) |
1938 then |
2021 |
1939 inc(Gear^.Damage, hwRound(Gear^.dX * _70)) |
2022 else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then |
1940 else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) |
2023 inc(Gear^.Damage, hwRound(Gear^.dY * -_70)) |
1941 then |
2024 |
1942 inc(Gear^.Damage, hwRound(Gear^.dY * -_70)) |
2025 else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then |
1943 else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) |
2026 inc(Gear^.Damage, hwRound(Gear^.dX * -_70)); |
1944 then |
|
1945 inc(Gear^.Damage, hwRound(Gear^.dX * -_70)); |
|
1946 |
2027 |
1947 doStepFallingGear(Gear); |
2028 doStepFallingGear(Gear); |
1948 CalcRotationDirAngle(Gear); |
2029 CalcRotationDirAngle(Gear); |
1949 //CheckGearDrowning(Gear) |
2030 //CheckGearDrowning(Gear) |
1950 end |
2031 end |
1951 else |
2032 else |
1952 begin |
2033 begin |
1953 Gear^.State := Gear^.State or gsttmpFlag; |
2034 Gear^.State := Gear^.State or gsttmpFlag; |
1954 AddGearCI(Gear) |
2035 AddGearCI(Gear) |
1955 end; |
2036 end; |
1956 |
2037 |
1957 (* |
2038 (* |
1958 Attempt to make a barrel knock itself over an edge. Would need more checks to avoid issues like burn damage |
2039 Attempt to make a barrel knock itself over an edge. Would need more checks to avoid issues like burn damage |
1959 begin |
2040 begin |
1960 x:= hwRound(Gear^.X); |
2041 x:= hwRound(Gear^.X); |
1968 Gear^.dX:= _0_08; |
2049 Gear^.dX:= _0_08; |
1969 end; |
2050 end; |
1970 if Gear^.dX.QWordValue = 0 then AddGearCI(Gear) |
2051 if Gear^.dX.QWordValue = 0 then AddGearCI(Gear) |
1971 end; *) |
2052 end; *) |
1972 |
2053 |
1973 if not Gear^.dY.isNegative and (Gear^.dY < _0_001) and (TestCollisionYwithGear(Gear, 1) <> 0) then Gear |
2054 if not Gear^.dY.isNegative and (Gear^.dY < _0_001) and (TestCollisionYwithGear(Gear, 1) <> 0) then |
1974 ^.dY := _0; |
2055 Gear^.dY := _0; |
1975 if hwAbs(Gear^.dX) < _0_001 then Gear^.dX := _0; |
2056 if hwAbs(Gear^.dX) < _0_001 then |
|
2057 Gear^.dX := _0; |
1976 |
2058 |
1977 if (Gear^.Health > 0) and ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then |
2059 if (Gear^.Health > 0) and ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then |
1978 if (cBarrelHealth div Gear^.Health) > 2 then |
2060 if (cBarrelHealth div Gear^.Health) > 2 then |
1979 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke) |
2061 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke) |
1980 else |
2062 else |
1981 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite); |
2063 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite); |
1982 dec(Gear^.Health, Gear^.Damage); |
2064 dec(Gear^.Health, Gear^.Damage); |
1983 Gear^.Damage := 0; |
2065 Gear^.Damage := 0; |
1984 if Gear^.Health <= 0 then Gear^.doStep := @doStepCase; |
2066 if Gear^.Health <= 0 then |
|
2067 Gear^.doStep := @doStepCase; |
1985 // Hand off to doStepCase for the explosion |
2068 // Hand off to doStepCase for the explosion |
1986 |
2069 |
1987 end; |
2070 end; |
1988 |
2071 |
1989 procedure doStepCase(Gear: PGear); |
2072 procedure doStepCase(Gear: PGear); |
1996 begin |
2079 begin |
1997 k := Gear^.Kind; |
2080 k := Gear^.Kind; |
1998 exBoom := false; |
2081 exBoom := false; |
1999 |
2082 |
2000 if (Gear^.Message and gmDestroy) > 0 then |
2083 if (Gear^.Message and gmDestroy) > 0 then |
2001 begin |
2084 begin |
2002 DeleteGear(Gear); |
2085 DeleteGear(Gear); |
2003 FreeActionsList; |
2086 FreeActionsList; |
2004 SetAllToActive; |
2087 SetAllToActive; |
2005 // something (hh, mine, etc...) could be on top of the case |
2088 // something (hh, mine, etc...) could be on top of the case |
2006 with CurrentHedgehog^ do |
2089 with CurrentHedgehog^ do |
2007 if Gear <> nil then Gear^.Message := Gear^.Message and (not (gmLJump or gmHJump)); |
2090 if Gear <> nil then |
|
2091 Gear^.Message := Gear^.Message and (not (gmLJump or gmHJump)); |
2008 exit |
2092 exit |
2009 end; |
2093 end; |
2010 |
2094 |
2011 if k = gtExplosives then |
2095 if k = gtExplosives then |
2012 begin |
2096 begin |
2013 //if V > _0_03 then Gear^.State:= Gear^.State or gstAnimation; |
2097 //if V > _0_03 then Gear^.State:= Gear^.State or gstAnimation; |
2014 if (hwAbs(Gear^.dX) > _0_15) or ((hwAbs(Gear^.dY) > _0_15) and (hwAbs(Gear^.dX) > _0_02)) |
2098 if (hwAbs(Gear^.dX) > _0_15) or ((hwAbs(Gear^.dY) > _0_15) and (hwAbs(Gear^.dX) > _0_02)) then |
2015 then Gear^.doStep := @doStepRollingBarrel; |
2099 Gear^.doStep := @doStepRollingBarrel; |
2016 |
2100 |
2017 if (Gear^.Health > 0) and ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then |
2101 if (Gear^.Health > 0) and ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then |
2018 if (cBarrelHealth div Gear^.Health) > 2 then |
2102 if (cBarrelHealth div Gear^.Health) > 2 then |
2019 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke) |
2103 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke) |
2020 else |
2104 else |
2021 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite); |
2105 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite); |
2022 dec(Gear^.Health, Gear^.Damage); |
2106 dec(Gear^.Health, Gear^.Damage); |
2023 Gear^.Damage := 0; |
2107 Gear^.Damage := 0; |
2024 if Gear^.Health <= 0 then |
2108 if Gear^.Health <= 0 then |
2025 exBoom := true; |
2109 exBoom := true; |
2026 end; |
2110 end; |
2027 |
2111 |
2028 if (Gear^.Damage > 0) or exBoom then |
2112 if (Gear^.Damage > 0) or exBoom then |
2029 begin |
2113 begin |
2030 x := hwRound(Gear^.X); |
2114 x := hwRound(Gear^.X); |
2031 y := hwRound(Gear^.Y); |
2115 y := hwRound(Gear^.Y); |
2032 hog:= Gear^.Hedgehog; |
2116 hog:= Gear^.Hedgehog; |
2033 |
2117 |
2034 DeleteGear(Gear); |
2118 DeleteGear(Gear); |
2035 // <-- delete gear! |
2119 // <-- delete gear! |
2036 |
2120 |
2037 if k = gtCase then |
2121 if k = gtCase then |
2038 begin |
2122 begin |
2039 doMakeExplosion(x, y, 25, hog, EXPLAutoSound); |
2123 doMakeExplosion(x, y, 25, hog, EXPLAutoSound); |
2040 for i:= 0 to 63 do |
2124 for i:= 0 to 63 do |
2041 AddGear(x, y, gtFlame, 0, _0, _0, 0); |
2125 AddGear(x, y, gtFlame, 0, _0, _0, 0); |
2042 end |
2126 end |
2043 else if k = gtExplosives then |
2127 else if k = gtExplosives then |
2044 begin |
2128 begin |
2045 doMakeExplosion(x, y, 75, hog, EXPLAutoSound); |
2129 doMakeExplosion(x, y, 75, hog, EXPLAutoSound); |
2046 for i:= 0 to 31 do |
2130 for i:= 0 to 31 do |
2047 begin |
2131 begin |
2048 dX := AngleCos(i * 64) * _0_5 * (getrandom + _1); |
2132 dX := AngleCos(i * 64) * _0_5 * (getrandom + _1); |
2049 dY := AngleSin(i * 64) * _0_5 * (getrandom + _1); |
2133 dY := AngleSin(i * 64) * _0_5 * (getrandom + _1); |
2050 AddGear(x, y, gtFlame, 0, dX, dY, 0); |
2134 AddGear(x, y, gtFlame, 0, dX, dY, 0); |
2051 AddGear(x, y, gtFlame, gstTmpFlag, -dX, -dY, 0); |
2135 AddGear(x, y, gtFlame, gstTmpFlag, -dX, -dY, 0); |
2052 end |
2136 end |
2053 end; |
2137 end; |
2054 exit |
2138 exit |
2055 end; |
2139 end; |
2056 |
2140 |
2057 if (Gear^.dY.QWordValue <> 0) or (TestCollisionYwithGear(Gear, 1) = 0) then |
2141 if (Gear^.dY.QWordValue <> 0) |
2058 begin |
2142 or (TestCollisionYwithGear(Gear, 1) = 0) then |
|
2143 begin |
2059 AllInactive := false; |
2144 AllInactive := false; |
2060 Gear^.dY := Gear^.dY + cGravity; |
2145 Gear^.dY := Gear^.dY + cGravity; |
2061 Gear^.Y := Gear^.Y + Gear^.dY; |
2146 Gear^.Y := Gear^.Y + Gear^.dY; |
2062 if (not Gear^.dY.isNegative) and (Gear^.dY > _0_001) then SetAllHHToActive; |
2147 if (not Gear^.dY.isNegative) and (Gear^.dY > _0_001) then |
2063 if (Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, -1) <> 0) then Gear^.dY := _0; |
2148 SetAllHHToActive; |
|
2149 |
|
2150 if (Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, -1) <> 0) then |
|
2151 Gear^.dY := _0; |
|
2152 |
2064 if (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) <> 0) then |
2153 if (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) <> 0) then |
2065 begin |
2154 begin |
2066 if (Gear^.dY > _0_2) and (k = gtExplosives) then |
2155 if (Gear^.dY > _0_2) and (k = gtExplosives) then |
2067 inc(Gear^.Damage, hwRound(Gear^.dY * _70)); |
2156 inc(Gear^.Damage, hwRound(Gear^.dY * _70)); |
2068 |
2157 |
2069 if Gear^.dY > _0_2 then |
2158 if Gear^.dY > _0_2 then |
2070 for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do |
2159 for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do |
2071 AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust) |
2160 AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust); |
2072 ; |
2161 |
2073 Gear^.dY := - Gear^.dY * Gear^.Elasticity; |
2162 Gear^.dY := - Gear^.dY * Gear^.Elasticity; |
2074 if Gear^.dY > - _0_001 then Gear^.dY := _0 |
2163 if Gear^.dY > - _0_001 then |
|
2164 Gear^.dY := _0 |
2075 else if Gear^.dY < - _0_03 then |
2165 else if Gear^.dY < - _0_03 then |
2076 PlaySound(Gear^.ImpactSound); |
2166 PlaySound(Gear^.ImpactSound); |
2077 end; |
2167 end; |
2078 //if Gear^.dY > - _0_001 then Gear^.dY:= _0 |
2168 //if Gear^.dY > - _0_001 then Gear^.dY:= _0 |
2079 CheckGearDrowning(Gear); |
2169 CheckGearDrowning(Gear); |
2080 end; |
2170 end; |
2081 |
2171 |
2082 if (Gear^.dY.QWordValue = 0) then AddGearCI(Gear) |
2172 if (Gear^.dY.QWordValue = 0) then |
2083 else if (Gear^.dY.QWordValue <> 0) then DeleteCI(Gear) |
2173 AddGearCI(Gear) |
|
2174 else if (Gear^.dY.QWordValue <> 0) then |
|
2175 DeleteCI(Gear) |
2084 end; |
2176 end; |
2085 |
2177 |
2086 //////////////////////////////////////////////////////////////////////////////// |
2178 //////////////////////////////////////////////////////////////////////////////// |
2087 |
2179 |
2088 procedure doStepTarget(Gear: PGear); |
2180 procedure doStepTarget(Gear: PGear); |
2264 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
2363 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
2265 end; |
2364 end; |
2266 |
2365 |
2267 // This one is interesting. I think I understand the purpose, but I wonder if a bit more fuzzy of kicking could be done with getrandom. |
2366 // This one is interesting. I think I understand the purpose, but I wonder if a bit more fuzzy of kicking could be done with getrandom. |
2268 Gear^.Timer := 100 - Gear^.Tag * 3; |
2367 Gear^.Timer := 100 - Gear^.Tag * 3; |
2269 if (Gear^.Damage > 3000+Gear^.Tag*1500) then Gear^.Health := 0 |
2368 if (Gear^.Damage > 3000+Gear^.Tag*1500) then |
|
2369 Gear^.Health := 0 |
|
2370 end |
2270 end |
2371 end |
2271 end |
2372 end; |
2272 end; |
|
2273 if Gear^.Health = 0 then |
2373 if Gear^.Health = 0 then |
2274 begin |
2374 begin |
2275 gX := hwRound(Gear^.X); |
2375 gX := hwRound(Gear^.X); |
2276 gY := hwRound(Gear^.Y); |
2376 gY := hwRound(Gear^.Y); |
2277 if not sticky then |
2377 if not sticky then |
2278 begin |
2378 begin |
2279 if ((GameTicks and $3) = 0) and (Random(1) = 0) then |
2379 if ((GameTicks and $3) = 0) and (Random(1) = 0) then |
2280 begin |
2380 begin |
2281 for i:= 1 to Random(2)+1 do |
2381 for i:= 1 to Random(2)+1 do |
2282 begin |
2382 begin |
2283 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
2383 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
|
2384 end; |
2284 end; |
2385 end; |
2285 end; |
2386 end |
2286 end |
|
2287 else |
2387 else |
2288 begin |
2388 begin |
2289 for i:= 0 to Random(3) do |
2389 for i:= 0 to Random(3) do |
2290 begin |
2390 begin |
2291 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
2391 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); |
2292 end; |
2392 end; |
2293 end; |
2393 end; |
2294 |
2394 |
2295 DeleteGear(Gear) |
2395 DeleteGear(Gear) |
2296 end; |
2396 end; |
2297 end; |
2397 end; |
2298 |
2398 |
2299 //////////////////////////////////////////////////////////////////////////////// |
2399 //////////////////////////////////////////////////////////////////////////////// |
2300 procedure doStepFirePunchWork(Gear: PGear); |
2400 procedure doStepFirePunchWork(Gear: PGear); |
2301 var |
2401 var |
2302 HHGear: PGear; |
2402 HHGear: PGear; |
2303 begin |
2403 begin |
2304 AllInactive := false; |
2404 AllInactive := false; |
2305 if ((Gear^.Message and gmDestroy) <> 0) then |
2405 if ((Gear^.Message and gmDestroy) <> 0) then |
2306 begin |
2406 begin |
2307 DeleteGear(Gear); |
2407 DeleteGear(Gear); |
2308 AfterAttack; |
2408 AfterAttack; |
2309 exit |
2409 exit |
2310 end; |
2410 end; |
2311 |
2411 |
2312 HHGear := Gear^.Hedgehog^.Gear; |
2412 HHGear := Gear^.Hedgehog^.Gear; |
2313 if hwRound(HHGear^.Y) <= Gear^.Tag - 2 then |
2413 if hwRound(HHGear^.Y) <= Gear^.Tag - 2 then |
2314 begin |
2414 begin |
2315 Gear^.Tag := hwRound(HHGear^.Y); |
2415 Gear^.Tag := hwRound(HHGear^.Y); |
2316 DrawTunnel(HHGear^.X - int2hwFloat(cHHRadius), HHGear^.Y - _1, _0_5, _0, cHHRadius * 4, 2); |
2416 DrawTunnel(HHGear^.X - int2hwFloat(cHHRadius), HHGear^.Y - _1, _0_5, _0, cHHRadius * 4, 2); |
2317 HHGear^.State := HHGear^.State or gstNoDamage; |
2417 HHGear^.State := HHGear^.State or gstNoDamage; |
2318 Gear^.Y := HHGear^.Y; |
2418 Gear^.Y := HHGear^.Y; |
2319 AmmoShove(Gear, 30, 40); |
2419 AmmoShove(Gear, 30, 40); |
2320 HHGear^.State := HHGear^.State and (not gstNoDamage) |
2420 HHGear^.State := HHGear^.State and (not gstNoDamage) |
2321 end; |
2421 end; |
2322 |
2422 |
2323 HHGear^.dY := HHGear^.dY + cGravity; |
2423 HHGear^.dY := HHGear^.dY + cGravity; |
2324 if not (HHGear^.dY.isNegative) then |
2424 if not (HHGear^.dY.isNegative) then |
2325 begin |
2425 begin |
2326 HHGear^.State := HHGear^.State or gstMoving; |
2426 HHGear^.State := HHGear^.State or gstMoving; |
2327 DeleteGear(Gear); |
2427 DeleteGear(Gear); |
2328 AfterAttack; |
2428 AfterAttack; |
2329 exit |
2429 exit |
2330 end; |
2430 end; |
2331 |
2431 |
2332 if CheckLandValue(hwRound(HHGear^.X), hwRound(HHGear^.Y + HHGear^.dY + SignAs(_6,Gear^.dY)), |
2432 if CheckLandValue(hwRound(HHGear^.X), hwRound(HHGear^.Y + HHGear^.dY + SignAs(_6,Gear^.dY)), |
2333 lfIndestructible) then |
2433 lfIndestructible) then |
2334 HHGear^.Y := HHGear^.Y + HHGear^.dY |
2434 HHGear^.Y := HHGear^.Y + HHGear^.dY |
2335 end; |
2435 end; |
2336 |
2436 |
2337 procedure doStepFirePunch(Gear: PGear); |
2437 procedure doStepFirePunch(Gear: PGear); |
2338 var |
2438 var |
2339 HHGear: PGear; |
2439 HHGear: PGear; |
2364 HHGear := Gear^.Hedgehog^.Gear; |
2464 HHGear := Gear^.Hedgehog^.Gear; |
2365 |
2465 |
2366 inc(Gear^.Timer); |
2466 inc(Gear^.Timer); |
2367 |
2467 |
2368 if (TestCollisionYwithGear(HHGear, 1) <> 0) |
2468 if (TestCollisionYwithGear(HHGear, 1) <> 0) |
2369 or ((HHGear^.State and gstHHDriven) = 0) |
2469 or ((HHGear^.State and gstHHDriven) = 0) |
2370 or CheckGearDrowning(HHGear) |
2470 or CheckGearDrowning(HHGear) |
2371 or ((Gear^.Message and gmAttack) <> 0) then |
2471 or ((Gear^.Message and gmAttack) <> 0) then |
2372 begin |
2472 begin |
2373 with HHGear^ do |
2473 with HHGear^ do |
2374 begin |
2474 begin |
2375 Message := 0; |
2475 Message := 0; |
2376 SetLittle(dX); |
2476 SetLittle(dX); |
2377 dY := _0; |
2477 dY := _0; |
2378 State := State or gstMoving; |
2478 State := State or gstMoving; |
2379 end; |
2479 end; |
2380 DeleteGear(Gear); |
2480 DeleteGear(Gear); |
2381 isCursorVisible := false; |
2481 isCursorVisible := false; |
2382 ApplyAmmoChanges(HHGear^.Hedgehog^); |
2482 ApplyAmmoChanges(HHGear^.Hedgehog^); |
2383 exit |
2483 exit |
2384 end; |
2484 end; |
2385 |
2485 |
2386 HHGear^.X := HHGear^.X + cWindSpeed * 200; |
2486 HHGear^.X := HHGear^.X + cWindSpeed * 200; |
2387 |
2487 |
2388 if (Gear^.Message and gmLeft) <> 0 then HHGear^.X := HHGear^.X - cMaxWindSpeed * 80 |
2488 if (Gear^.Message and gmLeft) <> 0 then |
2389 else if (Gear^.Message and gmRight) <> 0 then HHGear^.X := HHGear^.X + cMaxWindSpeed * 80; |
2489 HHGear^.X := HHGear^.X - cMaxWindSpeed * 80 |
2390 if (Gear^.Message and gmUp) <> 0 then HHGear^.Y := HHGear^.Y - cGravity * 40 |
2490 |
2391 else if (Gear^.Message and gmDown) <> 0 then HHGear^.Y := HHGear^.Y + cGravity * 40; |
2491 else if (Gear^.Message and gmRight) <> 0 then |
|
2492 HHGear^.X := HHGear^.X + cMaxWindSpeed * 80; |
|
2493 |
|
2494 if (Gear^.Message and gmUp) <> 0 then |
|
2495 HHGear^.Y := HHGear^.Y - cGravity * 40 |
|
2496 |
|
2497 else if (Gear^.Message and gmDown) <> 0 then |
|
2498 HHGear^.Y := HHGear^.Y + cGravity * 40; |
2392 |
2499 |
2393 // don't drift into obstacles |
2500 // don't drift into obstacles |
2394 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then |
2501 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then |
2395 HHGear^.X := HHGear^.X - int2hwFloat(hwSign(HHGear^.dX)); |
2502 HHGear^.X := HHGear^.X - int2hwFloat(hwSign(HHGear^.dX)); |
2396 HHGear^.Y := HHGear^.Y + cGravity * 100; |
2503 HHGear^.Y := HHGear^.Y + cGravity * 100; |
2424 Gear^.X := Gear^.X + cAirPlaneSpeed * Gear^.Tag; |
2531 Gear^.X := Gear^.X + cAirPlaneSpeed * Gear^.Tag; |
2425 |
2532 |
2426 if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then |
2533 if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then |
2427 begin |
2534 begin |
2428 dec(Gear^.Health); |
2535 dec(Gear^.Health); |
2429 case Gear^.State of |
2536 case Gear^.State of |
2430 0: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * |
2537 0: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0); |
2431 Gear^.Tag, _0, 0); |
2538 1: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine, 0, cBombsSpeed * Gear^.Tag, _0, 0); |
2432 1: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine, 0, cBombsSpeed * |
2539 2: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtNapalmBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0); |
2433 Gear^.Tag, _0, 0); |
2540 3: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtDrill, gsttmpFlag, cBombsSpeed * Gear^.Tag, _0, Gear^.Timer + 1); |
2434 2: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtNapalmBomb, 0, cBombsSpeed * |
|
2435 Gear^.Tag, _0, 0); |
|
2436 3: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtDrill, gsttmpFlag, cBombsSpeed * |
|
2437 Gear^.Tag, _0, Gear^.Timer + 1); |
|
2438 //4: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtWaterMelon, 0, cBombsSpeed * |
2541 //4: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtWaterMelon, 0, cBombsSpeed * |
2439 // Gear^.Tag, _0, 5000); |
2542 // Gear^.Tag, _0, 5000); |
2440 end; |
2543 end; |
2441 Gear^.dX := Gear^.dX + int2hwFloat(30 * Gear^.Tag); |
2544 Gear^.dX := Gear^.dX + int2hwFloat(30 * Gear^.Tag); |
2442 StopSound(Gear^.SoundChannel, 4000); |
2545 StopSound(Gear^.SoundChannel, 4000); |
2515 tx := int2hwFloat(Gear^.Target.X); |
2618 tx := int2hwFloat(Gear^.Target.X); |
2516 ty := int2hwFloat(Gear^.Target.Y); |
2619 ty := int2hwFloat(Gear^.Target.Y); |
2517 x := HHGear^.X; |
2620 x := HHGear^.X; |
2518 y := HHGear^.Y; |
2621 y := HHGear^.Y; |
2519 |
2622 |
2520 if (Distance(tx - x, ty - y) > _256) or |
2623 if (Distance(tx - x, ty - y) > _256) |
2521 (not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprAmGirder].Width div 2, |
2624 or (not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprAmGirder].Width div 2, Gear^.Target.Y - SpritesData[sprAmGirder].Height div 2, sprAmGirder, Gear^.State, true, false)) then |
2522 Gear^.Target.Y - SpritesData[sprAmGirder].Height div 2, |
2625 begin |
2523 sprAmGirder, Gear^.State, true, false)) then |
|
2524 begin |
|
2525 PlaySound(sndDenied); |
2626 PlaySound(sndDenied); |
2526 HHGear^.Message := HHGear^.Message and (not gmAttack); |
2627 HHGear^.Message := HHGear^.Message and (not gmAttack); |
2527 HHGear^.State := HHGear^.State and (not gstAttacking); |
2628 HHGear^.State := HHGear^.State and (not gstAttacking); |
2528 HHGear^.State := HHGear^.State or gstHHChooseTarget; |
2629 HHGear^.State := HHGear^.State or gstHHChooseTarget; |
2529 isCursorVisible := true; |
2630 isCursorVisible := true; |
2530 DeleteGear(Gear) |
2631 DeleteGear(Gear) |
2531 end |
2632 end |
2532 else |
2633 else |
2533 begin |
2634 begin |
2534 PlaySound(sndPlaced); |
2635 PlaySound(sndPlaced); |
2535 DeleteGear(Gear); |
2636 DeleteGear(Gear); |
2536 AfterAttack; |
2637 AfterAttack; |
2537 end; |
2638 end; |
2538 |
2639 |
2539 HHGear^.State := HHGear^.State and (not (gstAttacking or gstAttacked)); |
2640 HHGear^.State := HHGear^.State and (not (gstAttacking or gstAttacked)); |
2540 HHGear^.Message := HHGear^.Message and (not gmAttack); |
2641 HHGear^.Message := HHGear^.Message and (not gmAttack); |
2541 end; |
2642 end; |
2542 |
2643 |
2550 HHGear^.Y := HHGear^.Y + HHGear^.dY; |
2651 HHGear^.Y := HHGear^.Y + HHGear^.dY; |
2551 HHGear^.X := HHGear^.X + HHGear^.dX; |
2652 HHGear^.X := HHGear^.X + HHGear^.dX; |
2552 // hedgehog falling to collect cases |
2653 // hedgehog falling to collect cases |
2553 HHGear^.dY := HHGear^.dY + cGravity; |
2654 HHGear^.dY := HHGear^.dY + cGravity; |
2554 if (TestCollisionYwithGear(HHGear, 1) <> 0) |
2655 if (TestCollisionYwithGear(HHGear, 1) <> 0) |
2555 or CheckGearDrowning(HHGear) then |
2656 or CheckGearDrowning(HHGear) then |
2556 begin |
2657 begin |
2557 DeleteGear(Gear); |
2658 DeleteGear(Gear); |
2558 AfterAttack |
2659 AfterAttack |
2559 end |
2660 end |
2560 end; |
2661 end; |
2561 |
2662 |
2562 procedure doStepTeleportAnim(Gear: PGear); |
2663 procedure doStepTeleportAnim(Gear: PGear); |
2563 begin |
2664 begin |
2564 inc(Gear^.Timer); |
2665 inc(Gear^.Timer); |
2565 if Gear^.Timer = 65 then |
2666 if Gear^.Timer = 65 then |
2566 begin |
2667 begin |
2567 Gear^.Timer := 0; |
2668 Gear^.Timer := 0; |
2568 inc(Gear^.Pos); |
2669 inc(Gear^.Pos); |
2569 if Gear^.Pos = 11 then |
2670 if Gear^.Pos = 11 then |
2570 Gear^.doStep := @doStepTeleportAfter |
2671 Gear^.doStep := @doStepTeleportAfter |
2571 end; |
2672 end; |
2572 end; |
2673 end; |
2573 |
2674 |
2574 procedure doStepTeleport(Gear: PGear); |
2675 procedure doStepTeleport(Gear: PGear); |
2575 var |
2676 var |
2576 HHGear: PGear; |
2677 HHGear: PGear; |
2577 begin |
2678 begin |
2578 AllInactive := false; |
2679 AllInactive := false; |
2579 |
2680 |
2580 HHGear := Gear^.Hedgehog^.Gear; |
2681 HHGear := Gear^.Hedgehog^.Gear; |
2581 if not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprHHTelepMask].Width div 2, |
2682 if not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprHHTelepMask].Width div 2, |
2582 Gear^.Target.Y - SpritesData[sprHHTelepMask].Height div 2, |
2683 Gear^.Target.Y - SpritesData[sprHHTelepMask].Height div 2, |
2583 sprHHTelepMask, 0, false, false) then |
2684 sprHHTelepMask, 0, false, false) then |
2584 begin |
2685 begin |
2585 HHGear^.Message := HHGear^.Message and (not gmAttack); |
2686 HHGear^.Message := HHGear^.Message and (not gmAttack); |
2586 HHGear^.State := HHGear^.State and (not gstAttacking); |
2687 HHGear^.State := HHGear^.State and (not gstAttacking); |
2587 HHGear^.State := HHGear^.State or gstHHChooseTarget; |
2688 HHGear^.State := HHGear^.State or gstHHChooseTarget; |
2588 DeleteGear(Gear); |
2689 DeleteGear(Gear); |
2589 isCursorVisible := true; |
2690 isCursorVisible := true; |
2590 PlaySound(sndDenied) |
2691 PlaySound(sndDenied) |
2591 end |
2692 end |
2592 else |
2693 else |
2593 begin |
2694 begin |
2594 DeleteCI(HHGear); |
2695 DeleteCI(HHGear); |
2595 SetAllHHToActive; |
2696 SetAllHHToActive; |
2596 Gear^.doStep := @doStepTeleportAnim; |
2697 Gear^.doStep := @doStepTeleportAnim; |
2597 |
2698 |
2598 // copy old HH position and direction to Gear (because we need them for drawing the vanishing hog) |
2699 // copy old HH position and direction to Gear (because we need them for drawing the vanishing hog) |
2616 Msg, State: Longword; |
2717 Msg, State: Longword; |
2617 begin |
2718 begin |
2618 AllInactive := false; |
2719 AllInactive := false; |
2619 |
2720 |
2620 if ((Gear^.Message and (not gmSwitch)) <> 0) or (TurnTimeLeft = 0) then |
2721 if ((Gear^.Message and (not gmSwitch)) <> 0) or (TurnTimeLeft = 0) then |
2621 begin |
2722 begin |
2622 HHGear := Gear^.Hedgehog^.Gear; |
2723 HHGear := Gear^.Hedgehog^.Gear; |
2623 //Msg := Gear^.Message and (not gmSwitch); |
2724 //Msg := Gear^.Message and (not gmSwitch); |
2624 DeleteGear(Gear); |
2725 DeleteGear(Gear); |
2625 ApplyAmmoChanges(HHGear^.Hedgehog^); |
2726 ApplyAmmoChanges(HHGear^.Hedgehog^); |
2626 |
2727 |
2627 HHGear := CurrentHedgehog^.Gear; |
2728 HHGear := CurrentHedgehog^.Gear; |
2628 ApplyAmmoChanges(HHGear^.Hedgehog^); |
2729 ApplyAmmoChanges(HHGear^.Hedgehog^); |
2629 //HHGear^.Message := Msg; |
2730 //HHGear^.Message := Msg; |
2630 exit |
2731 exit |
2631 end; |
2732 end; |
2632 |
2733 |
2633 if (Gear^.Message and gmSwitch) <> 0 then |
2734 if (Gear^.Message and gmSwitch) <> 0 then |
2634 begin |
2735 begin |
2635 HHGear := CurrentHedgehog^.Gear; |
2736 HHGear := CurrentHedgehog^.Gear; |
2636 HHGear^.Message := HHGear^.Message and (not gmSwitch); |
2737 HHGear^.Message := HHGear^.Message and (not gmSwitch); |
2637 Gear^.Message := Gear^.Message and (not gmSwitch); |
2738 Gear^.Message := Gear^.Message and (not gmSwitch); |
2638 State := HHGear^.State; |
2739 State := HHGear^.State; |
2639 HHGear^.State := 0; |
2740 HHGear^.State := 0; |
2689 dxn := Gear^.dX.isNegative; |
2789 dxn := Gear^.dX.isNegative; |
2690 dyn := Gear^.dY.isNegative; |
2790 dyn := Gear^.dY.isNegative; |
2691 |
2791 |
2692 doStepFallingGear(Gear); |
2792 doStepFallingGear(Gear); |
2693 if (Gear^.State and gstCollision) <> 0 then |
2793 if (Gear^.State and gstCollision) <> 0 then |
2694 begin |
2794 begin |
2695 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLAutoSound); |
2795 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLAutoSound); |
2696 |
2796 |
2697 Gear^.dX.isNegative := not dxn; |
2797 Gear^.dX.isNegative := not dxn; |
2698 Gear^.dY.isNegative := not dyn; |
2798 Gear^.dY.isNegative := not dyn; |
2699 for i:= 0 to 4 do |
2799 for i:= 0 to 4 do |
2700 begin |
2800 begin |
2701 dX := Gear^.dX + (GetRandom - _0_5) * _0_03; |
2801 dX := Gear^.dX + (GetRandom - _0_5) * _0_03; |
2702 dY := Gear^.dY + (GetRandom - _0_5) * _0_03; |
2802 dY := Gear^.dY + (GetRandom - _0_5) * _0_03; |
2703 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25); |
2803 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25); |
2704 end; |
2804 end; |
2705 |
2805 |
2706 DeleteGear(Gear); |
2806 DeleteGear(Gear); |
2707 exit |
2807 exit |
2708 end; |
2808 end; |
2709 |
2809 |
2710 if (GameTicks and $3F) = 0 then |
2810 if (GameTicks and $3F) = 0 then |
2711 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) |
2811 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) |
2712 end; |
2812 end; |
2713 |
2813 |
2753 |
2854 |
2754 // if TestCollisionXwithGear(HHGear, hwSign(Gear^.dX)) |
2855 // if TestCollisionXwithGear(HHGear, hwSign(Gear^.dX)) |
2755 // or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY)) then inc(Gear^.Damage, 3); |
2856 // or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY)) then inc(Gear^.Damage, 3); |
2756 |
2857 |
2757 dec(i) |
2858 dec(i) |
2758 until (i = 0) or (Gear^.Damage > Gear^.Health); |
2859 until (i = 0) |
|
2860 or (Gear^.Damage > Gear^.Health); |
2759 |
2861 |
2760 inc(upd); |
2862 inc(upd); |
2761 if upd > 3 then |
2863 if upd > 3 then |
2762 begin |
2864 begin |
2763 if Gear^.Health < 1500 then |
2865 if Gear^.Health < 1500 then |
2764 begin |
2866 begin |
2765 if Gear^.AdvBounce <> 0 then |
2867 if Gear^.AdvBounce <> 0 then |
2766 Gear^.Pos := 3 |
2868 Gear^.Pos := 3 |
2767 else |
2869 else |
2768 Gear^.Pos := 2; |
2870 Gear^.Pos := 2; |
2769 end; |
2871 end; |
2770 |
2872 |
2771 AmmoShove(Gear, 30, 40); |
2873 AmmoShove(Gear, 30, 40); |
2772 |
2874 |
2773 DrawTunnel(HHGear^.X - HHGear^.dX * 10, |
2875 DrawTunnel(HHGear^.X - HHGear^.dX * 10, |
2774 HHGear^.Y - _2 - HHGear^.dY * 10 + hwAbs(HHGear^.dY) * 2, |
2876 HHGear^.Y - _2 - HHGear^.dY * 10 + hwAbs(HHGear^.dY) * 2, |
2775 HHGear^.dX, |
2877 HHGear^.dX, |
2776 HHGear^.dY, |
2878 HHGear^.dY, |
2777 20 + cHHRadius * 2, |
2879 20 + cHHRadius * 2, |
2778 cHHRadius * 2 + 7); |
2880 cHHRadius * 2 + 7); |
2779 |
2881 |
2780 upd := 0 |
2882 upd := 0 |
2781 end; |
2883 end; |
2782 |
2884 |
2783 if Gear^.Health < Gear^.Damage then |
2885 if Gear^.Health < Gear^.Damage then |
2784 begin |
2886 begin |
2785 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound); |
2887 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound); |
2786 if hasWishes then |
2888 if hasWishes then |
2787 for i:= 0 to 31 do |
2889 for i:= 0 to 31 do |
2788 begin |
2890 begin |
2789 sparkles:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtStraightShot); |
2891 sparkles:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtStraightShot); |
2925 |
3032 |
2926 if (xx = 0) then |
3033 if (xx = 0) then |
2927 if TestCollisionYwithGear(Gear, yy) <> 0 then |
3034 if TestCollisionYwithGear(Gear, yy) <> 0 then |
2928 PrevAngle(Gear, dA) |
3035 PrevAngle(Gear, dA) |
2929 else |
3036 else |
2930 begin |
3037 begin |
2931 Gear^.Tag := 0; |
3038 Gear^.Tag := 0; |
2932 Gear^.Y := Gear^.Y + int2hwFloat(yy); |
3039 Gear^.Y := Gear^.Y + int2hwFloat(yy); |
2933 if not TestCollisionXwithGear(Gear, xxn) then |
3040 if not TestCollisionXwithGear(Gear, xxn) then |
2934 begin |
3041 begin |
2935 Gear^.X := Gear^.X + int2hwFloat(xxn); |
3042 Gear^.X := Gear^.X + int2hwFloat(xxn); |
2936 NextAngle(Gear, dA) |
3043 NextAngle(Gear, dA) |
2937 end; |
3044 end; |
2938 end; |
3045 end; |
2939 |
3046 |
2940 if (yy = 0) then |
3047 if (yy = 0) then |
2941 if TestCollisionXwithGear(Gear, xx) then |
3048 if TestCollisionXwithGear(Gear, xx) then |
2942 PrevAngle(Gear, dA) |
3049 PrevAngle(Gear, dA) |
2943 else |
3050 else |
2944 begin |
3051 begin |
2945 Gear^.Tag := 0; |
3052 Gear^.Tag := 0; |
2946 Gear^.X := Gear^.X + int2hwFloat(xx); |
3053 Gear^.X := Gear^.X + int2hwFloat(xx); |
2947 if not TestCollisionY(Gear, yyn) then |
3054 if not TestCollisionY(Gear, yyn) then |
2948 begin |
3055 begin |
2949 Gear^.Y := Gear^.Y + int2hwFloat(yyn); |
3056 Gear^.Y := Gear^.Y + int2hwFloat(yyn); |
2950 NextAngle(Gear, dA) |
3057 NextAngle(Gear, dA) |
2951 end; |
3058 end; |
2952 end; |
3059 end; |
2953 |
3060 |
2954 if Gear^.Tag = 0 then |
3061 if Gear^.Tag = 0 then |
2955 begin |
3062 begin |
2956 CakeI := (CakeI + 1) mod cakeh; |
3063 CakeI := (CakeI + 1) mod cakeh; |
2957 tdx := CakePoints[CakeI].x - Gear^.X; |
3064 tdx := CakePoints[CakeI].x - Gear^.X; |
2958 tdy := - CakePoints[CakeI].y + Gear^.Y; |
3065 tdy := - CakePoints[CakeI].y + Gear^.Y; |
2959 CakePoints[CakeI].x := Gear^.X; |
3066 CakePoints[CakeI].x := Gear^.X; |
2960 CakePoints[CakeI].y := Gear^.Y; |
3067 CakePoints[CakeI].y := Gear^.Y; |
2961 Gear^.DirAngle := DxDy2Angle(tdx, tdy); |
3068 Gear^.DirAngle := DxDy2Angle(tdx, tdy); |
2962 end; |
3069 end; |
2963 |
3070 |
2964 dec(Gear^.Health); |
3071 dec(Gear^.Health); |
2965 Gear^.Timer := Gear^.Health*10; |
3072 Gear^.Timer := Gear^.Health*10; |
2966 if Gear^.Health mod 100 = 0 then Gear^.PortalCounter:= 0; |
3073 if Gear^.Health mod 100 = 0 then |
|
3074 Gear^.PortalCounter:= 0; |
2967 // This is not seconds, but at least it is *some* feedback |
3075 // This is not seconds, but at least it is *some* feedback |
2968 if (Gear^.Health = 0) or ((Gear^.Message and gmAttack) <> 0) then |
3076 if (Gear^.Health = 0) or ((Gear^.Message and gmAttack) <> 0) then |
2969 begin |
3077 begin |
2970 FollowGear := Gear; |
3078 FollowGear := Gear; |
2971 Gear^.RenderTimer := false; |
3079 Gear^.RenderTimer := false; |
2972 Gear^.doStep := @doStepCakeDown |
3080 Gear^.doStep := @doStepCakeDown |
2973 end |
3081 end |
2974 end; |
3082 end; |
2975 |
3083 |
2976 procedure doStepCakeUp(Gear: PGear); |
3084 procedure doStepCakeUp(Gear: PGear); |
2977 var |
3085 var |
2978 i: Longword; |
3086 i: Longword; |
2979 begin |
3087 begin |
2980 AllInactive := false; |
3088 AllInactive := false; |
2981 |
3089 |
2982 inc(Gear^.Tag); |
3090 inc(Gear^.Tag); |
2983 if Gear^.Tag < 100 then exit; |
3091 if Gear^.Tag < 100 then |
|
3092 exit; |
2984 Gear^.Tag := 0; |
3093 Gear^.Tag := 0; |
2985 |
3094 |
2986 if Gear^.Pos = 6 then |
3095 if Gear^.Pos = 6 then |
2987 begin |
3096 begin |
2988 for i:= 0 to Pred(cakeh) do |
3097 for i:= 0 to Pred(cakeh) do |
2989 begin |
3098 begin |
2990 CakePoints[i].x := Gear^.X; |
3099 CakePoints[i].x := Gear^.X; |
2991 CakePoints[i].y := Gear^.Y |
3100 CakePoints[i].y := Gear^.Y |
2992 end; |
3101 end; |
2993 CakeI := 0; |
3102 CakeI := 0; |
2994 Gear^.doStep := @doStepCakeWork |
3103 Gear^.doStep := @doStepCakeWork |
2995 end |
3104 end |
2996 else inc(Gear^.Pos) |
3105 else |
|
3106 inc(Gear^.Pos) |
2997 end; |
3107 end; |
2998 |
3108 |
2999 procedure doStepCakeFall(Gear: PGear); |
3109 procedure doStepCakeFall(Gear: PGear); |
3000 begin |
3110 begin |
3001 AllInactive := false; |
3111 AllInactive := false; |
3002 |
3112 |
3003 Gear^.dY := Gear^.dY + cGravity; |
3113 Gear^.dY := Gear^.dY + cGravity; |
3004 if TestCollisionYwithGear(Gear, 1) <> 0 then Gear^.doStep := @doStepCakeUp |
3114 if TestCollisionYwithGear(Gear, 1) <> 0 then |
|
3115 Gear^.doStep := @doStepCakeUp |
3005 else |
3116 else |
3006 begin |
3117 begin |
3007 Gear^.Y := Gear^.Y + Gear^.dY; |
3118 Gear^.Y := Gear^.Y + Gear^.dY; |
3008 if CheckGearDrowning(Gear) then AfterAttack |
3119 if CheckGearDrowning(Gear) then |
|
3120 AfterAttack |
3009 end |
3121 end |
3010 end; |
3122 end; |
3011 |
3123 |
3012 procedure doStepCake(Gear: PGear); |
3124 procedure doStepCake(Gear: PGear); |
3013 var |
3125 var |
3161 Gear^.Y := Gear^.Y + Gear^.dY; |
3276 Gear^.Y := Gear^.Y + Gear^.dY; |
3162 DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 2, 6); |
3277 DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 2, 6); |
3163 if (Gear^.Timer mod 30) = 0 then |
3278 if (Gear^.Timer mod 30) = 0 then |
3164 AddVisualGear(hwRound(Gear^.X + _20 * Gear^.dX), hwRound(Gear^.Y + _20 * Gear^.dY), vgtDust); |
3279 AddVisualGear(hwRound(Gear^.X + _20 * Gear^.dX), hwRound(Gear^.Y + _20 * Gear^.dY), vgtDust); |
3165 if (CheckGearDrowning(Gear)) then |
3280 if (CheckGearDrowning(Gear)) then |
3166 begin |
3281 begin |
3167 StopSound(Gear^.SoundChannel); |
3282 StopSound(Gear^.SoundChannel); |
3168 exit |
3283 exit |
3169 end |
3284 end |
3170 end; |
3285 end; |
3171 |
3286 |
3172 if GameTicks > Gear^.FlightTime then t := CheckGearsCollision(Gear) |
3287 if GameTicks > Gear^.FlightTime then |
|
3288 t := CheckGearsCollision(Gear) |
|
3289 |
3173 else t := nil; |
3290 else t := nil; |
3174 //fixes drill not exploding when touching HH bug |
3291 //fixes drill not exploding when touching HH bug |
3175 if (Gear^.Timer = 0) or ((t <> nil) and (t^.Count <> 0)) or |
3292 |
3176 ( ((Gear^.State and gsttmpFlag) = 0) and |
3293 if (Gear^.Timer = 0) or ((t <> nil) and (t^.Count <> 0)) |
3177 (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) |
3294 or ( ((Gear^.State and gsttmpFlag) = 0) and (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX)))) |
3178 and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX)))) |
|
3179 // CheckLandValue returns true if the type isn't matched |
3295 // CheckLandValue returns true if the type isn't matched |
3180 or (not CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible)) then |
3296 or (not CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y), lfIndestructible)) then |
3181 begin |
3297 begin |
3182 //out of time or exited ground |
3298 //out of time or exited ground |
3183 StopSound(Gear^.SoundChannel); |
3299 StopSound(Gear^.SoundChannel); |
3184 if (Gear^.State and gsttmpFlag) <> 0 then |
3300 if (Gear^.State and gsttmpFlag) <> 0 then |
3185 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound) |
3301 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound) |
3186 else |
3302 else |
3187 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); |
3303 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound); |
3188 DeleteGear(Gear); |
3304 DeleteGear(Gear); |
3189 exit |
3305 exit |
3190 end |
3306 end |
|
3307 |
3191 else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))) then |
3308 else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))) then |
3192 begin |
3309 begin |
3193 StopSound(Gear^.SoundChannel); |
3310 StopSound(Gear^.SoundChannel); |
3194 Gear^.Tag := 1; |
3311 Gear^.Tag := 1; |
3195 Gear^.doStep := @doStepDrill |
3312 Gear^.doStep := @doStepDrill |
3216 |
3333 |
3217 if (GameTicks and $3F) = 0 then |
3334 if (GameTicks and $3F) = 0 then |
3218 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); |
3335 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); |
3219 |
3336 |
3220 if ((Gear^.State and gstCollision) <> 0) then |
3337 if ((Gear^.State and gstCollision) <> 0) then |
3221 begin |
3338 begin |
3222 //hit |
3339 //hit |
3223 Gear^.dX := oldDx; |
3340 Gear^.dX := oldDx; |
3224 Gear^.dY := oldDy; |
3341 Gear^.dY := oldDy; |
3225 |
3342 |
3226 if GameTicks > Gear^.FlightTime then t := CheckGearsCollision(Gear) |
3343 if GameTicks > Gear^.FlightTime then |
3227 else t := nil; |
3344 t := CheckGearsCollision(Gear) |
|
3345 else |
|
3346 t := nil; |
3228 if (t = nil) or (t^.Count = 0) then |
3347 if (t = nil) or (t^.Count = 0) then |
3229 begin |
3348 begin |
3230 //hit the ground not the HH |
3349 //hit the ground not the HH |
3231 t2 := _0_5 / Distance(Gear^.dX, Gear^.dY); |
3350 t2 := _0_5 / Distance(Gear^.dX, Gear^.dY); |
3232 Gear^.dX := Gear^.dX * t2; |
3351 Gear^.dX := Gear^.dX * t2; |
3233 Gear^.dY := Gear^.dY * t2; |
3352 Gear^.dY := Gear^.dY * t2; |
3234 end |
3353 end |
|
3354 |
3235 else if (t <> nil) then |
3355 else if (t <> nil) then |
3236 begin |
3356 begin |
3237 //explode right on contact with HH |
3357 //explode right on contact with HH |
3238 if (Gear^.State and gsttmpFlag) <> 0 then |
3358 if (Gear^.State and gsttmpFlag) <> 0 then |
3239 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound) |
3359 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound) |
3273 HHGear := Gear^.Hedgehog^.Gear; |
3395 HHGear := Gear^.Hedgehog^.Gear; |
3274 HedgehogChAngle(HHGear); |
3396 HedgehogChAngle(HHGear); |
3275 gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle); |
3397 gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle); |
3276 gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle); |
3398 gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle); |
3277 if (Gear^.Timer mod 100) = 0 then |
3399 if (Gear^.Timer mod 100) = 0 then |
3278 begin |
3400 begin |
3279 rx := rndSign(getRandom * _0_1); |
3401 rx := rndSign(getRandom * _0_1); |
3280 ry := rndSign(getRandom * _0_1); |
3402 ry := rndSign(getRandom * _0_1); |
3281 |
3403 |
3282 AddGear(gx, gy, gtBall, 0, |
3404 AddGear(gx, gy, gtBall, 0, SignAs(AngleSin(HHGear^.Angle) * _0_8, HHGear^.dX) + rx, AngleCos(HHGear^.Angle) * ( - _0_8) + ry, 0); |
3283 SignAs(AngleSin(HHGear^.Angle) * _0_8, HHGear^.dX) + rx, |
|
3284 AngleCos(HHGear^.Angle) * ( - _0_8) + ry, |
|
3285 0); |
|
3286 |
3405 |
3287 PlaySound(sndGun); |
3406 PlaySound(sndGun); |
3288 end; |
3407 end; |
3289 |
3408 |
3290 if (Gear^.Timer = 0) or (HHGear^.Damage <> 0) then |
3409 if (Gear^.Timer = 0) or (HHGear^.Damage <> 0) then |
3291 begin |
3410 begin |
3292 DeleteGear(Gear); |
3411 DeleteGear(Gear); |
3293 AfterAttack |
3412 AfterAttack |
3294 end |
3413 end |
3295 end; |
3414 end; |
3296 |
3415 |
3297 procedure doStepBallgun(Gear: PGear); |
3416 procedure doStepBallgun(Gear: PGear); |
3298 var |
3417 var |
3299 HHGear: PGear; |
3418 HHGear: PGear; |
3319 AllInactive := false; |
3438 AllInactive := false; |
3320 |
3439 |
3321 HHGear := Gear^.Hedgehog^.Gear; |
3440 HHGear := Gear^.Hedgehog^.Gear; |
3322 FollowGear := Gear; |
3441 FollowGear := Gear; |
3323 |
3442 |
3324 if Gear^.Timer > 0 then dec(Gear^.Timer); |
3443 if Gear^.Timer > 0 then |
|
3444 dec(Gear^.Timer); |
3325 |
3445 |
3326 fChanged := false; |
3446 fChanged := false; |
3327 if ((HHGear^.State and gstHHDriven) = 0) or (Gear^.Timer = 0) then |
3447 if ((HHGear^.State and gstHHDriven) = 0) or (Gear^.Timer = 0) then |
3328 begin |
3448 begin |
3329 fChanged := true; |
3449 fChanged := true; |
3330 if Gear^.Angle > 2048 then dec(Gear^.Angle) |
3450 if Gear^.Angle > 2048 then |
|
3451 dec(Gear^.Angle) |
3331 else |
3452 else |
3332 if Gear^.Angle < 2048 then inc(Gear^.Angle) |
3453 if Gear^.Angle < 2048 then |
3333 else fChanged := false |
3454 inc(Gear^.Angle) |
|
3455 else |
|
3456 fChanged := false |
3334 end |
3457 end |
3335 else |
3458 else |
3336 begin |
3459 begin |
3337 if ((Gear^.Message and gmLeft) <> 0) then |
3460 if ((Gear^.Message and gmLeft) <> 0) then |
3338 begin |
3461 begin |
3339 fChanged := true; |
3462 fChanged := true; |
3340 Gear^.Angle := (Gear^.Angle + (4096 - cAngleSpeed)) mod 4096 |
3463 Gear^.Angle := (Gear^.Angle + (4096 - cAngleSpeed)) mod 4096 |
3341 end; |
3464 end; |
3342 |
3465 |
3343 if ((Gear^.Message and gmRight) <> 0) then |
3466 if ((Gear^.Message and gmRight) <> 0) then |
3344 begin |
3467 begin |
3345 fChanged := true; |
3468 fChanged := true; |
3346 Gear^.Angle := (Gear^.Angle + cAngleSpeed) mod 4096 |
3469 Gear^.Angle := (Gear^.Angle + cAngleSpeed) mod 4096 |
3347 end |
3470 end |
3348 end; |
3471 end; |
3349 |
3472 |
3350 if fChanged then |
3473 if fChanged then |
3351 begin |
3474 begin |
3352 Gear^.dX.isNegative := (Gear^.Angle > 2048); |
3475 Gear^.dX.isNegative := (Gear^.Angle > 2048); |
3353 if Gear^.dX.isNegative then |
3476 if Gear^.dX.isNegative then |
3354 trueAngle := 4096 - Gear^.Angle |
3477 trueAngle := 4096 - Gear^.Angle |
3355 else |
3478 else |
3356 trueAngle := Gear^.Angle; |
3479 trueAngle := Gear^.Angle; |
3357 |
3480 |
3358 Gear^.dX := SignAs(AngleSin(trueAngle), Gear^.dX) * _0_25; |
3481 Gear^.dX := SignAs(AngleSin(trueAngle), Gear^.dX) * _0_25; |
3359 Gear^.dY := AngleCos(trueAngle) * -_0_25; |
3482 Gear^.dY := AngleCos(trueAngle) * -_0_25; |
3360 end; |
3483 end; |
3361 |
3484 |
3362 Gear^.X := Gear^.X + Gear^.dX; |
3485 Gear^.X := Gear^.X + Gear^.dX; |
3363 Gear^.Y := Gear^.Y + Gear^.dY; |
3486 Gear^.Y := Gear^.Y + Gear^.dY; |
3364 |
3487 |
3365 if (GameTicks and $FF) = 0 then |
3488 if (GameTicks and $FF) = 0 then |
3367 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEvilTrace) |
3490 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEvilTrace) |
3368 else |
3491 else |
3369 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); |
3492 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); |
3370 |
3493 |
3371 if ((HHGear^.Message and gmAttack) <> 0) and (Gear^.Health <> 0) then |
3494 if ((HHGear^.Message and gmAttack) <> 0) and (Gear^.Health <> 0) then |
3372 begin |
3495 begin |
3373 HHGear^.Message := HHGear^.Message and (not gmAttack); |
3496 HHGear^.Message := HHGear^.Message and (not gmAttack); |
3374 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY * |
3497 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY * |
3375 _0_5, 0); |
3498 _0_5, 0); |
3376 dec(Gear^.Health) |
3499 dec(Gear^.Health) |
3377 end; |
3500 end; |
3378 |
3501 |
3379 if ((HHGear^.Message and gmLJump) <> 0) |
3502 if ((HHGear^.Message and gmLJump) <> 0) and ((Gear^.State and gsttmpFlag) = 0) then |
3380 and ((Gear^.State and gsttmpFlag) = 0) then |
3503 begin |
3381 begin |
|
3382 Gear^.State := Gear^.State or gsttmpFlag; |
3504 Gear^.State := Gear^.State or gsttmpFlag; |
3383 PauseMusic; |
3505 PauseMusic; |
3384 playSound(sndRideOfTheValkyries); |
3506 playSound(sndRideOfTheValkyries); |
3385 end; |
3507 end; |
3386 |
3508 |
3387 // pickup bonuses |
3509 // pickup bonuses |
3388 t := CheckGearNear(Gear, gtCase, 36, 36); |
3510 t := CheckGearNear(Gear, gtCase, 36, 36); |
3389 if t <> nil then |
3511 if t <> nil then |
3390 PickUp(HHGear, t); |
3512 PickUp(HHGear, t); |
3391 |
3513 |
3392 CheckCollision(Gear); |
3514 CheckCollision(Gear); |
3393 |
3515 |
3394 if ((Gear^.State and gstCollision) <> 0) or CheckGearDrowning(Gear) then |
3516 if ((Gear^.State and gstCollision) <> 0) or CheckGearDrowning(Gear) then |
3395 begin |
3517 begin |
3396 StopSound(Gear^.SoundChannel); |
3518 StopSound(Gear^.SoundChannel); |
3397 StopSound(sndRideOfTheValkyries); |
3519 StopSound(sndRideOfTheValkyries); |
3398 ResumeMusic; |
3520 ResumeMusic; |
3399 |
3521 |
3400 if ((Gear^.State and gstCollision) <> 0) then |
3522 if ((Gear^.State and gstCollision) <> 0) then |
3401 begin |
3523 begin |
3402 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, Gear^.Hedgehog, EXPLAutoSound); |
3524 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, Gear^.Hedgehog, EXPLAutoSound); |
3403 for i:= 0 to 15 do |
3525 for i:= 0 to 15 do |
3404 begin |
3526 begin |
3405 dX := AngleCos(i * 64) * _0_5 * (GetRandom + _1); |
3527 dX := AngleCos(i * 64) * _0_5 * (GetRandom + _1); |
3406 dY := AngleSin(i * 64) * _0_5 * (GetRandom + _1); |
3528 dY := AngleSin(i * 64) * _0_5 * (GetRandom + _1); |
3407 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0); |
3529 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0); |
3408 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0); |
3530 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0); |
3409 end; |
3531 end; |
3410 DeleteGear(Gear) |
3532 DeleteGear(Gear) |
3411 end; |
3533 end; |
3412 |
3534 |
3413 AfterAttack; |
3535 AfterAttack; |
3414 CurAmmoGear := nil; |
3536 CurAmmoGear := nil; |
3415 if (GameFlags and gfInfAttack) = 0 then |
3537 if (GameFlags and gfInfAttack) = 0 then |
3416 begin |
3538 begin |
3417 if TagTurnTimeLeft = 0 then TagTurnTimeLeft:= TurnTimeLeft; |
3539 if TagTurnTimeLeft = 0 then |
|
3540 TagTurnTimeLeft:= TurnTimeLeft; |
|
3541 |
3418 TurnTimeLeft:= 14 * 125; |
3542 TurnTimeLeft:= 14 * 125; |
3419 end; |
3543 end; |
3420 |
3544 |
3421 HHGear^.Message := 0; |
3545 HHGear^.Message := 0; |
3422 ParseCommand('/taunt ' + #1, true) |
3546 ParseCommand('/taunt ' + #1, true) |
3423 end |
3547 end |
3424 end; |
3548 end; |
3425 |
3549 |
3426 procedure doStepRCPlane(Gear: PGear); |
3550 procedure doStepRCPlane(Gear: PGear); |
3427 var |
3551 var |
3428 HHGear: PGear; |
3552 HHGear: PGear; |
3511 begin |
3639 begin |
3512 Gear^.Timer := 0; |
3640 Gear^.Timer := 0; |
3513 Gear^.MsgParam := 0 |
3641 Gear^.MsgParam := 0 |
3514 end; |
3642 end; |
3515 |
3643 |
3516 if Gear^.Health < 0 then Gear^.Health := 0; |
3644 if Gear^.Health < 0 then |
|
3645 Gear^.Health := 0; |
|
3646 |
3517 i:= Gear^.Health div 20; |
3647 i:= Gear^.Health div 20; |
|
3648 |
3518 if (i <> Gear^.Damage) and ((GameTicks and $3F) = 0) then |
3649 if (i <> Gear^.Damage) and ((GameTicks and $3F) = 0) then |
3519 begin |
3650 begin |
3520 Gear^.Damage:= i; |
3651 Gear^.Damage:= i; |
3521 //AddCaption('Fuel: '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate); |
3652 //AddCaption('Fuel: '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate); |
3522 FreeTexture(Gear^.Tex); |
3653 FreeTexture(Gear^.Tex); |
3523 Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) + |
3654 Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) + '%', cWhiteColor, fntSmall) |
3524 '%', cWhiteColor, fntSmall) |
|
3525 end; |
3655 end; |
3526 |
3656 |
3527 if HHGear^.Message and (gmAttack or gmUp or gmPrecise or gmLeft or gmRight) <> 0 then |
3657 if HHGear^.Message and (gmAttack or gmUp or gmPrecise or gmLeft or gmRight) <> 0 then |
3528 Gear^.State := Gear^.State and (not gsttmpFlag); |
3658 Gear^.State := Gear^.State and (not gsttmpFlag); |
|
3659 |
3529 HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight)); |
3660 HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight)); |
3530 HHGear^.State := HHGear^.State or gstMoving; |
3661 HHGear^.State := HHGear^.State or gstMoving; |
3531 |
3662 |
3532 Gear^.X := HHGear^.X; |
3663 Gear^.X := HHGear^.X; |
3533 Gear^.Y := HHGear^.Y; |
3664 Gear^.Y := HHGear^.Y; |
3534 // For some reason I need to reapply followgear here, something else grabs it otherwise. |
3665 // For some reason I need to reapply followgear here, something else grabs it otherwise. |
3535 // This is probably not needed anymore |
3666 // This is probably not needed anymore |
3536 if not CurrentTeam^.ExtDriven then FollowGear := HHGear; |
3667 if not CurrentTeam^.ExtDriven then |
3537 |
3668 FollowGear := HHGear; |
3538 if not isUnderWater and hasBorder and ((HHGear^.X < _0) or (hwRound(HHGear^.X) > LAND_WIDTH)) then HHGear^.dY.isNegative:= false; |
3669 |
3539 if ((Gear^.State and gsttmpFlag) = 0) or (HHGear^.dY < _0) then doStepHedgehogMoving(HHGear); |
3670 if not isUnderWater and hasBorder and ((HHGear^.X < _0) |
|
3671 or (hwRound(HHGear^.X) > LAND_WIDTH)) then |
|
3672 HHGear^.dY.isNegative:= false; |
|
3673 |
|
3674 if ((Gear^.State and gsttmpFlag) = 0) |
|
3675 or (HHGear^.dY < _0) then |
|
3676 doStepHedgehogMoving(HHGear); |
3540 |
3677 |
3541 if // (Gear^.Health = 0) |
3678 if // (Gear^.Health = 0) |
3542 (HHGear^.Damage <> 0) |
3679 (HHGear^.Damage <> 0) |
3543 //or CheckGearDrowning(HHGear) |
3680 //or CheckGearDrowning(HHGear) |
3544 or (cWaterLine + 512 < hwRound(HHGear^.Y)) |
3681 or (cWaterLine + 512 < hwRound(HHGear^.Y)) |
3545 or (TurnTimeLeft = 0) |
3682 or (TurnTimeLeft = 0) |
3546 // allow brief ground touches - to be fair on this, might need another counter |
3683 // allow brief ground touches - to be fair on this, might need another counter |
3547 or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0)) |
3684 or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0)) |
3548 or ((Gear^.Message and gmAttack) <> 0) then |
3685 or ((Gear^.Message and gmAttack) <> 0) then |
3549 begin |
3686 begin |
3550 with HHGear^ do |
3687 with HHGear^ do |
3551 begin |
3688 begin |
3552 Message := 0; |
3689 Message := 0; |
3553 Active := true; |
3690 Active := true; |
3554 State := State or gstMoving |
3691 State := State or gstMoving |
3555 end; |
3692 end; |
3556 DeleteGear(Gear); |
3693 DeleteGear(Gear); |
3557 isCursorVisible := false; |
3694 isCursorVisible := false; |
3558 ApplyAmmoChanges(HHGear^.Hedgehog^); |
3695 ApplyAmmoChanges(HHGear^.Hedgehog^); |
3559 // if Gear^.Tex <> nil then FreeTexture(Gear^.Tex); |
3696 // if Gear^.Tex <> nil then FreeTexture(Gear^.Tex); |
3560 |
3697 |
3561 // Gear^.Tex:= RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(round(Gear^.Health / 20)) + '%', cWhiteColor, fntSmall) |
3698 // Gear^.Tex:= RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(round(Gear^.Health / 20)) + '%', cWhiteColor, fntSmall) |
3562 |
3699 |
3563 //AddCaption(trmsg[sidFuel]+': '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate); |
3700 //AddCaption(trmsg[sidFuel]+': '+inttostr(round(Gear^.Health/20))+'%', cWhiteColor, capgrpAmmostate); |
3564 end |
3701 end |
3565 end; |
3702 end; |
3566 |
3703 |
3567 procedure doStepJetpack(Gear: PGear); |
3704 procedure doStepJetpack(Gear: PGear); |
3568 var |
3705 var |
3569 HHGear: PGear; |
3706 HHGear: PGear; |
3616 fuel := 50; |
3754 fuel := 50; |
3617 |
3755 |
3618 if Gear^.Pos > 0 then |
3756 if Gear^.Pos > 0 then |
3619 dec(Gear^.Pos, 1) |
3757 dec(Gear^.Pos, 1) |
3620 else if (HHGear^.Message and (gmLeft or gmRight or gmUp)) <> 0 then |
3758 else if (HHGear^.Message and (gmLeft or gmRight or gmUp)) <> 0 then |
3621 Gear^.Pos := 500; |
3759 Gear^.Pos := 500; |
3622 |
3760 |
3623 if HHGear^.dX.isNegative then |
3761 if HHGear^.dX.isNegative then |
3624 Gear^.Tag := -1 |
3762 Gear^.Tag := -1 |
3625 else |
3763 else |
3626 Gear^.Tag := 1; |
3764 Gear^.Tag := 1; |
3627 |
3765 |
3628 if (HHGear^.Message and gmUp) <> 0 then |
3766 if (HHGear^.Message and gmUp) <> 0 then |
3629 begin |
3767 begin |
3630 if (not HHGear^.dY.isNegative) or (HHGear^.Y > -_256) then |
3768 if (not HHGear^.dY.isNegative) |
|
3769 or (HHGear^.Y > -_256) then |
3631 HHGear^.dY := HHGear^.dY - move; |
3770 HHGear^.dY := HHGear^.dY - move; |
|
3771 |
3632 dec(Gear^.Health, fuel); |
3772 dec(Gear^.Health, fuel); |
3633 Gear^.MsgParam := Gear^.MsgParam or gmUp; |
3773 Gear^.MsgParam := Gear^.MsgParam or gmUp; |
3634 end; |
3774 end; |
|
3775 |
3635 if (HHGear^.Message and gmLeft) <> 0 then move.isNegative := true; |
3776 if (HHGear^.Message and gmLeft) <> 0 then move.isNegative := true; |
3636 if (HHGear^.Message and (gmLeft or gmRight)) <> 0 then |
3777 if (HHGear^.Message and (gmLeft or gmRight)) <> 0 then |
3637 begin |
3778 begin |
3638 HHGear^.dX := HHGear^.dX + (move * _0_1); |
3779 HHGear^.dX := HHGear^.dX + (move * _0_1); |
3639 dec(Gear^.Health, fuel div 5); |
3780 dec(Gear^.Health, fuel div 5); |
3640 Gear^.MsgParam := Gear^.MsgParam or (HHGear^.Message and (gmLeft or gmRight)); |
3781 Gear^.MsgParam := Gear^.MsgParam or (HHGear^.Message and (gmLeft or gmRight)); |
3641 end; |
3782 end; |
3642 |
3783 |
3643 if Gear^.Health < 0 then Gear^.Health := 0; |
3784 if Gear^.Health < 0 then |
|
3785 Gear^.Health := 0; |
|
3786 |
3644 if ((GameTicks and $FF) = 0) and (Gear^.Health < 500) then |
3787 if ((GameTicks and $FF) = 0) and (Gear^.Health < 500) then |
3645 for i:= ((500-Gear^.Health) div 250) downto 0 do |
3788 for i:= ((500-Gear^.Health) div 250) downto 0 do |
3646 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFeather); |
3789 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFeather); |
3647 |
3790 |
3648 if (HHGear^.Message and gmAttack <> 0) then |
3791 if (HHGear^.Message and gmAttack <> 0) then |
3656 end; |
3799 end; |
3657 end; |
3800 end; |
3658 |
3801 |
3659 if HHGear^.Message and (gmUp or gmPrecise or gmLeft or gmRight) <> 0 then |
3802 if HHGear^.Message and (gmUp or gmPrecise or gmLeft or gmRight) <> 0 then |
3660 Gear^.State := Gear^.State and (not gsttmpFlag); |
3803 Gear^.State := Gear^.State and (not gsttmpFlag); |
|
3804 |
3661 HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight)); |
3805 HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight)); |
3662 HHGear^.State := HHGear^.State or gstMoving; |
3806 HHGear^.State := HHGear^.State or gstMoving; |
3663 |
3807 |
3664 Gear^.X := HHGear^.X; |
3808 Gear^.X := HHGear^.X; |
3665 Gear^.Y := HHGear^.Y - int2hwFloat(32); |
3809 Gear^.Y := HHGear^.Y - int2hwFloat(32); |
3666 // For some reason I need to reapply followgear here, something else grabs it otherwise. |
3810 // For some reason I need to reapply followgear here, something else grabs it otherwise. |
3667 // this is probably not needed anymore |
3811 // this is probably not needed anymore |
3668 if not CurrentTeam^.ExtDriven then FollowGear := HHGear; |
3812 if not CurrentTeam^.ExtDriven then FollowGear := HHGear; |
3669 |
3813 |
3670 if ((Gear^.State and gsttmpFlag) = 0) or (HHGear^.dY < _0) then doStepHedgehogMoving(HHGear); |
3814 if ((Gear^.State and gsttmpFlag) = 0) |
|
3815 or (HHGear^.dY < _0) then |
|
3816 doStepHedgehogMoving(HHGear); |
3671 |
3817 |
3672 if (Gear^.Health = 0) |
3818 if (Gear^.Health = 0) |
3673 or (HHGear^.Damage <> 0) |
3819 or (HHGear^.Damage <> 0) |
3674 or CheckGearDrowning(HHGear) |
3820 or CheckGearDrowning(HHGear) |
3675 or (TurnTimeLeft = 0) |
3821 or (TurnTimeLeft = 0) |
3676 // allow brief ground touches - to be fair on this, might need another counter |
3822 // allow brief ground touches - to be fair on this, might need another counter |
3677 or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0)) |
3823 or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0)) |
3678 or ((Gear^.Message and gmAttack) <> 0) then |
3824 or ((Gear^.Message and gmAttack) <> 0) then |
3679 begin |
3825 begin |
3680 with HHGear^ do |
3826 with HHGear^ do |
3681 begin |
3827 begin |
3682 Message := 0; |
3828 Message := 0; |
3683 Active := true; |
3829 Active := true; |
3684 State := State or gstMoving |
3830 State := State or gstMoving |
3685 end; |
3831 end; |
3686 Gear^.State := Gear^.State or gstAnimation or gstTmpFlag; |
3832 Gear^.State := Gear^.State or gstAnimation or gstTmpFlag; |
3687 if HHGear^.dY < _0 then |
3833 if HHGear^.dY < _0 then |
3688 begin |
3834 begin |
3689 Gear^.dX := HHGear^.dX; |
3835 Gear^.dX := HHGear^.dX; |
3690 Gear^.dY := HHGear^.dY; |
3836 Gear^.dY := HHGear^.dY; |
3691 end; |
3837 end; |
3692 Gear^.Timer := 0; |
3838 Gear^.Timer := 0; |
3693 Gear^.doStep := @doStepBirdyDisappear; |
3839 Gear^.doStep := @doStepBirdyDisappear; |
3694 CurAmmoGear := nil; |
3840 CurAmmoGear := nil; |
3695 isCursorVisible := false; |
3841 isCursorVisible := false; |
3696 AfterAttack; |
3842 AfterAttack; |
3697 end |
3843 end |
3698 end; |
3844 end; |
3699 |
3845 |
3700 procedure doStepBirdyDescend(Gear: PGear); |
3846 procedure doStepBirdyDescend(Gear: PGear); |
3701 var |
3847 var |
3702 HHGear: PGear; |
3848 HHGear: PGear; |
3703 begin |
3849 begin |
3704 if Gear^.Timer > 0 then |
3850 if Gear^.Timer > 0 then |
3705 dec(Gear^.Timer, 1) |
3851 dec(Gear^.Timer, 1) |
3706 else if Gear^.Hedgehog^.Gear = nil then |
3852 else if Gear^.Hedgehog^.Gear = nil then |
3707 begin |
3853 begin |
3708 DeleteGear(Gear); |
3854 DeleteGear(Gear); |
3709 AfterAttack; |
3855 AfterAttack; |
3710 exit |
3856 exit |
3711 end; |
3857 end; |
3712 HHGear := Gear^.Hedgehog^.Gear; |
3858 HHGear := Gear^.Hedgehog^.Gear; |
3713 HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight)); |
3859 HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight)); |
3714 if abs(hwRound(HHGear^.Y - Gear^.Y)) > 32 then |
3860 if abs(hwRound(HHGear^.Y - Gear^.Y)) > 32 then |
3715 begin |
3861 begin |
3716 if Gear^.Timer = 0 then |
3862 if Gear^.Timer = 0 then |
3717 Gear^.Y := Gear^.Y + _0_1 |
3863 Gear^.Y := Gear^.Y + _0_1 |
3718 end |
3864 end |
3719 else if Gear^.Timer = 0 then |
3865 else if Gear^.Timer = 0 then |
3720 begin |
3866 begin |
3721 Gear^.doStep := @doStepBirdyFly; |
3867 Gear^.doStep := @doStepBirdyFly; |
3722 HHGear^.dY := -_0_2 |
3868 HHGear^.dY := -_0_2 |
3723 end |
3869 end |
3724 end; |
3870 end; |
3725 |
3871 |
3726 procedure doStepBirdyAppear(Gear: PGear); |
3872 procedure doStepBirdyAppear(Gear: PGear); |
3727 begin |
3873 begin |
3728 Gear^.Pos := 0; |
3874 Gear^.Pos := 0; |
3729 if Gear^.Timer < 2000 then |
3875 if Gear^.Timer < 2000 then |
3730 inc(Gear^.Timer, 1) |
3876 inc(Gear^.Timer, 1) |
3731 else |
3877 else |
3732 begin |
3878 begin |
3733 Gear^.Timer := 500; |
3879 Gear^.Timer := 500; |
3734 Gear^.dX := _0; |
3880 Gear^.dX := _0; |
3735 Gear^.dY := _0; |
3881 Gear^.dY := _0; |
3736 Gear^.State := Gear^.State and (not gstAnimation); |
3882 Gear^.State := Gear^.State and (not gstAnimation); |
3737 Gear^.doStep := @doStepBirdyDescend; |
3883 Gear^.doStep := @doStepBirdyDescend; |
3738 end |
3884 end |
3739 end; |
3885 end; |
3740 |
3886 |
3741 procedure doStepBirdy(Gear: PGear); |
3887 procedure doStepBirdy(Gear: PGear); |
3742 var |
3888 var |
3743 HHGear: PGear; |
3889 HHGear: PGear; |
3744 begin |
3890 begin |
3745 gear^.State := gear^.State or gstAnimation and (not gstTmpFlag); |
3891 gear^.State := gear^.State or gstAnimation and (not gstTmpFlag); |
3746 Gear^.doStep := @doStepBirdyAppear; |
3892 Gear^.doStep := @doStepBirdyAppear; |
|
3893 |
3747 if CurrentHedgehog = nil then |
3894 if CurrentHedgehog = nil then |
3748 begin |
3895 begin |
3749 DeleteGear(Gear); |
3896 DeleteGear(Gear); |
3750 exit |
3897 exit |
3751 end; |
3898 end; |
3752 |
3899 |
3753 HHGear := CurrentHedgehog^.Gear; |
3900 HHGear := CurrentHedgehog^.Gear; |
3754 |
3901 |
3755 if HHGear^.dX.isNegative then |
3902 if HHGear^.dX.isNegative then |
3756 Gear^.Tag := -1 |
3903 Gear^.Tag := -1 |
3777 doStepFallingGear(Gear); |
3924 doStepFallingGear(Gear); |
3778 // CheckGearDrowning(Gear); // already checked for in doStepFallingGear |
3925 // CheckGearDrowning(Gear); // already checked for in doStepFallingGear |
3779 CalcRotationDirAngle(Gear); |
3926 CalcRotationDirAngle(Gear); |
3780 |
3927 |
3781 if (Gear^.State and gstCollision) <> 0 then |
3928 if (Gear^.State and gstCollision) <> 0 then |
3782 begin |
3929 begin |
3783 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, Gear^.Hedgehog, EXPLPoisoned, $C0E0FFE0); |
3930 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, Gear^.Hedgehog, EXPLPoisoned, $C0E0FFE0); |
3784 PlaySound(sndEggBreak); |
3931 PlaySound(sndEggBreak); |
3785 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEgg); |
3932 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEgg); |
3786 vg := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEgg); |
3933 vg := AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtEgg); |
3787 if vg <> nil then vg^.Frame := 2; |
3934 if vg <> nil then |
|
3935 vg^.Frame := 2; |
3788 |
3936 |
3789 for i:= 10 downto 0 do |
3937 for i:= 10 downto 0 do |
3790 begin |
3938 begin |
3791 vg := AddVisualGear(hwRound(Gear^.X) - 3 + Random(6), hwRound(Gear^.Y) - 3 + Random(6), |
3939 vg := AddVisualGear(hwRound(Gear^.X) - 3 + Random(6), hwRound(Gear^.Y) - 3 + Random(6), |
3792 vgtDust); |
3940 vgtDust); |
3793 if vg <> nil then vg^.dX := vg^.dX + (Gear^.dX.QWordValue / 21474836480); |
3941 if vg <> nil then |
3794 end; |
3942 vg^.dX := vg^.dX + (Gear^.dX.QWordValue / 21474836480); |
|
3943 end; |
3795 |
3944 |
3796 DeleteGear(Gear); |
3945 DeleteGear(Gear); |
3797 exit |
3946 exit |
3798 end; |
3947 end; |
3799 end; |
3948 end; |
3800 |
3949 |
3801 //////////////////////////////////////////////////////////////////////////////// |
3950 //////////////////////////////////////////////////////////////////////////////// |
3802 procedure doPortalColorSwitch(); |
3951 procedure doPortalColorSwitch(); |
3803 var CurWeapon: PAmmo; |
3952 var CurWeapon: PAmmo; |
3804 begin |
3953 begin |
3805 if (CurrentHedgehog <> nil) |
3954 if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and ((CurrentHedgehog^.Gear^.Message and gmSwitch) <> 0) then |
3806 and (CurrentHedgehog^.Gear <> nil) |
3955 with CurrentHedgehog^ do |
3807 and ((CurrentHedgehog^.Gear^.Message and gmSwitch) <> 0) then |
3956 if (CurAmmoType = amPortalGun) then |
3808 with CurrentHedgehog^ do |
3957 begin |
3809 if (CurAmmoType = amPortalGun) then |
3958 CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSwitch); |
3810 begin |
|
3811 CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSwitch); |
|
3812 |
3959 |
3813 CurWeapon:= GetAmmoEntry(CurrentHedgehog^); |
3960 CurWeapon:= GetAmmoEntry(CurrentHedgehog^); |
3814 if CurWeapon^.Pos <> 0 then |
3961 if CurWeapon^.Pos <> 0 then |
3815 CurWeapon^.Pos := 0 |
3962 CurWeapon^.Pos := 0 |
3816 else |
3963 |
|
3964 else |
3817 CurWeapon^.Pos := 1; |
3965 CurWeapon^.Pos := 1; |
3818 end; |
3966 end; |
3819 end; |
3967 end; |
3820 |
3968 |
3821 procedure doStepPortal(Gear: PGear); |
3969 procedure doStepPortal(Gear: PGear); |
3822 var |
3970 var |
3823 iterator, conPortal: PGear; |
3971 iterator, conPortal: PGear; |
3884 // this is the max range we accept incoming gears in |
4032 // this is the max range we accept incoming gears in |
3885 r := Int2hwFloat(iterator^.Radius+Gear^.Radius); |
4033 r := Int2hwFloat(iterator^.Radius+Gear^.Radius); |
3886 |
4034 |
3887 // too far away? |
4035 // too far away? |
3888 if (iterator^.X < Gear^.X - r) |
4036 if (iterator^.X < Gear^.X - r) |
3889 or (iterator^.X > Gear^.X + r) |
4037 or (iterator^.X > Gear^.X + r) |
3890 or (iterator^.Y < Gear^.Y - r) |
4038 or (iterator^.Y < Gear^.Y - r) |
3891 or (iterator^.Y > Gear^.Y + r) then |
4039 or (iterator^.Y > Gear^.Y + r) then |
3892 continue; |
4040 continue; |
3893 |
4041 |
3894 hasdxy := (((iterator^.dX.QWordValue <> 0) or (iterator^.dY.QWordValue <> 0)) |
4042 hasdxy := (((iterator^.dX.QWordValue <> 0) or (iterator^.dY.QWordValue <> 0)) or ((iterator^.State or gstMoving) = 0)); |
3895 or ((iterator^.State or gstMoving) = 0)); |
|
3896 |
4043 |
3897 // in case the object is not moving, let's asume it's falling towards the portal |
4044 // in case the object is not moving, let's asume it's falling towards the portal |
3898 if not hasdxy then |
4045 if not hasdxy then |
3899 begin |
4046 begin |
3900 if Gear^.Y < iterator^.Y then |
4047 if Gear^.Y < iterator^.Y then |
3901 continue; |
4048 continue; |
3902 ox:= Gear^.X - iterator^.X; |
4049 ox:= Gear^.X - iterator^.X; |
3903 oy:= Gear^.Y - iterator^.Y; |
4050 oy:= Gear^.Y - iterator^.Y; |
3904 end |
4051 end |
3905 else |
4052 else |
3906 begin |
4053 begin |
3907 ox:= iterator^.dX; |
4054 ox:= iterator^.dX; |
3908 oy:= iterator^.dY; |
4055 oy:= iterator^.dY; |
3909 end; |
4056 end; |
3910 |
4057 |
3911 // cake will need extra treatment... it's so delicious and moist! |
4058 // cake will need extra treatment... it's so delicious and moist! |
3912 iscake:= (iterator^.Kind = gtCake); |
4059 iscake:= (iterator^.Kind = gtCake); |
3913 |
4060 |
3914 // won't port stuff that does not move towards the front/portal entrance |
4061 // won't port stuff that does not move towards the front/portal entrance |
3915 if iscake then |
4062 if iscake then |
3916 begin |
4063 begin |
3917 if not (((iterator^.X - Gear^.X)*ox + (iterator^.Y - Gear^.Y)*oy).isNegative) then |
4064 if not (((iterator^.X - Gear^.X)*ox + (iterator^.Y - Gear^.Y)*oy).isNegative) then |
3918 continue; |
4065 continue; |
3919 end |
4066 end |
3920 else |
4067 else |
3921 if not ((Gear^.dX*ox + Gear^.dY*oy).isNegative) then |
4068 if not ((Gear^.dX*ox + Gear^.dY*oy).isNegative) then |
3922 continue; |
4069 continue; |
3923 |
4070 |
3924 isbullet:= (iterator^.Kind in [gtShotgunShot, gtDEagleShot, gtSniperRifleShot, gtSineGunShot]); |
4071 isbullet:= (iterator^.Kind in [gtShotgunShot, gtDEagleShot, gtSniperRifleShot, gtSineGunShot]); |
3925 |
4072 |
3926 r:= int2hwFloat(iterator^.Radius); |
4073 r:= int2hwFloat(iterator^.Radius); |
3927 |
4074 |
3928 if not (isbullet or iscake) then |
4075 if not (isbullet or iscake) then |
3929 begin |
4076 begin |
3930 // wow! good candidate there, let's see if the distance and direction is okay! |
4077 // wow! good candidate there, let's see if the distance and direction is okay! |
3931 if hasdxy then |
4078 if hasdxy then |
3932 begin |
4079 begin |
3933 s := r / Distance(iterator^.dX, iterator^.dY); |
4080 s := r / Distance(iterator^.dX, iterator^.dY); |
3934 ox:= iterator^.X + s * iterator^.dX; |
4081 ox:= iterator^.X + s * iterator^.dX; |
3935 oy:= iterator^.Y + s * iterator^.dY; |
4082 oy:= iterator^.Y + s * iterator^.dY; |
3936 end |
4083 end |
3937 else |
4084 else |
3938 begin |
4085 begin |
3939 ox:= iterator^.X; |
4086 ox:= iterator^.X; |
3940 oy:= iterator^.Y + r; |
4087 oy:= iterator^.Y + r; |
3941 end; |
4088 end; |
3942 |
4089 |
3943 if (hwRound(Distance(Gear^.X-ox,Gear^.Y-oy)) > Gear^.Radius + 1 ) then |
4090 if (hwRound(Distance(Gear^.X-ox,Gear^.Y-oy)) > Gear^.Radius + 1 ) then |
3944 continue; |
4091 continue; |
3945 end; |
4092 end; |
3946 |
4093 |
3947 // draw bullet trail |
4094 // draw bullet trail |
3948 if isbullet then |
4095 if isbullet then |
3949 spawnBulletTrail(iterator); |
4096 spawnBulletTrail(iterator); |
3950 |
4097 |
3987 |
4134 |
3988 if isBullet and (hwRound(hwAbs(noffs)) >= Gear^.Radius) then |
4135 if isBullet and (hwRound(hwAbs(noffs)) >= Gear^.Radius) then |
3989 continue; |
4136 continue; |
3990 |
4137 |
3991 // avoid gravity related loops of not really moving gear |
4138 // avoid gravity related loops of not really moving gear |
3992 if not (iscake or isbullet) and (Gear^.dY.isNegative) and (conPortal^.dY.isNegative) |
4139 if not (iscake or isbullet) |
3993 and ((iterator^.dX.QWordValue + iterator^.dY.QWordValue) < _0_08.QWordValue) |
4140 and (Gear^.dY.isNegative) |
3994 and (iterator^.PortalCounter > 0) then |
4141 and (conPortal^.dY.isNegative) |
3995 continue; |
4142 and ((iterator^.dX.QWordValue + iterator^.dY.QWordValue) < _0_08.QWordValue) |
|
4143 and (iterator^.PortalCounter > 0) then |
|
4144 continue; |
3996 |
4145 |
3997 // calc gear speed along to the vector and the normal vector of the portal |
4146 // calc gear speed along to the vector and the normal vector of the portal |
3998 if hasdxy then |
4147 if hasdxy then |
3999 begin |
4148 begin |
4000 pspeed:= (Gear^.dX * iterator^.dX + Gear^.dY * iterator^.dY); |
4149 pspeed:= (Gear^.dX * iterator^.dX + Gear^.dY * iterator^.dY); |
4001 nspeed:= (nx * iterator^.dX + ny * iterator^.dY); |
4150 nspeed:= (nx * iterator^.dX + ny * iterator^.dY); |
4002 end |
4151 end |
4003 else |
4152 else |
4004 begin |
4153 begin |
4005 pspeed:= hwAbs(cGravity * oy); |
4154 pspeed:= hwAbs(cGravity * oy); |
4006 nspeed:= _0; |
4155 nspeed:= _0; |
4007 end; |
4156 end; |
4008 |
4157 |
4009 // creating normal vector of connected (exit) portal |
4158 // creating normal vector of connected (exit) portal |
4010 nx := conPortal^.dY; |
4159 nx := conPortal^.dY; |
4011 ny := conPortal^.dX; |
4160 ny := conPortal^.dX; |
4012 if conPortal^.Elasticity.isNegative then |
4161 if conPortal^.Elasticity.isNegative then |
4023 iterator^.dY := -pspeed * conPortal^.dY + nspeed * ny; |
4172 iterator^.dY := -pspeed * conPortal^.dY + nspeed * ny; |
4024 |
4173 |
4025 // make the gear's exit position close to the portal while |
4174 // make the gear's exit position close to the portal while |
4026 // still respecting the movement direction |
4175 // still respecting the movement direction |
4027 |
4176 |
4028 // determine the distance (in exit vector direction) |
4177 // determine the distance (in exit vector direction) |
4029 // that we want the gear at |
4178 // that we want the gear at |
4030 if iscake then |
4179 if iscake then |
4031 ox:= (r - _0_7) |
4180 ox:= (r - _0_7) |
4032 else |
4181 else |
4033 ox:= (r * _1_5); |
4182 ox:= (r * _1_5); |
4034 s:= ox / poffs; |
4183 s:= ox / poffs; |
4035 poffs:= ox; |
4184 poffs:= ox; |
4036 if (nspeed.QWordValue <> 0) and (pspeed > _0) then |
4185 if (nspeed.QWordValue <> 0) |
4037 noffs:= noffs * s * (nspeed / pspeed); |
4186 and (pspeed > _0) then |
|
4187 noffs:= noffs * s * (nspeed / pspeed); |
4038 |
4188 |
4039 // move stuff with high normal offset closer to the portal's center |
4189 // move stuff with high normal offset closer to the portal's center |
4040 if not isbullet then |
4190 if not isbullet then |
4041 begin |
4191 begin |
4042 s := hwAbs(noffs) + r - int2hwFloat(Gear^.Radius); |
4192 s := hwAbs(noffs) + r - int2hwFloat(Gear^.Radius); |
4043 if s > _0 then |
4193 if s > _0 then |
4044 noffs:= noffs - SignAs(s,noffs) |
4194 noffs:= noffs - SignAs(s,noffs) |
4045 end; |
4195 end; |
4046 |
4196 |
4047 iterator^.X := conPortal^.X + poffs * conPortal^.dX + noffs * nx; |
4197 iterator^.X := conPortal^.X + poffs * conPortal^.dX + noffs * nx; |
4048 iterator^.Y := conPortal^.Y + poffs * conPortal^.dY + noffs * ny; |
4198 iterator^.Y := conPortal^.Y + poffs * conPortal^.dY + noffs * ny; |
4049 |
4199 |
4050 if not hasdxy and (not (conPortal^.dY.isNegative)) then |
4200 if not hasdxy and (not (conPortal^.dY.isNegative)) then |
4051 begin |
4201 begin |
4052 iterator^.dY:= iterator^.dY + hwAbs(cGravity * (iterator^.Y - conPortal^.Y)) |
4202 iterator^.dY:= iterator^.dY + hwAbs(cGravity * (iterator^.Y - conPortal^.Y)) |
4053 end; |
4203 end; |
4054 |
4204 |
4055 // see if the space on the exit side actually is enough |
4205 // see if the space on the exit side actually is enough |
4056 |
4206 |
4057 if not (isBullet or isCake) then |
4207 if not (isBullet or isCake) then |
4058 begin |
4208 begin |
4059 // TestCollisionXwithXYShift requires a hwFloat for xShift |
4209 // TestCollisionXwithXYShift requires a hwFloat for xShift |
4060 ox.QWordValue := _1.QWordValue; |
4210 ox.QWordValue := _1.QWordValue; |
4061 ox.isNegative := not iterator^.dX.isNegative; |
4211 ox.isNegative := not iterator^.dX.isNegative; |
4062 |
4212 |
4063 sx := hwSign(iterator^.dX); |
4213 sx := hwSign(iterator^.dX); |
4069 // check front |
4219 // check front |
4070 isCollision := TestCollisionY(iterator, sy) |
4220 isCollision := TestCollisionY(iterator, sy) |
4071 or TestCollisionX(iterator, sx); |
4221 or TestCollisionX(iterator, sx); |
4072 |
4222 |
4073 if not isCollision then |
4223 if not isCollision then |
4074 begin |
4224 begin |
4075 // check center area (with half the radius so that the |
4225 // check center area (with half the radius so that the |
4076 // the square check won't check more pixels than we want to) |
4226 // the square check won't check more pixels than we want to) |
4077 iterator^.Radius := 1 + resetr div 2; |
4227 iterator^.Radius := 1 + resetr div 2; |
4078 rh := resetr div 4; |
4228 rh := resetr div 4; |
4079 isCollision := TestCollisionYwithXYShift(iterator, 0, -sy * rh, sy, false) |
4229 isCollision := TestCollisionYwithXYShift(iterator, 0, -sy * rh, sy, false) |
4080 or TestCollisionXwithXYShift(iterator, ox * rh, 0, sx, false); |
4230 or TestCollisionXwithXYShift(iterator, ox * rh, 0, sx, false); |
4081 end; |
4231 end; |
4082 |
4232 |
4083 iterator^.Radius := resetr; |
4233 iterator^.Radius := resetr; |
4084 |
4234 |
4085 if isCollision then |
4235 if isCollision then |
4086 begin |
4236 begin |
4087 // collision! oh crap! go back! |
4237 // collision! oh crap! go back! |
4088 iterator^.X := resetx; |
4238 iterator^.X := resetx; |
4089 iterator^.Y := resety; |
4239 iterator^.Y := resety; |
4090 iterator^.dX := resetdx; |
4240 iterator^.dX := resetdx; |
4091 iterator^.dY := resetdy; |
4241 iterator^.dY := resetdy; |
4092 continue; |
4242 continue; |
4093 end; |
4243 end; |
4094 end; |
4244 end; |
4095 |
4245 |
4096 // |
4246 // |
4097 // You're now officially portaled! |
4247 // You're now officially portaled! |
4098 // |
4248 // |
4099 |
4249 |
4100 // Until loops are reliably broken |
4250 // Until loops are reliably broken |
4101 if iscake then iterator^.PortalCounter:= 33 |
4251 if iscake then |
|
4252 iterator^.PortalCounter:= 33 |
4102 else |
4253 else |
4103 begin |
4254 begin |
4104 inc(iterator^.PortalCounter); |
4255 inc(iterator^.PortalCounter); |
4105 iterator^.State:= iterator^.State and (not gstHHHJump) |
4256 iterator^.State:= iterator^.State and (not gstHHHJump) |
4106 end; |
4257 end; |
4107 |
4258 |
4108 if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) |
4259 if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) |
4109 and (iterator = CurrentHedgehog^.Gear) and (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = |
4260 and (iterator = CurrentHedgehog^.Gear) |
4110 gtRope) then CurAmmoGear^.PortalCounter:= 1; |
4261 and (CurAmmoGear <> nil) |
4111 |
4262 and (CurAmmoGear^.Kind =gtRope) then |
4112 if not isbullet and (iterator^.Kind <> gtFlake) then |
4263 CurAmmoGear^.PortalCounter:= 1; |
|
4264 |
|
4265 if not isbullet |
|
4266 and (iterator^.Kind <> gtFlake) then |
4113 FollowGear := iterator; |
4267 FollowGear := iterator; |
4114 |
4268 |
4115 // store X/Y values of exit for net bullet trail |
4269 // store X/Y values of exit for net bullet trail |
4116 if isbullet then |
4270 if isbullet then |
4117 begin |
4271 begin |
4118 iterator^.Elasticity:= iterator^.X; |
4272 iterator^.Elasticity:= iterator^.X; |
4119 iterator^.Friction := iterator^.Y; |
4273 iterator^.Friction := iterator^.Y; |
4120 end; |
4274 end; |
4121 |
4275 |
4122 // This jiggles gears, to ensure a portal connection just placed under a gear takes effect. |
4276 // This jiggles gears, to ensure a portal connection just placed under a gear takes effect. |
4123 iterator:= GearsList; |
4277 iterator:= GearsList; |
4124 while iterator <> nil do |
4278 while iterator <> nil do |
4125 begin |
4279 begin |
4126 if (iterator^.Kind <> gtPortal) and |
4280 if (iterator^.Kind <> gtPortal) and ((iterator^.Hedgehog <> CurrentHedgehog) |
4127 ((iterator^.Hedgehog <> CurrentHedgehog) or ((iterator^.Message and gmAllStoppable) = 0)) then |
4281 or ((iterator^.Message and gmAllStoppable) = 0)) then |
4128 begin |
4282 begin |
4129 iterator^.Active:= true; |
4283 iterator^.Active:= true; |
4130 if iterator^.dY.QWordValue = _0.QWordValue then iterator^.dY.isNegative:= false; |
4284 if iterator^.dY.QWordValue = _0.QWordValue then |
4131 iterator^.State:= iterator^.State or gstMoving; |
4285 iterator^.dY.isNegative:= false; |
4132 DeleteCI(iterator); |
4286 iterator^.State:= iterator^.State or gstMoving; |
|
4287 DeleteCI(iterator); |
4133 //inc(iterator^.dY.QWordValue,10); |
4288 //inc(iterator^.dY.QWordValue,10); |
4134 end; |
4289 end; |
4135 iterator:= iterator^.NextGear |
4290 iterator:= iterator^.NextGear |
4136 end; |
4291 end; |
4137 |
4292 |
4138 if Gear^.Health > 1 then dec(Gear^.Health); |
4293 if Gear^.Health > 1 then |
|
4294 dec(Gear^.Health); |
4139 end; |
4295 end; |
4140 end; |
4296 end; |
4141 |
4297 |
4142 |
4298 |
4143 |
4299 |
4177 tx := 0; |
4334 tx := 0; |
4178 ty := 0; |
4335 ty := 0; |
4179 // avoid compiler hints |
4336 // avoid compiler hints |
4180 |
4337 |
4181 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > 255) then |
4338 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > 255) then |
4182 begin |
4339 begin |
4183 Gear^.State := Gear^.State or gstCollision; |
4340 Gear^.State := Gear^.State or gstCollision; |
4184 Gear^.State := Gear^.State and (not gstMoving); |
4341 Gear^.State := Gear^.State and (not gstMoving); |
|
4342 |
4185 if not CalcSlopeTangent(Gear, x, y, tx, ty, 255) |
4343 if not CalcSlopeTangent(Gear, x, y, tx, ty, 255) |
4186 or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain |
4344 or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain |
4187 begin |
4345 begin |
4188 loadNewPortalBall(Gear, true); |
4346 loadNewPortalBall(Gear, true); |
4189 EXIT; |
4347 EXIT; |
4190 end; |
4348 end; |
4191 |
4349 |
4192 // making a normalized normal vector |
4350 // making a normalized normal vector |
4193 s := _1/DistanceI(tx,ty); |
4351 s := _1/DistanceI(tx,ty); |
4194 Gear^.dX := s * ty; |
4352 Gear^.dX := s * ty; |
4195 Gear^.dY := -s * tx; |
4353 Gear^.dY := -s * tx; |
4196 |
4354 |
4197 Gear^.DirAngle := DxDy2Angle(-Gear^.dY,Gear^.dX); |
4355 Gear^.DirAngle := DxDy2Angle(-Gear^.dY,Gear^.dX); |
4198 if not Gear^.dX.isNegative then Gear^.DirAngle := 180-Gear^.DirAngle; |
4356 if not Gear^.dX.isNegative then |
|
4357 Gear^.DirAngle := 180-Gear^.DirAngle; |
4199 |
4358 |
4200 if ((Gear^.IntersectGear = nil) |
4359 if ((Gear^.IntersectGear = nil) |
4201 or (hwRound(Distance(Gear^.X - Gear^.IntersectGear^.X,Gear^.Y-Gear^.IntersectGear^.Y)) >= |
4360 or (hwRound(Distance(Gear^.X - Gear^.IntersectGear^.X,Gear^.Y-Gear^.IntersectGear^.Y)) >=Gear^.Radius*2)) then |
4202 Gear^.Radius*2)) |
4361 begin |
4203 then |
|
4204 begin |
|
4205 loadNewPortalBall(Gear, false); |
4362 loadNewPortalBall(Gear, false); |
4206 inc(Gear^.Tag); |
4363 inc(Gear^.Tag); |
4207 Gear^.doStep := @doStepPortal; |
4364 Gear^.doStep := @doStepPortal; |
4208 end |
4365 end |
4209 else |
4366 else |
4210 loadNewPortalBall(Gear, true); |
4367 loadNewPortalBall(Gear, true); |
4211 end |
4368 end |
4212 else if (y > cWaterLine) or (y < -LAND_WIDTH) |
4369 |
4213 or (x > 2*LAND_WIDTH) or (x < -LAND_WIDTH) then |
4370 else if (y > cWaterLine) |
4214 loadNewPortalBall(Gear, true); |
4371 or (y < -LAND_WIDTH) |
|
4372 or (x > 2*LAND_WIDTH) |
|
4373 or (x < -LAND_WIDTH) then |
|
4374 loadNewPortalBall(Gear, true); |
4215 end; |
4375 end; |
4216 |
4376 |
4217 procedure doStepMovingPortal(Gear: PGear); |
4377 procedure doStepMovingPortal(Gear: PGear); |
4218 begin |
4378 begin |
4219 doPortalColorSwitch(); |
4379 doPortalColorSwitch(); |
4220 doStepPerPixel(Gear, @doStepMovingPortal_real, true); |
4380 doStepPerPixel(Gear, @doStepMovingPortal_real, true); |
4221 if (Gear^.Timer < 1) |
4381 if (Gear^.Timer < 1) |
4222 or (Gear^.Hedgehog^.Team <> CurrentHedgehog^.Team) then |
4382 or (Gear^.Hedgehog^.Team <> CurrentHedgehog^.Team) then |
4223 deleteGear(Gear); |
4383 deleteGear(Gear); |
4224 end; |
4384 end; |
4225 |
4385 |
4226 procedure doStepPortalShot(newPortal: PGear); |
4386 procedure doStepPortalShot(newPortal: PGear); |
4227 var |
4387 var |
4228 iterator: PGear; |
4388 iterator: PGear; |
4288 r0, r1: LongInt; |
4448 r0, r1: LongInt; |
4289 odY: hwFloat; |
4449 odY: hwFloat; |
4290 begin |
4450 begin |
4291 AllInactive := false; |
4451 AllInactive := false; |
4292 if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and |
4452 if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and |
4293 ((CurrentHedgehog^.Gear^.Message and gmSlot) <> 0) then |
4453 ((CurrentHedgehog^.Gear^.Message and gmSlot) <> 0) then |
4294 begin |
4454 begin |
4295 case CurrentHedgehog^.Gear^.MsgParam of |
4455 case CurrentHedgehog^.Gear^.MsgParam of |
4296 0: PlaySound(sndPiano0); |
4456 0: PlaySound(sndPiano0); |
4297 1: PlaySound(sndPiano1); |
4457 1: PlaySound(sndPiano1); |
4298 2: PlaySound(sndPiano2); |
4458 2: PlaySound(sndPiano2); |
4299 3: PlaySound(sndPiano3); |
4459 3: PlaySound(sndPiano3); |
4300 4: PlaySound(sndPiano4); |
4460 4: PlaySound(sndPiano4); |
4301 5: PlaySound(sndPiano5); |
4461 5: PlaySound(sndPiano5); |
4302 6: PlaySound(sndPiano6); |
4462 6: PlaySound(sndPiano6); |
4303 7: PlaySound(sndPiano7); |
4463 7: PlaySound(sndPiano7); |
4304 else PlaySound(sndPiano8); |
4464 else PlaySound(sndPiano8); |
4305 end; |
4465 end; |
4306 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtNote); |
4466 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtNote); |
4307 CurrentHedgehog^.Gear^.MsgParam := 0; |
4467 CurrentHedgehog^.Gear^.MsgParam := 0; |
4308 CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSlot); |
4468 CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSlot); |
4309 end; |
4469 end; |
4310 |
4470 |
4415 x := hwRound(Gear^.X); |
4578 x := hwRound(Gear^.X); |
4416 y := hwRound(Gear^.Y); |
4579 y := hwRound(Gear^.Y); |
4417 |
4580 |
4418 // if borders are on, stop outside land array |
4581 // if borders are on, stop outside land array |
4419 if hasBorder and (((x and LAND_WIDTH_MASK) <> 0) or ((y and LAND_HEIGHT_MASK) <> 0)) then |
4582 if hasBorder and (((x and LAND_WIDTH_MASK) <> 0) or ((y and LAND_HEIGHT_MASK) <> 0)) then |
4420 begin |
4583 begin |
4421 Gear^.Damage := 0; |
4584 Gear^.Damage := 0; |
4422 Gear^.Health := 0; |
4585 Gear^.Health := 0; |
4423 end |
4586 end |
4424 else |
4587 else |
4425 begin |
4588 begin |
4426 if (rY <= cWaterLine) or (y <= cWaterLine) then |
4589 if (rY <= cWaterLine) or (y <= cWaterLine) then |
4427 begin |
4590 begin |
4428 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) |
4591 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) |
4429 and (Land[y, x] <> 0) then |
4592 and (Land[y, x] <> 0) then |
4430 begin |
4593 begin |
4431 if justCollided then |
4594 if justCollided then |
4432 begin |
4595 begin |
4433 Gear^.Damage := 0; |
4596 Gear^.Damage := 0; |
4434 Gear^.Health := 0; |
4597 Gear^.Health := 0; |
4435 end |
4598 end |
4436 else |
4599 else |
4437 begin |
4600 begin |
4438 inc(Gear^.Damage,3); |
4601 inc(Gear^.Damage,3); |
4439 justCollided := true; |
4602 justCollided := true; |
4440 end; |
4603 end; |
4441 end |
4604 end |
4442 else |
4605 else |
4443 justCollided := false; |
4606 justCollided := false; |
4444 |
4607 |
4445 // kick nearby hogs, dig tunnel and add some fire |
4608 // kick nearby hogs, dig tunnel and add some fire |
4446 // if at least 5 collisions occured |
4609 // if at least 5 collisions occured |
4447 if Gear^.Damage > 0 then |
4610 if Gear^.Damage > 0 then |
4448 begin |
4611 begin |
4449 DrawExplosion(rX,rY,Gear^.Radius); |
4612 DrawExplosion(rX,rY,Gear^.Radius); |
4450 |
4613 |
4451 // kick nearby hogs |
4614 // kick nearby hogs |
4452 AmmoShove(Gear, 35, 50); |
4615 AmmoShove(Gear, 35, 50); |
4453 |
4616 |
4456 |
4619 |
4457 // add some fire to the tunnel |
4620 // add some fire to the tunnel |
4458 if getRandom(6) = 0 then |
4621 if getRandom(6) = 0 then |
4459 AddGear(x - Gear^.Radius + LongInt(getRandom(2 * Gear^.Radius)), y - |
4622 AddGear(x - Gear^.Radius + LongInt(getRandom(2 * Gear^.Radius)), y - |
4460 getRandom(Gear^.Radius + 1), gtFlame, gsttmpFlag, _0, _0, 0); |
4623 getRandom(Gear^.Radius + 1), gtFlame, gsttmpFlag, _0, _0, 0); |
4461 end; |
4624 end; |
4462 |
4625 |
4463 if getRandom(100) = 0 then |
4626 if getRandom(100) = 0 then |
4464 AddVisualGear(x, y, vgtSmokeTrace); |
4627 AddVisualGear(x, y, vgtSmokeTrace); |
|
4628 end |
|
4629 else dec(Gear^.Health, 5); // if underwater get additional damage |
|
4630 end; |
|
4631 |
|
4632 dec(Gear^.Health); |
|
4633 |
|
4634 // decrease bullet size towards the end |
|
4635 if (Gear^.Radius > 4) then |
|
4636 begin |
|
4637 if (Gear^.Health <= (initHealth div 3)) then |
|
4638 dec(Gear^.Radius) |
4465 end |
4639 end |
4466 else dec(Gear^.Health, 5); // if underwater get additional damage |
4640 else if (Gear^.Radius > 3) then |
4467 end; |
4641 begin |
4468 |
4642 if (Gear^.Health <= (initHealth div 4)) then |
4469 dec(Gear^.Health); |
4643 dec(Gear^.Radius) |
4470 |
4644 end |
4471 // decrease bullet size towards the end |
|
4472 if (Gear^.Radius > 4) then begin |
|
4473 if (Gear^.Health <= (initHealth div 3)) then dec(Gear^.Radius) end |
|
4474 else if (Gear^.Radius > 3) then begin |
|
4475 if (Gear^.Health <= (initHealth div 4)) then dec(Gear^.Radius) end |
|
4476 else if (Gear^.Radius > 2) then begin |
4645 else if (Gear^.Radius > 2) then begin |
4477 if (Gear^.Health <= (initHealth div 5)) then dec(Gear^.Radius) end |
4646 if (Gear^.Health <= (initHealth div 5)) then |
4478 else if (Gear^.Radius > 1) then begin |
4647 dec(Gear^.Radius) |
4479 if (Gear^.Health <= (initHealth div 6)) then dec(Gear^.Radius) end; |
4648 end |
|
4649 else if (Gear^.Radius > 1) then |
|
4650 begin |
|
4651 if (Gear^.Health <= (initHealth div 6)) then |
|
4652 dec(Gear^.Radius) |
|
4653 end; |
4480 |
4654 |
4481 until (Gear^.Health <= 0); |
4655 until (Gear^.Health <= 0); |
4482 |
4656 |
4483 DeleteGear(Gear); |
4657 DeleteGear(Gear); |
4484 AfterAttack; |
4658 AfterAttack; |
4693 tmp:= t^.ar[i]; |
4875 tmp:= t^.ar[i]; |
4694 if (tmp^.State and gstNoDamage) = 0 then |
4876 if (tmp^.State and gstNoDamage) = 0 then |
4695 if (tmp^.Kind = gtHedgehog) or (tmp^.Kind = gtMine) or (tmp^.Kind = gtExplosives) then |
4877 if (tmp^.Kind = gtHedgehog) or (tmp^.Kind = gtMine) or (tmp^.Kind = gtExplosives) then |
4696 begin |
4878 begin |
4697 //tmp^.State:= tmp^.State or gstFlatened; |
4879 //tmp^.State:= tmp^.State or gstFlatened; |
4698 if not tmp^.Invulnerable then ApplyDamage(tmp, CurrentHedgehog, tmp^.Health div 3, dsUnknown); |
4880 if not tmp^.Invulnerable then |
|
4881 ApplyDamage(tmp, CurrentHedgehog, tmp^.Health div 3, dsUnknown); |
4699 //DrawTunnel(tmp^.X, tmp^.Y - _1, _0, _0_5, cHHRadius * 6, cHHRadius * 3); |
4882 //DrawTunnel(tmp^.X, tmp^.Y - _1, _0, _0_5, cHHRadius * 6, cHHRadius * 3); |
4700 tmp2:= AddGear(hwRound(tmp^.X), hwRound(tmp^.Y), gtHammerHit, 0, _0, _0, 0); |
4883 tmp2:= AddGear(hwRound(tmp^.X), hwRound(tmp^.Y), gtHammerHit, 0, _0, _0, 0); |
4701 tmp2^.IntersectGear:= tmp; |
4884 tmp2^.IntersectGear:= tmp; |
4702 SetAllToActive |
4885 SetAllToActive |
4703 end |
4886 end |
4854 begin |
5041 begin |
4855 // now really resurrect the hogs with the hp saved in the graves |
5042 // now really resurrect the hogs with the hp saved in the graves |
4856 for i:= 0 to High(graves) do |
5043 for i:= 0 to High(graves) do |
4857 if graves[i]^.Health > 0 then |
5044 if graves[i]^.Health > 0 then |
4858 begin |
5045 begin |
4859 resgear := AddGear(hwRound(graves[i]^.X), hwRound(graves[i]^.Y), |
5046 resgear := AddGear(hwRound(graves[i]^.X), hwRound(graves[i]^.Y), gtHedgehog, gstWait, _0, _0, 0); |
4860 gtHedgehog, gstWait, _0, _0, 0); |
|
4861 resgear^.Hedgehog := graves[i]^.Hedgehog; |
5047 resgear^.Hedgehog := graves[i]^.Hedgehog; |
4862 resgear^.Health := graves[i]^.Health; |
5048 resgear^.Health := graves[i]^.Health; |
4863 PHedgehog(graves[i]^.Hedgehog)^.Gear := resgear; |
5049 PHedgehog(graves[i]^.Hedgehog)^.Gear := resgear; |
4864 DeleteGear(graves[i]); |
5050 DeleteGear(graves[i]); |
4865 RenderHealth(resgear^.Hedgehog^); |
5051 RenderHealth(resgear^.Hedgehog^); |
4866 RecountTeamHealth(resgear^.Hedgehog^.Team); |
5052 RecountTeamHealth(resgear^.Hedgehog^.Team); |
4867 resgear^.Hedgehog^.Effects[heResurrected]:= true; |
5053 resgear^.Hedgehog^.Effects[heResurrected]:= true; |
4868 // only make hat-less hedgehogs look like zombies, preserve existing hats |
5054 // only make hat-less hedgehogs look like zombies, preserve existing hats |
|
5055 |
4869 if resgear^.Hedgehog^.Hat = 'NoHat' then |
5056 if resgear^.Hedgehog^.Hat = 'NoHat' then |
4870 LoadHedgehogHat(resgear, 'Reserved/Zombie'); |
5057 LoadHedgehogHat(resgear, 'Reserved/Zombie'); |
4871 end; |
5058 end; |
4872 |
5059 |
4873 hh^.Gear^.dY := _0; |
5060 hh^.Gear^.dY := _0; |
5107 if (Gear^.Pos = 4) then |
5301 if (Gear^.Pos = 4) then |
5108 begin |
5302 begin |
5109 cnt:= 0; |
5303 cnt:= 0; |
5110 for j:= 0 to Pred(HH^.Team^.Clan^.TeamsNumber) do |
5304 for j:= 0 to Pred(HH^.Team^.Clan^.TeamsNumber) do |
5111 for i:= 0 to Pred(HH^.Team^.Clan^.Teams[j]^.HedgehogsNumber) do |
5305 for i:= 0 to Pred(HH^.Team^.Clan^.Teams[j]^.HedgehogsNumber) do |
5112 if (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear <> nil) and |
5306 if (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear <> nil) |
5113 ((HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.State and gstDrowning) = 0) and |
5307 and ((HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.State and gstDrowning) = 0) |
5114 (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Health > |
5308 and (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Health > HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Damage) then |
5115 HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Damage) then inc(cnt); |
5309 inc(cnt); |
|
5310 |
5116 if (cnt = 0) or SuddenDeathDmg or (Gear^.Timer = 0) then |
5311 if (cnt = 0) or SuddenDeathDmg or (Gear^.Timer = 0) then |
5117 begin |
5312 begin |
5118 Gear^.SoundChannel := LoopSound(sndTardis); |
5313 Gear^.SoundChannel := LoopSound(sndTardis); |
5119 Gear^.Pos:= 1; |
5314 Gear^.Pos:= 1; |
5120 Gear^.Power:= 0; |
5315 Gear^.Power:= 0; |
5121 Gear^.Timer:= 0; |
5316 Gear^.Timer:= 0; |
5122 if HH^.GearHidden <> nil then FindPlace(HH^.GearHidden, false, 0, LAND_WIDTH,true); |
5317 |
|
5318 if HH^.GearHidden <> nil then |
|
5319 FindPlace(HH^.GearHidden, false, 0, LAND_WIDTH,true); |
|
5320 |
5123 if HH^.GearHidden <> nil then |
5321 if HH^.GearHidden <> nil then |
5124 begin |
5322 begin |
5125 Gear^.X:= HH^.GearHidden^.X; |
5323 Gear^.X:= HH^.GearHidden^.X; |
5126 Gear^.Y:= HH^.GearHidden^.Y; |
5324 Gear^.Y:= HH^.GearHidden^.Y; |
5127 //HH^.Gear:=HH^.GearHidden; |
5325 //HH^.Gear:=HH^.GearHidden; |