- Fixed bubble theme object
authorunc0rr
Thu, 19 Jan 2006 21:12:20 +0000
changeset 53 0e27949850e3
parent 52 ae2950c5465c
child 54 839fd258ae6f
- Fixed bubble theme object - Hedgehogs are round now when checking collisions and hedgehog isn't going, increased perfomance - Gears are square when checking collisions - Ability to load map from png file - Show more clear information when fail to load file
hedgewars/Data/Maps/test/map.png
hedgewars/Data/Themes/bubbles/round.png
hedgewars/GSHandlers.inc
hedgewars/HHHandlers.inc
hedgewars/hwengine.dpr
hedgewars/tunsetborder.inc
hedgewars/uAI.pas
hedgewars/uAIAmmoTests.pas
hedgewars/uAIMisc.pas
hedgewars/uCollisions.pas
hedgewars/uConsole.pas
hedgewars/uConsts.pas
hedgewars/uGears.pas
hedgewars/uIO.pas
hedgewars/uLand.pas
hedgewars/uMisc.pas
hedgewars/uSound.pas
hedgewars/uStore.pas
hedgewars/uWorld.pas
Binary file hedgewars/Data/Maps/test/map.png has changed
Binary file hedgewars/Data/Themes/bubbles/round.png has changed
--- a/hedgewars/GSHandlers.inc	Sun Jan 15 23:56:47 2006 +0000
+++ b/hedgewars/GSHandlers.inc	Thu Jan 19 21:12:20 2006 +0000
@@ -35,7 +35,7 @@
 
 function CheckGearDrowning(Gear: PGear): boolean;
 begin
-Result:= Gear.Y + Gear.HalfHeight >= cWaterLine;
+Result:= Gear.Y + Gear.Radius >= cWaterLine;
 if Result then
    begin
    Gear.State:= gstDrowning;
@@ -73,7 +73,7 @@
 begin
 AllInactive:= false;
 Gear.Y:= Gear.Y + cDrownSpeed;
-if round(Gear.Y) > Gear.HalfHeight + cWaterLine + 48 + cVisibleWater then DeleteGear(Gear)
+if round(Gear.Y) > Gear.Radius + cWaterLine + 48 + cVisibleWater then DeleteGear(Gear)
 end;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -171,10 +171,10 @@
 begin
 AllInactive:= false;
 if Gear.dY < 0 then
-   if TestCollisionY(Gear, -1) then Gear.dY:= 0;
+   if TestCollisionYwithGear(Gear, -1) then Gear.dY:= 0;
 
 if Gear.dY >=0 then
-   if TestCollisionY(Gear, 1) then
+   if TestCollisionYwithGear(Gear, 1) then
       begin
       Gear.dY:= - Gear.dY * Gear.Elasticity;
       if Gear.dY > - 0.001 then
@@ -234,7 +234,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 procedure doStepShotgunShot(Gear: PGear);
 var i: LongWord;
-    t: PGear;
 begin
 AllInactive:= false;
 if Gear.Timer > 0 then
@@ -250,10 +249,7 @@
 CheckCollision(Gear);
 if (Gear.State and gstCollision) <> 0 then
    begin
-   t:= CheckGearsCollision(Gear, Sign(Gear.dX), true);
-   if t = nil then t:= CheckGearsCollision(Gear, Sign(Gear.dY), false);
-   if t <> nil then
-      AmmoShove(Gear, t, 25);
+   AmmoShove(Gear, 25);
    doMakeExplosion(round(Gear.X), round(Gear.Y), 25, EXPLNoDamage or EXPLDoNotTouchHH);
    DeleteGear(Gear);
    exit
@@ -268,7 +264,6 @@
 procedure doStepDEagleShot(Gear: PGear);
 var i, x, y: LongWord;
     oX, oY: real;
-    t: PGear;
 begin
 AllInactive:= false;
 i:= 80;
@@ -281,14 +276,7 @@
   y:= round(Gear.Y);
   if ((y and $FFFFFC00) = 0) and ((x and $FFFFF800) = 0)
      and (Land[y, x] <> 0) then inc(Gear.Damage);
-  t:= CheckGearsCollision(Gear, Sign(Gear.dX), true);
-  if t = nil then t:= CheckGearsCollision(Gear, Sign(Gear.dY), false);
-  if t <> nil then
-     begin
-     AmmoShove(Gear, t, 12);
-     inc(Gear.Damage, 10);
-     if t.CollIndex < High(Longword) then DeleteCR(t)
-     end;
+  AmmoShove(Gear, 12);
   dec(i)
 until (i = 0) or (Gear.Damage > Gear.Health);
 if Gear.Damage > 0 then
@@ -340,8 +328,8 @@
 HHGear:= PHedgehog(Gear.Hedgehog).Gear;
 if (Gear.Timer and $3F) = 0 then
    begin
-   i:= round(Gear.X) - Gear.HalfWidth  - GetRandom(2);
-   ei:= round(Gear.X) + Gear.HalfWidth + GetRandom(2);
+   i:= round(Gear.X) - Gear.Radius  - GetRandom(2);
+   ei:= round(Gear.X) + Gear.Radius + GetRandom(2);
    while i <= ei do
          begin
          doMakeExplosion(i, round(Gear.Y) + 3, 3, 0);
@@ -365,7 +353,7 @@
 
 Gear.X:= Gear.X + HHGear.dX;
 HHGear.X:= Gear.X;
-HHGear.Y:= Gear.Y - cHHHalfHeight;
+HHGear.Y:= Gear.Y - cHHRadius;
 
 if (Gear.Message and gm_Attack) <> 0 then
    if (Gear.State and gsttmpFlag) <> 0 then Gear.Timer:= 1 else else
@@ -380,15 +368,15 @@
     ar: TRangeArray;
 begin
 i:= 0;
-y:= round(Gear.Y) - cHHHalfHeight*2;
+y:= round(Gear.Y) - cHHRadius*2;
 while y < round(Gear.Y) do
    begin
-   ar[i].Left := round(Gear.X) - Gear.HalfWidth - GetRandom(2);
-   ar[i].Right:= round(Gear.X) + Gear.HalfWidth + GetRandom(2);
+   ar[i].Left := round(Gear.X) - Gear.Radius - GetRandom(2);
+   ar[i].Right:= round(Gear.X) + Gear.Radius + GetRandom(2);
    inc(y, 2);
    inc(i)
    end;
-DrawHLinesExplosions(@ar, 3, round(Gear.Y) - cHHHalfHeight*2, 2, Pred(i));
+DrawHLinesExplosions(@ar, 3, round(Gear.Y) - cHHRadius*2, 2, Pred(i));
 Gear.dY:= PHedgehog(Gear.Hedgehog).Gear.dY;
 doStepPickHammerWork(Gear);
 Gear.doStep:= doStepPickHammerWork
@@ -609,11 +597,11 @@
 begin
 if (Gear.dX <> 0) or (Gear.dY <> 0) then
    begin
-   if Gear.CollIndex < High(Longword) then DeleteCR(Gear);
+   if Gear.CollIndex < High(Longword) then DeleteCI(Gear);
    doStepFallingGear(Gear);
    if Gear.Active = false then
       begin
