66 begin |
66 begin |
67 CheckGearDrowning:= true; |
67 CheckGearDrowning:= true; |
68 Gear^.State:= gstDrowning; |
68 Gear^.State:= gstDrowning; |
69 Gear^.RenderTimer:= false; |
69 Gear^.RenderTimer:= false; |
70 Gear^.doStep:= @doStepDrowningGear; |
70 Gear^.doStep:= @doStepDrowningGear; |
71 if Gear^.Kind = gtHedgehog then |
71 if Gear^.Kind = gtHedgehog then |
72 begin |
72 begin |
73 Gear^.State:= Gear^.State and (not gstHHDriven); |
73 Gear^.State:= Gear^.State and (not gstHHDriven); |
74 AddCaption(Format(GetEventString(eidDrowned), PHedgehog(Gear^.Hedgehog)^.Name), cWhiteColor, capgrpMessage); |
74 AddCaption(Format(GetEventString(eidDrowned), PHedgehog(Gear^.Hedgehog)^.Name), cWhiteColor, capgrpMessage); |
75 end |
75 end |
76 end; |
76 end; |
77 PlaySound(sndSplash) |
77 PlaySound(sndSplash) |
78 end |
78 end |
79 else |
79 else |
80 CheckGearDrowning:= false |
80 CheckGearDrowning:= false |
81 end; |
81 end; |
82 |
82 |
83 procedure CheckCollision(Gear: PGear); |
83 procedure CheckCollision(Gear: PGear); |
84 begin |
84 begin |
85 if TestCollisionXwithGear(Gear, hwSign(Gear^.X)) or TestCollisionYwithGear(Gear, hwSign(Gear^.Y)) |
85 if TestCollisionXwithGear(Gear, hwSign(Gear^.X)) or TestCollisionYwithGear(Gear, hwSign(Gear^.Y)) |
86 then Gear^.State:= Gear^.State or gstCollision |
86 then Gear^.State:= Gear^.State or gstCollision |
87 else Gear^.State:= Gear^.State and not gstCollision |
87 else Gear^.State:= Gear^.State and not gstCollision |
88 end; |
88 end; |
89 |
89 |
90 procedure CheckHHDamage(Gear: PGear); |
90 procedure CheckHHDamage(Gear: PGear); |
91 var |
91 var |
92 dmg: Longword; |
92 dmg: Longword; |
93 i: LongInt; |
93 i: LongInt; |
94 particle: PVisualGear; |
94 particle: PVisualGear; |
95 begin |
95 begin |
96 if _0_4 < Gear^.dY then |
96 if _0_4 < Gear^.dY then |
97 begin |
97 begin |
98 dmg:= ModifyDamage(1 + hwRound((hwAbs(Gear^.dY) - _0_4) * 70), Gear); |
98 dmg:= ModifyDamage(1 + hwRound((hwAbs(Gear^.dY) - _0_4) * 70), Gear); |
99 if dmg < 1 then exit; |
99 if dmg < 1 then exit; |
100 |
100 |
101 for i:= min(12, (3 + dmg div 10)) downto 0 do begin |
101 for i:= min(12, (3 + dmg div 10)) downto 0 do begin |
102 particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust); |
102 particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust); |
103 if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX / 5); |
103 if particle <> nil then particle^.dX := particle^.dX + (Gear^.dX / 5); |
104 end; |
104 end; |
105 |
105 |
106 if(Gear^.Invulnerable) then exit; |
106 if(Gear^.Invulnerable) then exit; |
107 |
107 |
108 if _0_6 < Gear^.dY then |
108 if _0_6 < Gear^.dY then |
109 PlaySound(sndOw4, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack) |
109 PlaySound(sndOw4, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack) |
110 else |
110 else |
111 PlaySound(sndOw1, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack); |
111 PlaySound(sndOw1, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack); |
112 |
112 |
113 ApplyDamage(Gear, dmg); |
113 ApplyDamage(Gear, dmg); |
114 end |
114 end |
115 end; |
115 end; |
116 |
116 |
117 //////////////////////////////////////////////////////////////////////////////// |
117 //////////////////////////////////////////////////////////////////////////////// |
118 //////////////////////////////////////////////////////////////////////////////// |
118 //////////////////////////////////////////////////////////////////////////////// |
119 procedure CalcRotationDirAngle(Gear: PGear); |
119 procedure CalcRotationDirAngle(Gear: PGear); |
120 var dAngle: real; |
120 var dAngle: real; |
121 begin |
121 begin |
122 dAngle:= (hwAbs(Gear^.dX) + hwAbs(Gear^.dY)).QWordValue / $80000000; |
122 dAngle:= (hwAbs(Gear^.dX) + hwAbs(Gear^.dY)).QWordValue / $80000000; |
123 if not Gear^.dX.isNegative then |
123 if not Gear^.dX.isNegative then |
124 Gear^.DirAngle:= Gear^.DirAngle + dAngle |
124 Gear^.DirAngle:= Gear^.DirAngle + dAngle |
125 else |
125 else |
126 Gear^.DirAngle:= Gear^.DirAngle - dAngle; |
126 Gear^.DirAngle:= Gear^.DirAngle - dAngle; |
127 |
127 |
128 if Gear^.DirAngle < 0 then Gear^.DirAngle:= Gear^.DirAngle + 360 |
128 if Gear^.DirAngle < 0 then Gear^.DirAngle:= Gear^.DirAngle + 360 |
129 else if 360 < Gear^.DirAngle then Gear^.DirAngle:= Gear^.DirAngle - 360 |
129 else if 360 < Gear^.DirAngle then Gear^.DirAngle:= Gear^.DirAngle - 360 |
130 end; |
130 end; |
131 |
131 |
149 var isFalling: boolean; |
149 var isFalling: boolean; |
150 begin |
150 begin |
151 Gear^.State:= Gear^.State and not gstCollision; |
151 Gear^.State:= Gear^.State and not gstCollision; |
152 |
152 |
153 if Gear^.dY.isNegative then |
153 if Gear^.dY.isNegative then |
154 begin |
154 begin |
155 isFalling:= true; |
155 isFalling:= true; |
156 if TestCollisionYwithGear(Gear, -1) then |
156 if TestCollisionYwithGear(Gear, -1) then |
157 begin |
157 begin |
158 Gear^.dX:= Gear^.dX * Gear^.Friction; |
158 Gear^.dX:= Gear^.dX * Gear^.Friction; |
159 Gear^.dY:= - Gear^.dY * Gear^.Elasticity; |
159 Gear^.dY:= - Gear^.dY * Gear^.Elasticity; |
160 Gear^.State:= Gear^.State or gstCollision |
160 Gear^.State:= Gear^.State or gstCollision |
161 end |
161 end |
162 end else |
162 end else |
163 if TestCollisionYwithGear(Gear, 1) then |
163 if TestCollisionYwithGear(Gear, 1) then |
164 begin |
164 begin |
165 isFalling:= false; |
165 isFalling:= false; |
166 Gear^.dX:= Gear^.dX * Gear^.Friction; |
166 Gear^.dX:= Gear^.dX * Gear^.Friction; |
167 Gear^.dY:= - Gear^.dY * Gear^.Elasticity; |
167 Gear^.dY:= - Gear^.dY * Gear^.Elasticity; |
168 Gear^.State:= Gear^.State or gstCollision |
168 Gear^.State:= Gear^.State or gstCollision |
169 end else isFalling:= true; |
169 end else isFalling:= true; |
170 |
170 |
171 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then |
171 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then |
172 begin |
172 begin |
173 Gear^.dX:= - Gear^.dX * Gear^.Elasticity; |
173 Gear^.dX:= - Gear^.dX * Gear^.Elasticity; |
174 Gear^.dY:= Gear^.dY * Gear^.Elasticity; |
174 Gear^.dY:= Gear^.dY * Gear^.Elasticity; |
175 Gear^.State:= Gear^.State or gstCollision |
175 Gear^.State:= Gear^.State or gstCollision |
176 end; |
176 end; |
177 |
177 |
178 if isFalling then Gear^.dY:= Gear^.dY + cGravity; |
178 if isFalling then Gear^.dY:= Gear^.dY + cGravity; |
179 |
179 |
180 Gear^.X:= Gear^.X + Gear^.dX; |
180 Gear^.X:= Gear^.X + Gear^.dX; |
181 Gear^.Y:= Gear^.Y + Gear^.dY; |
181 Gear^.Y:= Gear^.Y + Gear^.dY; |
182 CheckGearDrowning(Gear); |
182 CheckGearDrowning(Gear); |
183 if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_0002) and |
183 if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_0002) and |
184 (not isFalling) then |
184 (not isFalling) then |
185 Gear^.State:= Gear^.State and not gstMoving |
185 Gear^.State:= Gear^.State and not gstMoving |
186 else |
186 else |
187 Gear^.State:= Gear^.State or gstMoving |
187 Gear^.State:= Gear^.State or gstMoving |
188 end; |
188 end; |
189 |
189 |
190 //////////////////////////////////////////////////////////////////////////////// |
190 //////////////////////////////////////////////////////////////////////////////// |
191 procedure doStepBomb(Gear: PGear); |
191 procedure doStepBomb(Gear: PGear); |
192 var i: LongInt; |
192 var i: LongInt; |
197 |
197 |
198 doStepFallingGear(Gear); |
198 doStepFallingGear(Gear); |
199 |
199 |
200 dec(Gear^.Timer); |
200 dec(Gear^.Timer); |
201 if Gear^.Timer = 1000 then // might need adjustments |
201 if Gear^.Timer = 1000 then // might need adjustments |
202 case Gear^.Kind of |
202 case Gear^.Kind of |
203 gtAmmo_Bomb: makeHogsWorry(Gear^.X, Gear^.Y, 50); |
203 gtAmmo_Bomb: makeHogsWorry(Gear^.X, Gear^.Y, 50); |
204 gtClusterBomb: makeHogsWorry(Gear^.X, Gear^.Y, 20); |
204 gtClusterBomb: makeHogsWorry(Gear^.X, Gear^.Y, 20); |
205 gtWatermelon: makeHogsWorry(Gear^.X, Gear^.Y, 75); |
205 gtWatermelon: makeHogsWorry(Gear^.X, Gear^.Y, 75); |
206 gtHellishBomb: makeHogsWorry(Gear^.X, Gear^.Y, 90); |
206 gtHellishBomb: makeHogsWorry(Gear^.X, Gear^.Y, 90); |
207 end; |
207 end; |
208 if Gear^.Timer = 0 then |
208 if Gear^.Timer = 0 then |
209 begin |
209 begin |
210 case Gear^.Kind of |
210 case Gear^.Kind of |
211 gtAmmo_Bomb: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
211 gtAmmo_Bomb: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
212 gtBall: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 40, EXPLAutoSound); |
212 gtBall: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 40, EXPLAutoSound); |
213 gtClusterBomb: begin |
213 gtClusterBomb: begin |
214 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, EXPLAutoSound); |
214 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, EXPLAutoSound); |
215 for i:= 0 to 4 do |
215 for i:= 0 to 4 do |
216 begin |
216 begin |
217 dX:= rndSign(GetRandom * _0_1); |
217 dX:= rndSign(GetRandom * _0_1); |
218 dY:= (GetRandom - _3) * _0_08; |
218 dY:= (GetRandom - _3) * _0_08; |
219 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25); |
219 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25); |
220 end |
220 end |
221 end; |
221 end; |
222 gtWatermelon: begin |
222 gtWatermelon: begin |
223 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, EXPLAutoSound); |
223 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, EXPLAutoSound); |
224 for i:= 0 to 5 do |
224 for i:= 0 to 5 do |
225 begin |
225 begin |
226 dX:= rndSign(GetRandom * _0_1); |
226 dX:= rndSign(GetRandom * _0_1); |
227 dY:= (GetRandom - _1_5) * _0_3; |
227 dY:= (GetRandom - _1_5) * _0_3; |
228 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMelonPiece, 0, dX, dY, 75)^.DirAngle:= i * 60; |
228 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMelonPiece, 0, dX, dY, 75)^.DirAngle:= i * 60; |
229 end |
229 end |
230 end; |
230 end; |
231 gtHellishBomb: begin |
231 gtHellishBomb: begin |
232 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 90, EXPLAutoSound); |
232 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 90, EXPLAutoSound); |
233 for i:= 0 to 127 do |
233 for i:= 0 to 127 do |
234 begin |
234 begin |
235 dX:= AngleCos(i * 16) * _0_5 * (GetRandom + _1); |
235 dX:= AngleCos(i * 16) * _0_5 * (GetRandom + _1); |
236 dY:= AngleSin(i * 16) * _0_5 * (GetRandom + _1); |
236 dY:= AngleSin(i * 16) * _0_5 * (GetRandom + _1); |
237 Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0); |
237 Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0); |
238 if i mod 2 = 0 then Fire^.State:= Fire^.State or gsttmpFlag; |
238 if i mod 2 = 0 then Fire^.State:= Fire^.State or gsttmpFlag; |
239 Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0); |
239 Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0); |
240 if i mod 2 <> 0 then Fire^.State:= Fire^.State or gsttmpFlag; |
240 if i mod 2 <> 0 then Fire^.State:= Fire^.State or gsttmpFlag; |
241 end |
241 end |
242 end; |
242 end; |
243 end; |
243 end; |
244 DeleteGear(Gear); |
244 DeleteGear(Gear); |
245 exit |
245 exit |
246 end; |
246 end; |
247 |
247 |
248 CalcRotationDirAngle(Gear); |
248 CalcRotationDirAngle(Gear); |
249 |
249 |
250 if Gear^.Kind = gtHellishBomb then |
250 if Gear^.Kind = gtHellishBomb then |
251 begin |
251 begin |
252 if Gear^.Timer = 3000 then PlaySound(sndHellish); |
252 if Gear^.Timer = 3000 then PlaySound(sndHellish); |
253 |
253 |
254 if (GameTicks and $3F) = 0 then |
254 if (GameTicks and $3F) = 0 then |
255 if (Gear^.State and gstCollision) = 0 then |
255 if (Gear^.State and gstCollision) = 0 then |
256 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtEvilTrace, 0, _0, _0, 0); |
256 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtEvilTrace, 0, _0, _0, 0); |
257 end; |
257 end; |
258 |
258 |
259 if (Gear^.State and (gstCollision or gstMoving)) = (gstCollision or gstMoving) then |
259 if (Gear^.State and (gstCollision or gstMoving)) = (gstCollision or gstMoving) then |
260 if (hwAbs(Gear^.dX) > _0_1) or |
260 if (hwAbs(Gear^.dX) > _0_1) or |
261 (hwAbs(Gear^.dY) > _0_1) then |
261 (hwAbs(Gear^.dY) > _0_1) then |
262 PlaySound(sndGrenadeImpact) |
262 PlaySound(sndGrenadeImpact) |
263 end; |
263 end; |
264 //////////////////////////////////////////////////////////////////////////////// |
264 //////////////////////////////////////////////////////////////////////////////// |
265 procedure doStepMolotov(Gear: PGear); |
265 procedure doStepMolotov(Gear: PGear); |
266 var i: LongInt; |
266 var i: LongInt; |
267 dX, dY: hwFloat; |
267 dX, dY: hwFloat; |
268 Fire: PGear; |
268 Fire: PGear; |
269 begin |
269 begin |
270 AllInactive:= false; |
270 AllInactive:= false; |
271 |
271 |
272 doStepFallingGear(Gear); |
272 doStepFallingGear(Gear); |
273 CalcRotationDirAngle(Gear); |
273 CalcRotationDirAngle(Gear); |
274 |
274 |
275 if (Gear^.State and gstCollision) <> 0 then begin |
275 if (Gear^.State and gstCollision) <> 0 then begin |
276 PlaySound(sndMolotov); |
276 PlaySound(sndMolotov); |
277 //doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 5, EXPLAutoSound); |
277 //doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 5, EXPLAutoSound); |
278 for i:= 0 to 20 do begin |
278 for i:= 0 to 20 do begin |
279 dX:= AngleCos(i * 2) * ((_0_1*(i div 5))) * (GetRandom + _1); |
279 dX:= AngleCos(i * 2) * ((_0_1*(i div 5))) * (GetRandom + _1); |
280 dY:= AngleSin(i * 8) * _0_5 * (GetRandom + _1); |
280 dY:= AngleSin(i * 8) * _0_5 * (GetRandom + _1); |
281 Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0); |
281 Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0); |
282 Fire^.State:= Fire^.State or gsttmpFlag; |
282 Fire^.State:= Fire^.State or gsttmpFlag; |
283 Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0); |
283 Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0); |
284 Fire^.State:= Fire^.State or gsttmpFlag; |
284 Fire^.State:= Fire^.State or gsttmpFlag; |
285 Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, -dX, dY, 0); |
285 Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, -dX, dY, 0); |
286 Fire^.State:= Fire^.State or gsttmpFlag; |
286 Fire^.State:= Fire^.State or gsttmpFlag; |
287 Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, -dX, -dY, 0); |
287 Fire:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, -dX, -dY, 0); |
288 Fire^.State:= Fire^.State or gsttmpFlag; |
288 Fire^.State:= Fire^.State or gsttmpFlag; |
289 end; |
289 end; |
290 DeleteGear(Gear); |
290 DeleteGear(Gear); |
291 exit |
291 exit |
292 end; |
292 end; |
293 end; |
293 end; |
294 |
294 |
295 procedure doStepWatermelon(Gear: PGear); |
295 procedure doStepWatermelon(Gear: PGear); |
296 begin |
296 begin |
297 AllInactive:= false; |
297 AllInactive:= false; |
301 procedure doStepCluster(Gear: PGear); |
301 procedure doStepCluster(Gear: PGear); |
302 begin |
302 begin |
303 AllInactive:= false; |
303 AllInactive:= false; |
304 doStepFallingGear(Gear); |
304 doStepFallingGear(Gear); |
305 if (Gear^.State and gstCollision) <> 0 then |
305 if (Gear^.State and gstCollision) <> 0 then |
306 begin |
306 begin |
307 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Timer, EXPLAutoSound); |
307 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Timer, EXPLAutoSound); |
308 DeleteGear(Gear); |
308 DeleteGear(Gear); |
309 exit |
309 exit |
310 end; |
310 end; |
311 |
311 |
312 if Gear^.Kind = gtMelonPiece then |
312 if Gear^.Kind = gtMelonPiece then |
313 CalcRotationDirAngle(Gear) |
313 CalcRotationDirAngle(Gear) |
314 else |
314 else |
315 if (GameTicks and $1F) = 0 then |
315 if (GameTicks and $1F) = 0 then |
316 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0) |
316 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0) |
317 end; |
317 end; |
318 |
318 |
319 //////////////////////////////////////////////////////////////////////////////// |
319 //////////////////////////////////////////////////////////////////////////////// |
320 procedure doStepGrenade(Gear: PGear); |
320 procedure doStepGrenade(Gear: PGear); |
321 begin |
321 begin |
322 AllInactive:= false; |
322 AllInactive:= false; |
323 Gear^.dX:= Gear^.dX + cWindSpeed; |
323 Gear^.dX:= Gear^.dX + cWindSpeed; |
324 doStepFallingGear(Gear); |
324 doStepFallingGear(Gear); |
325 if (Gear^.State and gstCollision) <> 0 then |
325 if (Gear^.State and gstCollision) <> 0 then |
326 begin |
326 begin |
327 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
327 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
328 DeleteGear(Gear); |
328 DeleteGear(Gear); |
329 exit |
329 exit |
330 end; |
330 end; |
331 if (GameTicks and $3F) = 0 then |
331 if (GameTicks and $3F) = 0 then |
332 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0) |
332 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0) |
333 end; |
333 end; |
334 |
334 |
335 //////////////////////////////////////////////////////////////////////////////// |
335 //////////////////////////////////////////////////////////////////////////////// |
336 procedure doStepHealthTagWork(Gear: PGear); |
336 procedure doStepHealthTagWork(Gear: PGear); |
337 begin |
337 begin |
338 if Gear^.Kind = gtHealthTag then |
338 if Gear^.Kind = gtHealthTag then |
339 AllInactive:= false; |
339 AllInactive:= false; |
340 |
340 |
341 dec(Gear^.Timer); |
341 dec(Gear^.Timer); |
342 Gear^.Y:= Gear^.Y + Gear^.dY; |
342 Gear^.Y:= Gear^.Y + Gear^.dY; |
343 |
343 |
344 if Gear^.Timer = 0 then |
344 if Gear^.Timer = 0 then |
345 begin |
345 begin |
346 if (Gear^.Kind = gtHealthTag) and (PHedgehog(Gear^.Hedgehog)^.Gear <> nil) then |
346 if (Gear^.Kind = gtHealthTag) and (PHedgehog(Gear^.Hedgehog)^.Gear <> nil) then |
347 PHedgehog(Gear^.Hedgehog)^.Gear^.Active:= true; // to let current hh die |
347 PHedgehog(Gear^.Hedgehog)^.Gear^.Active:= true; // to let current hh die |
348 DeleteGear(Gear) |
348 DeleteGear(Gear) |
349 end |
349 end |
350 end; |
350 end; |
351 |
351 |
352 procedure doStepHealthTagWorkUnderWater(Gear: PGear); |
352 procedure doStepHealthTagWorkUnderWater(Gear: PGear); |
353 begin |
353 begin |
354 AllInactive:= false; |
354 AllInactive:= false; |
355 |
355 |
356 Gear^.Y:= Gear^.Y - _0_08; |
356 Gear^.Y:= Gear^.Y - _0_08; |
357 |
357 |
358 if hwRound(Gear^.Y) < cWaterLine + 10 then |
358 if hwRound(Gear^.Y) < cWaterLine + 10 then |
359 DeleteGear(Gear) |
359 DeleteGear(Gear) |
360 end; |
360 end; |
361 |
361 |
362 procedure doStepHealthTag(Gear: PGear); |
362 procedure doStepHealthTag(Gear: PGear); |
363 var s: shortstring; |
363 var s: shortstring; |
364 begin |
364 begin |
457 procedure doStepShotIdle(Gear: PGear); |
457 procedure doStepShotIdle(Gear: PGear); |
458 begin |
458 begin |
459 AllInactive:= false; |
459 AllInactive:= false; |
460 inc(Gear^.Timer); |
460 inc(Gear^.Timer); |
461 if Gear^.Timer > 75 then |
461 if Gear^.Timer > 75 then |
462 begin |
462 begin |
463 DeleteGear(Gear); |
463 DeleteGear(Gear); |
464 AfterAttack |
464 AfterAttack |
465 end |
465 end |
466 end; |
466 end; |
467 |
467 |
468 procedure doStepShotgunShot(Gear: PGear); |
468 procedure doStepShotgunShot(Gear: PGear); |
469 var i: LongWord; |
469 var i: LongWord; |
470 shell: PVisualGear; |
470 shell: PVisualGear; |
471 begin |
471 begin |
472 AllInactive:= false; |
472 AllInactive:= false; |
473 |
473 |
474 if ((Gear^.State and gstAnimation) = 0) then |
474 if ((Gear^.State and gstAnimation) = 0) then |
475 begin |
475 begin |
476 dec(Gear^.Timer); |
476 dec(Gear^.Timer); |
477 if Gear^.Timer = 0 then |
477 if Gear^.Timer = 0 then |
478 begin |
478 begin |
479 PlaySound(sndShotgunFire); |
479 PlaySound(sndShotgunFire); |
480 shell:= AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell); |
480 shell:= AddVisualGear(hwRound(Gear^.x), hwRound(Gear^.y), vgtShell); |
481 if shell <> nil then |
481 if shell <> nil then |
482 begin |
482 begin |
483 shell^.dX:= gear^.dX / -4; |
483 shell^.dX:= gear^.dX / -4; |
484 shell^.dY:= gear^.dY / -4; |
484 shell^.dY:= gear^.dY / -4; |
485 shell^.Frame:= 0 |
485 shell^.Frame:= 0 |
486 end; |
486 end; |
487 Gear^.State:= Gear^.State or gstAnimation |
487 Gear^.State:= Gear^.State or gstAnimation |
488 end; |
488 end; |
489 exit |
489 exit |
490 end |
490 end |
491 else inc(Gear^.Timer); |
491 else inc(Gear^.Timer); |
492 |
492 |
493 i:= 200; |
493 i:= 200; |
494 repeat |
494 repeat |
495 Gear^.X:= Gear^.X + Gear^.dX; |
495 Gear^.X:= Gear^.X + Gear^.dX; |
496 Gear^.Y:= Gear^.Y + Gear^.dY; |
496 Gear^.Y:= Gear^.Y + Gear^.dY; |
497 CheckCollision(Gear); |
497 CheckCollision(Gear); |
498 if (Gear^.State and gstCollision) <> 0 then |
498 if (Gear^.State and gstCollision) <> 0 then |
499 begin |
499 begin |
500 Gear^.X:= Gear^.X + Gear^.dX * 8; |
500 Gear^.X:= Gear^.X + Gear^.dX * 8; |
501 Gear^.Y:= Gear^.Y + Gear^.dY * 8; |
501 Gear^.Y:= Gear^.Y + Gear^.dY * 8; |
502 ShotgunShot(Gear); |
502 ShotgunShot(Gear); |
503 Gear^.doStep:= @doStepShotIdle; |
503 Gear^.doStep:= @doStepShotIdle; |
504 exit |
504 exit |
505 end; |
505 end; |
506 dec(i) |
506 dec(i) |
507 until i = 0; |
507 until i = 0; |
508 if (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then |
508 if (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then |
509 Gear^.doStep:= @doStepShotIdle |
509 Gear^.doStep:= @doStepShotIdle |
510 end; |
510 end; |
511 |
511 |
512 //////////////////////////////////////////////////////////////////////////////// |
512 //////////////////////////////////////////////////////////////////////////////// |
513 procedure doStepBulletWork(Gear: PGear); |
513 procedure doStepBulletWork(Gear: PGear); |
514 var i, x, y: LongWord; |
514 var i, x, y: LongWord; |
643 begin |
643 begin |
644 AllInactive:= false; |
644 AllInactive:= false; |
645 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
645 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
646 dec(Gear^.Timer); |
646 dec(Gear^.Timer); |
647 if (Gear^.Timer = 0)or((Gear^.Message and gm_Destroy) <> 0)or((HHGear^.State and gstHHDriven) = 0) then |
647 if (Gear^.Timer = 0)or((Gear^.Message and gm_Destroy) <> 0)or((HHGear^.State and gstHHDriven) = 0) then |
648 begin |
648 begin |
649 StopSound(Gear^.SoundChannel); |
649 StopSound(Gear^.SoundChannel); |
650 DeleteGear(Gear); |
650 DeleteGear(Gear); |
651 AfterAttack; |
651 AfterAttack; |
652 exit |
652 exit |
653 end; |
653 end; |
654 |
654 |
655 if (Gear^.Timer mod 33) = 0 then |
655 if (Gear^.Timer mod 33) = 0 then |
656 begin |
656 begin |
657 HHGear^.State:= HHGear^.State or gstNoDamage; |
657 HHGear^.State:= HHGear^.State or gstNoDamage; |
658 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y) + 7, 6, EXPLDontDraw); |
658 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y) + 7, 6, EXPLDontDraw); |
659 HHGear^.State:= HHGear^.State and not gstNoDamage |
659 HHGear^.State:= HHGear^.State and not gstNoDamage |
660 end; |
660 end; |
661 |
661 |
662 if (Gear^.Timer mod 47) = 0 then |
662 if (Gear^.Timer mod 47) = 0 then |
663 begin |
663 begin |
664 i:= hwRound(Gear^.X) - Gear^.Radius - LongInt(GetRandom(2)); |
664 i:= hwRound(Gear^.X) - Gear^.Radius - LongInt(GetRandom(2)); |
665 ei:= hwRound(Gear^.X) + Gear^.Radius + LongInt(GetRandom(2)); |
665 ei:= hwRound(Gear^.X) + Gear^.Radius + LongInt(GetRandom(2)); |
666 while i <= ei do |
666 while i <= ei do |
667 begin |
667 begin |
668 DrawExplosion(i, hwRound(Gear^.Y) + 3, 3); |
668 DrawExplosion(i, hwRound(Gear^.Y) + 3, 3); |
669 inc(i, 1) |
669 inc(i, 1) |
670 end; |
670 end; |
671 |
671 |
672 if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9), COLOR_INDESTRUCTIBLE) then |
672 if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9), COLOR_INDESTRUCTIBLE) then |
673 begin |
673 begin |
674 Gear^.X:= Gear^.X + Gear^.dX; |
674 Gear^.X:= Gear^.X + Gear^.dX; |
675 Gear^.Y:= Gear^.Y + _1_9; |
675 Gear^.Y:= Gear^.Y + _1_9; |
676 end; |
676 end; |
677 SetAllHHToActive; |
677 SetAllHHToActive; |
678 end; |
678 end; |
679 if TestCollisionYwithGear(Gear, 1) then |
679 if TestCollisionYwithGear(Gear, 1) then |
680 begin |
680 begin |
681 Gear^.dY:= _0; |
681 Gear^.dY:= _0; |
682 SetLittle(HHGear^.dX); |
682 SetLittle(HHGear^.dX); |
683 HHGear^.dY:= _0; |
683 HHGear^.dY:= _0; |
684 end else |
684 end else |
685 begin |
685 begin |
686 Gear^.dY:= Gear^.dY + cGravity; |
686 Gear^.dY:= Gear^.dY + cGravity; |
687 Gear^.Y:= Gear^.Y + Gear^.dY; |
687 Gear^.Y:= Gear^.Y + Gear^.dY; |
688 if hwRound(Gear^.Y) > cWaterLine then Gear^.Timer:= 1 |
688 if hwRound(Gear^.Y) > cWaterLine then Gear^.Timer:= 1 |
689 end; |
689 end; |
690 |
690 |
691 Gear^.X:= Gear^.X + HHGear^.dX; |
691 Gear^.X:= Gear^.X + HHGear^.dX; |
692 HHGear^.X:= Gear^.X; |
692 HHGear^.X:= Gear^.X; |
693 HHGear^.Y:= Gear^.Y - int2hwFloat(cHHRadius); |
693 HHGear^.Y:= Gear^.Y - int2hwFloat(cHHRadius); |
694 |
694 |
729 //////////////////////////////////////////////////////////////////////////////// |
729 //////////////////////////////////////////////////////////////////////////////// |
730 var BTPrevAngle, BTSteps: LongInt; |
730 var BTPrevAngle, BTSteps: LongInt; |
731 |
731 |
732 procedure doStepBlowTorchWork(Gear: PGear); |
732 procedure doStepBlowTorchWork(Gear: PGear); |
733 var HHGear: PGear; |
733 var HHGear: PGear; |
734 b: boolean; |
734 b: boolean; |
735 prevX: LongInt; |
735 prevX: LongInt; |
736 begin |
736 begin |
737 AllInactive:= false; |
737 AllInactive:= false; |
738 dec(Gear^.Timer); |
738 dec(Gear^.Timer); |
739 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
739 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
740 |
740 |
741 HedgehogChAngle(HHGear); |
741 HedgehogChAngle(HHGear); |
742 |
742 |
743 b:= false; |
743 b:= false; |
744 |
744 |
745 if abs(LongInt(HHGear^.Angle) - BTPrevAngle) > 7 then |
745 if abs(LongInt(HHGear^.Angle) - BTPrevAngle) > 7 then |
746 begin |
746 begin |
747 Gear^.dX:= SignAs(AngleSin(HHGear^.Angle) * _0_5, HHGear^.dX); |
747 Gear^.dX:= SignAs(AngleSin(HHGear^.Angle) * _0_5, HHGear^.dX); |
748 Gear^.dY:= AngleCos(HHGear^.Angle) * ( - _0_5); |
748 Gear^.dY:= AngleCos(HHGear^.Angle) * ( - _0_5); |
749 BTPrevAngle:= HHGear^.Angle; |
749 BTPrevAngle:= HHGear^.Angle; |
750 b:= true |
750 b:= true |
751 end; |
751 end; |
752 |
752 |
753 if ((HHGear^.State and gstMoving) <> 0) then |
753 if ((HHGear^.State and gstMoving) <> 0) then |
754 begin |
754 begin |
755 doStepHedgehogMoving(HHGear); |
755 doStepHedgehogMoving(HHGear); |
756 if (HHGear^.State and gstHHDriven) = 0 then Gear^.Timer:= 0 |
756 if (HHGear^.State and gstHHDriven) = 0 then Gear^.Timer:= 0 |
757 end; |
757 end; |
758 |
758 |
759 if Gear^.Timer mod cHHStepTicks = 0 then |
759 if Gear^.Timer mod cHHStepTicks = 0 then |
760 begin |
760 begin |
761 b:= true; |
761 b:= true; |
762 if Gear^.dX.isNegative then |
762 if Gear^.dX.isNegative then |
763 HHGear^.Message:= (HHGear^.Message and (gm_Attack or gm_Up or gm_Down)) or gm_Left |
763 HHGear^.Message:= (HHGear^.Message and (gm_Attack or gm_Up or gm_Down)) or gm_Left |
764 else |
764 else |
765 HHGear^.Message:= (HHGear^.Message and (gm_Attack or gm_Up or gm_Down)) or gm_Right; |
765 HHGear^.Message:= (HHGear^.Message and (gm_Attack or gm_Up or gm_Down)) or gm_Right; |
766 |
766 |
767 if ((HHGear^.State and gstMoving) = 0) then |
767 if ((HHGear^.State and gstMoving) = 0) then |
768 begin |
768 begin |
769 HHGear^.State:= HHGear^.State and not gstAttacking; |
769 HHGear^.State:= HHGear^.State and not gstAttacking; |
770 prevX:= hwRound(HHGear^.X); |
770 prevX:= hwRound(HHGear^.X); |
771 |
771 |
772 // why the call to HedgehogStep then a further increment of X? |
772 // why the call to HedgehogStep then a further increment of X? |
773 if (prevX = hwRound(HHGear^.X)) and |
773 if (prevX = hwRound(HHGear^.X)) and |
774 CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y), COLOR_INDESTRUCTIBLE) then HedgehogStep(HHGear); |
774 CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y), COLOR_INDESTRUCTIBLE) then HedgehogStep(HHGear); |
775 |
775 |
776 if (prevX = hwRound(HHGear^.X)) and |
776 if (prevX = hwRound(HHGear^.X)) and |
777 CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y), COLOR_INDESTRUCTIBLE) then HHGear^.X:= HHGear^.X + SignAs(_1, HHGear^.dX); |
777 CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y), COLOR_INDESTRUCTIBLE) then HHGear^.X:= HHGear^.X + SignAs(_1, HHGear^.dX); |
778 HHGear^.State:= HHGear^.State or gstAttacking |
778 HHGear^.State:= HHGear^.State or gstAttacking |
779 end; |
779 end; |
780 |
780 |
781 inc(BTSteps); |
781 inc(BTSteps); |
782 if BTSteps = 7 then |
782 if BTSteps = 7 then |
783 begin |
783 begin |
784 BTSteps:= 0; |
784 BTSteps:= 0; |
785 if CheckLandValue(hwRound(HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC) + SignAs(_6,Gear^.dX)), hwRound(HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC)), COLOR_INDESTRUCTIBLE) then |
785 if CheckLandValue(hwRound(HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC) + SignAs(_6,Gear^.dX)), hwRound(HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC)), COLOR_INDESTRUCTIBLE) then |
786 begin |
786 begin |
787 Gear^.X:= HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC); |
787 Gear^.X:= HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC); |
788 Gear^.Y:= HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC); |
788 Gear^.Y:= HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC); |
789 end; |
789 end; |
790 HHGear^.State:= HHGear^.State or gstNoDamage; |
790 HHGear^.State:= HHGear^.State or gstNoDamage; |
791 AmmoShove(Gear, 2, 15); |
791 AmmoShove(Gear, 2, 15); |
792 HHGear^.State:= HHGear^.State and not gstNoDamage |
792 HHGear^.State:= HHGear^.State and not gstNoDamage |
793 end; |
793 end; |
794 end; |
794 end; |
795 |
795 |
796 if b then |
796 if b then |
797 DrawTunnel(HHGear^.X - Gear^.dX * cHHRadius, HHGear^.Y - _4 - Gear^.dY * cHHRadius + hwAbs(Gear^.dY) * 7, |
797 DrawTunnel(HHGear^.X - Gear^.dX * cHHRadius, HHGear^.Y - _4 - Gear^.dY * cHHRadius + hwAbs(Gear^.dY) * 7, |
798 Gear^.dX, Gear^.dY, |
798 Gear^.dX, Gear^.dY, |
799 cHHRadius * 5, cHHRadius * 2 + 7); |
799 cHHRadius * 5, cHHRadius * 2 + 7); |
800 |
800 |
801 if (Gear^.Timer = 0) or ((HHGear^.Message and gm_Attack) <> 0) then |
801 if (Gear^.Timer = 0) or ((HHGear^.Message and gm_Attack) <> 0) then |
802 begin |
802 begin |
803 HHGear^.Message:= 0; |
803 HHGear^.Message:= 0; |
804 HHGear^.State:= HHGear^.State and (not gstNotKickable); |
804 HHGear^.State:= HHGear^.State and (not gstNotKickable); |
805 DeleteGear(Gear); |
805 DeleteGear(Gear); |
806 AfterAttack |
806 AfterAttack |
807 end |
807 end |
808 end; |
808 end; |
809 |
809 |
810 procedure doStepBlowTorch(Gear: PGear); |
810 procedure doStepBlowTorch(Gear: PGear); |
811 var HHGear: PGear; |
811 var HHGear: PGear; |
812 begin |
812 begin |
843 HHGear^.X:= HHGear^.X + HHGear^.dX; |
843 HHGear^.X:= HHGear^.X + HHGear^.dX; |
844 HHGear^.Y:= HHGear^.Y + HHGear^.dY; |
844 HHGear^.Y:= HHGear^.Y + HHGear^.dY; |
845 HHGear^.dY:= HHGear^.dY + cGravity; |
845 HHGear^.dY:= HHGear^.dY + cGravity; |
846 |
846 |
847 if (Gear^.Message and gm_Attack) <> 0 then |
847 if (Gear^.Message and gm_Attack) <> 0 then |
848 begin |
848 begin |
849 Gear^.X:= HHGear^.X; |
849 Gear^.X:= HHGear^.X; |
850 Gear^.Y:= HHGear^.Y; |
850 Gear^.Y:= HHGear^.Y; |
851 |
851 |
852 ApplyAngleBounds(PHedgehog(Gear^.Hedgehog)^, amRope); |
852 ApplyAngleBounds(PHedgehog(Gear^.Hedgehog)^, amRope); |
853 |
853 |
854 Gear^.dX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX); |
854 Gear^.dX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX); |
855 Gear^.dY:= -AngleCos(HHGear^.Angle); |
855 Gear^.dY:= -AngleCos(HHGear^.Angle); |
856 Gear^.Friction:= _450; |
856 Gear^.Friction:= _450; |
857 Gear^.Elasticity:= _0; |
857 Gear^.Elasticity:= _0; |
858 Gear^.State:= Gear^.State and not gsttmpflag; |
858 Gear^.State:= Gear^.State and not gsttmpflag; |
859 Gear^.doStep:= @doStepRope |
859 Gear^.doStep:= @doStepRope |
860 end |
860 end |
861 end; |
861 end; |
862 |
862 |
863 procedure doStepRopeWork(Gear: PGear); |
863 procedure doStepRopeWork(Gear: PGear); |
864 var HHGear: PGear; |
864 var HHGear: PGear; |
865 len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat; |
865 len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat; |
866 lx, ly: LongInt; |
866 lx, ly: LongInt; |
867 haveCollision, |
867 haveCollision, |
868 haveDivided: boolean; |
868 haveDivided: boolean; |
869 |
869 |
870 procedure DeleteMe; |
870 procedure DeleteMe; |
871 begin |
871 begin |
872 with HHGear^ do |
872 with HHGear^ do |
873 begin |
873 begin |
874 Message:= Message and not gm_Attack; |
874 Message:= Message and not gm_Attack; |
875 State:= (State or gstMoving) and not gstWinner; |
875 State:= (State or gstMoving) and not gstWinner; |
876 end; |
876 end; |
877 DeleteGear(Gear) |
877 DeleteGear(Gear) |
878 end; |
878 end; |
879 |
879 |
880 procedure WaitCollision; |
880 procedure WaitCollision; |
881 begin |
881 begin |
882 with HHGear^ do |
882 with HHGear^ do |
883 begin |
883 begin |
884 Message:= Message and not gm_Attack; |
884 Message:= Message and not gm_Attack; |
885 State:= State or gstMoving; |
885 State:= State or gstMoving; |
886 end; |
886 end; |
887 RopePoints.Count:= 0; |
887 RopePoints.Count:= 0; |
888 Gear^.Elasticity:= _0; |
888 Gear^.Elasticity:= _0; |
889 Gear^.doStep:= @doStepRopeAfterAttack |
889 Gear^.doStep:= @doStepRopeAfterAttack |
890 end; |
890 end; |
891 |
891 |
892 begin |
892 begin |
893 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
893 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
894 |
894 |
895 if ((HHGear^.State and gstHHDriven) = 0) |
895 if ((HHGear^.State and gstHHDriven) = 0) |
896 or (CheckGearDrowning(HHGear)) then |
896 or (CheckGearDrowning(HHGear)) then |
897 begin |
897 begin |
898 DeleteMe; |
898 DeleteMe; |
899 exit |
899 exit |
900 end; |
900 end; |
901 |
901 |
902 if (Gear^.Message and gm_Left <> 0) then HHGear^.dX:= HHGear^.dX - _0_0002 else |
902 if (Gear^.Message and gm_Left <> 0) then HHGear^.dX:= HHGear^.dX - _0_0002 else |
903 if (Gear^.Message and gm_Right <> 0) then HHGear^.dX:= HHGear^.dX + _0_0002; |
903 if (Gear^.Message and gm_Right <> 0) then HHGear^.dX:= HHGear^.dX + _0_0002; |
904 |
904 |
905 if not TestCollisionYwithGear(HHGear, 1) then HHGear^.dY:= HHGear^.dY + cGravity; |
905 if not TestCollisionYwithGear(HHGear, 1) then HHGear^.dY:= HHGear^.dY + cGravity; |
915 |
915 |
916 Gear^.dX:= mdX; // for visual purposes only |
916 Gear^.dX:= mdX; // for visual purposes only |
917 Gear^.dY:= mdY; |
917 Gear^.dY:= mdY; |
918 |
918 |
919 ///// |
919 ///// |
920 tx:= HHGear^.X; |
920 tx:= HHGear^.X; |
921 ty:= HHGear^.Y; |
921 ty:= HHGear^.Y; |
922 |
922 |
923 if ((Gear^.Message and gm_Down) <> 0) and (Gear^.Elasticity < Gear^.Friction) then |
923 if ((Gear^.Message and gm_Down) <> 0) and (Gear^.Elasticity < Gear^.Friction) then |
924 if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx)) |
924 if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx)) |
925 or TestCollisionYwithGear(HHGear, hwSign(ropeDy))) then |
925 or TestCollisionYwithGear(HHGear, hwSign(ropeDy))) then |
926 Gear^.Elasticity:= Gear^.Elasticity + _0_3; |
926 Gear^.Elasticity:= Gear^.Elasticity + _0_3; |
927 |
927 |
928 if ((Gear^.Message and gm_Up) <> 0) and (Gear^.Elasticity > _30) then |
928 if ((Gear^.Message and gm_Up) <> 0) and (Gear^.Elasticity > _30) then |
929 if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx)) |
929 if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx)) |
930 or TestCollisionYwithGear(HHGear, -hwSign(ropeDy))) then |
930 or TestCollisionYwithGear(HHGear, -hwSign(ropeDy))) then |
931 Gear^.Elasticity:= Gear^.Elasticity - _0_3; |
931 Gear^.Elasticity:= Gear^.Elasticity - _0_3; |
932 |
932 |
933 HHGear^.X:= Gear^.X + mdX * Gear^.Elasticity; |
933 HHGear^.X:= Gear^.X + mdX * Gear^.Elasticity; |
934 HHGear^.Y:= Gear^.Y + mdY * Gear^.Elasticity; |
934 HHGear^.Y:= Gear^.Y + mdY * Gear^.Elasticity; |
935 |
935 |
936 HHGear^.dX:= HHGear^.X - tx; |
936 HHGear^.dX:= HHGear^.X - tx; |
937 HHGear^.dY:= HHGear^.Y - ty; |
937 HHGear^.dY:= HHGear^.Y - ty; |
938 //// |
938 //// |
939 |
939 |
940 |
940 |
941 haveDivided:= false; |
941 haveDivided:= false; |
942 // check whether rope needs dividing |
942 // check whether rope needs dividing |
943 len:= _1 / Distance(ropeDx, ropeDy); // old rope pos |
943 len:= _1 / Distance(ropeDx, ropeDy); // old rope pos |
944 nx:= ropeDx * len; |
944 nx:= ropeDx * len; |
945 ny:= ropeDy * len; |
945 ny:= ropeDy * len; |
946 |
946 |
947 len:= Gear^.Elasticity - _0_3x70; |
947 len:= Gear^.Elasticity - _0_3x70; |
948 while len > _3 do |
948 while len > _3 do |
949 begin |
949 begin |
950 lx:= hwRound(Gear^.X + mdX * len); |
950 lx:= hwRound(Gear^.X + mdX * len); |
951 ly:= hwRound(Gear^.Y + mdY * len); |
951 ly:= hwRound(Gear^.Y + mdY * len); |
952 if ((ly and LAND_HEIGHT_MASK) = 0) and ((lx and LAND_WIDTH_MASK) = 0) and (Land[ly, lx] <> 0) then |
952 if ((ly and LAND_HEIGHT_MASK) = 0) and ((lx and LAND_WIDTH_MASK) = 0) and (Land[ly, lx] <> 0) then |
953 begin |
953 begin |
954 with RopePoints.ar[RopePoints.Count] do |
954 with RopePoints.ar[RopePoints.Count] do |
955 begin |
955 begin |
956 X:= Gear^.X; |
956 X:= Gear^.X; |
957 Y:= Gear^.Y; |
957 Y:= Gear^.Y; |
958 if RopePoints.Count = 0 then RopePoints.HookAngle:= DxDy2Angle(Gear^.dY, Gear^.dX); |
958 if RopePoints.Count = 0 then RopePoints.HookAngle:= DxDy2Angle(Gear^.dY, Gear^.dX); |
959 b:= (nx * HHGear^.dY) > (ny * HHGear^.dX); |
959 b:= (nx * HHGear^.dY) > (ny * HHGear^.dX); |
960 dLen:= len |
960 dLen:= len |
961 end; |
961 end; |
962 with RopePoints.rounded[RopePoints.Count] do |
962 with RopePoints.rounded[RopePoints.Count] do |
963 begin |
963 begin |
964 X:= hwRound(Gear^.X); |
964 X:= hwRound(Gear^.X); |
965 Y:= hwRound(Gear^.Y); |
965 Y:= hwRound(Gear^.Y); |
966 end; |
966 end; |
967 |
967 |
968 Gear^.X:= Gear^.X + nx * len; |
968 Gear^.X:= Gear^.X + nx * len; |
969 Gear^.Y:= Gear^.Y + ny * len; |
969 Gear^.Y:= Gear^.Y + ny * len; |
970 inc(RopePoints.Count); |
970 inc(RopePoints.Count); |
971 TryDo(RopePoints.Count <= MAXROPEPOINTS, 'Rope points overflow', true); |
971 TryDo(RopePoints.Count <= MAXROPEPOINTS, 'Rope points overflow', true); |
972 Gear^.Elasticity:= Gear^.Elasticity - len; |
972 Gear^.Elasticity:= Gear^.Elasticity - len; |
973 Gear^.Friction:= Gear^.Friction - len; |
973 Gear^.Friction:= Gear^.Friction - len; |
974 haveDivided:= true; |
974 haveDivided:= true; |
975 break |
975 break |
976 end; |
976 end; |
977 len:= len - _0_3 // should be the same as increase step |
977 len:= len - _0_3 // should be the same as increase step |
978 end; |
978 end; |
979 |
979 |
980 if not haveDivided then |
980 if not haveDivided then |
981 if RopePoints.Count > 0 then // check whether the last dividing point could be removed |
981 if RopePoints.Count > 0 then // check whether the last dividing point could be removed |
982 begin |
982 begin |
983 tx:= RopePoints.ar[Pred(RopePoints.Count)].X; |
983 tx:= RopePoints.ar[Pred(RopePoints.Count)].X; |
984 ty:= RopePoints.ar[Pred(RopePoints.Count)].Y; |
984 ty:= RopePoints.ar[Pred(RopePoints.Count)].Y; |
985 if RopePoints.ar[Pred(RopePoints.Count)].b xor ((tx - Gear^.X) * (ty - HHGear^.Y) > (tx - HHGear^.X) * (ty - Gear^.Y)) then |
985 if RopePoints.ar[Pred(RopePoints.Count)].b xor ((tx - Gear^.X) * (ty - HHGear^.Y) > (tx - HHGear^.X) * (ty - Gear^.Y)) then |
986 begin |
986 begin |
987 dec(RopePoints.Count); |
987 dec(RopePoints.Count); |
988 Gear^.X:= RopePoints.ar[RopePoints.Count].X; |
988 Gear^.X:= RopePoints.ar[RopePoints.Count].X; |
989 Gear^.Y:= RopePoints.ar[RopePoints.Count].Y; |
989 Gear^.Y:= RopePoints.ar[RopePoints.Count].Y; |
990 Gear^.Elasticity:= Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen; |
990 Gear^.Elasticity:= Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen; |
991 Gear^.Friction:= Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen |
991 Gear^.Friction:= Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen |
992 end |
992 end |
993 end; |
993 end; |
994 |
994 |
995 haveCollision:= false; |
995 haveCollision:= false; |
996 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then |
996 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then |
997 begin |
997 begin |
998 HHGear^.dX:= -_0_6 * HHGear^.dX; |
998 HHGear^.dX:= -_0_6 * HHGear^.dX; |
999 haveCollision:= true |
999 haveCollision:= true |
1000 end; |
1000 end; |
1001 if TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) then |
1001 if TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) then |
1002 begin |
1002 begin |
1003 HHGear^.dY:= -_0_6 * HHGear^.dY; |
1003 HHGear^.dY:= -_0_6 * HHGear^.dY; |
1004 haveCollision:= true |
1004 haveCollision:= true |
1005 end; |
1005 end; |
1006 |
1006 |
1007 if haveCollision |
1007 if haveCollision |
1008 and (Gear^.Message and (gm_Left or gm_Right) <> 0) |
1008 and (Gear^.Message and (gm_Left or gm_Right) <> 0) |
1009 and (Gear^.Message and (gm_Up or gm_Down) <> 0) then |
1009 and (Gear^.Message and (gm_Up or gm_Down) <> 0) then |
1010 begin |
1010 begin |
1011 HHGear^.dX:= SignAs(hwAbs(HHGear^.dX) + _0_2, HHGear^.dX); |
1011 HHGear^.dX:= SignAs(hwAbs(HHGear^.dX) + _0_2, HHGear^.dX); |
1012 HHGear^.dY:= SignAs(hwAbs(HHGear^.dY) + _0_2, HHGear^.dY) |
1012 HHGear^.dY:= SignAs(hwAbs(HHGear^.dY) + _0_2, HHGear^.dY) |
1013 end; |
1013 end; |
1014 |
1014 |
1015 len:= Distance(HHGear^.dX, HHGear^.dY); |
1015 len:= Distance(HHGear^.dX, HHGear^.dY); |
1016 if len > _0_8 then |
1016 if len > _0_8 then |
1017 begin |
1017 begin |
1018 len:= _0_8 / len; |
1018 len:= _0_8 / len; |
1019 HHGear^.dX:= HHGear^.dX * len; |
1019 HHGear^.dX:= HHGear^.dX * len; |
1020 HHGear^.dY:= HHGear^.dY * len; |
1020 HHGear^.dY:= HHGear^.dY * len; |
1021 end; |
1021 end; |
1022 |
1022 |
1023 if (Gear^.Message and gm_Attack) <> 0 then |
1023 if (Gear^.Message and gm_Attack) <> 0 then |
1024 if (Gear^.State and gsttmpFlag) <> 0 then |
1024 if (Gear^.State and gsttmpFlag) <> 0 then |
1025 with PHedgehog(Gear^.Hedgehog)^ do |
1025 with PHedgehog(Gear^.Hedgehog)^ do |
1026 if Ammo^[CurSlot, CurAmmo].AmmoType <> amParachute then |
1026 if Ammo^[CurSlot, CurAmmo].AmmoType <> amParachute then |
1027 WaitCollision |
1027 WaitCollision |
1028 else |
1028 else |
1029 DeleteMe |
1029 DeleteMe |
1030 else |
1030 else |
1031 else |
1031 else |
1032 if (Gear^.State and gsttmpFlag) = 0 then |
1032 if (Gear^.State and gsttmpFlag) = 0 then |
1033 Gear^.State:= Gear^.State or gsttmpFlag; |
1033 Gear^.State:= Gear^.State or gsttmpFlag; |
1034 end; |
1034 end; |
1035 |
1035 |
1036 procedure doStepRopeAttach(Gear: PGear); |
1036 procedure doStepRopeAttach(Gear: PGear); |
1037 var HHGear: PGear; |
1037 var HHGear: PGear; |
1038 tx, ty, tt: hwFloat; |
1038 tx, ty, tt: hwFloat; |
1039 |
1039 |
1040 procedure RemoveFromAmmo; |
1040 procedure RemoveFromAmmo; |
1041 begin |
1041 begin |
1042 if (Gear^.State and gstAttacked) = 0 then |
1042 if (Gear^.State and gstAttacked) = 0 then |
1043 begin |
1043 begin |
1044 OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^); |
1044 OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^); |
1045 Gear^.State:= Gear^.State or gstAttacked |
1045 Gear^.State:= Gear^.State or gstAttacked |
1046 end; |
1046 end; |
1047 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^) |
1047 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^) |
1048 end; |
1048 end; |
1049 |
1049 |
1050 begin |
1050 begin |
1051 Gear^.X:= Gear^.X - Gear^.dX; |
1051 Gear^.X:= Gear^.X - Gear^.dX; |
1052 Gear^.Y:= Gear^.Y - Gear^.dY; |
1052 Gear^.Y:= Gear^.Y - Gear^.dY; |
1053 Gear^.Elasticity:= Gear^.Elasticity + _1; |
1053 Gear^.Elasticity:= Gear^.Elasticity + _1; |
1054 |
1054 |
1055 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
1055 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
1056 DeleteCI(HHGear); |
1056 DeleteCI(HHGear); |
1057 |
1057 |
1058 if (HHGear^.State and gstMoving) <> 0 then |
1058 if (HHGear^.State and gstMoving) <> 0 then |
1059 begin |
1059 begin |
1060 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX); |
1060 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then SetLittle(HHGear^.dX); |
1061 if HHGear^.dY.isNegative and TestCollisionYwithGear(HHGear, -1) then HHGear^.dY:= _0; |
1061 if HHGear^.dY.isNegative and TestCollisionYwithGear(HHGear, -1) then HHGear^.dY:= _0; |
1062 |
1062 |
1063 HHGear^.X:= HHGear^.X + HHGear^.dX; |
1063 HHGear^.X:= HHGear^.X + HHGear^.dX; |
1064 Gear^.X:= Gear^.X + HHGear^.dX; |
1064 Gear^.X:= Gear^.X + HHGear^.dX; |
1065 |
1065 |
1066 if TestCollisionYwithGear(HHGear, 1) then |
1066 if TestCollisionYwithGear(HHGear, 1) then |
1067 begin |
1067 begin |
1068 CheckHHDamage(HHGear); |
1068 CheckHHDamage(HHGear); |
1069 HHGear^.dY:= _0; |
1069 HHGear^.dY:= _0; |
1070 //HHGear^.State:= HHGear^.State and not (gstHHJumping or gstHHHJump); |
1070 //HHGear^.State:= HHGear^.State and not (gstHHJumping or gstHHHJump); |
1071 end else |
1071 end else |
1072 begin |
1072 begin |
1073 HHGear^.Y:= HHGear^.Y + HHGear^.dY; |
1073 HHGear^.Y:= HHGear^.Y + HHGear^.dY; |
1074 Gear^.Y:= Gear^.Y + HHGear^.dY; |
1074 Gear^.Y:= Gear^.Y + HHGear^.dY; |
1075 HHGear^.dY:= HHGear^.dY + cGravity; |
1075 HHGear^.dY:= HHGear^.dY + cGravity; |
1076 end; |
1076 end; |
1077 |
1077 |
1078 tt:= Gear^.Elasticity; |
1078 tt:= Gear^.Elasticity; |
1079 tx:= _0; |
1079 tx:= _0; |
1080 ty:= _0; |
1080 ty:= _0; |
1081 while tt > _20 do |
1081 while tt > _20 do |
1082 begin |
1082 begin |
1083 if TestCollisionXwithXYShift(Gear, tx, hwRound(ty), -hwSign(Gear^.dX)) |
1083 if TestCollisionXwithXYShift(Gear, tx, hwRound(ty), -hwSign(Gear^.dX)) |
1084 or TestCollisionYwithXYShift(Gear, hwRound(tx), hwRound(ty), -hwSign(Gear^.dY)) then |
1084 or TestCollisionYwithXYShift(Gear, hwRound(tx), hwRound(ty), -hwSign(Gear^.dY)) then |
1085 begin |
1085 begin |
1086 Gear^.X:= Gear^.X + tx; |
1086 Gear^.X:= Gear^.X + tx; |
1087 Gear^.Y:= Gear^.Y + ty; |
1087 Gear^.Y:= Gear^.Y + ty; |
1088 Gear^.Elasticity:= tt; |
1088 Gear^.Elasticity:= tt; |
1089 Gear^.doStep:= @doStepRopeWork; |
1089 Gear^.doStep:= @doStepRopeWork; |
1090 with HHGear^ do State:= State and not (gstAttacking or gstHHJumping or gstHHHJump); |
1090 with HHGear^ do State:= State and not (gstAttacking or gstHHJumping or gstHHHJump); |
1091 |
1091 |
1092 RemoveFromAmmo; |
1092 RemoveFromAmmo; |
1093 |
1093 |
1094 tt:= _0; |
1094 tt:= _0; |
1095 exit |
1095 exit |
1096 end; |
1096 end; |
1097 tx:= tx + Gear^.dX + Gear^.dX; |
1097 tx:= tx + Gear^.dX + Gear^.dX; |
1098 ty:= ty + Gear^.dY + Gear^.dY; |
1098 ty:= ty + Gear^.dY + Gear^.dY; |
1099 tt:= tt - _2; |
1099 tt:= tt - _2; |
1100 end; |
1100 end; |
1101 end; |
1101 end; |
1102 |
1102 |
1103 CheckCollision(Gear); |
1103 CheckCollision(Gear); |
1104 |
1104 |
1105 if (Gear^.State and gstCollision) <> 0 then |
1105 if (Gear^.State and gstCollision) <> 0 then |
1106 if Gear^.Elasticity < _10 then |
1106 if Gear^.Elasticity < _10 then |
1107 Gear^.Elasticity:= _10000 |
1107 Gear^.Elasticity:= _10000 |
1108 else |
1108 else |
1109 begin |
1109 begin |
1110 Gear^.doStep:= @doStepRopeWork; |
1110 Gear^.doStep:= @doStepRopeWork; |
1111 with HHGear^ do State:= State and not (gstAttacking or gstHHJumping or gstHHHJump); |
1111 with HHGear^ do State:= State and not (gstAttacking or gstHHJumping or gstHHHJump); |
1112 |
1112 |
1113 RemoveFromAmmo; |
1113 RemoveFromAmmo; |
1114 |
1114 |
1115 exit |
1115 exit |
1116 end; |
1116 end; |
1117 |
1117 |
1118 if (Gear^.Elasticity > Gear^.Friction) |
1118 if (Gear^.Elasticity > Gear^.Friction) |
1119 or ((Gear^.Message and gm_Attack) = 0) |
1119 or ((Gear^.Message and gm_Attack) = 0) |
1120 or ((HHGear^.State and gstHHDriven) = 0) |
1120 or ((HHGear^.State and gstHHDriven) = 0) |
1121 or (HHGear^.Damage > 0) then |
1121 or (HHGear^.Damage > 0) then |
1122 begin |
1122 begin |
1123 with PHedgehog(Gear^.Hedgehog)^.Gear^ do |
1123 with PHedgehog(Gear^.Hedgehog)^.Gear^ do |
1124 begin |
1124 begin |
1125 State:= State and not gstAttacking; |
1125 State:= State and not gstAttacking; |
1126 Message:= Message and not gm_Attack |
1126 Message:= Message and not gm_Attack |
1127 end; |
1127 end; |
1128 DeleteGear(Gear) |
1128 DeleteGear(Gear) |
1129 end |
1129 end |
1130 end; |
1130 end; |
1131 |
1131 |
1132 procedure doStepRope(Gear: PGear); |
1132 procedure doStepRope(Gear: PGear); |
1133 begin |
1133 begin |
1134 Gear^.dX:= - Gear^.dX; |
1134 Gear^.dX:= - Gear^.dX; |
1173 |
1173 |
1174 //////////////////////////////////////////////////////////////////////////////// |
1174 //////////////////////////////////////////////////////////////////////////////// |
1175 procedure doStepMine(Gear: PGear); |
1175 procedure doStepMine(Gear: PGear); |
1176 begin |
1176 begin |
1177 if (Gear^.State and gstMoving) <> 0 then |
1177 if (Gear^.State and gstMoving) <> 0 then |
1178 begin |
1178 begin |
1179 DeleteCI(Gear); |
1179 DeleteCI(Gear); |
1180 doStepFallingGear(Gear); |
1180 doStepFallingGear(Gear); |
1181 if (Gear^.State and gstMoving) = 0 then |
1181 if (Gear^.State and gstMoving) = 0 then |
1182 begin |
1182 begin |
1183 AddGearCI(Gear); |
1183 AddGearCI(Gear); |
1184 Gear^.dX:= _0; |
1184 Gear^.dX:= _0; |
1185 Gear^.dY:= _0 |
1185 Gear^.dY:= _0 |
1186 end; |
1186 end; |
1187 CalcRotationDirAngle(Gear); |
1187 CalcRotationDirAngle(Gear); |
1188 AllInactive:= false |
1188 AllInactive:= false |
1189 end else |
1189 end else |
1190 if ((GameTicks and $3F) = 25) then |
1190 if ((GameTicks and $3F) = 25) then |
1191 doStepFallingGear(Gear); |
1191 doStepFallingGear(Gear); |
1192 |
1192 |
1193 if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Health <> 0) then |
1193 if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Health <> 0) then |
1194 if ((Gear^.State and gstAttacking) = 0) then |
1194 if ((Gear^.State and gstAttacking) = 0) then |
1195 begin |
1195 begin |
1196 if ((GameTicks and $1F) = 0) then |
1196 if ((GameTicks and $1F) = 0) then |
1197 if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then Gear^.State:= Gear^.State or gstAttacking |
1197 if CheckGearNear(Gear, gtHedgehog, 46, 32) <> nil then Gear^.State:= Gear^.State or gstAttacking |
1198 end else // gstAttacking <> 0 |
1198 end else // gstAttacking <> 0 |
1199 begin |
1199 begin |
1200 AllInactive:= false; |
1200 AllInactive:= false; |
1201 if (Gear^.Timer and $FF) = 0 then PlaySound(sndMineTick); |
1201 if (Gear^.Timer and $FF) = 0 then PlaySound(sndMineTick); |
1202 if Gear^.Timer = 0 then |
1202 if Gear^.Timer = 0 then |
1203 begin |
1203 begin |
1204 if ((Gear^.State and gstWait) <> 0) or |
1204 if ((Gear^.State and gstWait) <> 0) or |
1205 (cMineDudPercent = 0) or |
1205 (cMineDudPercent = 0) or |
1206 (getRandom(100) > cMineDudPercent) then |
1206 (getRandom(100) > cMineDudPercent) then |
1207 begin |
1207 begin |
1208 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
1208 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
1209 DeleteGear(Gear) |
1209 DeleteGear(Gear) |
1210 end |
1210 end |
1211 else |
1211 else |
1212 begin |
1212 begin |
1213 AddVisualGear(hwRound(Gear^.X) - 4 + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke); |
1213 AddVisualGear(hwRound(Gear^.X) - 4 + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke); |
1214 PlaySound(sndVaporize); |
1214 PlaySound(sndVaporize); |
1215 Gear^.Health:= 0; |
1215 Gear^.Health:= 0; |
1216 end; |
1216 end; |
1217 exit |
1217 exit |
1218 end; |
1218 end; |
1219 dec(Gear^.Timer); |
1219 dec(Gear^.Timer); |
1220 end else // gsttmpFlag = 0 |
1220 end else // gsttmpFlag = 0 |
1221 if TurnTimeLeft = 0 then Gear^.State:= Gear^.State or gsttmpFlag; |
1221 if TurnTimeLeft = 0 then Gear^.State:= Gear^.State or gsttmpFlag; |
1222 end; |
1222 end; |
1223 |
1223 |
1224 //////////////////////////////////////////////////////////////////////////////// |
1224 //////////////////////////////////////////////////////////////////////////////// |
1225 procedure doStepDynamite(Gear: PGear); |
1225 procedure doStepDynamite(Gear: PGear); |
1226 begin |
1226 begin |
1227 doStepFallingGear(Gear); |
1227 doStepFallingGear(Gear); |
1228 AllInactive:= false; |
1228 AllInactive:= false; |
1229 if Gear^.Timer mod 166 = 0 then inc(Gear^.Tag); |
1229 if Gear^.Timer mod 166 = 0 then inc(Gear^.Tag); |
1230 if Gear^.Timer = 1000 then // might need better timing |
1230 if Gear^.Timer = 1000 then // might need better timing |
1231 makeHogsWorry(Gear^.X, Gear^.Y, 75); |
1231 makeHogsWorry(Gear^.X, Gear^.Y, 75); |
1232 if Gear^.Timer = 0 then |
1232 if Gear^.Timer = 0 then |
1233 begin |
1233 begin |
1234 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, EXPLAutoSound); |
1234 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 75, EXPLAutoSound); |
1235 DeleteGear(Gear); |
1235 DeleteGear(Gear); |
1236 exit |
1236 exit |
1237 end; |
1237 end; |
1238 dec(Gear^.Timer); |
1238 dec(Gear^.Timer); |
1239 end; |
1239 end; |
1240 |
1240 |
1241 /////////////////////////////////////////////////////////////////////////////// |
1241 /////////////////////////////////////////////////////////////////////////////// |
1242 |
1242 |
1305 |
1305 |
1306 end; |
1306 end; |
1307 |
1307 |
1308 procedure doStepCase(Gear: PGear); |
1308 procedure doStepCase(Gear: PGear); |
1309 var i, x, y: LongInt; |
1309 var i, x, y: LongInt; |
1310 k: TGearType; |
1310 k: TGearType; |
1311 exBoom: boolean; |
1311 exBoom: boolean; |
1312 dX, dY: HWFloat; |
1312 dX, dY: HWFloat; |
1313 begin |
1313 begin |
1314 k:= Gear^.Kind; |
1314 k:= Gear^.Kind; |
1315 exBoom:= false; |
1315 exBoom:= false; |
1316 |
1316 |
1317 if (Gear^.Message and gm_Destroy) > 0 then |
1317 if (Gear^.Message and gm_Destroy) > 0 then |
1318 begin |
1318 begin |
1319 DeleteGear(Gear); |
1319 DeleteGear(Gear); |
1320 FreeActionsList; |
1320 FreeActionsList; |
1321 SetAllToActive; // something (hh, mine, etc...) could be on top of the case |
1321 SetAllToActive; // something (hh, mine, etc...) could be on top of the case |
1322 with CurrentHedgehog^ do |
1322 with CurrentHedgehog^ do |
1323 if Gear <> nil then Gear^.Message:= Gear^.Message and not (gm_LJump or gm_HJump); |
1323 if Gear <> nil then Gear^.Message:= Gear^.Message and not (gm_LJump or gm_HJump); |
1324 exit |
1324 exit |
1325 end; |
1325 end; |
1326 |
1326 |
1327 if k = gtExplosives then |
1327 if k = gtExplosives then |
1328 begin |
1328 begin |
1329 //if V > _0_03 then Gear^.State:= Gear^.State or gstAnimation; |
1329 //if V > _0_03 then Gear^.State:= Gear^.State or gstAnimation; |
1330 if hwAbs(Gear^.dX) > _0_15 then Gear^.doStep:= @doStepRollingBarrel; |
1330 if hwAbs(Gear^.dX) > _0_15 then Gear^.doStep:= @doStepRollingBarrel; |
1331 |
1331 |
1332 if ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then |
1332 if ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then |
1333 if (cBarrelHealth div Gear^.Health) > 2 then |
1333 if (cBarrelHealth div Gear^.Health) > 2 then |
1334 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke) |
1334 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke) |
1335 else |
1335 else |
1336 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite); |
1336 AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite); |
1337 dec(Gear^.Health, Gear^.Damage); |
1337 dec(Gear^.Health, Gear^.Damage); |
1338 Gear^.Damage:= 0; |
1338 Gear^.Damage:= 0; |
1339 if Gear^.Health <= 0 then |
1339 if Gear^.Health <= 0 then |
1340 exBoom:= true; |
1340 exBoom:= true; |
1341 end; |
1341 end; |
1342 |
1342 |
1343 if (Gear^.Damage > 0) or exBoom then |
1343 if (Gear^.Damage > 0) or exBoom then |
1344 begin |
1344 begin |
1345 x:= hwRound(Gear^.X); |
1345 x:= hwRound(Gear^.X); |
1346 y:= hwRound(Gear^.Y); |
1346 y:= hwRound(Gear^.Y); |
1347 DeleteGear(Gear); // <-- delete gear! |
1347 DeleteGear(Gear); // <-- delete gear! |
1348 |
1348 |
1349 if k = gtCase then |
1349 if k = gtCase then |
1350 begin |
1350 begin |
1351 doMakeExplosion(x, y, 25, EXPLAutoSound); |
1351 doMakeExplosion(x, y, 25, EXPLAutoSound); |
1352 for i:= 0 to 63 do |
1352 for i:= 0 to 63 do |
1353 AddGear(x, y, gtFlame, 0, _0, _0, 0); |
1353 AddGear(x, y, gtFlame, 0, _0, _0, 0); |
1354 end |
1354 end |
1355 else if k = gtExplosives then |
1355 else if k = gtExplosives then |
1356 begin |
1356 begin |
1357 doMakeExplosion(x, y, 75, EXPLAutoSound); |
1357 doMakeExplosion(x, y, 75, EXPLAutoSound); |
1358 for i:= 0 to 31 do |
1358 for i:= 0 to 31 do |
1359 begin |
1359 begin |
1360 dX:= AngleCos(i * 64) * _0_5 * (getrandom + _1); |
1360 dX:= AngleCos(i * 64) * _0_5 * (getrandom + _1); |
1361 dY:= AngleSin(i * 64) * _0_5 * (getrandom + _1); |
1361 dY:= AngleSin(i * 64) * _0_5 * (getrandom + _1); |
1362 AddGear(x, y, gtFlame, 0, dX, dY, 0); |
1362 AddGear(x, y, gtFlame, 0, dX, dY, 0); |
1363 AddGear(x, y, gtFlame, 0, -dX, -dY, 0)^.State:= gsttmpFlag; |
1363 AddGear(x, y, gtFlame, 0, -dX, -dY, 0)^.State:= gsttmpFlag; |
1364 end |
1364 end |
1365 end; |
1365 end; |
1366 exit |
1366 exit |
1367 end; |
1367 end; |
1368 |
1368 |
1369 if (Gear^.dY.QWordValue <> 0) or (not TestCollisionYwithGear(Gear, 1)) then |
1369 if (Gear^.dY.QWordValue <> 0) or (not TestCollisionYwithGear(Gear, 1)) then |
1370 begin |
1370 begin |
1371 AllInactive:= false; |
1371 AllInactive:= false; |
1372 Gear^.dY:= Gear^.dY + cGravity; |
1372 Gear^.dY:= Gear^.dY + cGravity; |
1373 Gear^.Y:= Gear^.Y + Gear^.dY; |
1373 Gear^.Y:= Gear^.Y + Gear^.dY; |
1374 if (not Gear^.dY.isNegative) and (Gear^.dY > _0_001) then SetAllHHToActive; |
1374 if (not Gear^.dY.isNegative) and (Gear^.dY > _0_001) then SetAllHHToActive; |
1375 if (Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, -1) then Gear^.dY:= _0; |
1375 if (Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, -1) then Gear^.dY:= _0; |
1376 if (not Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, 1) then |
1376 if (not Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, 1) then |
1377 begin |
1377 begin |
1378 if (Gear^.dY > _0_02) and (k = gtExplosives) then |
1378 if (Gear^.dY > _0_02) and (k = gtExplosives) then |
1379 inc(Gear^.Damage, hwRound(Gear^.dY * _30)); |
1379 inc(Gear^.Damage, hwRound(Gear^.dY * _30)); |
1380 |
1380 |
1381 if Gear^.dY > _0_2 then |
1381 if Gear^.dY > _0_2 then |
1382 for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do |
1382 for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do |
1383 AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust); |
1383 AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust); |
1384 Gear^.dY:= - Gear^.dY * Gear^.Elasticity; |
1384 Gear^.dY:= - Gear^.dY * Gear^.Elasticity; |
1385 if Gear^.dY > - _0_001 then Gear^.dY:= _0 |
1385 if Gear^.dY > - _0_001 then Gear^.dY:= _0 |
1386 else if Gear^.dY < - _0_03 then PlaySound(sndGraveImpact) |
1386 else if Gear^.dY < - _0_03 then PlaySound(sndGraveImpact) |
1387 end; |
1387 end; |
1388 //if Gear^.dY > - _0_001 then Gear^.dY:= _0 |
1388 //if Gear^.dY > - _0_001 then Gear^.dY:= _0 |
1389 CheckGearDrowning(Gear); |
1389 CheckGearDrowning(Gear); |
1390 end; |
1390 end; |
1391 |
1391 |
1392 if (Gear^.dY.QWordValue = 0) then AddGearCI(Gear) |
1392 if (Gear^.dY.QWordValue = 0) then AddGearCI(Gear) |
1393 else if (Gear^.dY.QWordValue <> 0) then DeleteCI(Gear) |
1393 else if (Gear^.dY.QWordValue <> 0) then DeleteCI(Gear) |
1394 end; |
1394 end; |
1395 |
1395 |
1396 //////////////////////////////////////////////////////////////////////////////// |
1396 //////////////////////////////////////////////////////////////////////////////// |
1397 |
1397 |
1398 procedure doStepTarget(Gear: PGear); |
1398 procedure doStepTarget(Gear: PGear); |
1399 begin |
1399 begin |
1400 if (Gear^.Timer = 0) and (Gear^.Tag = 0) then |
1400 if (Gear^.Timer = 0) and (Gear^.Tag = 0) then |
1401 PlaySound(sndWarp); |
1401 PlaySound(sndWarp); |
1402 |
1402 |
1403 if (Gear^.Tag = 0) and (Gear^.Timer < 1000) then |
1403 if (Gear^.Tag = 0) and (Gear^.Timer < 1000) then |
1404 inc(Gear^.Timer) |
1404 inc(Gear^.Timer) |
1405 else if Gear^.Tag = 1 then |
1405 else if Gear^.Tag = 1 then |
1406 begin |
1406 begin |
1407 Gear^.Tag:= 2; |
1407 Gear^.Tag:= 2; |
1408 if (TrainingFlags and tfTimeTrial) <> 0 then |
1408 if (TrainingFlags and tfTimeTrial) <> 0 then |
1409 begin |
1409 begin |
1410 inc(TurnTimeLeft, TrainingTimeInc); |
1410 inc(TurnTimeLeft, TrainingTimeInc); |
1411 |
1411 |
1412 if TrainingTimeInc > TrainingTimeInM then |
1412 if TrainingTimeInc > TrainingTimeInM then |
1413 dec(TrainingTimeInc, TrainingTimeInD); |
1413 dec(TrainingTimeInc, TrainingTimeInD); |
1414 if TurnTimeLeft > TrainingTimeMax then |
1414 if TurnTimeLeft > TrainingTimeMax then |
1415 TurnTimeLeft:= TrainingTimeMax; |
1415 TurnTimeLeft:= TrainingTimeMax; |
1416 end; |
1416 end; |
1417 end |
1417 end |
1418 else if Gear^.Tag = 2 then |
1418 else if Gear^.Tag = 2 then |
1419 if Gear^.Timer > 0 then |
1419 if Gear^.Timer > 0 then |
1420 dec(Gear^.Timer) |
1420 dec(Gear^.Timer) |
1421 else |
1421 else |
1422 begin |
1422 begin |
1423 if (TrainingFlags and tfTargetRespawn) <> 0 then |
1423 if (TrainingFlags and tfTargetRespawn) <> 0 then |
1424 begin |
1424 begin |
1425 TrainingTargetGear:= AddGear(0, 0, gtTarget, 0, _0, _0, 0); |
1425 TrainingTargetGear:= AddGear(0, 0, gtTarget, 0, _0, _0, 0); |
1426 FindPlace(TrainingTargetGear, false, 0, LAND_WIDTH); |
1426 FindPlace(TrainingTargetGear, false, 0, LAND_WIDTH); |
1427 end; |
1427 end; |
1428 DeleteGear(Gear); |
1428 DeleteGear(Gear); |
1429 exit; |
1429 exit; |
1430 end; |
1430 end; |
1431 |
1431 |
1432 doStepCase(Gear) |
1432 doStepCase(Gear) |
1433 end; |
1433 end; |
1434 |
1434 |
1435 //////////////////////////////////////////////////////////////////////////////// |
1435 //////////////////////////////////////////////////////////////////////////////// |
1436 procedure doStepIdle(Gear: PGear); |
1436 procedure doStepIdle(Gear: PGear); |
1437 begin |
1437 begin |
1438 AllInactive:= false; |
1438 AllInactive:= false; |
1439 dec(Gear^.Timer); |
1439 dec(Gear^.Timer); |
1440 if Gear^.Timer = 0 then |
1440 if Gear^.Timer = 0 then |
1441 begin |
1441 begin |
1442 DeleteGear(Gear); |
1442 DeleteGear(Gear); |
1443 AfterAttack |
1443 AfterAttack |
1444 end |
1444 end |
1445 end; |
1445 end; |
1446 |
1446 |
1447 procedure doStepShover(Gear: PGear); |
1447 procedure doStepShover(Gear: PGear); |
1448 var HHGear: PGear; |
1448 var HHGear: PGear; |
1449 begin |
1449 begin |
1682 begin |
1682 begin |
1683 AllInactive:= false; |
1683 AllInactive:= false; |
1684 Gear^.X:= Gear^.X + cAirPlaneSpeed * Gear^.Tag; |
1684 Gear^.X:= Gear^.X + cAirPlaneSpeed * Gear^.Tag; |
1685 |
1685 |
1686 if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then |
1686 if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then |
1687 begin |
1687 begin |
1688 dec(Gear^.Health); |
1688 dec(Gear^.Health); |
1689 case Gear^.State of |
1689 case Gear^.State of |
1690 0: FollowGear:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0); |
1690 0: FollowGear:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0); |
1691 1: FollowGear:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine, 0, cBombsSpeed * Gear^.Tag, _0, 0); |
1691 1: FollowGear:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine, 0, cBombsSpeed * Gear^.Tag, _0, 0); |
1692 2: for i:= -19 to 19 do |
1692 2: for i:= -19 to 19 do |
1693 FollowGear:= AddGear(hwRound(Gear^.X) + i div 3, hwRound(Gear^.Y), gtFlame, 0, _0_001 * i, _0, 0); |
1693 FollowGear:= AddGear(hwRound(Gear^.X) + i div 3, hwRound(Gear^.Y), gtFlame, 0, _0_001 * i, _0, 0); |
1694 end; |
1694 end; |
1695 Gear^.dX:= Gear^.dX + int2hwFloat(30 * Gear^.Tag) |
1695 Gear^.dX:= Gear^.dX + int2hwFloat(30 * Gear^.Tag) |
1696 end; |
1696 end; |
1697 |
1697 |
1698 if (GameTicks and $3F) = 0 then |
1698 if (GameTicks and $3F) = 0 then |
1699 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0); |
1699 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0); |
1700 |
1700 |
1701 if (hwRound(Gear^.X) > (LAND_WIDTH+1024)) or (hwRound(Gear^.X) < -1024) then DeleteGear(Gear) |
1701 if (hwRound(Gear^.X) > (LAND_WIDTH+1024)) or (hwRound(Gear^.X) < -1024) then DeleteGear(Gear) |
1702 end; |
1702 end; |
1703 |
1703 |
1704 procedure doStepAirAttack(Gear: PGear); |
1704 procedure doStepAirAttack(Gear: PGear); |
1705 begin |
1705 begin |
1706 AllInactive:= false; |
1706 AllInactive:= false; |
1707 |
1707 |
1708 if Gear^.X.QWordValue = 0 then |
1708 if Gear^.X.QWordValue = 0 then |
1709 begin |
1709 begin |
1710 Gear^.Tag:= 1; |
1710 Gear^.Tag:= 1; |
1711 Gear^.X:= -_1024; |
1711 Gear^.X:= -_1024; |
1712 end |
1712 end |
1713 else |
1713 else |
1714 begin |
1714 begin |
1715 Gear^.Tag:= -1; |
1715 Gear^.Tag:= -1; |
1716 Gear^.X:= int2hwFloat(LAND_WIDTH + 1024); |
1716 Gear^.X:= int2hwFloat(LAND_WIDTH + 1024); |
1717 end; |
1717 end; |
1718 |
1718 |
1719 Gear^.Y:= int2hwFloat(topY-300); |
1719 Gear^.Y:= int2hwFloat(topY-300); |
1720 Gear^.dX:= int2hwFloat(TargetPoint.X - 5 * Gear^.Tag * 15); |
1720 Gear^.dX:= int2hwFloat(TargetPoint.X - 5 * Gear^.Tag * 15); |
1721 |
1721 |
1722 if (int2hwFloat(TargetPoint.Y) - Gear^.Y > _0) and (Gear^.State <> 2) then |
1722 if (int2hwFloat(TargetPoint.Y) - Gear^.Y > _0) and (Gear^.State <> 2) then |
1723 Gear^.dX:= Gear^.dX - cBombsSpeed * hwSqrt((int2hwFloat(TargetPoint.Y) - Gear^.Y) * 2 / cGravity) * Gear^.Tag; |
1723 Gear^.dX:= Gear^.dX - cBombsSpeed * hwSqrt((int2hwFloat(TargetPoint.Y) - Gear^.Y) * 2 / cGravity) * Gear^.Tag; |
1724 |
1724 |
1725 Gear^.Health:= 6; |
1725 Gear^.Health:= 6; |
1726 Gear^.doStep:= @doStepAirAttackWork; |
1726 Gear^.doStep:= @doStepAirAttackWork; |
1727 end; |
1727 end; |
1728 |
1728 |
1846 Msg, State: Longword; |
1846 Msg, State: Longword; |
1847 begin |
1847 begin |
1848 AllInactive:= false; |
1848 AllInactive:= false; |
1849 |
1849 |
1850 if ((Gear^.Message and not gm_Switch) <> 0) or (TurnTimeLeft = 0) then |
1850 if ((Gear^.Message and not gm_Switch) <> 0) or (TurnTimeLeft = 0) then |
1851 begin |
1851 begin |
1852 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
1852 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
1853 Msg:= Gear^.Message and not gm_Switch; |
1853 Msg:= Gear^.Message and not gm_Switch; |
1854 DeleteGear(Gear); |
1854 DeleteGear(Gear); |
1855 OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^); |
1855 OnUsedAmmo(PHedgehog(HHGear^.Hedgehog)^); |
1856 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); |
1856 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); |
1857 |
1857 |
1858 HHGear:= CurrentHedgehog^.Gear; |
1858 HHGear:= CurrentHedgehog^.Gear; |
1859 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); |
1859 ApplyAmmoChanges(PHedgehog(HHGear^.Hedgehog)^); |
1860 HHGear^.Message:= Msg; |
1860 HHGear^.Message:= Msg; |
1861 exit |
1861 exit |
1862 end; |
1862 end; |
1863 |
1863 |
1864 if (Gear^.Message and gm_Switch) <> 0 then |
1864 if (Gear^.Message and gm_Switch) <> 0 then |
1865 begin |
1865 begin |
1866 HHGear:= CurrentHedgehog^.Gear; |
1866 HHGear:= CurrentHedgehog^.Gear; |
1867 HHGear^.Message:= HHGear^.Message and not gm_Switch; |
1867 HHGear^.Message:= HHGear^.Message and not gm_Switch; |
1868 Gear^.Message:= Gear^.Message and not gm_Switch; |
1868 Gear^.Message:= Gear^.Message and not gm_Switch; |
1869 State:= HHGear^.State; |
1869 State:= HHGear^.State; |
1870 HHGear^.State:= 0; |
1870 HHGear^.State:= 0; |
1871 HHGear^.Active:= false; |
1871 HHGear^.Active:= false; |
1872 HHGear^.Z:= cHHZ; |
1872 HHGear^.Z:= cHHZ; |
1873 RemoveGearFromList(HHGear); |
1873 RemoveGearFromList(HHGear); |
1874 InsertGearToList(HHGear); |
1874 InsertGearToList(HHGear); |
1875 |
1875 |
1876 PlaySound(sndSwitchHog); |
1876 PlaySound(sndSwitchHog); |
1877 |
1877 |
1878 repeat |
1878 repeat |
1879 CurrentTeam^.CurrHedgehog:= Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber); |
1879 CurrentTeam^.CurrHedgehog:= Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber); |
1880 until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil); |
1880 until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil); |
1881 |
1881 |
1882 CurrentHedgehog:= @CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]; |
1882 CurrentHedgehog:= @CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]; |
1883 |
1883 |
1884 HHGear:= CurrentHedgehog^.Gear; |
1884 HHGear:= CurrentHedgehog^.Gear; |
1885 HHGear^.State:= State; |
1885 HHGear^.State:= State; |
1886 HHGear^.Active:= true; |
1886 HHGear^.Active:= true; |
1887 FollowGear:= HHGear; |
1887 FollowGear:= HHGear; |
1888 HHGear^.Z:= cCurrHHZ; |
1888 HHGear^.Z:= cCurrHHZ; |
1889 RemoveGearFromList(HHGear); |
1889 RemoveGearFromList(HHGear); |
1890 InsertGearToList(HHGear); |
1890 InsertGearToList(HHGear); |
1891 Gear^.X:= HHGear^.X; |
1891 Gear^.X:= HHGear^.X; |
1892 Gear^.Y:= HHGear^.Y |
1892 Gear^.Y:= HHGear^.Y |
1893 end; |
1893 end; |
1894 end; |
1894 end; |
1895 |
1895 |
1896 procedure doStepSwitcher(Gear: PGear); |
1896 procedure doStepSwitcher(Gear: PGear); |
1897 var HHGear: PGear; |
1897 var HHGear: PGear; |
1898 begin |
1898 begin |
1899 Gear^.doStep:= @doStepSwitcherWork; |
1899 Gear^.doStep:= @doStepSwitcherWork; |
1900 |
1900 |
1901 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
1901 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
1902 with HHGear^ do |
1902 with HHGear^ do |
1903 begin |
1903 begin |
1904 State:= State and not gstAttacking; |
1904 State:= State and not gstAttacking; |
1905 Message:= Message and not gm_Attack |
1905 Message:= Message and not gm_Attack |
1906 end |
1906 end |
1907 end; |
1907 end; |
1908 |
1908 |
1909 //////////////////////////////////////////////////////////////////////////////// |
1909 //////////////////////////////////////////////////////////////////////////////// |
1910 procedure doStepMortar(Gear: PGear); |
1910 procedure doStepMortar(Gear: PGear); |
1911 var dX, dY: hwFloat; |
1911 var dX, dY: hwFloat; |
1950 HHGear^.State:= HHGear^.State or gstNoDamage; |
1950 HHGear^.State:= HHGear^.State or gstNoDamage; |
1951 DeleteCI(HHGear); |
1951 DeleteCI(HHGear); |
1952 |
1952 |
1953 i:= 2; |
1953 i:= 2; |
1954 repeat |
1954 repeat |
1955 Gear^.X:= Gear^.X + HHGear^.dX; |
1955 Gear^.X:= Gear^.X + HHGear^.dX; |
1956 Gear^.Y:= Gear^.Y + HHGear^.dY; |
1956 Gear^.Y:= Gear^.Y + HHGear^.dY; |
1957 HHGear^.X:= Gear^.X; |
1957 HHGear^.X:= Gear^.X; |
1958 HHGear^.Y:= Gear^.Y; |
1958 HHGear^.Y:= Gear^.Y; |
1959 |
1959 |
1960 inc(Gear^.Damage, 2); |
1960 inc(Gear^.Damage, 2); |
1961 |
1961 |
1962 // if TestCollisionXwithGear(HHGear, hwSign(Gear^.dX)) |
1962 // if TestCollisionXwithGear(HHGear, hwSign(Gear^.dX)) |
1963 // or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY)) then inc(Gear^.Damage, 3); |
1963 // or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY)) then inc(Gear^.Damage, 3); |
1964 |
1964 |
1965 dec(i) |
1965 dec(i) |
1966 until (i = 0) or (Gear^.Damage > Gear^.Health); |
1966 until (i = 0) or (Gear^.Damage > Gear^.Health); |
1967 |
1967 |
1968 inc(upd); |
1968 inc(upd); |
1969 if upd > 3 then |
1969 if upd > 3 then |
1970 begin |
1970 begin |
1971 if Gear^.Health < 1500 then Gear^.Pos:= 2; |
1971 if Gear^.Health < 1500 then Gear^.Pos:= 2; |
1972 |
1972 |
1973 AmmoShove(Gear, 30, 40); |
1973 AmmoShove(Gear, 30, 40); |
1974 |
1974 |
1975 DrawTunnel(HHGear^.X - HHGear^.dX * 10, |
1975 DrawTunnel(HHGear^.X - HHGear^.dX * 10, |
1976 HHGear^.Y - _2 - HHGear^.dY * 10 + hwAbs(HHGear^.dY) * 2, |
1976 HHGear^.Y - _2 - HHGear^.dY * 10 + hwAbs(HHGear^.dY) * 2, |
1977 HHGear^.dX, |
1977 HHGear^.dX, |
1978 HHGear^.dY, |
1978 HHGear^.dY, |
1979 20 + cHHRadius * 2, |
1979 20 + cHHRadius * 2, |
1980 cHHRadius * 2 + 6); |
1980 cHHRadius * 2 + 6); |
1981 |
1981 |
1982 upd:= 0 |
1982 upd:= 0 |
1983 end; |
1983 end; |
1984 |
1984 |
1985 if Gear^.Health < Gear^.Damage then |
1985 if Gear^.Health < Gear^.Damage then |
1986 begin |
1986 begin |
1987 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, EXPLAutoSound); |
1987 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, EXPLAutoSound); |
1988 AfterAttack; |
1988 AfterAttack; |
1989 DeleteGear(Gear); |
1989 DeleteGear(Gear); |
1990 DeleteGear(HHGear); |
1990 DeleteGear(HHGear); |
1991 end else |
1991 end else |
1992 begin |
1992 begin |
1993 dec(Gear^.Health, Gear^.Damage); |
1993 dec(Gear^.Health, Gear^.Damage); |
1994 Gear^.Damage:= 0 |
1994 Gear^.Damage:= 0 |
1995 end |
1995 end |
1996 end; |
1996 end; |
1997 |
1997 |
1998 procedure doStepKamikazeIdle(Gear: PGear); |
1998 procedure doStepKamikazeIdle(Gear: PGear); |
1999 begin |
1999 begin |
2000 AllInactive:= false; |
2000 AllInactive:= false; |
2001 dec(Gear^.Timer); |
2001 dec(Gear^.Timer); |
2002 if Gear^.Timer = 0 then |
2002 if Gear^.Timer = 0 then |
2003 begin |
2003 begin |
2004 Gear^.Pos:= 1; |
2004 Gear^.Pos:= 1; |
2005 PlaySound(sndKamikaze, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack); |
2005 PlaySound(sndKamikaze, PHedgehog(Gear^.Hedgehog)^.Team^.voicepack); |
2006 Gear^.doStep:= @doStepKamikazeWork |
2006 Gear^.doStep:= @doStepKamikazeWork |
2007 end |
2007 end |
2008 end; |
2008 end; |
2009 |
2009 |
2010 procedure doStepKamikaze(Gear: PGear); |
2010 procedure doStepKamikaze(Gear: PGear); |
2011 var HHGear: PGear; |
2011 var HHGear: PGear; |
2012 begin |
2012 begin |
2099 yy:= dirs[Gear^.Angle].y; |
2099 yy:= dirs[Gear^.Angle].y; |
2100 xxn:= dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].x; |
2100 xxn:= dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].x; |
2101 yyn:= dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].y; |
2101 yyn:= dirs[(LongInt(Gear^.Angle) + 4 + dA) mod 4].y; |
2102 |
2102 |
2103 if (xx = 0) then |
2103 if (xx = 0) then |
2104 if TestCollisionYwithGear(Gear, yy) then |
2104 if TestCollisionYwithGear(Gear, yy) then |
2105 PrevAngle |
2105 PrevAngle |
2106 else begin |
2106 else begin |
2107 Gear^.Tag:= 0; |
2107 Gear^.Tag:= 0; |
2108 Gear^.Y:= Gear^.Y + int2hwFloat(yy); |
2108 Gear^.Y:= Gear^.Y + int2hwFloat(yy); |
2109 if not TestCollisionXwithGear(Gear, xxn) then |
2109 if not TestCollisionXwithGear(Gear, xxn) then |
2110 begin |
2110 begin |
2111 Gear^.X:= Gear^.X + int2hwFloat(xxn); |
2111 Gear^.X:= Gear^.X + int2hwFloat(xxn); |
2112 NextAngle |
2112 NextAngle |
2113 end; |
2113 end; |
2114 end; |
2114 end; |
2115 |
2115 |
2116 if (yy = 0) then |
2116 if (yy = 0) then |
2117 if TestCollisionXwithGear(Gear, xx) then |
2117 if TestCollisionXwithGear(Gear, xx) then |
2118 PrevAngle |
2118 PrevAngle |
2119 else begin |
2119 else begin |
2120 Gear^.Tag:= 0; |
2120 Gear^.Tag:= 0; |
2121 Gear^.X:= Gear^.X + int2hwFloat(xx); |
2121 Gear^.X:= Gear^.X + int2hwFloat(xx); |
2122 if not TestCollisionYwithGear(Gear, yyn) then |
2122 if not TestCollisionYwithGear(Gear, yyn) then |
2123 begin |
2123 begin |
2124 Gear^.Y:= Gear^.Y + int2hwFloat(yyn); |
2124 Gear^.Y:= Gear^.Y + int2hwFloat(yyn); |
2125 NextAngle |
2125 NextAngle |
2126 end; |
2126 end; |
2127 end; |
2127 end; |
2128 |
2128 |
2129 if Gear^.Tag = 0 then |
2129 if Gear^.Tag = 0 then |
2130 begin |
2130 begin |
2131 CakeI:= (CakeI + 1) mod cakeh; |
2131 CakeI:= (CakeI + 1) mod cakeh; |
2132 tdx:= CakePoints[CakeI].x - Gear^.X; |
2132 tdx:= CakePoints[CakeI].x - Gear^.X; |
2133 tdy:= - CakePoints[CakeI].y + Gear^.Y; |
2133 tdy:= - CakePoints[CakeI].y + Gear^.Y; |
2134 CakePoints[CakeI].x:= Gear^.X; |
2134 CakePoints[CakeI].x:= Gear^.X; |
2135 CakePoints[CakeI].y:= Gear^.Y; |
2135 CakePoints[CakeI].y:= Gear^.Y; |
2136 Gear^.DirAngle:= DxDy2Angle(tdx, tdy); |
2136 Gear^.DirAngle:= DxDy2Angle(tdx, tdy); |
2137 end; |
2137 end; |
2138 |
2138 |
2139 dec(Gear^.Health); |
2139 dec(Gear^.Health); |
2140 Gear^.Timer:= Gear^.Health*10; // This is not seconds, but at least it is *some* feedback |
2140 Gear^.Timer:= Gear^.Health*10; // This is not seconds, but at least it is *some* feedback |
2141 if (Gear^.Health = 0) or ((Gear^.Message and gm_Attack) <> 0) then |
2141 if (Gear^.Health = 0) or ((Gear^.Message and gm_Attack) <> 0) then |
2142 begin |
2142 begin |
2143 FollowGear:= Gear; |
2143 FollowGear:= Gear; |
2144 Gear^.RenderTimer:= false; |
2144 Gear^.RenderTimer:= false; |
2145 Gear^.doStep:= @doStepCakeDown |
2145 Gear^.doStep:= @doStepCakeDown |
2146 end |
2146 end |
2147 end; |
2147 end; |
2148 |
2148 |
2149 procedure doStepCakeUp(Gear: PGear); |
2149 procedure doStepCakeUp(Gear: PGear); |
2150 var i: Longword; |
2150 var i: Longword; |
2151 begin |
2151 begin |
2254 begin |
2254 begin |
2255 AllInactive:= false; |
2255 AllInactive:= false; |
2256 |
2256 |
2257 inc(Gear^.Timer); |
2257 inc(Gear^.Timer); |
2258 if Gear^.Timer = 17 then |
2258 if Gear^.Timer = 17 then |
2259 Gear^.Timer:= 0 |
2259 Gear^.Timer:= 0 |
2260 else |
2260 else |
2261 exit; |
2261 exit; |
2262 |
2262 |
2263 if cWaterLine > 0 then |
2263 if cWaterLine > 0 then |
2264 begin |
2264 begin |
2265 dec(cWaterLine); |
2265 dec(cWaterLine); |
2266 for i:= 0 to LAND_WIDTH - 1 do |
2266 for i:= 0 to LAND_WIDTH - 1 do |
2267 Land[cWaterLine, i]:= 0; |
2267 Land[cWaterLine, i]:= 0; |
2268 SetAllToActive |
2268 SetAllToActive |
2269 end; |
2269 end; |
2270 |
2270 |
2271 inc(Gear^.Tag); |
2271 inc(Gear^.Tag); |
2272 if (Gear^.Tag = 47) or (cWaterLine = 0) then |
2272 if (Gear^.Tag = 47) or (cWaterLine = 0) then |
2273 DeleteGear(Gear) |
2273 DeleteGear(Gear) |
2274 end; |
2274 end; |
2275 |
2275 |
2276 //////////////////////////////////////////////////////////////////////////////// |
2276 //////////////////////////////////////////////////////////////////////////////// |
2277 procedure doStepDrillDrilling(Gear: PGear); |
2277 procedure doStepDrillDrilling(Gear: PGear); |
2278 var t: PGearArray; |
2278 var t: PGearArray; |
2279 ox, oy: hwFloat; |
2279 ox, oy: hwFloat; |
2280 begin |
2280 begin |
2281 AllInactive:= false; |
2281 AllInactive:= false; |
2282 |
2282 |
2283 if (Gear^.Timer > 0) and ((Gear^.Timer mod 10) = 0) then |
2283 if (Gear^.Timer > 0) and ((Gear^.Timer mod 10) = 0) then |
2284 begin |
2284 begin |
2285 ox:= Gear^.X; |
2285 ox:= Gear^.X; |
2286 oy:= Gear^.Y; |
2286 oy:= Gear^.Y; |
2287 Gear^.X:= Gear^.X + Gear^.dX; |
2287 Gear^.X:= Gear^.X + Gear^.dX; |
2288 Gear^.Y:= Gear^.Y + Gear^.dY; |
2288 Gear^.Y:= Gear^.Y + Gear^.dY; |
2289 DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 2, 6); |
2289 DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 2, 6); |
2290 if(CheckGearDrowning(Gear)) then |
2290 if(CheckGearDrowning(Gear)) then |
2291 begin |
2291 begin |
2292 StopSound(Gear^.SoundChannel); |
2292 StopSound(Gear^.SoundChannel); |
2293 exit |
2293 exit |
2294 end |
2294 end |
2295 end; |
2295 end; |
2296 |
2296 |
2297 t:= CheckGearsCollision(Gear); //fixes drill not exploding when touching HH bug |
2297 t:= CheckGearsCollision(Gear); //fixes drill not exploding when touching HH bug |
2298 if (Gear^.Timer = 0) |
2298 if (Gear^.Timer = 0) |
2299 or (t^.Count <> 0) |
2299 or (t^.Count <> 0) |
2300 or (not TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) |
2300 or (not TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) |
2301 and not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))) |
2301 and not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))) |
2302 or (Land[hwRound(Gear^.Y), hwRound(Gear^.X)] = COLOR_INDESTRUCTIBLE) then |
2302 or (Land[hwRound(Gear^.Y), hwRound(Gear^.X)] = COLOR_INDESTRUCTIBLE) then |
2303 begin //out of time or exited ground |
2303 begin //out of time or exited ground |
2304 StopSound(Gear^.SoundChannel); |
2304 StopSound(Gear^.SoundChannel); |
2305 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
2305 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
2306 DeleteGear(Gear); |
2306 DeleteGear(Gear); |
2307 exit |
2307 exit |
2308 end; |
2308 end; |
2309 |
2309 |
2310 dec(Gear^.Timer); |
2310 dec(Gear^.Timer); |
2311 end; |
2311 end; |
2312 |
2312 |
2313 procedure doStepDrill(Gear: PGear); |
2313 procedure doStepDrill(Gear: PGear); |
2314 var t: PGearArray; |
2314 var t: PGearArray; |
2315 oldDx, oldDy: hwFloat; |
2315 oldDx, oldDy: hwFloat; |
2316 t2: hwFloat; |
2316 t2: hwFloat; |
2317 begin |
2317 begin |
2318 AllInactive:= false; |
2318 AllInactive:= false; |
2319 |
2319 |
2320 Gear^.dX:= Gear^.dX + cWindSpeed; |
2320 Gear^.dX:= Gear^.dX + cWindSpeed; |
2321 oldDx:= Gear^.dX; |
2321 oldDx:= Gear^.dX; |
2322 oldDy:= Gear^.dY; |
2322 oldDy:= Gear^.dY; |
2323 |
2323 |
2324 doStepFallingGear(Gear); |
2324 doStepFallingGear(Gear); |
2325 |
2325 |
2326 if (GameTicks and $3F) = 0 then |
2326 if (GameTicks and $3F) = 0 then |
2327 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0); |
2327 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0); |
2328 |
2328 |
2329 if ((Gear^.State and gstCollision) <> 0) then begin //hit |
2329 if ((Gear^.State and gstCollision) <> 0) then begin //hit |
2330 Gear^.dX:= oldDx; |
2330 Gear^.dX:= oldDx; |
2331 Gear^.dY:= oldDy; |
2331 Gear^.dY:= oldDy; |
2332 |
2332 |
2333 t:= CheckGearsCollision(Gear); |
2333 t:= CheckGearsCollision(Gear); |
2334 if (t^.Count = 0) then begin //hit the ground not the HH |
2334 if (t^.Count = 0) then begin //hit the ground not the HH |
2335 t2 := _0_5 / Distance(Gear^.dX, Gear^.dY); |
2335 t2 := _0_5 / Distance(Gear^.dX, Gear^.dY); |
2336 Gear^.dX:= Gear^.dX * t2; |
2336 Gear^.dX:= Gear^.dX * t2; |
2337 Gear^.dY:= Gear^.dY * t2; |
2337 Gear^.dY:= Gear^.dY * t2; |
2338 end else begin //explode right on contact with HH |
2338 end else begin //explode right on contact with HH |
2339 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
2339 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, EXPLAutoSound); |
2340 DeleteGear(Gear); |
2340 DeleteGear(Gear); |
2341 exit; |
2341 exit; |
2342 end; |
2342 end; |
2343 |
2343 |
2344 Gear^.SoundChannel:= LoopSound(sndPickhammer); |
2344 Gear^.SoundChannel:= LoopSound(sndPickhammer); |
2345 Gear^.doStep:= @doStepDrillDrilling; |
2345 Gear^.doStep:= @doStepDrillDrilling; |
2346 dec(Gear^.Timer) |
2346 dec(Gear^.Timer) |
2347 end |
2347 end |
2348 end; |
2348 end; |
2349 |
2349 |
2350 //////////////////////////////////////////////////////////////////////////////// |
2350 //////////////////////////////////////////////////////////////////////////////// |
2351 procedure doStepBallgunWork(Gear: PGear); |
2351 procedure doStepBallgunWork(Gear: PGear); |
2352 var HHGear: PGear; |
2352 var HHGear: PGear; |
2353 rx, ry: hwFloat; |
2353 rx, ry: hwFloat; |
2354 begin |
2354 begin |
2355 AllInactive:= false; |
2355 AllInactive:= false; |
2356 dec(Gear^.Timer); |
2356 dec(Gear^.Timer); |
2357 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
2357 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
2358 HedgehogChAngle(HHGear); |
2358 HedgehogChAngle(HHGear); |
2359 if (Gear^.Timer mod 100) = 0 then |
2359 if (Gear^.Timer mod 100) = 0 then |
2360 begin |
2360 begin |
2361 rx:= rndSign(getRandom * _0_1); |
2361 rx:= rndSign(getRandom * _0_1); |
2362 ry:= rndSign(getRandom * _0_1); |
2362 ry:= rndSign(getRandom * _0_1); |
2363 |
2363 |
2364 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtBall, 0, |
2364 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtBall, 0, |
2365 SignAs(AngleSin(HHGear^.Angle) * _0_8, HHGear^.dX) + rx, |
2365 SignAs(AngleSin(HHGear^.Angle) * _0_8, HHGear^.dX) + rx, |
2366 AngleCos(HHGear^.Angle) * ( - _0_8) + ry, |
2366 AngleCos(HHGear^.Angle) * ( - _0_8) + ry, |
2367 0); |
2367 0); |
2368 |
2368 |
2369 PlaySound(sndGun); |
2369 PlaySound(sndGun); |
2370 end; |
2370 end; |
2371 |
2371 |
2372 if (Gear^.Timer = 0) or (HHGear^.Damage <> 0) then |
2372 if (Gear^.Timer = 0) or (HHGear^.Damage <> 0) then |
2373 begin |
2373 begin |
2374 DeleteGear(Gear); |
2374 DeleteGear(Gear); |
2375 AfterAttack |
2375 AfterAttack |
2376 end |
2376 end |
2377 end; |
2377 end; |
2378 |
2378 |
2379 procedure doStepBallgun(Gear: PGear); |
2379 procedure doStepBallgun(Gear: PGear); |
2380 var HHGear: PGear; |
2380 var HHGear: PGear; |
2381 begin |
2381 begin |
2404 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
2404 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
2405 FollowGear:= Gear; |
2405 FollowGear:= Gear; |
2406 |
2406 |
2407 fChanged:= false; |
2407 fChanged:= false; |
2408 if ((HHGear^.State and gstHHDriven) = 0) or (Gear^.Timer = 0) then |
2408 if ((HHGear^.State and gstHHDriven) = 0) or (Gear^.Timer = 0) then |
2409 begin |
2409 begin |
2410 fChanged:= true; |
2410 fChanged:= true; |
2411 if Gear^.Angle > 2048 then dec(Gear^.Angle) else |
2411 if Gear^.Angle > 2048 then dec(Gear^.Angle) else |
2412 if Gear^.Angle < 2048 then inc(Gear^.Angle) else fChanged:= false |
2412 if Gear^.Angle < 2048 then inc(Gear^.Angle) else fChanged:= false |
2413 end |
2413 end |
2414 else |
2414 else |
2415 begin |
2415 begin |
2416 if ((Gear^.Message and gm_Left) <> 0) then |
2416 if ((Gear^.Message and gm_Left) <> 0) then |
2417 begin |
2417 begin |
2418 fChanged:= true; |
2418 fChanged:= true; |
2419 Gear^.Angle:= (Gear^.Angle + (4096 - cAngleSpeed)) mod 4096 |
2419 Gear^.Angle:= (Gear^.Angle + (4096 - cAngleSpeed)) mod 4096 |
2420 end; |
2420 end; |
2421 |
2421 |
2422 if ((Gear^.Message and gm_Right) <> 0) then |
2422 if ((Gear^.Message and gm_Right) <> 0) then |
2423 begin |
2423 begin |
2424 fChanged:= true; |
2424 fChanged:= true; |
2425 Gear^.Angle:= (Gear^.Angle + cAngleSpeed) mod 4096 |
2425 Gear^.Angle:= (Gear^.Angle + cAngleSpeed) mod 4096 |
2426 end |
2426 end |
2427 end; |
2427 end; |
2428 |
2428 |
2429 if fChanged then |
2429 if fChanged then |
2430 begin |
2430 begin |
2431 Gear^.dX.isNegative:= (Gear^.Angle > 2048); |
2431 Gear^.dX.isNegative:= (Gear^.Angle > 2048); |
2432 if Gear^.dX.isNegative then |
2432 if Gear^.dX.isNegative then |
2433 trueAngle:= 4096 - Gear^.Angle |
2433 trueAngle:= 4096 - Gear^.Angle |
2434 else |
2434 else |
2435 trueAngle:= Gear^.Angle; |
2435 trueAngle:= Gear^.Angle; |
2436 |
2436 |
2437 Gear^.dX:= SignAs(AngleSin(trueAngle), Gear^.dX) * _0_25; |
2437 Gear^.dX:= SignAs(AngleSin(trueAngle), Gear^.dX) * _0_25; |
2438 Gear^.dY:= AngleCos(trueAngle) * -_0_25; |
2438 Gear^.dY:= AngleCos(trueAngle) * -_0_25; |
2439 end; |
2439 end; |
2440 |
2440 |
2441 Gear^.X:= Gear^.X + Gear^.dX; |
2441 Gear^.X:= Gear^.X + Gear^.dX; |
2442 Gear^.Y:= Gear^.Y + Gear^.dY; |
2442 Gear^.Y:= Gear^.Y + Gear^.dY; |
2443 |
2443 |
2444 if (TrainingFlags and tfRCPlane) = 0 then |
2444 if (TrainingFlags and tfRCPlane) = 0 then |
2445 begin |
2445 begin |
2446 if (GameTicks and $FF) = 0 then |
2446 if (GameTicks and $FF) = 0 then |
2447 if Gear^.Timer < 3500 then |
2447 if Gear^.Timer < 3500 then |
2448 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtEvilTrace, 0, _0, _0, 0) |
2448 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtEvilTrace, 0, _0, _0, 0) |
2449 else |
2449 else |
2450 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0); |
2450 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0); |
2451 |
2451 |
2452 if ((HHGear^.Message and gm_Attack) <> 0) and (Gear^.Health <> 0) then |
2452 if ((HHGear^.Message and gm_Attack) <> 0) and (Gear^.Health <> 0) then |
2453 begin |
2453 begin |
2454 HHGear^.Message := HHGear^.Message and not gm_Attack; |
2454 HHGear^.Message := HHGear^.Message and not gm_Attack; |
2455 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY * _0_5, 0); |
2455 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, Gear^.dX * _0_5, Gear^.dY * _0_5, 0); |
2456 dec(Gear^.Health) |
2456 dec(Gear^.Health) |
2457 end; |
2457 end; |
2458 |
2458 |
2459 if ((HHGear^.Message and gm_LJump) <> 0) |
2459 if ((HHGear^.Message and gm_LJump) <> 0) |
2460 and ((Gear^.State and gsttmpFlag) = 0) then |
2460 and ((Gear^.State and gsttmpFlag) = 0) then |
2461 begin |
2461 begin |
2462 Gear^.State:= Gear^.State or gsttmpFlag; |
2462 Gear^.State:= Gear^.State or gsttmpFlag; |
2463 PauseMusic; |
2463 PauseMusic; |
2464 playSound(sndRideOfTheValkyries); |
2464 playSound(sndRideOfTheValkyries); |
2465 end; |
2465 end; |
2466 |
2466 |
2467 // pickup bonuses |
2467 // pickup bonuses |
2468 t:= CheckGearNear(Gear, gtCase, 36, 36); |
2468 t:= CheckGearNear(Gear, gtCase, 36, 36); |
2469 if t <> nil then |
2469 if t <> nil then |
2470 PickUp(HHGear, t); |
2470 PickUp(HHGear, t); |
2471 end |
2471 end |
2472 else |
2472 else |
2473 begin |
2473 begin |
2474 if (GameTicks and $FF) = 0 then |
2474 if (GameTicks and $FF) = 0 then |
2475 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0); |
2475 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtSmokeTrace, 0, _0, _0, 0); |
2476 |
2476 |
2477 // pickup targets |
2477 // pickup targets |
2478 t:= CheckGearNear(Gear, gtTarget, 36, 36); |
2478 t:= CheckGearNear(Gear, gtTarget, 36, 36); |
2479 if t <> nil then |
2479 if t <> nil then |
2480 begin |
2480 begin |
2481 if t^.Tag <> 0 then // collect it only once |
2481 if t^.Tag <> 0 then // collect it only once |
2482 exit; |
2482 exit; |
2483 PlaySound(sndShotgunReload); |
2483 PlaySound(sndShotgunReload); |
2484 t^.Tag:= 1; |
2484 t^.Tag:= 1; |
2485 TrainingTargetGear:= nil; // remove target cursor |
2485 TrainingTargetGear:= nil; // remove target cursor |
2486 exit; |
2486 exit; |
2487 end; |
2487 end; |
2488 |
2488 |
2489 if (TurnTimeLeft > 0) then |
2489 if (TurnTimeLeft > 0) then |
2490 dec(TurnTimeLeft) |
2490 dec(TurnTimeLeft) |
2491 end; |
2491 end; |
2492 |
2492 |
2493 CheckCollision(Gear); |
2493 CheckCollision(Gear); |
2494 |
2494 |
2495 if ((Gear^.State and gstCollision) <> 0) or (((TrainingFlags and tfRCPlane) <> 0) and (TurnTimeLeft = 0)) |
2495 if ((Gear^.State and gstCollision) <> 0) or (((TrainingFlags and tfRCPlane) <> 0) and (TurnTimeLeft = 0)) |
2496 or CheckGearDrowning(Gear) then |
2496 or CheckGearDrowning(Gear) then |
2497 begin |
2497 begin |
2498 if ((TrainingFlags and tfRCPlane) <> 0) and ((TrainingFlags and tfTimeTrial) <> 0 ) and (TimeTrialStopTime = 0) then TimeTrialStopTime:= RealTicks; |
2498 if ((TrainingFlags and tfRCPlane) <> 0) and ((TrainingFlags and tfTimeTrial) <> 0 ) and (TimeTrialStopTime = 0) then TimeTrialStopTime:= RealTicks; |
2499 StopSound(Gear^.SoundChannel); |
2499 StopSound(Gear^.SoundChannel); |
2500 StopSound(sndRideOfTheValkyries); |
2500 StopSound(sndRideOfTheValkyries); |
2501 ResumeMusic; |
2501 ResumeMusic; |
2502 |
2502 |
2503 if ((Gear^.State and gstCollision) <> 0) or (((TrainingFlags and tfRCPlane) <> 0) and (TurnTimeLeft = 0)) then |
2503 if ((Gear^.State and gstCollision) <> 0) or (((TrainingFlags and tfRCPlane) <> 0) and (TurnTimeLeft = 0)) then |
2504 begin |
2504 begin |
2505 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, EXPLAutoSound); |
2505 doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, EXPLAutoSound); |
2506 for i:= 0 to 32 do |
2506 for i:= 0 to 32 do |
2507 begin |
2507 begin |
2508 dX:= AngleCos(i * 64) * _0_5 * (GetRandom + _1); |
2508 dX:= AngleCos(i * 64) * _0_5 * (GetRandom + _1); |
2509 dY:= AngleSin(i * 64) * _0_5 * (GetRandom + _1); |
2509 dY:= AngleSin(i * 64) * _0_5 * (GetRandom + _1); |
2510 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0); |
2510 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, dY, 0); |
2511 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0); |
2511 AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtFlame, 0, dX, -dY, 0); |
2512 end; |
2512 end; |
2513 DeleteGear(Gear) |
2513 DeleteGear(Gear) |
2514 end; |
2514 end; |
2515 |
2515 |
2516 AfterAttack; |
2516 AfterAttack; |
2517 CurAmmoGear:= nil; |
2517 CurAmmoGear:= nil; |
2518 TurnTimeLeft:= 14 * 125; |
2518 TurnTimeLeft:= 14 * 125; |
2519 |
2519 |
2520 if (TrainingFlags and tfRCPlane) <> 0 then |
2520 if (TrainingFlags and tfRCPlane) <> 0 then |
2521 TurnTimeLeft:= 0; // HACK: RCPlane training allows unlimited plane starts in last 2 seconds |
2521 TurnTimeLeft:= 0; // HACK: RCPlane training allows unlimited plane starts in last 2 seconds |
2522 |
2522 |
2523 HHGear^.Message:= 0; |
2523 HHGear^.Message:= 0; |
2524 ParseCommand('/taunt '#1, true) |
2524 ParseCommand('/taunt '#1, true) |
2525 end |
2525 end |
2526 end; |
2526 end; |
2527 |
2527 |
2528 procedure doStepRCPlane(Gear: PGear); |
2528 procedure doStepRCPlane(Gear: PGear); |
2529 var HHGear: PGear; |
2529 var HHGear: PGear; |
2530 begin |
2530 begin |