hedgewars/uGearsUtils.pas
branchqmlfrontend
changeset 10515 7705784902e1
parent 10512 25021aac078e
child 10526 b43d175d1577
equal deleted inserted replaced
10458:f7a199346c3e 10515:7705784902e1
    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;
   544         skipDecay := _0_87;
   554         skipDecay := _0_87;
   545 
   555 
   546 
   556 
   547         // skipping
   557         // skipping
   548 
   558 
   549         if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > skipSpeed)
   559         if (not isSubmersible) and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > skipSpeed)
   550         and ( ((not isDirH) and (hwAbs(Gear^.dX) > skipAngle * hwAbs(Gear^.dY)))
   560         and ( ((not isDirH) and (hwAbs(Gear^.dX) > skipAngle * hwAbs(Gear^.dY)))
   551           or (isDirH and (hwAbs(Gear^.dY) > skipAngle * hwAbs(Gear^.dX))) ) then
   561           or (isDirH and (hwAbs(Gear^.dY) > skipAngle * hwAbs(Gear^.dX))) ) then
   552             begin
   562             begin
   553             isSkip:= true;
   563             isSkip:= true;
   554             // if skipping we move the gear out of water
   564             // if skipping we move the gear out of water
   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.