-      if Gear.CollIndex = High(Longword) then AddGearCR(Gear);
+      if Gear.CollIndex = High(Longword) then AddGearCI(Gear);
       Gear.dX:= 0;
       Gear.dY:= 0
       end;
@@ -663,13 +651,13 @@
    exit
    end;
 
-if (Gear.dY <> 0) or (not TestCollisionY(Gear, 1)) then
+if (Gear.dY <> 0) or (not TestCollisionYwithGear(Gear, 1)) then
    begin
    AllInactive:= false;
    Gear.dY:= Gear.dY + cGravity;
    Gear.Y:= Gear.Y + Gear.dY;
-   if (Gear.dY < 0) and TestCollisionY(Gear, -1) then Gear.dY:= 0 else
-   if (Gear.dY >= 0) and TestCollisionY(Gear, 1) then
+   if (Gear.dY < 0) and TestCollisionYwithGear(Gear, -1) then Gear.dY:= 0 else
+   if (Gear.dY >= 0) and TestCollisionYwithGear(Gear, 1) then
       begin
       Gear.dY:= - Gear.dY * Gear.Elasticity;
       if Gear.dY > - 0.001 then Gear.dY:= 0
@@ -678,8 +666,8 @@
    CheckGearDrowning(Gear);
    end;
 
-if (Gear.CollIndex = High(Longword)) and (Gear.dY = 0) then AddGearCR(Gear)
-   else if (Gear.CollIndex < High(Longword)) and (Gear.dY <> 0) then DeleteCR(Gear);
+if (Gear.CollIndex = High(Longword)) and (Gear.dY = 0) then AddGearCI(Gear)
+   else if (Gear.CollIndex < High(Longword)) and (Gear.dY <> 0) then DeleteCI(Gear);
 
 if Gear.Damage > 0 then
    begin
--- a/hedgewars/HHHandlers.inc	Sun Jan 15 23:56:47 2006 +0000
+++ b/hedgewars/HHHandlers.inc	Thu Jan 19 21:12:20 2006 +0000
@@ -31,69 +31,6 @@
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *)
 
-procedure AddIntersectorsCR(Gear: PGear);
-var t: PGear;
-    x, xw, y, yh: real;
-    ar: array[0..Pred(cMaxHHs)] of PGear;
-    cnt: Longword;
-    b: boolean;
-begin
-x:= Gear.X - Gear.HalfWidth;
-xw:= Gear.X + Gear.HalfWidth;
-y:= Gear.Y - Gear.HalfHeight;
-yh:= Gear.Y + Gear.HalfHeight;
-t:= GearsList;
-b:= false;
-cnt:= 0;
-while (t <> nil) do
-      begin
-      if (t <> Gear) and not (t.Kind in [gtGrave, gtMine]) then
-         if (x < t.X + t.HalfWidth ) and (t.X - t.HalfWidth  < xw) and
-            (y < t.Y + t.HalfHeight) and (t.Y - t.HalfHeight < yh) then
-            if t.Kind = gtHedgehog then
-               begin
-               ar[cnt]:= t;
-               inc(cnt)
-               end else b:= true;
-      t:= t.NextGear
-      end;
-ar[cnt]:= Gear;
-inc(cnt);
-if b then
-   begin
-   repeat
-     dec(cnt);
-     if ar[cnt].CollIndex < High(Longword) then DeleteCR(ar[cnt])
-   until cnt = 0;
-   end else
-   begin
-   repeat
-     dec(cnt);
-     if ar[cnt].CollIndex = High(Longword) then AddGearCR(ar[cnt])
-   until cnt = 0
-   end
-end;
-
-procedure RemoveIntersectorsCR(Gear: PGear);
-var t: PGear;
-    x, xw, y, yh: real;
-begin
-x:= Gear.X - Gear.HalfWidth;
-xw:= Gear.X + Gear.HalfWidth;
-y:= Gear.Y - Gear.HalfHeight;
-yh:= Gear.Y + Gear.HalfHeight;
-t:= GearsList;
-while (t <> nil) do
-      begin
-      if (t <> Gear) then
-         if (x < t.X + t.HalfWidth ) and (t.X - t.HalfWidth  < xw) and
-            (y < t.Y + t.HalfHeight) and (t.Y - t.HalfHeight < yh) then
-               if t.CollIndex < High(Longword) then DeleteCR(t);
-      t:= t.NextGear
-      end;
-if Gear.CollIndex < High(Longword) then DeleteCR(Gear);
-end;
-
 ////////////////////////////////////////////////////////////////////////////////
 procedure Attack(Gear: PGear);
 var xx, yy: real;
@@ -132,7 +69,7 @@
                                  FollowGear:= AddGear(round(X), round(Y), gtDEagleShot,   0, xx * 0.5, yy * 0.5);
                                  end;
                          amSkip: TurnTimeLeft:= 0;
-                   amPickHammer: CurAmmoGear:= AddGear(round(Gear.X), round(Gear.Y) + cHHHalfHeight, gtPickHammer, 0);
+                   amPickHammer: CurAmmoGear:= AddGear(round(Gear.X), round(Gear.Y) + cHHRadius, gtPickHammer, 0);
                          amRope: CurAmmoGear:= AddGear(round(Gear.X), round(Gear.Y), gtRope, 0, xx, yy);
                          amMine: AddGear(round(X) + Sign(dX) * 7, round(Y), gtMine, 0, Sign(dX) * 0.01, 0, 3000);
                      amDynamite: AddGear(round(X) + Sign(dX) * 7, round(Y), gtDynamite, 0, Sign(dX) * 0.01, 0, 5000); 
@@ -191,10 +128,10 @@
 begin
 if isinMultiShoot and (Gear.Damage = 0) then
    begin
-   if Gear.CollIndex = High(Longword) then AddIntersectorsCR(Gear);
    exit
    end;
 AllInactive:= false;
+DeleteCI(Gear);
 if (TurnTimeLeft = 0) or (Gear.Damage > 0) then
    begin
    if ((Gear.State and (gstMoving or gstFalling)) = 0)
@@ -244,7 +181,6 @@
 
 if ((Gear.State and gstAttacking) <> 0) and ((Gear.Message and gm_Attack) = 0) then
    begin
-   RemoveIntersectorsCR(Gear);
    Attack(Gear);
    StepTicks:= 40
    end;
@@ -276,7 +212,7 @@
       end;
    CheckGearDrowning(Gear);
    exit
-   end else if Gear.CollIndex = High(Longword) then AddIntersectorsCR(Gear);
+   end ;//else if Gear.CollIndex = High(Longword) then AddIntersectorsCR(Gear);
 
 if StepTicks > 0 then dec(StepTicks);
 
@@ -290,7 +226,6 @@
    if ((Gear.Message and gm_LJump )<>0) then
       begin
       Gear.Message:= 0;
-      RemoveIntersectorsCR(Gear);
       if not HHTestCollisionYwithGear(Gear, -1) then
          if not TestCollisionXwithXYShift(Gear, 0, -2, Sign(Gear.dX)) then Gear.Y:= Gear.Y - 2 else
          if not TestCollisionXwithXYShift(Gear, 0, -1, Sign(Gear.dX)) then Gear.Y:= Gear.Y - 1;
