hedgewars/uGears.pas
changeset 4443 d393b9ccd328
parent 4417 6bf00d99fc47
child 4455 a0c8779713f2
equal deleted inserted replaced
4442:f8424e1bc936 4443:d393b9ccd328
    38 procedure AssignHHCoords;
    38 procedure AssignHHCoords;
    39 function  GearByUID(uid : Longword) : PGear;
    39 function  GearByUID(uid : Longword) : PGear;
    40 procedure InsertGearToList(Gear: PGear);
    40 procedure InsertGearToList(Gear: PGear);
    41 procedure RemoveGearFromList(Gear: PGear);
    41 procedure RemoveGearFromList(Gear: PGear);
    42 function  ModifyDamage(dmg: Longword; Gear: PGear): Longword;
    42 function  ModifyDamage(dmg: Longword; Gear: PGear): Longword;
    43 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt);
    43 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean = false);
       
    44 procedure DeleteGear(Gear: PGear); 
    44 
    45 
    45 
    46 
    46 implementation
    47 implementation
    47 uses uStore, uSound, uTeams, uRandom, uCollisions, uIO, uLandGraphics,
    48 uses uStore, uSound, uTeams, uRandom, uCollisions, uIO, uLandGraphics,
    48      uAIMisc, uLocale, uAI, uAmmos, uStats, uVisualGears, uScript, GLunit, uMobile, uVariables,
    49      uAIMisc, uLocale, uAI, uAmmos, uStats, uVisualGears, uScript, GLunit, uMobile, uVariables,
    49      uCommands, uUtils, uTextures, uRenderUtils, uGearsRender, uCaptions, uDebug;
    50      uCommands, uUtils, uTextures, uRenderUtils, uGearsRender, uCaptions, uDebug;
    50 
    51 
    51 
    52 
    52 procedure DeleteGear(Gear: PGear); forward;
       
    53 procedure doMakeExplosion(X, Y, Radius: LongInt; Mask: LongWord); forward;
    53 procedure doMakeExplosion(X, Y, Radius: LongInt; Mask: LongWord); forward;
    54 procedure doMakeExplosion(X, Y, Radius: LongInt; Mask, Tint: LongWord); forward;
    54 procedure doMakeExplosion(X, Y, Radius: LongInt; Mask, Tint: LongWord); forward;
    55 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); forward;
    55 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); forward;
    56 //procedure AmmoFlameWork(Ammo: PGear); forward;
    56 //procedure AmmoFlameWork(Ammo: PGear); forward;
    57 function  GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): TPGearArray; forward;
    57 function  GearsNear(X, Y: hwFloat; Kind: TGearType; r: LongInt): TPGearArray; forward;
  1457         if Team^.AIKillsTex <> nil then FreeTexture(Team^.AIKillsTex);
  1457         if Team^.AIKillsTex <> nil then FreeTexture(Team^.AIKillsTex);
  1458         Team^.AIKillsTex := RenderStringTex(inttostr(Team^.stats.AIKills), Team^.Clan^.Color, fnt16);
  1458         Team^.AIKillsTex := RenderStringTex(inttostr(Team^.stats.AIKills), Team^.Clan^.Color, fnt16);
  1459     end;
  1459     end;
  1460     tempTeam := gear^.Hedgehog^.Team;
  1460     tempTeam := gear^.Hedgehog^.Team;
  1461     DeleteCI(gear);
  1461     DeleteCI(gear);
  1462     FindPlace(gear, false, 0, LAND_WIDTH); 
  1462     FindPlace(gear, false, 0, LAND_WIDTH, true); 
  1463     if gear <> nil then begin
  1463     if gear <> nil then begin
  1464         RenderHealth(gear^.Hedgehog^);
  1464         RenderHealth(gear^.Hedgehog^);
  1465         ScriptCall('onGearResurrect', gear^.uid);
  1465         ScriptCall('onGearResurrect', gear^.uid);
  1466     end;
  1466     end;
  1467     RecountTeamHealth(tempTeam);
  1467     RecountTeamHealth(tempTeam);
  1587     if (FollowGear <> nil) then
  1587     if (FollowGear <> nil) then
  1588         PlaySound(sndReinforce, CurrentTeam^.voicepack)
  1588         PlaySound(sndReinforce, CurrentTeam^.voicepack)
  1589     end
  1589     end
  1590 end;
  1590 end;
  1591 
  1591 
  1592 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt);
  1592 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean = false);
  1593 
  1593 
  1594     function CountNonZeroz(x, y, r, c: LongInt): LongInt;
  1594     function CountNonZeroz(x, y, r, c: LongInt): LongInt;
  1595     var i: LongInt;
  1595     var i: LongInt;
  1596         count: LongInt = 0;
  1596         count: LongInt = 0;
  1597     begin
  1597     begin
  1609     y, sy: LongInt;
  1609     y, sy: LongInt;
  1610     ar: array[0..511] of TPoint;
  1610     ar: array[0..511] of TPoint;
  1611     ar2: array[0..1023] of TPoint;
  1611     ar2: array[0..1023] of TPoint;
  1612     cnt, cnt2: Longword;
  1612     cnt, cnt2: Longword;
  1613     delta: LongInt;
  1613     delta: LongInt;
  1614 begin
  1614     reallySkip, tryAgain: boolean;
  1615 delta:= 250;
  1615 begin
  1616 cnt2:= 0;
  1616 reallySkip:= false; // try not skipping proximity at first
  1617 repeat
  1617 tryAgain:= true;
  1618     x:= Left + LongInt(GetRandom(Delta));
  1618 while tryAgain do
       
  1619     begin
       
  1620     delta:= 250;
       
  1621     cnt2:= 0;
  1619     repeat
  1622     repeat
  1620         inc(x, Delta);
  1623         x:= Left + LongInt(GetRandom(Delta));
  1621         cnt:= 0;
  1624         repeat
  1622         y:= min(1024, topY) - 2 * Gear^.Radius;
  1625             inc(x, Delta);
  1623         while y < cWaterLine do
  1626             cnt:= 0;
  1624             begin
  1627             y:= min(1024, topY) - 2 * Gear^.Radius;
  1625             repeat
  1628             while y < cWaterLine do
  1626                 inc(y, 2);
       
  1627             until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) = 0);
       
  1628 
       
  1629             sy:= y;
       
  1630 
       
  1631             repeat
       
  1632                 inc(y);
       
  1633             until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) <> 0);
       
  1634 
       
  1635             if (y - sy > Gear^.Radius * 2) and
       
  1636                (((Gear^.Kind = gtExplosives)
       
  1637                    and (y < cWaterLine)
       
  1638                    and (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 60, 60) = nil)
       
  1639                    and (CountNonZeroz(x, y+1, Gear^.Radius - 1, Gear^.Radius+1) > Gear^.Radius))
       
  1640                or
       
  1641                  ((Gear^.Kind <> gtExplosives)
       
  1642                    and (y < cWaterLine)
       
  1643                    and (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 110, 110) = nil))) then
       
  1644                 begin
  1629                 begin
  1645                 ar[cnt].X:= x;
  1630                 repeat
  1646                 if withFall then ar[cnt].Y:= sy + Gear^.Radius
  1631                     inc(y, 2);
  1647                             else ar[cnt].Y:= y - Gear^.Radius;
  1632                 until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) = 0);
  1648                 inc(cnt)
  1633 
  1649                 end;
  1634                 sy:= y;
  1650 
  1635 
  1651             inc(y, 45)
  1636                 repeat
  1652             end;
  1637                     inc(y);
  1653 
  1638                 until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) <> 0);
  1654         if cnt > 0 then
  1639 
  1655             with ar[GetRandom(cnt)] do
  1640                 if (y - sy > Gear^.Radius * 2) and
  1656                 begin
  1641                    (((Gear^.Kind = gtExplosives)
  1657                 ar2[cnt2].x:= x;
  1642                        and (y < cWaterLine)
  1658                 ar2[cnt2].y:= y;
  1643                        and (reallySkip or (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 60, 60) = nil))
  1659                 inc(cnt2)
  1644                        and (CountNonZeroz(x, y+1, Gear^.Radius - 1, Gear^.Radius+1) > Gear^.Radius))
  1660                 end
  1645                    or
  1661     until (x + Delta > Right);
  1646                      ((Gear^.Kind <> gtExplosives)
  1662 
  1647                        and (y < cWaterLine)
  1663     dec(Delta, 60)
  1648                        and (reallySkip or (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 110, 110) = nil)))) then
  1664 until (cnt2 > 0) or (Delta < 70);
  1649                     begin
       
  1650                     ar[cnt].X:= x;
       
  1651                     if withFall then ar[cnt].Y:= sy + Gear^.Radius
       
  1652                                 else ar[cnt].Y:= y - Gear^.Radius;
       
  1653                     inc(cnt)
       
  1654                     end;
       
  1655 
       
  1656                 inc(y, 45)
       
  1657                 end;
       
  1658 
       
  1659             if cnt > 0 then
       
  1660                 with ar[GetRandom(cnt)] do
       
  1661                     begin
       
  1662                     ar2[cnt2].x:= x;
       
  1663                     ar2[cnt2].y:= y;
       
  1664                     inc(cnt2)
       
  1665                     end
       
  1666         until (x + Delta > Right);
       
  1667 
       
  1668         dec(Delta, 60)
       
  1669     until (cnt2 > 0) or (Delta < 70);
       
  1670     if (cnt2 = 0) and skipProximity and not reallySkip then tryAgain:= true
       
  1671     else tryAgain:= false;
       
  1672     reallySkip:= true;
       
  1673     end;
  1665 
  1674 
  1666 if cnt2 > 0 then
  1675 if cnt2 > 0 then
  1667     with ar2[GetRandom(cnt2)] do
  1676     with ar2[GetRandom(cnt2)] do
  1668         begin
  1677         begin
  1669         Gear^.X:= int2hwFloat(x);
  1678         Gear^.X:= int2hwFloat(x);