214 // Wrapper to test various approaches. If it works reasonably, will just replace. |
214 // Wrapper to test various approaches. If it works reasonably, will just replace. |
215 // Right now, converting to hwFloat is a tad inefficient since the x/y were hwFloat to begin with... |
215 // Right now, converting to hwFloat is a tad inefficient since the x/y were hwFloat to begin with... |
216 function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline; |
216 function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline; |
217 var MeX, MeY: LongInt; |
217 var MeX, MeY: LongInt; |
218 begin |
218 begin |
|
219 TestCollExcludingMe:= false; |
219 if ((x and LAND_WIDTH_MASK) = 0) and ((y and LAND_HEIGHT_MASK) = 0) then |
220 if ((x and LAND_WIDTH_MASK) = 0) and ((y and LAND_HEIGHT_MASK) = 0) then |
220 begin |
221 begin |
221 MeX:= hwRound(Me^.X); |
222 MeX:= hwRound(Me^.X); |
222 MeY:= hwRound(Me^.Y); |
223 MeY:= hwRound(Me^.Y); |
223 // We are still inside the hog. Skip radius test |
224 // We are still inside the hog. Skip radius test |
224 if ((((x-MeX)*(x-MeX)) + ((y-MeY)*(y-MeY))) < 256) and ((Land[y, x] and $FF00) = 0) then |
225 if ((((x-MeX)*(x-MeX)) + ((y-MeY)*(y-MeY))) < 256) and ((Land[y, x] and $FF00) = 0) then |
225 exit(false); |
226 exit; |
226 end; |
227 end; |
227 exit(TestColl(x, y, r)) |
228 TestCollExcludingMe:= TestColl(x, y, r) |
228 end; |
229 end; |
229 |
230 |
230 function TestColl(x, y, r: LongInt): boolean; inline; |
231 function TestColl(x, y, r: LongInt): boolean; inline; |
231 var b: boolean; |
232 var b: boolean; |
232 begin |
233 begin |
233 b:= (((x-r) and LAND_WIDTH_MASK) = 0)and(((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] <> 0); |
234 TestColl:= true; |
234 if b then |
235 |
235 exit(true); |
236 b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] <> 0); |
|
237 if b then |
|
238 exit; |
236 |
239 |
237 b:=(((x-r) and LAND_WIDTH_MASK) = 0)and(((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] <> 0); |
240 b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] <> 0); |
238 if b then |
241 if b then |
239 exit(true); |
242 exit; |
240 |
243 |
241 b:=(((x+r) and LAND_WIDTH_MASK) = 0)and(((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] <> 0); |
244 b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] <> 0); |
242 if b then |
245 if b then |
243 exit(true); |
246 exit; |
244 |
247 |
245 TestColl:=(((x+r) and LAND_WIDTH_MASK) = 0)and(((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] <> 0) |
248 b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] <> 0); |
|
249 if b then |
|
250 exit; |
|
251 |
|
252 TestColl:= false; |
246 end; |
253 end; |
247 |
254 |
248 function TestCollWithLand(x, y, r: LongInt): boolean; inline; |
255 function TestCollWithLand(x, y, r: LongInt): boolean; inline; |
249 var b: boolean; |
256 var b: boolean; |
250 begin |
257 begin |
251 b:= (((x-r) and LAND_WIDTH_MASK) = 0)and(((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] > 255); |
258 TestCollWithLand:= true; |
252 if b then |
|
253 exit(true); |
|
254 |
259 |
255 b:=(((x-r) and LAND_WIDTH_MASK) = 0)and(((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] > 255); |
260 b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] > 255); |
256 if b then |
261 if b then |
257 exit(true); |
262 exit; |
258 |
263 |
259 b:=(((x+r) and LAND_WIDTH_MASK) = 0)and(((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] > 255); |
264 b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] > 255); |
260 if b then |
265 if b then |
261 exit(true); |
266 exit; |
262 |
267 |
263 TestCollWithLand:=(((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] > 255) |
268 b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] > 255); |
|
269 if b then |
|
270 exit; |
|
271 |
|
272 b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] > 255); |
|
273 if b then |
|
274 exit; |
|
275 |
|
276 TestCollWithLand:= false; |
264 end; |
277 end; |
265 |
278 |
266 function TraceFall(eX, eY: LongInt; x, y, dX, dY: Real; r: LongWord): LongInt; |
279 function TraceFall(eX, eY: LongInt; x, y, dX, dY: Real; r: LongWord): LongInt; |
267 var skipLandCheck: boolean; |
280 var skipLandCheck: boolean; |
268 rCorner: real; |
281 rCorner: real; |
272 if x - eX < 0 then dX:= -dX; |
285 if x - eX < 0 then dX:= -dX; |
273 if y - eY < 0 then dY:= -dY; |
286 if y - eY < 0 then dY:= -dY; |
274 // ok. attempt approximate search for an unbroken trajectory into water. if it continues far enough, assume out of map |
287 // ok. attempt approximate search for an unbroken trajectory into water. if it continues far enough, assume out of map |
275 rCorner:= r * 0.75; |
288 rCorner:= r * 0.75; |
276 while true do |
289 while true do |
277 begin |
290 begin |
278 x:= x + dX; |
291 x:= x + dX; |
279 y:= y + dY; |
292 y:= y + dY; |
280 dY:= dY + cGravityf; |
293 dY:= dY + cGravityf; |
281 skipLandCheck:= skipLandCheck and (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner)); |
294 skipLandCheck:= skipLandCheck and (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner)); |
282 if not skipLandCheck and TestCollWithLand(trunc(x), trunc(y), cHHRadius) then |
295 if not skipLandCheck and TestCollWithLand(trunc(x), trunc(y), cHHRadius) then |
283 begin |
296 begin |
284 if 0.4 < dY then |
297 if 0.4 < dY then |
|
298 begin |
|
299 dmg := 1 + trunc((abs(dY) - 0.4) * 70); |
|
300 if dmg >= 1 then |
285 begin |
301 begin |
286 dmg := 1 + trunc((abs(dY) - 0.4) * 70); |
302 TraceFall:= dmg; |
287 if dmg >= 1 then exit(dmg) |
303 exit |
288 end; |
304 end; |
289 exit(0) |
305 end; |
290 end; |
306 TraceFall:= 0; |
291 if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(-1); // returning -1 for drowning so it can be considered in the Rate routine |
307 exit |
292 end; |
308 end; |
|
309 if (y > cWaterLine) or (x > 4096) or (x < 0) then |
|
310 begin |
|
311 // returning -1 for drowning so it can be considered in the Rate routine |
|
312 TraceFall:= -1; |
|
313 exit; |
|
314 end; |
|
315 end; |
293 end; |
316 end; |
294 |
317 |
295 function TraceShoveFall(Me: PGear; x, y, dX, dY: Real): LongInt; |
318 function TraceShoveFall(Me: PGear; x, y, dX, dY: Real): LongInt; |
296 var dmg: LongInt; |
319 var dmg: LongInt; |
297 begin |
320 begin |
298 while true do |
321 while true do |
299 begin |
322 begin |
300 x:= x + dX; |
323 x:= x + dX; |
301 y:= y + dY; |
324 y:= y + dY; |
302 dY:= dY + cGravityf; |
325 dY:= dY + cGravityf; |
303 // consider adding dX/dY calc here for fall damage |
326 // consider adding dX/dY calc here for fall damage |
304 if TestCollExcludingMe(Me, trunc(x), trunc(y), cHHRadius) then |
327 if TestCollExcludingMe(Me, trunc(x), trunc(y), cHHRadius) then |
305 begin |
328 begin |
306 if 0.4 < dY then |
329 if 0.4 < dY then |
|
330 begin |
|
331 dmg := 1 + trunc((abs(dY) - 0.4) * 70); |
|
332 if dmg >= 1 then |
307 begin |
333 begin |
308 dmg := 1 + trunc((abs(dY) - 0.4) * 70); |
334 TraceShoveFall:= dmg; |
309 if dmg >= 1 then exit(dmg) |
335 exit |
310 end; |
336 end; |
311 exit(0) |
337 end; |
312 end; |
338 TraceShoveFall:= 0; |
313 if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(-1); // returning -1 for drowning so it can be considered in the Rate routine |
339 exit |
314 end; |
340 end; |
|
341 if (y > cWaterLine) or (x > 4096) or (x < 0) then |
|
342 begin |
|
343 // returning -1 for drowning so it can be considered in the Rate routine |
|
344 TraceShoveFall:= -1; |
|
345 exit; |
|
346 end; |
|
347 end; |
315 end; |
348 end; |
316 |
349 |
317 // Flags are not defined yet but 1 for checking drowning and 2 for assuming land erasure. |
350 // Flags are not defined yet but 1 for checking drowning and 2 for assuming land erasure. |
318 function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; |
351 function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; |
319 begin |
352 begin |
493 RateHammer:= rate * 1024; |
526 RateHammer:= rate * 1024; |
494 end; |
527 end; |
495 |
528 |
496 function HHJump(Gear: PGear; JumpType: TJumpType; var GoInfo: TGoInfo): boolean; |
529 function HHJump(Gear: PGear; JumpType: TJumpType; var GoInfo: TGoInfo): boolean; |
497 var bX, bY: LongInt; |
530 var bX, bY: LongInt; |
498 bRes: boolean; |
531 begin |
499 begin |
532 HHJump:= false; |
500 bRes:= false; |
|
501 GoInfo.Ticks:= 0; |
533 GoInfo.Ticks:= 0; |
502 GoInfo.JumpType:= jmpNone; |
534 GoInfo.JumpType:= jmpNone; |
503 bX:= hwRound(Gear^.X); |
535 bX:= hwRound(Gear^.X); |
504 bY:= hwRound(Gear^.Y); |
536 bY:= hwRound(Gear^.Y); |
505 case JumpType of |
537 case JumpType of |
506 jmpNone: |
538 jmpNone: exit; |
507 exit(bRes); |
|
508 |
539 |
509 jmpHJump: |
540 jmpHJump: |
510 if TestCollisionYwithGear(Gear, -1) = 0 then |
541 if TestCollisionYwithGear(Gear, -1) = 0 then |
511 begin |
542 begin |
512 Gear^.dY:= -_0_2; |
543 Gear^.dY:= -_0_2; |
513 SetLittle(Gear^.dX); |
544 SetLittle(Gear^.dX); |
514 Gear^.State:= Gear^.State or gstMoving or gstHHJumping; |
545 Gear^.State:= Gear^.State or gstMoving or gstHHJumping; |
515 end |
546 end |
516 else |
547 else |
517 exit(bRes); |
548 exit; |
518 |
549 |
519 jmpLJump: |
550 jmpLJump: |
520 begin |
551 begin |
521 if TestCollisionYwithGear(Gear, -1) <> 0 then |
552 if TestCollisionYwithGear(Gear, -1) <> 0 then |
522 if not TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) then |
553 if not TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) then |
523 Gear^.Y:= Gear^.Y - int2hwFloat(2) |
554 Gear^.Y:= Gear^.Y - int2hwFloat(2) |
524 else |
555 else |
525 if not TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) then |
556 if not TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) then |
526 Gear^.Y:= Gear^.Y - _1; |
557 Gear^.Y:= Gear^.Y - _1; |
527 if not (TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) |
558 if not (TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) or |
528 or (TestCollisionYwithGear(Gear, -1) <> 0)) then |
559 (TestCollisionYwithGear(Gear, -1) <> 0)) then |
529 begin |
560 begin |
530 Gear^.dY:= -_0_15; |
561 Gear^.dY:= -_0_15; |
531 Gear^.dX:= SignAs(_0_15, Gear^.dX); |
562 Gear^.dX:= SignAs(_0_15, Gear^.dX); |
532 Gear^.State:= Gear^.State or gstMoving or gstHHJumping |
563 Gear^.State:= Gear^.State or gstMoving or gstHHJumping |
533 end |
564 end |
534 else |
565 else |
535 exit(bRes) |
566 exit |
536 end |
567 end |
537 end; |
568 end; |
538 |
569 |
539 repeat |
570 repeat |
540 if not (hwRound(Gear^.Y) + cHHRadius < cWaterLine) then |
571 if not (hwRound(Gear^.Y) + cHHRadius < cWaterLine) then |
541 exit(bRes); |
572 exit; |
542 if (Gear^.State and gstMoving) <> 0 then |
573 if (Gear^.State and gstMoving) <> 0 then |
543 begin |
574 begin |
544 if (GoInfo.Ticks = 350) then |
575 if (GoInfo.Ticks = 350) then |
545 if (not (hwAbs(Gear^.dX) > cLittle)) and (Gear^.dY < -_0_02) then |
576 if (not (hwAbs(Gear^.dX) > cLittle)) and (Gear^.dY < -_0_02) then |
546 begin |
577 begin |
547 Gear^.dY:= -_0_25; |
578 Gear^.dY:= -_0_25; |
548 Gear^.dX:= SignAs(_0_02, Gear^.dX) |
579 Gear^.dX:= SignAs(_0_02, Gear^.dX) |
549 end; |
580 end; |
550 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then SetLittle(Gear^.dX); |
581 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then SetLittle(Gear^.dX); |
551 Gear^.X:= Gear^.X + Gear^.dX; |
582 Gear^.X:= Gear^.X + Gear^.dX; |
552 inc(GoInfo.Ticks); |
583 inc(GoInfo.Ticks); |
553 Gear^.dY:= Gear^.dY + cGravity; |
584 Gear^.dY:= Gear^.dY + cGravity; |
554 if Gear^.dY > _0_4 then |
585 if Gear^.dY > _0_4 then |
555 exit(bRes); |
586 exit; |
556 if (Gear^.dY.isNegative)and (TestCollisionYwithGear(Gear, -1) <> 0) then |
587 if (Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, -1) <> 0) then |
557 Gear^.dY:= _0; |
588 Gear^.dY:= _0; |
558 Gear^.Y:= Gear^.Y + Gear^.dY; |
589 Gear^.Y:= Gear^.Y + Gear^.dY; |
559 if (not Gear^.dY.isNegative)and (TestCollisionYwithGear(Gear, 1) <> 0) then |
590 if (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) <> 0) then |
560 begin |
591 begin |
561 Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); |
592 Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); |
562 Gear^.dY:= _0; |
593 Gear^.dY:= _0; |
563 case JumpType of |
594 case JumpType of |
564 jmpHJump: |
595 jmpHJump: |
565 if bY - hwRound(Gear^.Y) > 5 then |
596 if bY - hwRound(Gear^.Y) > 5 then |
566 begin |
597 begin |
567 bRes:= true; |
598 HHJump:= true; |
568 GoInfo.JumpType:= jmpHJump; |
599 GoInfo.JumpType:= jmpHJump; |
569 inc(GoInfo.Ticks, 300 + 300) // 300 before jump, 300 after |
600 inc(GoInfo.Ticks, 300 + 300) // 300 before jump, 300 after |
570 end; |
601 end; |
571 jmpLJump: if abs(bX - hwRound(Gear^.X)) > 30 then |
602 jmpLJump: |
572 begin |
603 if abs(bX - hwRound(Gear^.X)) > 30 then |
573 bRes:= true; |
604 begin |
574 GoInfo.JumpType:= jmpLJump; |
605 HHJump:= true; |
575 inc(GoInfo.Ticks, 300 + 300) // 300 before jump, 300 after |
606 GoInfo.JumpType:= jmpLJump; |
576 end |
607 inc(GoInfo.Ticks, 300 + 300) // 300 before jump, 300 after |
577 end; |
608 end |
578 exit(bRes) |
609 end; |
579 end; |
610 exit |
580 end; |
611 end; |
|
612 end; |
581 until false |
613 until false |
582 end; |
614 end; |
583 |
615 |
584 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; |
616 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; |
585 var pX, pY: LongInt; |
617 var pX, pY: LongInt; |
586 begin |
618 begin |
|
619 HHGo:= false; |
587 AltGear^:= Gear^; |
620 AltGear^:= Gear^; |
588 |
621 |
589 GoInfo.Ticks:= 0; |
622 GoInfo.Ticks:= 0; |
590 GoInfo.FallPix:= 0; |
623 GoInfo.FallPix:= 0; |
591 GoInfo.JumpType:= jmpNone; |
624 GoInfo.JumpType:= jmpNone; |
592 repeat |
625 repeat |
593 pX:= hwRound(Gear^.X); |
626 pX:= hwRound(Gear^.X); |
594 pY:= hwRound(Gear^.Y); |
627 pY:= hwRound(Gear^.Y); |
595 if pY + cHHRadius >= cWaterLine then |
628 if pY + cHHRadius >= cWaterLine then |
596 exit(false); |
629 exit; |
597 if (Gear^.State and gstMoving) <> 0 then |
630 if (Gear^.State and gstMoving) <> 0 then |
598 begin |
631 begin |
599 inc(GoInfo.Ticks); |
632 inc(GoInfo.Ticks); |
600 Gear^.dY:= Gear^.dY + cGravity; |
633 Gear^.dY:= Gear^.dY + cGravity; |
601 if Gear^.dY > _0_4 then |
634 if Gear^.dY > _0_4 then |
602 begin |
635 begin |
603 Goinfo.FallPix:= 0; |
636 Goinfo.FallPix:= 0; |
604 HHJump(AltGear, jmpLJump, GoInfo); // try ljump instead of fall with damage |
637 HHJump(AltGear, jmpLJump, GoInfo); // try ljump instead of fall with damage |
605 exit(false) |
638 exit |
606 end; |
639 end; |
607 Gear^.Y:= Gear^.Y + Gear^.dY; |
640 Gear^.Y:= Gear^.Y + Gear^.dY; |
608 if hwRound(Gear^.Y) > pY then |
641 if hwRound(Gear^.Y) > pY then |
609 inc(GoInfo.FallPix); |
642 inc(GoInfo.FallPix); |
610 if TestCollisionYwithGear(Gear, 1) <> 0 then |
643 if TestCollisionYwithGear(Gear, 1) <> 0 then |
611 begin |
644 begin |
612 inc(GoInfo.Ticks, 410); |
645 inc(GoInfo.Ticks, 410); |
613 Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); |
646 Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); |
614 Gear^.dY:= _0; |
647 Gear^.dY:= _0; |
615 HHJump(AltGear, jmpLJump, GoInfo); // try ljump instead of fall |
648 HHJump(AltGear, jmpLJump, GoInfo); // try ljump instead of fall |
616 exit(true) |
649 HHGo:= true; |
|
650 exit |
617 end; |
651 end; |
618 continue |
652 continue |
619 end; |
653 end; |
620 if (Gear^.Message and gmLeft )<>0 then |
654 if (Gear^.Message and gmLeft )<>0 then |
621 Gear^.dX:= -cLittle |
655 Gear^.dX:= -cLittle |
622 else |
656 else |
623 if (Gear^.Message and gmRight )<>0 then |
657 if (Gear^.Message and gmRight )<>0 then |
624 Gear^.dX:= cLittle |
658 Gear^.dX:= cLittle |
625 else |
659 else |
626 exit(false); |
660 exit; |
627 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then |
661 if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then |
628 begin |
662 begin |
629 if not (TestCollisionXwithXYShift(Gear, _0, -6, hwSign(Gear^.dX)) |
663 if not (TestCollisionXwithXYShift(Gear, _0, -6, hwSign(Gear^.dX)) |
630 or (TestCollisionYwithGear(Gear, -1) <> 0)) then |
664 or (TestCollisionYwithGear(Gear, -1) <> 0)) then |
631 Gear^.Y:= Gear^.Y - _1; |
665 Gear^.Y:= Gear^.Y - _1; |