@@ -306,7 +241,6 @@
    if ((Gear.Message and gm_HJump )<>0) then
       begin
       Gear.Message:= 0;
-      RemoveIntersectorsCR(Gear);
       if not HHTestCollisionYwithGear(Gear, -1) then
          begin
          Gear.dY:= -0.20;
@@ -320,7 +254,6 @@
    if (Gear.Message and gm_Right )<>0 then Gear.dX:=  1.0 else exit;
    PHedgehog(Gear.Hedgehog).visStepPos:= (PHedgehog(Gear.Hedgehog).visStepPos + 1) and 7;
    StepTicks:= cStepTicks;
-   RemoveIntersectorsCR(Gear);
    if TestCollisionXwithGear(Gear, Sign(Gear.dX)) then
       begin
       if not (TestCollisionXwithXYShift(Gear, 0, -6, Sign(Gear.dX))
@@ -338,7 +271,6 @@
       end;
    if not TestCollisionXwithGear(Gear, Sign(Gear.dX)) then Gear.X:= Gear.X + Gear.dX;
 
-   AddIntersectorsCR(Gear);
    if not HHTestCollisionYwithGear(Gear, 1) then
    begin
    Gear.Y:= Gear.Y + 1;
@@ -391,8 +323,7 @@
    if ((Gear.State and gstMoving) <> 0) then Gear.dX:= Gear.dX * Gear.Friction
    end;
 
-if (Gear.State <> 0) and (Gear.CollIndex < High(Longword)) then DeleteCR(Gear);
-
+if (Gear.State <> 0) then DeleteCI(Gear);
 
 if (Gear.State and gstMoving) <> 0 then
    if TestCollisionXwithGear(Gear, Sign(Gear.dX)) then
@@ -447,7 +378,7 @@
       begin
       Gear.State:= 0;
       Gear.Active:= false;
-      AddIntersectorsCR(Gear);
+      AddGearCI(Gear);
       exit
       end
 end;
--- a/hedgewars/hwengine.dpr	Sun Jan 15 23:56:47 2006 +0000
+++ b/hedgewars/hwengine.dpr	Thu Jan 19 21:12:20 2006 +0000
@@ -156,6 +156,7 @@
 ////////////////////
 procedure GetParams;
 var c: integer;
+    s: string;
 {$IFDEF DEBUGFILE}
     i: integer;
 begin
@@ -166,10 +167,12 @@
 {$ENDIF}
 if ParamCount=6 then
    begin
-   //TODO: сделать передачу через IPC
    val(ParamStr(1), cScreenWidth, c);
    val(ParamStr(2), cScreenHeight, c);
-   Pathz[ptThemeCurrent]:= Pathz[ptThemes] + ParamStr(3)+'/';
+   // "/mapname" is map, "avematan" is theme
+   s:= ParamStr(3);
+   if (Length(s) > 0) and (s[1] = '/') then Pathz[ptMapCurrent]:= Pathz[ptMaps] + s
+                                       else Pathz[ptThemeCurrent]:= Pathz[ptThemes] + '/' + ParamStr(3);
    val(ParamStr(4), ipcPort, c);
    SetRandomParams(ParamStr(5), rndfillstr);
    cFullScreen:= ParamStr(6)[1] = '1'
@@ -190,10 +193,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 /////////////////////////////// m a i n ////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
-{$INCLUDE revision.inc}
 
 begin
-WriteLnToConsole('HedgeWars 0.1, svn '+cRevision);
+WriteLnToConsole('HedgeWars 0.1 alpha');
 WriteLnToConsole('  -= by unC0Rr =-  ');
 GetParams;
 Randomize;
--- a/hedgewars/tunsetborder.inc	Sun Jan 15 23:56:47 2006 +0000
+++ b/hedgewars/tunsetborder.inc	Thu Jan 19 21:12:20 2006 +0000
@@ -3,7 +3,7 @@
         Y:= Y + dY;
         tx:= round(X);
         ty:= round(Y);
-        if ((ty and $FFFFFC00) = 0) and ((tx and $FFFFF800) = 0)and (Land[ty, tx] <> 0) then
+        if ((ty and $FFFFFC00) = 0) and ((tx and $FFFFF800) = 0)and (Land[ty, tx] = $FFFFFF) then
         case LandSurface.format.BytesPerPixel of
              1: ;
              2: PWord(p + LandSurface.pitch * ty + tx * 2)^:= cExplosionBorderColor;
--- a/hedgewars/uAI.pas	Sun Jan 15 23:56:47 2006 +0000
+++ b/hedgewars/uAI.pas	Thu Jan 19 21:12:20 2006 +0000
@@ -156,8 +156,8 @@
 
 procedure ProcessBot;
 begin
-with CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do
-     if (Gear <> nil)and((Gear.State and gstHHDriven) <> 0) then
+with CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do          //HACK: v--- temp hack to make AI work
+     if (Gear <> nil)and((Gear.State and gstHHDriven) <> 0) and (TurnTimeLeft < 29990) then
         begin
         if IsActionListEmpty then Think;
         ProcessAction
--- a/hedgewars/uAIAmmoTests.pas	Sun Jan 15 23:56:47 2006 +0000
+++ b/hedgewars/uAIAmmoTests.pas	Thu Jan 19 21:12:20 2006 +0000
@@ -136,8 +136,8 @@
     var x, y, dX, dY: real;
         t: integer;
     begin
-    x:= Me.X + Vx*20;
-    y:= Me.Y + Vy*20;
+    x:= Me.X;
+    y:= Me.Y;
     dX:= Vx;
     dY:= -Vy;
     Result:= false;
--- a/hedgewars/uAIMisc.pas	Sun Jan 15 23:56:47 2006 +0000
+++ b/hedgewars/uAIMisc.pas	Thu Jan 19 21:12:20 2006 +0000
@@ -182,7 +182,7 @@
 repeat
 pX:= round(Gear.X);
 pY:= round(Gear.Y);
-if pY + cHHHalfHeight >= cWaterLine then exit;
+if pY + cHHRadius >= cWaterLine then exit;
 if (Gear.State and gstFalling) <> 0 then
    begin
    Gear.dY:= Gear.dY + cGravity;
--- a/hedgewars/uCollisions.pas	Sun Jan 15 23:56:47 2006 +0000
+++ b/hedgewars/uCollisions.pas	Thu Jan 19 21:12:20 2006 +0000
@@ -35,98 +35,93 @@
 interface
 uses uGears;
 {$INCLUDE options.inc}
+const cMaxGearArrayInd = 255;
 
-type TCollisionEntry = record
-                       X, Y, HWidth, HHeight: integer;
-                       cGear: PGear;
-                       end;
+type TDirection = record
+                  dX, dY: integer
+                  end;
+     PGearArray = ^TGearArray;
+     TGearArray = record
+                  ar: array[0..cMaxGearArrayInd] of PGear;
+                  Count: Longword
+                  end;
 
-procedure AddGearCR(Gear: PGear);
-procedure UpdateCR(NewX, NewY: integer; Index: Longword);
-procedure DeleteCR(Gear: PGear);
-function  CheckGearsCollision(Gear: PGear; Dir: integer; forX: boolean): PGear;
+procedure FillRoundInLand(X, Y, Radius: integer; Value: Longword);
+procedure AddGearCI(Gear: PGear);
+procedure DeleteCI(Gear: PGear);
+function CheckGearsCollision(Gear: PGear): PGearArray;
 function  HHTestCollisionYwithGear(Gear: PGear; Dir: integer): boolean;
 function TestCollisionXwithGear(Gear: PGear; Dir: integer): boolean;
 function TestCollisionYwithGear(Gear: PGear; Dir: integer): boolean;
 function TestCollisionXwithXYShift(Gear: PGear; ShiftX, ShiftY: integer; Dir: integer): boolean;
 function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: integer; Dir: integer): boolean;
