153 x:= hwRound(Gear^.X); |
153 x:= hwRound(Gear^.X); |
154 if Dir < 0 then |
154 if Dir < 0 then |
155 x:= x - Gear^.Radius |
155 x:= x - Gear^.Radius |
156 else |
156 else |
157 x:= x + Gear^.Radius; |
157 x:= x + Gear^.Radius; |
|
158 |
|
159 TestCollisionXwithGear:= true; |
158 if (x and LAND_WIDTH_MASK) = 0 then |
160 if (x and LAND_WIDTH_MASK) = 0 then |
159 begin |
161 begin |
160 y:= hwRound(Gear^.Y) - Gear^.Radius + 1; |
162 y:= hwRound(Gear^.Y) - Gear^.Radius + 1; |
161 i:= y + Gear^.Radius * 2 - 2; |
163 i:= y + Gear^.Radius * 2 - 2; |
162 repeat |
164 repeat |
163 if (y and LAND_HEIGHT_MASK) = 0 then |
165 if (y and LAND_HEIGHT_MASK) = 0 then |
164 if Land[y, x] > TestWord then |
166 if Land[y, x] > TestWord then |
165 exit(true); |
167 exit; |
166 inc(y) |
168 inc(y) |
167 until (y > i); |
169 until (y > i); |
168 end; |
170 end; |
169 TestCollisionXwithGear:= false |
171 TestCollisionXwithGear:= false |
170 end; |
172 end; |
196 x:= hwRound(Gear^.X) - Gear^.Radius + 1; |
198 x:= hwRound(Gear^.X) - Gear^.Radius + 1; |
197 i:= x + Gear^.Radius * 2 - 2; |
199 i:= x + Gear^.Radius * 2 - 2; |
198 repeat |
200 repeat |
199 if (x and LAND_WIDTH_MASK) = 0 then |
201 if (x and LAND_WIDTH_MASK) = 0 then |
200 if Land[y, x] > TestWord then |
202 if Land[y, x] > TestWord then |
201 exit(Land[y, x]); |
203 begin |
|
204 TestCollisionYwithGear:= Land[y, x]; |
|
205 exit; |
|
206 end; |
202 inc(x) |
207 inc(x) |
203 until (x > i); |
208 until (x > i); |
204 end; |
209 end; |
205 TestCollisionYwithGear:= 0 |
210 TestCollisionYwithGear:= 0 |
206 end; |
211 end; |
213 x:= hwRound(Gear^.X); |
218 x:= hwRound(Gear^.X); |
214 if Dir < 0 then |
219 if Dir < 0 then |
215 x:= x - Gear^.Radius |
220 x:= x - Gear^.Radius |
216 else |
221 else |
217 x:= x + Gear^.Radius; |
222 x:= x + Gear^.Radius; |
|
223 |
|
224 TestCollisionXKick:= true; |
218 if (x and LAND_WIDTH_MASK) = 0 then |
225 if (x and LAND_WIDTH_MASK) = 0 then |
219 begin |
226 begin |
220 y:= hwRound(Gear^.Y) - Gear^.Radius + 1; |
227 y:= hwRound(Gear^.Y) - Gear^.Radius + 1; |
221 i:= y + Gear^.Radius * 2 - 2; |
228 i:= y + Gear^.Radius * 2 - 2; |
222 repeat |
229 repeat |
223 if (y and LAND_HEIGHT_MASK) = 0 then |
230 if (y and LAND_HEIGHT_MASK) = 0 then |
224 if Land[y, x] > 255 then |
231 if Land[y, x] > 255 then |
225 exit(true) |
232 exit |
226 else if Land[y, x] <> 0 then |
233 else if Land[y, x] <> 0 then |
227 flag:= true; |
234 flag:= true; |
228 inc(y) |
235 inc(y) |
229 until (y > i); |
236 until (y > i); |
230 end; |
237 end; |
270 y:= hwRound(Gear^.Y); |
278 y:= hwRound(Gear^.Y); |
271 if Dir < 0 then |
279 if Dir < 0 then |
272 y:= y - Gear^.Radius |
280 y:= y - Gear^.Radius |
273 else |
281 else |
274 y:= y + Gear^.Radius; |
282 y:= y + Gear^.Radius; |
|
283 |
|
284 TestCollisionYKick:= true; |
275 if (y and LAND_HEIGHT_MASK) = 0 then |
285 if (y and LAND_HEIGHT_MASK) = 0 then |
276 begin |
286 begin |
277 x:= hwRound(Gear^.X) - Gear^.Radius + 1; |
287 x:= hwRound(Gear^.X) - Gear^.Radius + 1; |
278 i:= x + Gear^.Radius * 2 - 2; |
288 i:= x + Gear^.Radius * 2 - 2; |
279 repeat |
289 repeat |
280 if (x and LAND_WIDTH_MASK) = 0 then |
290 if (x and LAND_WIDTH_MASK) = 0 then |
281 if Land[y, x] > 0 then |
291 if Land[y, x] > 0 then |
282 if Land[y, x] > 255 then |
292 if Land[y, x] > 255 then |
283 exit(true) |
293 exit |
284 else if Land[y, x] <> 0 then |
294 else if Land[y, x] <> 0 then |
285 flag:= true; |
295 flag:= true; |
286 inc(x) |
296 inc(x) |
287 until (x > i); |
297 until (x > i); |
288 end; |
298 end; |
289 TestCollisionYKick:= flag; |
299 TestCollisionYKick:= flag; |
290 |
300 |
291 if flag then |
301 if flag then |
292 begin |
302 begin |
293 if hwAbs(Gear^.dY) < cHHKick then |
303 if hwAbs(Gear^.dY) < cHHKick then |
294 exit(true); |
304 exit; |
295 if (Gear^.State and gstHHJumping <> 0) |
305 if (Gear^.State and gstHHJumping <> 0) and (not Gear^.dY.isNegative) and (Gear^.dY < _0_4) then |
296 and (not Gear^.dY.isNegative) |
|
297 and (Gear^.dY < _0_4) then |
|
298 exit; |
306 exit; |
299 |
307 |
300 mx:= hwRound(Gear^.X); |
308 mx:= hwRound(Gear^.X); |
301 my:= hwRound(Gear^.Y); |
309 my:= hwRound(Gear^.Y); |
302 |
310 |
333 TestCollisionXwithXYShift:= TestCollisionXwithGear(Gear, Dir) |
342 TestCollisionXwithXYShift:= TestCollisionXwithGear(Gear, Dir) |
334 else TestCollisionXwithXYShift:= TestCollisionX(Gear, Dir); |
343 else TestCollisionXwithXYShift:= TestCollisionX(Gear, Dir); |
335 Gear^.X:= Gear^.X - ShiftX; |
344 Gear^.X:= Gear^.X - ShiftX; |
336 Gear^.Y:= Gear^.Y - int2hwFloat(ShiftY) |
345 Gear^.Y:= Gear^.Y - int2hwFloat(ShiftY) |
337 end; |
346 end; |
|
347 |
338 function TestCollisionX(Gear: PGear; Dir: LongInt): boolean; |
348 function TestCollisionX(Gear: PGear; Dir: LongInt): boolean; |
339 var x, y, i: LongInt; |
349 var x, y, i: LongInt; |
340 begin |
350 begin |
341 x:= hwRound(Gear^.X); |
351 x:= hwRound(Gear^.X); |
342 if Dir < 0 then |
352 if Dir < 0 then |
343 x:= x - Gear^.Radius |
353 x:= x - Gear^.Radius |
344 else |
354 else |
345 x:= x + Gear^.Radius; |
355 x:= x + Gear^.Radius; |
|
356 |
|
357 TestCollisionX:= true; |
346 if (x and LAND_WIDTH_MASK) = 0 then |
358 if (x and LAND_WIDTH_MASK) = 0 then |
347 begin |
359 begin |
348 y:= hwRound(Gear^.Y) - Gear^.Radius + 1; |
360 y:= hwRound(Gear^.Y) - Gear^.Radius + 1; |
349 i:= y + Gear^.Radius * 2 - 2; |
361 i:= y + Gear^.Radius * 2 - 2; |
350 repeat |
362 repeat |
351 if (y and LAND_HEIGHT_MASK) = 0 then |
363 if (y and LAND_HEIGHT_MASK) = 0 then |
352 if Land[y, x] > 255 then |
364 if Land[y, x] > 255 then |
353 exit(true); |
365 exit; |
354 inc(y) |
366 inc(y) |
355 until (y > i); |
367 until (y > i); |
356 end; |
368 end; |
357 TestCollisionX:= false |
369 TestCollisionX:= false |
358 end; |
370 end; |
363 y:= hwRound(Gear^.Y); |
375 y:= hwRound(Gear^.Y); |
364 if Dir < 0 then |
376 if Dir < 0 then |
365 y:= y - Gear^.Radius |
377 y:= y - Gear^.Radius |
366 else |
378 else |
367 y:= y + Gear^.Radius; |
379 y:= y + Gear^.Radius; |
|
380 |
|
381 TestCollisionY:= true; |
368 if (y and LAND_HEIGHT_MASK) = 0 then |
382 if (y and LAND_HEIGHT_MASK) = 0 then |
369 begin |
383 begin |
370 x:= hwRound(Gear^.X) - Gear^.Radius + 1; |
384 x:= hwRound(Gear^.X) - Gear^.Radius + 1; |
371 i:= x + Gear^.Radius * 2 - 2; |
385 i:= x + Gear^.Radius * 2 - 2; |
372 repeat |
386 repeat |
373 if (x and LAND_WIDTH_MASK) = 0 then |
387 if (x and LAND_WIDTH_MASK) = 0 then |
374 if Land[y, x] > 255 then |
388 if Land[y, x] > 255 then |
375 exit(true); |
389 exit; |
376 inc(x) |
390 inc(x) |
377 until (x > i); |
391 until (x > i); |
378 end; |
392 end; |
379 TestCollisionY:= false |
393 TestCollisionY:= false |
380 end; |
394 end; |
400 |
414 |
401 function TestRectancleForObstacle(x1, y1, x2, y2: LongInt; landOnly: boolean): boolean; |
415 function TestRectancleForObstacle(x1, y1, x2, y2: LongInt; landOnly: boolean): boolean; |
402 var x, y: LongInt; |
416 var x, y: LongInt; |
403 TestWord: LongWord; |
417 TestWord: LongWord; |
404 begin |
418 begin |
|
419 TestRectancleForObstacle:= true; |
|
420 |
405 if landOnly then |
421 if landOnly then |
406 TestWord:= 255 |
422 TestWord:= 255 |
407 else |
423 else |
408 TestWord:= 0; |
424 TestWord:= 0; |
409 |
425 |
410 if x1 > x2 then |
426 if x1 > x2 then |
411 begin |
427 begin |
412 x := x1; |
428 x := x1; |
413 x1 := x2; |
429 x1 := x2; |
414 x2 := x; |
430 x2 := x; |
415 end; |
431 end; |
416 |
432 |
417 if y1 > y2 then |
433 if y1 > y2 then |
418 begin |
434 begin |
419 y := y1; |
435 y := y1; |
420 y1 := y2; |
436 y1 := y2; |
421 y2 := y; |
437 y2 := y; |
422 end; |
438 end; |
423 |
439 |
424 if (hasBorder and ((y1 < 0) or (x1 < 0) or (x2 > LAND_WIDTH))) then |
440 if (hasBorder and ((y1 < 0) or (x1 < 0) or (x2 > LAND_WIDTH))) then |
425 exit(true); |
441 exit; |
426 |
442 |
427 for y := y1 to y2 do |
443 for y := y1 to y2 do |
428 for x := x1 to x2 do |
444 for x := x1 to x2 do |
429 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) |
445 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > TestWord) then |
430 and (Land[y, x] > TestWord) then |
446 exit; |
431 exit(true); |
|
432 |
447 |
433 TestRectancleForObstacle:= false |
448 TestRectancleForObstacle:= false |
434 end; |
449 end; |
435 |
450 |
436 function CalcSlopeTangent(Gear: PGear; collisionX, collisionY: LongInt; var outDeltaX, outDeltaY: LongInt; TestWord: LongWord): boolean; |
451 function CalcSlopeTangent(Gear: PGear; collisionX, collisionY: LongInt; var outDeltaX, outDeltaY: LongInt; TestWord: LongWord): boolean; |
564 |
581 |
565 ldx:= rdx - ldx; |
582 ldx:= rdx - ldx; |
566 ldy:= rdy - ldy; |
583 ldy:= rdy - ldy; |
567 |
584 |
568 if ((ldx = 0) and (ldy = 0)) then |
585 if ((ldx = 0) and (ldy = 0)) then |
569 EXIT(false); |
586 exit; |
570 |
587 |
571 outDeltaX:= ldx; |
588 outDeltaX:= ldx; |
572 outDeltaY:= ldy; |
589 outDeltaY:= ldy; |
573 exit(true); |
590 CalcSlopeTangent:= true; |
574 end; |
591 end; |
575 |
592 |
576 function CalcSlopeBelowGear(Gear: PGear): hwFloat; |
593 function CalcSlopeBelowGear(Gear: PGear): hwFloat; |
577 var dx, dy: hwFloat; |
594 var dx, dy: hwFloat; |
578 collX, i, y, x, gx, sdx, sdy: LongInt; |
595 collX, i, y, x, gx, sdx, sdy: LongInt; |