108 HHGear: PGear; |
108 HHGear: PGear; |
109 len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat; |
109 len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat; |
110 lx, ly, cd: LongInt; |
110 lx, ly, cd: LongInt; |
111 haveCollision, |
111 haveCollision, |
112 haveDivided: boolean; |
112 haveDivided: boolean; |
113 |
113 wrongSide: boolean; |
114 begin |
114 begin |
115 if GameTicks mod 4 <> 0 then exit; |
115 if GameTicks mod 4 <> 0 then exit; |
116 |
116 |
117 HHGear := Gear^.Hedgehog^.Gear; |
117 HHGear := Gear^.Hedgehog^.Gear; |
118 |
118 |
214 X := Gear^.X; |
214 X := Gear^.X; |
215 Y := Gear^.Y; |
215 Y := Gear^.Y; |
216 if RopePoints.Count = 0 then |
216 if RopePoints.Count = 0 then |
217 RopePoints.HookAngle := DxDy2Angle(Gear^.dY, Gear^.dX); |
217 RopePoints.HookAngle := DxDy2Angle(Gear^.dY, Gear^.dX); |
218 b := (nx * HHGear^.dY) > (ny * HHGear^.dX); |
218 b := (nx * HHGear^.dY) > (ny * HHGear^.dX); |
|
219 sx:= Gear^.dX.isNegative; |
|
220 sy:= Gear^.dY.isNegative; |
|
221 sb:= Gear^.dX.QWordValue < Gear^.dY.QWordValue; |
219 dLen := len |
222 dLen := len |
220 end; |
223 end; |
221 |
224 |
222 with RopePoints.rounded[RopePoints.Count] do |
225 with RopePoints.rounded[RopePoints.Count] do |
223 begin |
226 begin |
246 begin |
249 begin |
247 tx := RopePoints.ar[Pred(RopePoints.Count)].X; |
250 tx := RopePoints.ar[Pred(RopePoints.Count)].X; |
248 ty := RopePoints.ar[Pred(RopePoints.Count)].Y; |
251 ty := RopePoints.ar[Pred(RopePoints.Count)].Y; |
249 mdX := tx - Gear^.X; |
252 mdX := tx - Gear^.X; |
250 mdY := ty - Gear^.Y; |
253 mdY := ty - Gear^.Y; |
251 if RopePoints.ar[Pred(RopePoints.Count)].b xor (mdX * (ty - HHGear^.Y) > (tx - HHGear^.X) * mdY) then |
254 ropeDx:= tx - HHGear^.X; |
|
255 ropeDy:= ty - HHGear^.Y; |
|
256 if RopePoints.ar[Pred(RopePoints.Count)].b xor (mdX * ropeDy > ropeDx * mdY) then |
252 begin |
257 begin |
253 dec(RopePoints.Count); |
258 dec(RopePoints.Count); |
254 Gear^.X := RopePoints.ar[RopePoints.Count].X; |
259 Gear^.X := tx; |
255 Gear^.Y := RopePoints.ar[RopePoints.Count].Y; |
260 Gear^.Y := ty; |
256 Gear^.Elasticity := Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen; |
261 |
257 Gear^.Friction := Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen; |
262 // oops, opposite quadrant, don't restore hog position in such case, just remove the point |
258 |
263 wrongSide:= (ropeDx.isNegative = RopePoints.ar[RopePoints.Count].sx) |
259 // restore hog position |
264 and (ropeDy.isNegative = RopePoints.ar[RopePoints.Count].sy); |
260 len := _1 / Distance(mdX, mdY); |
265 |
261 mdX := mdX * len; |
266 // previous check could be inaccurate in vertical/horizontal rope positions, |
262 mdY := mdY * len; |
267 // so perform this check also, even though odds are 1 to 415927 to hit this |
263 |
268 if (not wrongSide) |
264 HHGear^.X := Gear^.X - mdX * Gear^.Elasticity; |
269 and ((ropeDx.isNegative = RopePoints.ar[RopePoints.Count].sx) |
265 HHGear^.Y := Gear^.Y - mdY * Gear^.Elasticity; |
270 <> (ropeDy.isNegative = RopePoints.ar[RopePoints.Count].sy)) then |
|
271 if RopePoints.ar[RopePoints.Count].sb then |
|
272 wrongSide:= ropeDy.isNegative = RopePoints.ar[RopePoints.Count].sy |
|
273 else |
|
274 wrongSide:= ropeDx.isNegative = RopePoints.ar[RopePoints.Count].sx; |
|
275 |
|
276 if wrongSide then |
|
277 begin |
|
278 Gear^.Elasticity := Gear^.Elasticity - RopePoints.ar[RopePoints.Count].dLen; |
|
279 Gear^.Friction := Gear^.Friction - RopePoints.ar[RopePoints.Count].dLen; |
|
280 end else |
|
281 begin |
|
282 Gear^.Elasticity := Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen; |
|
283 Gear^.Friction := Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen; |
|
284 |
|
285 // restore hog position |
|
286 len := _1 / Distance(mdX, mdY); |
|
287 mdX := mdX * len; |
|
288 mdY := mdY * len; |
|
289 |
|
290 HHGear^.X := Gear^.X - mdX * Gear^.Elasticity; |
|
291 HHGear^.Y := Gear^.Y - mdY * Gear^.Elasticity; |
|
292 end; |
266 end |
293 end |
267 end; |
294 end; |
268 |
295 |
269 haveCollision := false; |
296 haveCollision := false; |
270 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then |
297 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then |