-function TestCollisionY(Gear: PGear; Dir: integer): boolean;
 
 implementation
 uses uMisc, uConsts, uLand;
 
+type TCollisionEntry = record
+                       X, Y, Radius: integer;
+                       cGear: PGear;
+                       end;
+                       
 const MAXRECTSINDEX = 255;
 var Count: Longword = 0;
-    crects: array[0..MAXRECTSINDEX] of TCollisionEntry;
+    cinfos: array[0..MAXRECTSINDEX] of TCollisionEntry;
+    ga: TGearArray;
 
-procedure AddGearCR(Gear: PGear);
+procedure FillRoundInLand(X, Y, Radius: integer; Value: Longword);
+var ty, tx: integer;
 begin
+for ty:= max(-Radius, -y) to min(radius, 1023 - y) do
+    for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047,round(x+radius*sqrt(1-sqr(ty/radius)))) do
+        Land[ty + y, tx]:= Value;
+end;
+
+procedure AddGearCI(Gear: PGear);
+begin
+if Gear.CollIndex < High(Longword) then exit; 
 TryDo(Count <= MAXRECTSINDEX, 'Collision rects array overflow', true);
-with crects[Count] do
+with cinfos[Count] do
      begin
      X:= round(Gear.X);
      Y:= round(Gear.Y);
-     HWidth:= Gear.HalfWidth;
-     HHeight:= Gear.HalfHeight;
+     Radius:= Gear.Radius;
+     FillRoundInLand(X, Y, Radius, $FF);
      cGear:= Gear
      end;
 Gear.CollIndex:= Count;
 inc(Count)
 end;
 
-procedure UpdateCR(NewX, NewY: integer; Index: Longword);
+procedure DeleteCI(Gear: PGear);
 begin
-with crects[Index] do
-     begin
-     X:= NewX;
-     Y:= NewY
-     end
+if Gear.CollIndex < Count then
+   begin
+   with cinfos[Gear.CollIndex] do FillRoundInLand(X, Y, Radius, 0);
+   cinfos[Gear.CollIndex]:= cinfos[Pred(Count)];
+   cinfos[Gear.CollIndex].cGear.CollIndex:= Gear.CollIndex;
+   Gear.CollIndex:= High(Longword);
+   dec(Count)
+   end;
 end;
 
-procedure DeleteCR(Gear: PGear);
-begin
-if Gear.CollIndex < Pred(Count) then
-   begin
-   crects[Gear.CollIndex]:= crects[Pred(Count)];
-   crects[Gear.CollIndex].cGear.CollIndex:= Gear.CollIndex
-   end;
-Gear.CollIndex:= High(Longword);
-dec(Count)
-end;
-
-function CheckGearsCollision(Gear: PGear; Dir: integer; forX: boolean): PGear;
-var x1, x2, y1, y2: integer;
+function CheckGearsCollision(Gear: PGear): PGearArray;
+var mx, my: integer;
     i: Longword;
 begin
-Result:= nil;
+Result:= @ga;
+ga.Count:= 0;
 if Count = 0 then exit;
-x1:= round(Gear.X);
-y1:= round(Gear.Y);
-
-if forX then
-   begin
-   x1:= x1 + Dir*Gear.HalfWidth;
-   x2:= x1;
-   y2:= y1 + Gear.HalfHeight - 1;
-   y1:= y1 - Gear.HalfHeight + 1
-   end else
-   begin
-   y1:= y1 + Dir*Gear.HalfHeight;
-   y2:= y1;
-   x2:= x1 + Gear.HalfWidth - 1;
-   x1:= x1 - Gear.HalfWidth + 1
-   end;
+mx:= round(Gear.X);
+my:= round(Gear.Y);
 
 for i:= 0 to Pred(Count) do
-   with crects[i] do
-      if  (Gear.CollIndex <> i)
-         and (x1 <= X + HWidth)
-         and (x2 >= X - HWidth)
-         and (y1 <= Y + HHeight)
-         and (y2 >= Y - HHeight) then
+   with cinfos[i] do
+      if (Gear <> cGear) and
+         (sqrt(sqr(mx - x) + sqr(my - y)) <= Radius + Gear.Radius) then
              begin
-             Result:= crects[i].cGear;
-             exit
+             ga.ar[ga.Count]:= cinfos[i].cGear;
+             inc(ga.Count)
              end;
 end;
 
@@ -135,14 +130,14 @@
 begin
 Result:= false;
 y:= round(Gear.Y);
-if Dir < 0 then y:= y - Gear.HalfHeight
-           else y:= y + Gear.HalfHeight;
+if Dir < 0 then y:= y - Gear.Radius
+           else y:= y + Gear.Radius;
            
 if ((y - Dir) and $FFFFFC00) = 0 then
    begin
    x:= round(Gear.X);
-   if (((x - Gear.HalfWidth) and $FFFFF800) = 0)and(Land[y - Dir, x - Gear.HalfWidth] <> 0)
-    or(((x + Gear.HalfWidth) and $FFFFF800) = 0)and(Land[y - Dir, x + Gear.HalfWidth] <> 0) then
+   if (((x - Gear.Radius) and $FFFFF800) = 0)and(Land[y - Dir, x - Gear.Radius] <> 0)
+    or(((x + Gear.Radius) and $FFFFF800) = 0)and(Land[y - Dir, x + Gear.Radius] <> 0) then
       begin
       Result:= true;
       exit
@@ -151,15 +146,12 @@
 
 if (y and $FFFFFC00) = 0 then
    begin
-   x:= round(Gear.X) - Gear.HalfWidth + 1;
-   i:= x + Gear.HalfWidth * 2 - 2;
+   x:= round(Gear.X) - Gear.Radius + 1;
+   i:= x + Gear.Radius * 2 - 2;
    repeat
      if (x and $FFFFF800) = 0 then Result:= Land[y, x]<>0;
      inc(x)
-   until (x > i) or Result;
-   if Result then exit;
-
-   Result:= CheckGearsCollision(Gear, Dir, false) <> nil
+   until (x > i) or Result
    end
 end;
 
@@ -168,18 +160,16 @@
 begin
 Result:= false;
 x:= round(Gear.X);
