23 uses uTypes, uFloat; |
23 uses uTypes, uFloat; |
24 |
24 |
25 procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword); inline; |
25 procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword); inline; |
26 procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord); |
26 procedure doMakeExplosion(X, Y, Radius: LongInt; AttackingHog: PHedgehog; Mask: Longword; const Tint: LongWord); |
27 procedure AddSplashForGear(Gear: PGear; justSkipping: boolean); |
27 procedure AddSplashForGear(Gear: PGear; justSkipping: boolean); |
|
28 procedure AddBounceEffectForGear(Gear: PGear); |
28 |
29 |
29 function ModifyDamage(dmg: Longword; Gear: PGear): Longword; |
30 function ModifyDamage(dmg: Longword; Gear: PGear): Longword; |
30 procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource); |
31 procedure ApplyDamage(Gear: PGear; AttackerHog: PHedgehog; Damage: Longword; Source: TDamageSource); |
31 procedure spawnHealthTagForHH(HHGear: PGear; dmg: Longword); |
32 procedure spawnHealthTagForHH(HHGear: PGear; dmg: Longword); |
32 procedure HHHurt(Hedgehog: PHedgehog; Source: TDamageSource); |
33 procedure HHHurt(Hedgehog: PHedgehog; Source: TDamageSource); |
362 var x, y, i, distL, distR, distB, minDist, maxDrops: LongInt; |
363 var x, y, i, distL, distR, distB, minDist, maxDrops: LongInt; |
363 splash, particle: PVisualGear; |
364 splash, particle: PVisualGear; |
364 speed, hwTmp: hwFloat; |
365 speed, hwTmp: hwFloat; |
365 vi, vs, tmp: real; // impact speed and sideways speed |
366 vi, vs, tmp: real; // impact speed and sideways speed |
366 isImpactH, isImpactRight: boolean; |
367 isImpactH, isImpactRight: boolean; |
|
368 const dist2surf = 4; |
367 begin |
369 begin |
368 x:= hwRound(Gear^.X); |
370 x:= hwRound(Gear^.X); |
369 y:= hwRound(Gear^.Y); |
371 y:= hwRound(Gear^.Y); |
370 |
372 |
371 splash:= AddVisualGear(x, y, vgtSplash); |
373 // find position for splash and impact speed |
372 if splash = nil then |
|
373 exit; |
|
374 |
|
375 // correct position and angle |
|
376 |
374 |
377 distB:= cWaterline - y; |
375 distB:= cWaterline - y; |
378 |
376 |
379 if WorldEdge <> weSea then |
377 if WorldEdge <> weSea then |
380 minDist:= distB |
378 minDist:= distB |
387 |
385 |
388 isImpactH:= (minDist <> distB); |
386 isImpactH:= (minDist <> distB); |
389 |
387 |
390 if not isImpactH then |
388 if not isImpactH then |
391 begin |
389 begin |
392 dec(y, distB); |
390 y:= cWaterline - dist2surf; |
393 splash^.Y:= y; |
|
394 speed:= hwAbs(Gear^.dY); |
391 speed:= hwAbs(Gear^.dY); |
395 vs:= abs(hwFloat2Float(Gear^.dX)); |
|
396 end |
392 end |
397 else |
393 else |
398 begin |
394 begin |
399 isImpactRight := minDist = distR; |
395 isImpactRight := minDist = distR; |
400 if isImpactRight then |
396 if isImpactRight then |
401 begin |
397 x:= rightX - dist2surf |
402 inc(x, distR); |
|
403 splash^.Angle:= -90; |
|
404 end |
|
405 else |
398 else |
406 begin |
399 x:= leftX + dist2surf; |
407 dec(x, distL); |
|
408 splash^.Angle:= 90; |
|
409 end; |
|
410 splash^.X:= x; |
|
411 speed:= hwAbs(Gear^.dX); |
400 speed:= hwAbs(Gear^.dX); |
412 vs:= abs(hwFloat2Float(Gear^.dY)); |
401 end; |
413 end; |
|
414 |
|
415 vi:= hwFloat2Float(speed); |
|
416 |
402 |
417 // splash sound |
403 // splash sound |
418 |
404 |
419 if justSkipping then |
405 if justSkipping then |
420 PlaySound(sndSkip) |
406 PlaySound(sndSkip) |
428 else if hwTmp > _0_5 then |
414 else if hwTmp > _0_5 then |
429 PlaySound(sndSkip) |
415 PlaySound(sndSkip) |
430 else |
416 else |
431 PlaySound(sndDroplet2); |
417 PlaySound(sndDroplet2); |
432 end; |
418 end; |
|
419 |
|
420 |
|
421 // splash visuals |
|
422 |
|
423 if ((cReducedQuality and rqPlainSplash) <> 0) then |
|
424 exit; |
|
425 |
|
426 splash:= AddVisualGear(x, y, vgtSplash); |
|
427 if splash = nil then |
|
428 exit; |
|
429 |
|
430 if not isImpactH then |
|
431 vs:= abs(hwFloat2Float(Gear^.dX)) |
|
432 else |
|
433 begin |
|
434 if isImpactRight then |
|
435 splash^.Angle:= -90 |
|
436 else |
|
437 splash^.Angle:= 90; |
|
438 vs:= abs(hwFloat2Float(Gear^.dY)); |
|
439 end; |
|
440 |
|
441 |
|
442 vi:= hwFloat2Float(speed); |
433 |
443 |
434 with splash^ do |
444 with splash^ do |
435 begin |
445 begin |
436 Scale:= abs(hwFloat2Float(Gear^.Density / _3 * speed)); |
446 Scale:= abs(hwFloat2Float(Gear^.Density / _3 * speed)); |
437 if Scale > 1 then Scale:= power(Scale,0.3333) |
447 if Scale > 1 then Scale:= power(Scale,0.3333) |
512 isDirH:= false; |
522 isDirH:= false; |
513 |
523 |
514 if WorldEdge = weSea then |
524 if WorldEdge = weSea then |
515 begin |
525 begin |
516 tmp:= dist2Water; |
526 tmp:= dist2Water; |
517 dist2Water:= min(dist2Water, min(X - Gear^.Radius - leftX, rightX - (X + Gear^.Radius))); |
527 dist2Water:= min(dist2Water, min(X - Gear^.Radius - LongInt(leftX), LongInt(rightX) - (X + Gear^.Radius))); |
518 // if water on sides is closer than on bottom -> horizontal direction |
528 // if water on sides is closer than on bottom -> horizontal direction |
519 isDirH:= tmp <> dist2Water; |
529 isDirH:= tmp <> dist2Water; |
520 end; |
530 end; |
521 |
531 |
522 isImpact:= false; |
532 isImpact:= false; |
593 AddCaption(FormatA(GetEventString(eidDrowned), s), cWhiteColor, capgrpMessage); |
603 AddCaption(FormatA(GetEventString(eidDrowned), s), cWhiteColor, capgrpMessage); |
594 end |
604 end |
595 end |
605 end |
596 else |
606 else |
597 DrownGear(Gear); |
607 DrownGear(Gear); |
598 if (dist2Water < -1) or (Gear^.Kind = gtFlake) then |
608 if Gear^.Kind = gtFlake then |
599 exit(true); // skip splashes |
609 exit(true); // skip splashes |
600 end |
610 end |
601 else // submersible |
611 else // submersible |
602 begin |
612 begin |
603 // drown submersible grears if far below map |
613 // drown submersible grears if far below map |
626 begin |
636 begin |
627 tmp:= hwRound(Gear^.Y - Gear^.dY); |
637 tmp:= hwRound(Gear^.Y - Gear^.dY); |
628 tmp:= abs(cWaterLine - tmp); |
638 tmp:= abs(cWaterLine - tmp); |
629 end; |
639 end; |
630 |
640 |
631 // there was an impact if distance was same as radius |
641 // there was an impact if distance was >= radius |
632 isImpact:= (tmp = Gear^.Radius) |
642 isImpact:= (tmp >= Gear^.Radius) |
633 end; |
643 end; |
634 end; // end of submersible |
644 end; // end of submersible |
635 end; // end of not skipping |
645 end; // end of not skipping |
636 |
646 |
637 // splash sound animation and droplets |
647 // splash sound animation and droplets |
1295 if t<h then |
1305 if t<h then |
1296 begin |
1306 begin |
1297 FollowGear:= AddGear(0, 0, gtCase, 0, _0, _0, 0); |
1307 FollowGear:= AddGear(0, 0, gtCase, 0, _0, _0, 0); |
1298 FollowGear^.Health:= cHealthCaseAmount; |
1308 FollowGear^.Health:= cHealthCaseAmount; |
1299 FollowGear^.Pos:= posCaseHealth; |
1309 FollowGear^.Pos:= posCaseHealth; |
|
1310 // health crate is smaller than the other crates |
|
1311 FollowGear^.Radius := cCaseHealthRadius; |
1300 AddCaption(GetEventString(eidNewHealthPack), cWhiteColor, capgrpAmmoInfo); |
1312 AddCaption(GetEventString(eidNewHealthPack), cWhiteColor, capgrpAmmoInfo); |
1301 end |
1313 end |
1302 else if (t<a+h) then |
1314 else if (t<a+h) then |
1303 begin |
1315 begin |
1304 t:= aTot; |
1316 t:= aTot; |
1428 RightImpactTimer:= 333; |
1440 RightImpactTimer:= 333; |
1429 Gear^.dX.isNegative:= true; |
1441 Gear^.dX.isNegative:= true; |
1430 Gear^.X:= int2hwfloat(rightX-Gear^.Radius) |
1442 Gear^.X:= int2hwfloat(rightX-Gear^.Radius) |
1431 end; |
1443 end; |
1432 if (Gear^.Radius > 2) and (Gear^.dX.QWordValue > _0_001.QWordValue) then |
1444 if (Gear^.Radius > 2) and (Gear^.dX.QWordValue > _0_001.QWordValue) then |
1433 PlaySound(sndMelonImpact) |
1445 AddBounceEffectForGear(Gear); |
1434 end{ |
1446 end{ |
1435 else if WorldEdge = weSea then |
1447 else if WorldEdge = weSea then |
1436 begin |
1448 begin |
1437 if (hwRound(Gear^.Y) > cWaterLine) and (Gear^.State and gstSubmersible <> 0) then |
1449 if (hwRound(Gear^.Y) > cWaterLine) and (Gear^.State and gstSubmersible <> 0) then |
1438 Gear^.State:= Gear^.State and (not gstSubmersible) |
1450 Gear^.State:= Gear^.State and (not gstSubmersible) |
1463 *) |
1475 *) |
1464 WorldWrap:= true |
1476 WorldWrap:= true |
1465 end; |
1477 end; |
1466 end; |
1478 end; |
1467 |
1479 |
|
1480 procedure AddBounceEffectForGear(Gear: PGear); |
|
1481 var boing: PVisualGear; |
|
1482 begin |
|
1483 boing:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtStraightShot, 0, false, 1); |
|
1484 if boing <> nil then |
|
1485 with boing^ do |
|
1486 begin |
|
1487 Angle:= random(360); |
|
1488 dx:= 0; |
|
1489 dy:= 0; |
|
1490 FrameTicks:= 200; |
|
1491 Scale:= hwFloat2Float(Gear^.Density * hwAbs(Gear^.dY) + hwAbs(Gear^.dX)) / 1.5; |
|
1492 State:= ord(sprBoing) |
|
1493 end; |
|
1494 PlaySound(sndMelonImpact, true) |
|
1495 end; |
|
1496 |
1468 end. |
1497 end. |