-if Dir < 0 then x:= x - Gear.HalfWidth
-           else x:= x + Gear.HalfWidth;
+if Dir < 0 then x:= x - Gear.Radius
+           else x:= x + Gear.Radius;
 if (x and $FFFFF800) = 0 then
    begin
-   y:= round(Gear.Y) - Gear.HalfHeight + 1; {*}
-   i:= y + Gear.HalfHeight * 2 - 2;         {*}
+   y:= round(Gear.Y) - Gear.Radius + 1; {*}
+   i:= y + Gear.Radius * 2 - 2;         {*}
    repeat
      if (y and $FFFFFC00) = 0 then Result:= Land[y, x]<>0;
      inc(y)
    until (y > i) or Result;
-   if Result then exit;
-   Result:= CheckGearsCollision(Gear, Dir, true) <> nil
    end
 end;
 
@@ -197,32 +187,12 @@
 begin
 Result:= false;
 y:= round(Gear.Y);
-if Dir < 0 then y:= y - Gear.HalfHeight
-           else y:= y + Gear.HalfHeight;
+if Dir < 0 then y:= y - Gear.Radius
+           else y:= y + Gear.Radius;
 if (y and $FFFFFC00) = 0 then
    begin
-   x:= round(Gear.X) - Gear.HalfWidth + 1;    {*}
-   i:= x + Gear.HalfWidth * 2 - 2;            {*}
-   repeat
-     if (x and $FFFFF800) = 0 then Result:= Land[y, x]<>0;
-     inc(x)
-   until (x > i) or Result;
-   if Result then exit;
-   Result:= CheckGearsCollision(Gear, Dir, false) <> nil;
-   end
-end;
-
-function TestCollisionY(Gear: PGear; Dir: integer): boolean;
-var x, y, i: integer;
-begin
-Result:= false;
-y:= round(Gear.Y);
-if Dir < 0 then y:= y - Gear.HalfHeight
-           else y:= y + Gear.HalfHeight;
-if (y and $FFFFFC00) = 0 then
-   begin
-   x:= round(Gear.X) - Gear.HalfWidth + 1;    {*}
-   i:= x + Gear.HalfWidth * 2 - 2;            {*}
+   x:= round(Gear.X) - Gear.Radius + 1;    {*}
+   i:= x + Gear.Radius * 2 - 2;            {*}
    repeat
      if (x and $FFFFF800) = 0 then Result:= Land[y, x]<>0;
      inc(x)
--- a/hedgewars/uConsole.pas	Sun Jan 15 23:56:47 2006 +0000
+++ b/hedgewars/uConsole.pas	Thu Jan 19 21:12:20 2006 +0000
@@ -44,6 +44,7 @@
 procedure WriteLnToConsole(s: shortstring);
 procedure KeyPressConsole(Key: Longword);
 procedure ParseCommand(CmdStr: shortstring);
+function  GetLastConsoleLine: shortstring;
 
 implementation
 {$J+}
@@ -260,6 +261,12 @@
      end
 end;
 
+function GetLastConsoleLine: shortstring;
+begin
+if CurrLine = 0 then Result:= ConsoleLines[Pred(cLinesCount)]
+                else Result:= ConsoleLines[Pred(CurrLine)]
+end;
+
 {$INCLUDE CCHandlers.inc}
 
 initialization
--- a/hedgewars/uConsts.pas	Sun Jan 15 23:56:47 2006 +0000
+++ b/hedgewars/uConsts.pas	Thu Jan 19 21:12:20 2006 +0000
@@ -94,17 +94,17 @@
 
       cMaxHHIndex      = 9;
       cMaxHHs          = 20;
-      cMaxSpawnPoints  = 64;
+      cMaxSpawnPoints  = 1024;
       cHHSurfaceWidth     = 512;
       cHHSurfaceHeigth    = 256;
 
       cMaxEdgePoints = 16384;
 
-      cHHHalfHeight = 11;
+      cHHRadius = 9;
 
       cKeyMaxIndex = 322;
 
-      cMaxCaptions         = 4;
+      cMaxCaptions = 4;
 
       cInactDelay = 1500;
 
@@ -176,18 +176,18 @@
                                          );
 
       Pathz: array[TPathType] of string[ 64] = (
-                                               'Data/',                         // ptData
-                                               'Data/Graphics/',                // ptGraphics
-                                               'Data/Themes/',                  // ptThemes
-                                               'Data/Themes/Default/',          // ptThemeCurrent
-                                               'Data/Teams/',                   // ptTeams
-                                               'Data/Maps/',                    // ptMaps
-                                               'Data/Maps/Current/',            // ptMapCurrent
-                                               'Data/Demos/',                   // ptDemos
-                                               'Data/Sounds/',                  // ptSounds
-                                               'Data/Graphics/Graves/',         // ptGraves
-                                               'Data/Fonts/',                   // ptFonts
-                                               'Data/Forts/'                    // ptForts
+                                               'Data',                          // ptData
+                                               'Data/Graphics',                 // ptGraphics
+                                               'Data/Themes',                   // ptThemes
+                                               'Data/Themes/avematan',          // ptThemeCurrent
+                                               'Data/Teams',                    // ptTeams
+                                               'Data/Maps',                     // ptMaps
+                                               '',                              // ptMapCurrent
+                                               'Data/Demos',                    // ptDemos
+                                               'Data/Sounds',                   // ptSounds
+                                               'Data/Graphics/Graves',          // ptGraves
+                                               'Data/Fonts',                    // ptFonts
+                                               'Data/Forts'                     // ptForts
                                                );
 
       StuffLoadData: array[TStuff] of record
--- a/hedgewars/uGears.pas	Sun Jan 15 23:56:47 2006 +0000
+++ b/hedgewars/uGears.pas	Thu Jan 19 21:12:20 2006 +0000
@@ -50,7 +50,7 @@
              Kind: TGearType;
              Pos: Longword;
              doStep: TGearStepProcedure;
-             HalfWidth, HalfHeight: integer;
+             Radius: integer;
              Angle, Power : Cardinal;
              DirAngle: real;
              Timer : LongWord;
@@ -89,7 +89,7 @@
 
 procedure DeleteGear(Gear: PGear); forward;
 procedure doMakeExplosion(X, Y, Radius: integer; Mask: LongWord); forward;
-procedure AmmoShove(Ammo, Gear: PGear; Power: Longword); forward;
+procedure AmmoShove(Ammo: PGear; Power: integer); forward;
 function  CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: integer): PGear; forward;
 procedure SpawnBoxOfSmth; forward;
 procedure AfterAttack; forward;
@@ -137,47 +137,40 @@
    Result.Hedgehog:= @CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog];
 case Kind of
    gtAmmo_Bomb: begin
-                Result.HalfWidth:= 4;
-                Result.HalfHeight:= 4;
+                Result.Radius:= 4;
                 Result.Elasticity:= 0.6;
                 Result.Friction:= 0.995;
                 Result.Timer:= Timer
                 end;
     gtHedgehog: begin
-                Result.HalfWidth:= 6;
-                Result.HalfHeight:= cHHHalfHeight;
+                Result.Radius:= cHHRadius;
                 Result.Elasticity:= 0.002;
                 Result.Friction:= 0.999;
                 end;
 gtAmmo_Grenade: begin
-                Result.HalfWidth:= 4;
-                Result.HalfHeight:= 4;
+                Result.Radius:= 4;
                 end;
    gtHealthTag: begin
                 Result.Timer:= 1500;
                 end;
        gtGrave: begin
-                Result.HalfWidth:= 10;
-                Result.HalfHeight:= 10;
+                Result.Radius:= 10;
                 Result.Elasticity:= 0.6;
                 end;
          gtUFO: begin
-                Result.HalfWidth:= 5;
-                Result.HalfHeight:= 2;
+                Result.Radius:= 5;
                 Result.Timer:= 500;
                 Result.Elasticity:= 0.9
                 end;
  gtShotgunShot: begin
                 Result.Timer:= 900;
-                Result.HalfWidth:= 2;
-                Result.HalfHeight:= 2
+                Result.Radius:= 2
                 end;
  gtActionTimer: begin
                 Result.Timer:= Timer
                 end;
   gtPickHammer: begin
-                Result.HalfWidth:= 10;
-                Result.HalfHeight:= 2;
+                Result.Radius:= 10;
                 Result.Timer:= 4000
                 end;
   gtSmokeTrace: begin
@@ -186,8 +179,7 @@
                 Result.State:= 8
                 end;
         gtRope: begin
-                Result.HalfWidth:= 3;
-                Result.HalfHeight:= 3;
+                Result.Radius:= 3;
                 Result.Friction:= 500;
                 RopePoints.Count:= 0;
                 end;
@@ -196,25 +188,22 @@
                 Result.Y:= Result.Y - 25;
                 end;
         gtMine: begin
-                Result.HalfWidth:= 3;
-                Result.HalfHeight:= 3;
+                Result.Radius:= 3;
                 Result.Elasticity:= 0.55;
                 Result.Friction:= 0.995;
                 Result.Timer:= 3000;
                 end;
         gtCase: begin
-                Result.HalfWidth:= 14;
-                Result.HalfHeight:= 14;
+                Result.Radius:= 14;
                 Result.Elasticity:= 0.6
                 end;
   gtDEagleShot: begin
-                Result.HalfWidth:= 1;
-                Result.HalfHeight:= 1;
+                Result.Radius:= 1;
+                Result.Radius:= 1;
                 Result.Health:= 50
                 end;
     gtDynamite: begin
-                Result.HalfWidth:= 3;
-                Result.HalfHeight:= 3;
+                Result.Radius:= 3;
                 Result.Elasticity:= 0.03;
                 Result.Friction:= 0.03;
                 Result.Timer:= 5000;
@@ -231,7 +220,7 @@
 procedure DeleteGear(Gear: PGear);
 var team: PTeam;
 begin
-if Gear.CollIndex < High(Longword) then DeleteCR(Gear);
+if Gear.CollIndex < High(Longword) then DeleteCI(Gear);
 if Gear.Kind = gtHedgehog then
    if CurAmmoGear <> nil then
       begin
@@ -579,19 +568,28 @@
       end
 end;
 
-procedure AmmoShove(Ammo, Gear: PGear; Power: Longword);
+procedure AmmoShove(Ammo: PGear; Power: integer);
+var t: PGearArray;
+    i: integer;
 begin
-case Gear.Kind of
-     gtHedgehog,
-         gtMine,
-         gtCase: begin
-                 inc(Gear.Damage, Power);
-                 Gear.dX:= Ammo.dX * Power * 0.01;
-                 Gear.dY:= Ammo.dY * Power * 0.01;
-                 Gear.Active:= true;
-                 FollowGear:= Gear
-                 end;
-     end;
+t:= CheckGearsCollision(Ammo);
+i:= t.Count;
+while i > 0 do
+    begin
+    dec(i);
+    case t.ar[i].Kind of
+           gtHedgehog,
+               gtMine,
+               gtCase: begin
+                       inc(t.ar[i].Damage, Power);
+                       t.ar[i].dX:= Ammo.dX * Power * 0.01;
+                       t.ar[i].dY:= Ammo.dY * Power * 0.01;
+                       t.ar[i].Active:= true;
+                       DeleteCI(t.ar[i]);
+                       FollowGear:= t.ar[i]
+                       end;
+           end
+    end
 end;
 
 procedure AssignHHCoords;
@@ -676,7 +674,7 @@
         begin
         inc(y);
         i:= x - 13;
-        while (i <= x + 13) and not b do // 13 is gtCase HalfWidth-1
+        while (i <= x + 13) and not b do // 13 is gtCase Radius-1
               begin
               if Land[y, i] <> 0 then
                  begin
--- a/hedgewars/uIO.pas	Sun Jan 15 23:56:47 2006 +0000
+++ b/hedgewars/uIO.pas	Thu Jan 19 21:12:20 2006 +0000
@@ -216,8 +216,8 @@
     ar: array[0..Pred(cMAXFORTPOINTS)] of TPoint;
     p: TPoint;
 begin
-if isRight then Fort:= Pathz[ptForts] + Fort + 'R.txt'
-           else Fort:= Pathz[ptForts] + Fort + 'L.txt';
+if isRight then Fort:= Pathz[ptForts] + '/' + Fort + 'R.txt'
+           else Fort:= Pathz[ptForts] + '/' + Fort + 'L.txt';
 WriteToConsole(msgLoading + Fort + ' ');
 {$I-}
 AssignFile(f, Fort);
--- a/hedgewars/uLand.pas	Sun Jan 15 23:56:47 2006 +0000
+++ b/hedgewars/uLand.pas	Thu Jan 19 21:12:20 2006 +0000
@@ -402,6 +402,11 @@
          ar[i, 3]:= WaveAmplMin + getrandom * WaveAmplDelta;
          ar[i, 4]:= ar[i - 1, 4] + (getrandom * 0.7 + 0.3) * WaveFreqDelta;
          ar[i, 5]:= getrandom * pi * 2;
+         {$IFDEF DEBUGFILE}
+         AddFileLog('Wave params №' + inttostr(i) + ':');
+         AddFileLog('X: ampl = ' + floattostr(ar[i, 0]) + '; freq = ' + floattostr(ar[i, 1]) + '; shift = ' + floattostr(ar[i, 2]));
+         AddFileLog('Y: ampl = ' + floattostr(ar[i, 3]) + '; freq = ' + floattostr(ar[i, 4]) + '; shift = ' + floattostr(ar[i, 5]));
+         {$ENDIF}
          end;
      end;
 
@@ -464,9 +469,10 @@
 var tmpsurf: PSDL_Surface;
     i: Longword;
 begin
+WriteLnToConsole('Generating land...');
 for i:= 0 to sizeof(Land) div 4 do
     PLongword(Longword(@Land) + i * 4)^:= $FFFFFF;
-GenBlank(EdgeTemplates[8{getrandom(Succ(High(EdgeTemplates)))}]);
+GenBlank(EdgeTemplates[getrandom(Succ(High(EdgeTemplates)))]);
 
 AddProgress;
 with PixelFormat^ do
@@ -493,18 +499,19 @@
 var p: PTeam;
     tmpsurf: PSDL_Surface;
 begin
+WriteLnToConsole('Generating forts land...');
 p:= TeamsList;
 TryDo(p <> nil, 'No teams on map!', true);
 with PixelFormat^ do
      LandSurface:= SDL_CreateRGBSurface(SDL_HWSURFACE, 2048, 1024, BitsPerPixel, RMask, GMask, BMask, 0);
 SDL_FillRect(LandSurface, nil, 0);
-tmpsurf:= LoadImage(Pathz[ptForts] + p.FortName + 'L.png', false);
+tmpsurf:= LoadImage(Pathz[ptForts] + '/' + p.FortName + 'L.png', false);
 BlitImageAndGenerateCollisionInfo(0, 0, tmpsurf, LandSurface);
 SDL_FreeSurface(tmpsurf);
 LoadFortPoints(p.FortName, false, TeamSize(p));
 p:= p.Next;
 TryDo(p <> nil, 'Only one team on map!', true);
-tmpsurf:= LoadImage(Pathz[ptForts] + p.FortName + 'R.png', false);
+tmpsurf:= LoadImage(Pathz[ptForts] + '/' + p.FortName + 'R.png', false);
 BlitImageAndGenerateCollisionInfo(1024, 0, tmpsurf, LandSurface);
 SDL_FreeSurface(tmpsurf);
 LoadFortPoints(p.FortName, true, TeamSize(p));
@@ -512,9 +519,57 @@
 TryDo(p = nil, 'More than 2 teams on map in forts mode!', true);
 end;
 
+procedure LoadMap;
+var p, x, y, i: Longword;
+begin
+WriteLnToConsole('Loading land from file...');
+AddProgress;
+LandSurface:= LoadImage(Pathz[ptMapCurrent] + '/map.png', false);
+TryDo((LandSurface.w = 2048) and (LandSurface.h = 1024), 'Map dimensions should be 2048x1024!', true);
+
+if SDL_MustLock(LandSurface) then
+   SDLTry(SDL_LockSurface(LandSurface) >= 0, true);
+
+p:= Longword(LandSurface.pixels);
+i:= Longword(@Land);
+case LandSurface.format.BytesPerPixel of
+     1: OutError('We don''t work with 8 bit surfaces', true);
+     2: for y:= 0 to 1023 do
+            begin
+            for x:= 0 to 2047 do
+                if PWord(p + x * 2)^ <> 0 then PLongWord(i + x * 4)^:= $FFFFFF;
+            inc(i, 2048 * 4);
+            inc(p, LandSurface.pitch);
+            end;
+     3: for y:= 0 to 1023 do
+            begin
+            for x:= 0 to 2047 do
+                if  (PByte(p + x * 3 + 0)^ <> 0)
+                 or (PByte(p + x * 3 + 1)^ <> 0)
+                 or (PByte(p + x * 3 + 2)^ <> 0) then PLongWord(i + x * 4)^:= $FFFFFF;
+            inc(i, 2048 * 4);
+            inc(p, LandSurface.pitch);
+            end;
+     4: for y:= 0 to 1023 do
+            begin
+            for x:= 0 to 2047 do
+                if PLongword(p + x * 4)^ <> 0 then PLongWord(i + x * 4)^:= $FFFFFF;
+            inc(i, 2048 * 4);
+            inc(p, LandSurface.pitch);
+            end;
+     end;
+if SDL_MustLock(LandSurface) then
+   SDL_UnlockSurface(LandSurface);
+
+AddHHPoints;
+RandomizeHHPoints;
+end;
+
 procedure GenMap;
 begin
-if (GameFlags and gfForts) = 0 then GenLandSurface
+if (GameFlags and gfForts) = 0 then
+   if Pathz[ptMapCurrent] <> '' then LoadMap
+                                else GenLandSurface
                                else MakeFortsMap;
 AddProgress;
 {$IFDEF DEBUGFILE}LogLandDigest{$ENDIF}
--- a/hedgewars/uMisc.pas	Sun Jan 15 23:56:47 2006 +0000
+++ b/hedgewars/uMisc.pas	Thu Jan 19 21:12:20 2006 +0000
@@ -136,14 +136,13 @@
 procedure OutError(Msg: String; const isFatalError: boolean=false);
 begin
 {$IFDEF DEBUGFILE}AddFileLog(Msg);{$ENDIF}
+WriteLnToConsole(Msg);
 if isFatalError then
    begin
-   SendIPC('E' + Msg);
-   WriteLn(Msg);
+   SendIPC('E' + GetLastConsoleLine);
    SDL_Quit;
-//   Readln;
    halt(1)
-   end else WriteLnToConsole(Msg)
+   end
 end;
 
 procedure TryDo(Assert: boolean; Msg: string; isFatal: boolean);
@@ -168,7 +167,7 @@
 
 function FloatToStr(n: real): shortstring;
 begin
-str(n, Result)
+str(n:5:5, Result)
 end;
 
 function arctan(const Y, X: real): real;
--- a/hedgewars/uSound.pas	Sun Jan 15 23:56:47 2006 +0000
+++ b/hedgewars/uSound.pas	Thu Jan 19 21:12:20 2006 +0000
@@ -77,7 +77,7 @@
 if not isSoundEnabled then exit;
 for i:= Low(TSound) to High(TSound) do
     begin
-    s:= Pathz[ptSounds] + Soundz[i].FileName;
+    s:= Pathz[ptSounds] + '/' + Soundz[i].FileName;
     WriteToConsole(msgLoading + s + ' ');
     Soundz[i].id:= Mix_LoadWAV_RW(SDL_RWFromFile(PChar(s), 'rb'), 1);
     TryDo(Soundz[i].id <> nil, msgFailed, true);
--- a/hedgewars/uStore.pas	Sun Jan 15 23:56:47 2006 +0000
+++ b/hedgewars/uStore.pas	Thu Jan 19 21:12:20 2006 +0000
@@ -65,7 +65,7 @@
  SDLPrimSurface: PSDL_Surface;
 
 implementation
-uses uMisc, uIO, uConsole, uLand;
+uses uMisc, uIO, uConsole, uLand, uCollisions;
 
 var StoreSurface,
      TempSurface,
@@ -74,9 +74,7 @@
 procedure DrawExplosion(X, Y, Radius: integer);
 var ty, tx, p: integer;
 begin
-for ty:= max(-Radius, -y) to min(radius, 1023 - y) do
-    for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do
-        Land[ty + y, tx]:= 0;
+FillRoundInLand(X, Y, Radius, 0);
 
 if SDL_MustLock(LandSurface) then
    SDLTry(SDL_LockSurface(LandSurface) >= 0, true);
@@ -105,11 +103,11 @@
      1: ;// not supported
      2: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
             for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do
-               if Land[y + ty, tx] <> 0 then
+               if Land[y + ty, tx] = $FFFFFF then
                   PWord(p + LandSurface.pitch*(y + ty) + tx * 2)^:= cExplosionBorderColor;
      3: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
             for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do
-               if Land[y + ty, tx] <> 0 then
+               if Land[y + ty, tx] = $FFFFFF then
                 begin
                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 0)^:= cExplosionBorderColor and $FF;
                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 1)^:= (cExplosionBorderColor shr 8) and $FF;
@@ -117,7 +115,7 @@
                 end;
      4: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
             for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do
-               if Land[y + ty, tx] <> 0 then
+               if Land[y + ty, tx] = $FFFFFF then
                    PLongword(p + LandSurface.pitch*(y + ty) + tx * 4)^:= cExplosionBorderColor;
      end;
 
@@ -164,11 +162,11 @@
      1: ;
      2: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
             for tx:= max(0, round(ar[i].Left - radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(ar[i].Right + radius*sqrt(1-sqr(ty/radius)))) do
-               if Land[y + ty, tx] <> 0 then
+               if Land[y + ty, tx] = $FFFFFF then
                   PWord(p + LandSurface.pitch*(y + ty) + tx * 2)^:= cExplosionBorderColor;
      3: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
             for tx:= max(0, round(ar[i].Left - radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(ar[i].Right + radius*sqrt(1-sqr(ty/radius)))) do
-               if Land[y + ty, tx] <> 0 then
+               if Land[y + ty, tx] = $FFFFFF then
                 begin
                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 0)^:= cExplosionBorderColor and $FF;
                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 1)^:= (cExplosionBorderColor shr 8) and $FF;
@@ -176,7 +174,7 @@
                 end;
      4: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
             for tx:= max(0, round(ar[i].Left - radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(ar[i].Right + radius*sqrt(1-sqr(ty/radius)))) do
-               if Land[y + ty, tx] <> 0 then
+               if Land[y + ty, tx] = $FFFFFF then
                    PLongword(p + LandSurface.pitch*(y + ty) + tx * 4)^:= cExplosionBorderColor;
      end;
     inc(y, dY)
@@ -386,7 +384,7 @@
     r.y:= 256;
     r.w:= 16;
     r.h:= 16;
-    s:= Pathz[ptGraphics] + cCHFileName;
+    s:= Pathz[ptGraphics] + '/' + cCHFileName;
     WriteToConsole(msgLoading + s + ' ');
     tmpsurf:= IMG_Load(PChar(s));
     TryDo(tmpsurf <> nil, msgFailed, true);
@@ -436,7 +434,7 @@
           begin
           dec(l, 32);
           if p.GraveName = '' then p.GraveName:= 'Simple';
-          LoadToSurface(Pathz[ptGraves] + p.GraveName + '.png', StoreSurface, l, 512);
+          LoadToSurface(Pathz[ptGraves] + '/' + p.GraveName + '.png', StoreSurface, l, 512);
           p.GraveRect.x:= l;
           p.GraveRect.y:= 512;
           p.GraveRect.w:= 32;
@@ -465,7 +463,7 @@
     var f: textfile;
         c: integer;
     begin
-    s:= Pathz[ptThemeCurrent] + cThemeCFGFilename;
+    s:= Pathz[ptThemeCurrent] + '/' + cThemeCFGFilename;
     WriteToConsole(msgLoading + s + ' ');
     AssignFile(f, s);
     {$I-}
@@ -490,16 +488,14 @@
 for fi:= Low(THWFont) to High(THWFont) do
     with Fontz[fi] do
          begin
-         s:= Pathz[ptFonts] + Name;
+         s:= Pathz[ptFonts] + '/' + Name;
          WriteToConsole(msgLoading + s + ' ');
          Handle:= TTF_OpenFont(PChar(s), Height);
          TryDo(Handle <> nil, msgFailed, true);
          WriteLnToConsole(msgOK)
          end;
 AddProgress;
-//s:= Pathz[ptMapCurrent] + cLandFileName;
-//WriteToConsole(msgLoading + s + ' ');         
-//tmpsurf:= IMG_Load(PChar(s));
+
 tmpsurf:= LandSurface;
 TryDo(tmpsurf <> nil, msgFailed, true);
 if cFullScreen then
@@ -514,7 +510,7 @@
 
 AddProgress;
 for i:= Low(TStuff) to High(TStuff) do
-    LoadToSurface(Pathz[StuffLoadData[i].Path] + StuffLoadData[i].FileName, StoreSurface, StuffPoz[i].x, StuffPoz[i].y);
+    LoadToSurface(Pathz[StuffLoadData[i].Path] + '/' + StuffLoadData[i].FileName, StoreSurface, StuffPoz[i].x, StuffPoz[i].y);
 
 AddProgress;
 WriteNames(fnt16);
@@ -526,10 +522,10 @@
 AddProgress;
 for ii:= Low(TSprite) to High(TSprite) do
     with SpritesData[ii] do
-         Surface:= LoadImage(Pathz[Path] + FileName, hasAlpha);
+         Surface:= LoadImage(Pathz[Path] + '/' + FileName, hasAlpha);
 
 AddProgress;
-tmpsurf:= LoadImage(Pathz[ptGraphics] + cHHFileName, false);
+tmpsurf:= LoadImage(Pathz[ptGraphics] + '/' + cHHFileName, false);
 TryDo(SDL_SetColorKey(tmpsurf, SDL_SRCCOLORKEY or SDL_RLEACCEL, 0) = 0, errmsgTransparentSet, true);
 HHSurface:= SDL_DisplayFormat(tmpsurf);
 SDL_FreeSurface(tmpsurf);
--- a/hedgewars/uWorld.pas	Sun Jan 15 23:56:47 2006 +0000
+++ b/hedgewars/uWorld.pas	Thu Jan 19 21:12:20 2006 +0000
@@ -126,19 +126,19 @@
                   if Gear.State = 0 then
                      begin
                      DrawCaption( round(Gear.X) + WorldDx,
-                                  round(Gear.Y) - cHHHalfHeight - 30 + WorldDy,
+                                  round(Gear.Y) - cHHRadius - 30 + WorldDy,
                                   HealthRect, Surface, true);
                      DrawCaption( round(Gear.X) + WorldDx,
-                                  round(Gear.Y) - cHHHalfHeight - 54 + WorldDy,
+                                  round(Gear.Y) - cHHRadius - 54 + WorldDy,
                                   NameRect, Surface);
 //                     DrawCaption( round(Gear.X) + WorldDx,
-//                                  round(Gear.Y) - Gear.HalfHeight - 60 + WorldDy,
+//                                  round(Gear.Y) - Gear.Radius - 60 + WorldDy,
 //                                  Team.NameRect, Surface);
                      end else // Current hedgehog
                      begin
                      if (Gear.State and (gstMoving or gstAttacked or gstDrowning or gstFalling))=0 then
                         if (Gear.State and gstHHThinking) <> 0 then
-                           DrawGear(sQuestion, Round(Gear.X)  - 10 + WorldDx, Round(Gear.Y) - cHHHalfHeight - 34 + WorldDy, Surface)
+                           DrawGear(sQuestion, Round(Gear.X)  - 10 + WorldDx, Round(Gear.Y) - cHHRadius - 34 + WorldDy, Surface)
                         else
                         if ShowCrosshair then
                            DrawCaption(Round(Gear.X + Sign(Gear.dX) * Sin(Gear.Angle*pi/cMaxAngle)*60) + WorldDx,