- Improve renderer a bit, disallow nested functions
authorunc0rr
Thu, 01 Dec 2011 18:02:27 +0400
changeset 6474 42e9773eedfd
parent 6473 2bed5ba1a7ea
child 6475 fb50269c3953
- Improve renderer a bit, disallow nested functions - Start getting rid of nested functions
hedgewars/GSHandlers.inc
hedgewars/uAIActions.pas
hedgewars/uAIAmmoTests.pas
hedgewars/uAIMisc.pas
tools/pas2c.hs
--- a/hedgewars/GSHandlers.inc	Thu Dec 01 11:30:06 2011 +0400
+++ b/hedgewars/GSHandlers.inc	Thu Dec 01 18:02:27 2011 +0400
@@ -1378,15 +1378,7 @@
     end
 end;
 
-procedure doStepRopeWork(Gear: PGear);
-var 
-    HHGear: PGear;
-    len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat;
-    lx, ly, cd: LongInt;
-    haveCollision,
-    haveDivided: boolean;
-
-procedure DeleteMe;
+procedure RopeDeleteMe(Gear, HHGear: PGear);
 begin
     with HHGear^ do
     begin
@@ -1396,7 +1388,7 @@
     DeleteGear(Gear)
 end;
 
-procedure WaitCollision;
+procedure RopeWaitCollision(Gear, HHGear: PGear);
 begin
     with HHGear^ do
     begin
@@ -1408,6 +1400,14 @@
     Gear^.doStep := @doStepRopeAfterAttack
 end;
 
+procedure doStepRopeWork(Gear: PGear);
+var 
+    HHGear: PGear;
+    len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat;
+    lx, ly, cd: LongInt;
+    haveCollision,
+    haveDivided: boolean;
+
 begin
     HHGear := Gear^.Hedgehog^.Gear;
 
@@ -1415,7 +1415,7 @@
        or (CheckGearDrowning(HHGear)) then
         begin
         PlaySound(sndRopeRelease);
-        DeleteMe;
+        RopeDeleteMe(Gear, HHGear);
         exit
         end;
 
@@ -1629,9 +1629,9 @@
                 begin
                 PlaySound(sndRopeRelease);
                 if CurAmmoType <> amParachute then
-                    WaitCollision
+                    RopeWaitCollision(Gear, HHGear)
                 else
-                    DeleteMe
+                    RopeDeleteMe(Gear, HHGear)
                 end
         end
     else
@@ -1639,12 +1639,7 @@
             Gear^.State := Gear^.State or gsttmpFlag;
 end;
 
-procedure doStepRopeAttach(Gear: PGear);
-var 
-    HHGear: PGear;
-    tx, ty, tt: hwFloat;
-
-procedure RemoveFromAmmo;
+procedure RopeRemoveFromAmmo(Gear, HHGear: PGear);
 begin
     if (Gear^.State and gstAttacked) = 0 then
     begin
@@ -1654,6 +1649,10 @@
     ApplyAmmoChanges(HHGear^.Hedgehog^)
 end;
 
+procedure doStepRopeAttach(Gear: PGear);
+var 
+    HHGear: PGear;
+    tx, ty, tt: hwFloat;
 begin
     Gear^.X := Gear^.X - Gear^.dX;
     Gear^.Y := Gear^.Y - Gear^.dY;
@@ -1702,7 +1701,7 @@
                     Message := Message and (not gmAttack)
                     end;
 
-                RemoveFromAmmo;
+                RopeRemoveFromAmmo(Gear, HHGear);
 
                 tt := _0;
                 exit
@@ -1728,7 +1727,7 @@
             Message := Message and (not gmAttack)
             end;
 
-        RemoveFromAmmo;
+        RopeRemoveFromAmmo(Gear, HHGear);
 
         exit
         end;
--- a/hedgewars/uAIActions.pas	Thu Dec 01 11:30:06 2011 +0400
+++ b/hedgewars/uAIActions.pas	Thu Dec 01 18:02:27 2011 +0400
@@ -119,28 +119,27 @@
      end
 end;
 
+procedure CheckHang(Me: PGear);
+const PrevX: LongInt = 0;
+      timedelta: Longword = 0;
+begin
+if hwRound(Me^.X) <> PrevX then
+   begin
+   PrevX:= hwRound(Me^.X);
+   timedelta:= 0
+   end else
+   begin
+   inc(timedelta);
+   if timedelta > 1700 then
+      begin
+      timedelta:= 0;
+      FreeActionsList
+      end
+   end
+end;
+
 procedure ProcessAction(var Actions: TActions; Me: PGear);
 var s: shortstring;
-
-    procedure CheckHang;
-    const PrevX: LongInt = 0;
-          timedelta: Longword = 0;
-    begin
-    if hwRound(Me^.X) <> PrevX then
-       begin
-       PrevX:= hwRound(Me^.X);
-       timedelta:= 0
-       end else
-       begin
-       inc(timedelta);
-       if timedelta > 1700 then
-          begin
-          timedelta:= 0;
-          FreeActionsList
-          end
-       end
-    end;
-
 begin
 repeat
 if Actions.Pos >= Actions.Count then exit;
@@ -165,7 +164,7 @@
                                FreeActionsList;
                                exit
                                end
-                          else begin CheckHang; exit end;
+                          else begin CheckHang(Me); exit end;
            aia_WaitXR: if hwRound(Me^.X) = Param then
                           begin
                           Action:= aia_LookRight;
@@ -178,7 +177,7 @@
                                FreeActionsList;
                                exit
                                end
-                          else begin CheckHang; exit end;
+                          else begin CheckHang(Me); exit end;
          aia_LookLeft: if not Me^.dX.isNegative then
                           begin
                           ParseCommand('+left', true);
--- a/hedgewars/uAIAmmoTests.pas	Thu Dec 01 11:30:06 2011 +0400
+++ b/hedgewars/uAIAmmoTests.pas	Thu Dec 01 18:02:27 2011 +0400
@@ -124,33 +124,11 @@
 function TestBazooka(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
 var Vx, Vy, r, mX, mY: real;
     rTime: LongInt;
-    Score, EX, EY: LongInt;
+    EX, EY: LongInt;
     valueResult: LongInt;
-
-    function CheckTrace: LongInt;
-    var x, y, dX, dY: real;
-        t: LongInt;
-        value: LongInt;
-    begin
-    x:= mX;
-    y:= mY;
-    dX:= Vx;
-    dY:= -Vy;
-    t:= rTime;
-    repeat
-      x:= x + dX;
-      y:= y + dY;
-      dX:= dX + cWindSpeedf;
-      dY:= dY + cGravityf;
-      dec(t)
-    until TestCollExcludingMe(Me, trunc(x), trunc(y), 5) or (t <= 0);
-    EX:= trunc(x);
-    EY:= trunc(y);
-    value:= RateExplosion(Me, EX, EY, 101);
-    if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
-    CheckTrace:= value;
-    end;
-
+    x, y, dX, dY: real;
+    t: LongInt;
+    value: LongInt;
 begin
 mX:= hwFloat2Float(Me^.X);
 mY:= hwFloat2Float(Me^.Y);
@@ -165,15 +143,30 @@
   r:= sqrt(sqr(Vx) + sqr(Vy));
   if not (r > 1) then
      begin
-     Score:= CheckTrace;
-     if valueResult <= Score then
+        x:= mX;
+        y:= mY;
+        dX:= Vx;
+        dY:= -Vy;
+        t:= rTime;
+        repeat
+              x:= x + dX;
+              y:= y + dY;
+              dX:= dX + cWindSpeedf;
+              dY:= dY + cGravityf;
+              dec(t)
+        until TestCollExcludingMe(Me, trunc(x), trunc(y), 5) or (t <= 0);
+        EX:= trunc(x);
+        EY:= trunc(y);
+        value:= RateExplosion(Me, EX, EY, 101);
+        if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
+     if valueResult <= value then
         begin
         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
         ap.Power:= trunc(r * cMaxPower) - random((Level - 1) * 17 + 1);
         ap.ExplR:= 100;
         ap.ExplX:= EX;
         ap.ExplY:= EY;
-        valueResult:= Score
+        valueResult:= value
         end;
      end
 until (rTime > 4250);
@@ -183,32 +176,11 @@
 function TestSnowball(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
 var Vx, Vy, r: hwFloat;
     rTime: LongInt;
-    Score, EX, EY: LongInt;
+    EX, EY: LongInt;
     valueResult: LongInt;
-
-    function CheckTrace: LongInt;
-    var x, y, dX, dY: hwFloat;
-        t: LongInt;
-        value: LongInt;
-    begin
-    x:= Me^.X;
-    y:= Me^.Y;
-    dX:= Vx;
-    dY:= -Vy;
-    t:= rTime;
-    repeat
-      x:= x + dX;
-      y:= y + dY;
-      dX:= dX + cWindSpeed;
-      dY:= dY + cGravity;
-      dec(t)
-    until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t <= 0);
-    EX:= hwRound(x);
-    EY:= hwRound(y);
-    value:= RateExplosion(Me, EX, EY, 5);
-    if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
-    CheckTrace:= value;
-    end;
+    x, y, dX, dY: hwFloat;
+    t: LongInt;
+    value: LongInt;
 
 begin
 ap.Time:= 0;
@@ -222,16 +194,32 @@
   r:= Distance(Vx, Vy);
   if not (r > _1) then
      begin
-     Score:= CheckTrace;
-     if valueResult <= Score then
-        begin
-        ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
-        ap.Power:= hwRound(r * cMaxPower) - random((Level - 1) * 17 + 1);
-        ap.ExplR:= 100;
-        ap.ExplX:= EX;
-        ap.ExplY:= EY;
-        valueResult:= Score
-        end;
+        x:= Me^.X;
+        y:= Me^.Y;
+        dX:= Vx;
+        dY:= -Vy;
+        t:= rTime;
+        repeat
+          x:= x + dX;
+          y:= y + dY;
+          dX:= dX + cWindSpeed;
+          dY:= dY + cGravity;
+          dec(t)
+        until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t <= 0);
+        EX:= hwRound(x);
+        EY:= hwRound(y);
+        value:= RateExplosion(Me, EX, EY, 5);
+        if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
+
+        if valueResult <= value then
+            begin
+            ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
+            ap.Power:= hwRound(r * cMaxPower) - random((Level - 1) * 17 + 1);
+            ap.ExplR:= 100;
+            ap.ExplX:= EX;
+            ap.ExplY:= EY;
+            valueResult:= value
+            end;
      end
 until (rTime > 4250);
 TestSnowball:= valueResult
@@ -241,26 +229,8 @@
 var Vx, Vy, r: hwFloat;
     Score, EX, EY, valueResult: LongInt;
     TestTime: Longword;
-
-    function CheckTrace: LongInt;
-    var x, y, dY: hwFloat;
-        t: LongInt;
-    begin
-    x:= Me^.X;
-    y:= Me^.Y;
-    dY:= -Vy;
-    t:= TestTime;
-    repeat
-      x:= x + Vx;
-      y:= y + dY;
-      dY:= dY + cGravity;
-      dec(t)
-    until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 7) or (t = 0);
-    EX:= hwRound(x);
-    EY:= hwRound(y);
-    if t < 50 then CheckTrace:= RateExplosion(Me, EX, EY, 97)  // average of 17 attempts, most good, but some failing spectacularly
-              else CheckTrace:= BadTurn
-    end;
+    x, y, dY: hwFloat;
+    t: LongInt;
 begin
 valueResult:= BadTurn;
 TestTime:= 0;
@@ -272,17 +242,31 @@
   r:= Distance(Vx, Vy);
   if not (r > _1) then
      begin
-     Score:= CheckTrace;
-     if valueResult < Score then
-        begin
-        ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
-        ap.Power:= hwRound(r * cMaxPower) + AIrndSign(random(Level) * 15);
-        ap.Time:= TestTime;
-        ap.ExplR:= 100;
-        ap.ExplX:= EX;
-        ap.ExplY:= EY;
-        valueResult:= Score
-        end;
+        x:= Me^.X;
+        y:= Me^.Y;
+        dY:= -Vy;
+        t:= TestTime;
+        repeat
+          x:= x + Vx;
+          y:= y + dY;
+          dY:= dY + cGravity;
+          dec(t)
+        until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 7) or (t = 0);
+        EX:= hwRound(x);
+        EY:= hwRound(y);
+        if t < 50 then Score:= RateExplosion(Me, EX, EY, 97)  // average of 17 attempts, most good, but some failing spectacularly
+                  else Score:= BadTurn;
+                  
+        if valueResult < Score then
+            begin
+            ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
+            ap.Power:= hwRound(r * cMaxPower) + AIrndSign(random(Level) * 15);
+            ap.Time:= TestTime;
+            ap.ExplR:= 100;
+            ap.ExplX:= EX;
+            ap.ExplY:= EY;
+            valueResult:= Score
+            end;
      end
 until (TestTime > 4250);
 TestMolotov:= valueResult
@@ -293,26 +277,8 @@
 var Vx, Vy, r: hwFloat;
     Score, EX, EY, valueResult: LongInt;
     TestTime: Longword;
-
-    function CheckTrace: LongInt;
-    var x, y, dY: hwFloat;
-        t: LongInt;
-    begin
-    x:= Me^.X;
-    y:= Me^.Y;
-    dY:= -Vy;
-    t:= TestTime;
-    repeat
-      x:= x + Vx;
-      y:= y + dY;
-      dY:= dY + cGravity;
-      dec(t)
-    until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0);
-    EX:= hwRound(x);
-    EY:= hwRound(y);
-    if t < 50 then CheckTrace:= RateExplosion(Me, EX, EY, 101)
-              else CheckTrace:= BadTurn
-    end;
+    x, y, dY: hwFloat;
+    t: LongInt;
 begin
 valueResult:= BadTurn;
 TestTime:= 0;
@@ -323,9 +289,25 @@
   Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime + tDelta);
   r:= Distance(Vx, Vy);
   if not (r > _1) then
-     begin
-     Score:= CheckTrace;
-     if valueResult < Score then
+    begin
+    x:= Me^.X;
+    y:= Me^.Y;
+    dY:= -Vy;
+    t:= TestTime;
+    repeat
+        x:= x + Vx;
+        y:= y + dY;
+        dY:= dY + cGravity;
+        dec(t)
+    until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0);
+    EX:= hwRound(x);
+    EY:= hwRound(y);
+    if t < 50 then 
+        Score:= RateExplosion(Me, EX, EY, 101)
+    else 
+        Score:= BadTurn;
+
+    if valueResult < Score then
         begin
         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
         ap.Power:= hwRound(r * cMaxPower) + AIrndSign(random(Level) * 15);
@@ -335,7 +317,7 @@
         ap.ExplY:= EY;
         valueResult:= Score
         end;
-     end
+    end
 until (TestTime = 4000);
 TestGrenade:= valueResult
 end;
@@ -345,26 +327,8 @@
 var Vx, Vy, r: hwFloat;
     Score, EX, EY, valueResult: LongInt;
     TestTime: Longword;
-
-    function CheckTrace: LongInt;
-    var x, y, dY: hwFloat;
-        t: LongInt;
-    begin
-    x:= Me^.X;
-    y:= Me^.Y;
-    dY:= -Vy;
-    t:= TestTime;
-    repeat
-      x:= x + Vx;
-      y:= y + dY;
-      dY:= dY + cGravity;
-      dec(t)
-    until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0);
-    EX:= hwRound(x);
-    EY:= hwRound(y);
-    if t < 50 then CheckTrace:= RateExplosion(Me, EX, EY, 41)
-              else CheckTrace:= BadTurn
-    end;
+    x, y, dY: hwFloat;
+    t: LongInt;
 begin
 valueResult:= BadTurn;
 TestTime:= 0;
@@ -380,7 +344,23 @@
   r:= Distance(Vx, Vy);
   if not (r > _1) then
      begin
-     Score:= CheckTrace;
+    x:= Me^.X;
+    y:= Me^.Y;
+    dY:= -Vy;
+    t:= TestTime;
+    repeat
+        x:= x + Vx;
+        y:= y + dY;
+        dY:= dY + cGravity;
+        dec(t)
+    until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0);
+    EX:= hwRound(x);
+    EY:= hwRound(y);
+    if t < 50 then 
+        Score:= RateExplosion(Me, EX, EY, 41)
+    else 
+        Score:= BadTurn;
+
      if valueResult < Score then
         begin
         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
@@ -401,26 +381,8 @@
 var Vx, Vy, r: hwFloat;
     Score, EX, EY, valueResult: LongInt;
     TestTime: Longword;
-
-    function CheckTrace: LongInt;
-    var x, y, dY: hwFloat;
-        t: LongInt;
-    begin
-    x:= Me^.X;
-    y:= Me^.Y;
-    dY:= -Vy;
-    t:= TestTime;
-    repeat
-      x:= x + Vx;
-      y:= y + dY;
-      dY:= dY + cGravity;
-      dec(t)
-    until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0);
-    EX:= hwRound(x);
-    EY:= hwRound(y);
-    if t < 50 then CheckTrace:= RateExplosion(Me, EX, EY, 381)
-              else CheckTrace:= BadTurn
-    end;
+    x, y, dY: hwFloat;
+    t: LongInt;
 begin
 valueResult:= BadTurn;
 TestTime:= 0;
@@ -431,9 +393,25 @@
   Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y-200) - Me^.Y) / int2hwFloat(TestTime + tDelta);
   r:= Distance(Vx, Vy);
   if not (r > _1) then
-     begin
-     Score:= CheckTrace;
-     if valueResult < Score then
+    begin
+    x:= Me^.X;
+    y:= Me^.Y;
+    dY:= -Vy;
+    t:= TestTime;
+    repeat
+        x:= x + Vx;
+        y:= y + dY;
+        dY:= dY + cGravity;
+        dec(t)
+    until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0);
+    EX:= hwRound(x);
+    EY:= hwRound(y);
+    if t < 50 then 
+        Score:= RateExplosion(Me, EX, EY, 381)
+    else 
+        Score:= BadTurn;
+        
+    if valueResult < Score then
         begin
         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
         ap.Power:= hwRound(r * cMaxPower * _0_9) + AIrndSign(random(Level) * 15);
@@ -443,56 +421,19 @@
         ap.ExplY:= EY;
         valueResult:= Score
         end;
-     end
+    end
 until (TestTime = 4000);
 TestWatermelon:= valueResult
 end;
 
-function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-//const tDelta = 24;
-var Vx, Vy: hwFloat;
-    Score, EX, EY, valueResult: LongInt;
-    TestTime: Longword;
 
-    function CheckTrace: LongInt;
-    var x, y, dY: hwFloat;
-        value: LongInt;
-    begin
-        x:= Me^.X;
-        y:= Me^.Y;
-        dY:= -Vy;
-
-        repeat
-            x:= x + Vx;
-            y:= y + dY;
-            dY:= dY + cGravity;
-            EX:= hwRound(x);
-            EY:= hwRound(y);
-        until TestCollExcludingMe(Me, EX, EY, 5) or (EY > cWaterLine);
-
-        if (EY < cWaterLine) and (not dY.isNegative) then
-            begin
-            value:= RateExplosion(Me, EX, EY, 91);
-            if (value = 0) then
-                if (dY > _0_15) then
-                    value:= - abs(Targ.Y - EY) div 32
-                else
-                    value:= BadTurn
-            else if (value < 0) then value:= BadTurn
-            end
-        else
-            value:= BadTurn;
-
-        CheckTrace:= value;
-    end;
-
-    function Solve: LongWord;
+    function Solve(TX, TY, MX, MY: LongInt): LongWord;
     var A, B, D, T: hwFloat;
         C: LongInt;
     begin
         A:= hwSqr(cGravity) * _0_25;
-        B:= - cGravity * (Targ.Y - hwRound(Me^.Y)) - _1;
-        C:= sqr(Targ.Y - hwRound(Me^.Y)) + sqr(Targ.X - hwRound(Me^.X));
+        B:= - cGravity * (TY - MY) - _1;
+        C:= sqr(TY - MY) + sqr(TX - MX);
         D:= hwSqr(B) - (A * C * 4);
         if D.isNegative = false then
             begin
@@ -504,21 +445,51 @@
             Solve:= hwRound(T)
             end else Solve:= 0
     end;
-
+    
+function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+//const tDelta = 24;
+var Vx, Vy: hwFloat;
+    Score, EX, EY, valueResult: LongInt;
+    TestTime: Longword;
+    x, y, dY: hwFloat;
 begin
 valueResult:= BadTurn;
 ap.ExplR:= 0;
 
 if (Level > 2) then exit(BadTurn);
 
-TestTime:= Solve;
+TestTime:= Solve(Targ.X, Targ.Y, hwRound(Me^.X), hwRound(Me^.Y));
 
 if TestTime = 0 then exit(BadTurn);
 
     Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime);
     Vy:= cGravity * (TestTime div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime);
 
-    Score:= CheckTrace;
+    x:= Me^.X;
+    y:= Me^.Y;
+    dY:= -Vy;
+
+    repeat
+        x:= x + Vx;
+        y:= y + dY;
+        dY:= dY + cGravity;
+        EX:= hwRound(x);
+        EY:= hwRound(y);
+    until TestCollExcludingMe(Me, EX, EY, 5) or (EY > cWaterLine);
+
+    if (EY < cWaterLine) and (not dY.isNegative) then
+        begin
+        Score:= RateExplosion(Me, EX, EY, 91);
+        if (Score = 0) then
+            if (dY > _0_15) then
+                Score:= - abs(Targ.Y - EY) div 32
+            else
+                Score:= BadTurn
+        else if (Score < 0) then Score:= BadTurn
+        end
+    else
+        Score:= BadTurn;
+
     if valueResult < Score then
         begin
         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
--- a/hedgewars/uAIMisc.pas	Thu Dec 01 11:30:06 2011 +0400
+++ b/hedgewars/uAIMisc.pas	Thu Dec 01 18:02:27 2011 +0400
@@ -115,20 +115,19 @@
 else friendlyfactor:= max(30, 300 - f * 80 div max(1,e))
 end;
 
+procedure AddBonus(x, y: LongInt; r: Longword; s: LongInt);
+begin
+bonuses.ar[bonuses.Count].x:= x;
+bonuses.ar[bonuses.Count].y:= y;
+bonuses.ar[bonuses.Count].Radius:= r;
+bonuses.ar[bonuses.Count].Score:= s;
+inc(bonuses.Count);
+TryDo(bonuses.Count <= MAXBONUS, 'Bonuses overflow', true)
+end;
+
 procedure FillBonuses(isAfterAttack: boolean; filter: TGearsType);
 var Gear: PGear;
     MyClan: PClan;
-
-    procedure AddBonus(x, y: LongInt; r: Longword; s: LongInt);
-    begin
-    bonuses.ar[bonuses.Count].x:= x;
-    bonuses.ar[bonuses.Count].y:= y;
-    bonuses.ar[bonuses.Count].Radius:= r;
-    bonuses.ar[bonuses.Count].Score:= s;
-    inc(bonuses.Count);
-    TryDo(bonuses.Count <= MAXBONUS, 'Bonuses overflow', true)
-    end;
-
 begin
 bonuses.Count:= 0;
 MyClan:= ThinkingHH^.Hedgehog^.Team^.Clan;
--- a/tools/pas2c.hs	Thu Dec 01 11:30:06 2011 +0400
+++ b/tools/pas2c.hs	Thu Dec 01 18:02:27 2011 +0400
@@ -52,10 +52,14 @@
 
 toCFiles :: (String, PascalUnit) -> IO ()
 toCFiles (_, System) = return ()
-toCFiles (fn, p@(Program {})) = writeFile (fn ++ ".c") $ (render . pascal2C) p
-toCFiles (fn, (Unit _ interface implementation _ _)) = do
-    writeFile (fn ++ ".h") $ (render . interface2C) interface
-    writeFile (fn ++ ".c") $ (render . implementation2C) implementation
+toCFiles p@(fn, pu) = do
+    hPutStrLn stderr $ "Rendering '" ++ fn ++ "'..."
+    toCFiles' p
+    where
+    toCFiles' (fn, p@(Program {})) = writeFile (fn ++ ".c") $ (render . pascal2C) p
+    toCFiles' (fn, (Unit _ interface implementation _ _)) = do
+        writeFile (fn ++ ".h") $ (render . interface2C) interface
+        writeFile (fn ++ ".c") $ (render . implementation2C) implementation
                             
 usesFiles :: PascalUnit -> [String]
 usesFiles (Program _ (Implementation uses _) _) = uses2List uses
@@ -71,18 +75,18 @@
 pascal2C (Program _ implementation mainFunction) =
     implementation2C implementation
     $+$
-    tvar2C (FunctionDeclaration (Identifier "main") (SimpleType $ Identifier "int") [] (Just (TypesAndVars [], mainFunction)))
+    tvar2C True (FunctionDeclaration (Identifier "main") (SimpleType $ Identifier "int") [] (Just (TypesAndVars [], mainFunction)))
     
     
 interface2C :: Interface -> Doc
-interface2C (Interface uses tvars) = uses2C uses $+$ typesAndVars2C tvars
+interface2C (Interface uses tvars) = uses2C uses $+$ typesAndVars2C True tvars
 
 implementation2C :: Implementation -> Doc
-implementation2C (Implementation uses tvars) = uses2C uses $+$ typesAndVars2C tvars
+implementation2C (Implementation uses tvars) = uses2C uses $+$ typesAndVars2C True tvars
 
 
-typesAndVars2C :: TypesAndVars -> Doc
-typesAndVars2C (TypesAndVars ts) = vcat $ map tvar2C ts
+typesAndVars2C :: Bool -> TypesAndVars -> Doc
+typesAndVars2C b (TypesAndVars ts) = vcat $ map (tvar2C b) ts
 
 uses2C :: Uses -> Doc
 uses2C uses = vcat $ map (\i -> text $ "#include \"" ++ i ++ ".h\"") $ uses2List uses
@@ -90,15 +94,15 @@
 uses2List :: Uses -> [String]
 uses2List (Uses ids) = map (\(Identifier i) -> i) ids
 
-tvar2C :: TypeVarDeclaration -> Doc
-tvar2C (FunctionDeclaration (Identifier name) returnType params Nothing) = 
-    type2C returnType <+> text name <> parens (hcat $ map tvar2C params) <> text ";"
-tvar2C (FunctionDeclaration (Identifier name) returnType params (Just (tvars, phrase))) = 
-    type2C returnType <+> text name <> parens (hcat $ map tvar2C params)
+tvar2C :: Bool -> TypeVarDeclaration -> Doc
+tvar2C _ (FunctionDeclaration (Identifier name) returnType params Nothing) = 
+    type2C returnType <+> text name <> parens (hcat $ map (tvar2C False) params) <> text ";"
+tvar2C True (FunctionDeclaration (Identifier name) returnType params (Just (tvars, phrase))) = 
+    type2C returnType <+> text name <> parens (hcat $ map (tvar2C False) params)
     $+$
     text "{" 
     $+$ nest 4 (
-        typesAndVars2C tvars
+        typesAndVars2C False tvars
         $+$
         phrase2C' phrase
         )
@@ -107,8 +111,9 @@
     where
     phrase2C' (Phrases p) = vcat $ map phrase2C p
     phrase2C' p = phrase2C p
-tvar2C (TypeDeclaration (Identifier i) t) = text "type" <+> text i <+> type2C t <> text ";"
-tvar2C (VarDeclaration isConst (ids, t) mInitExpr) = 
+tvar2C False (FunctionDeclaration (Identifier name) _ _ _) = error $ "nested functions not allowed: " ++ name
+tvar2C _ (TypeDeclaration (Identifier i) t) = text "type" <+> text i <+> type2C t <> text ";"
+tvar2C _ (VarDeclaration isConst (ids, t) mInitExpr) = 
     if isConst then text "const" else empty
     <+>
     type2C t
@@ -121,8 +126,8 @@
     where
     initExpr Nothing = empty
     initExpr (Just e) = text "=" <+> initExpr2C e
-tvar2C (OperatorDeclaration op _ ret params body) = 
-    tvar2C (FunctionDeclaration (Identifier "<op>") ret params body)
+tvar2C f (OperatorDeclaration op _ ret params body) = 
+    tvar2C f (FunctionDeclaration (Identifier $ "<op " ++ op ++ ">") ret params body)
 
 initExpr2C :: InitExpression -> Doc
 initExpr2C (InitBinOp op expr1 expr2) = parens $ (initExpr2C expr1) <+> op2C op <+> (initExpr2C expr2)
@@ -140,7 +145,7 @@
 type2C (String l) = text $ "string" ++ show l
 type2C (SimpleType (Identifier i)) = text i
 type2C (PointerTo t) = type2C t <> text "*"
-type2C (RecordType tvs union) = text "{" $+$ (nest 4 . vcat . map tvar2C $ tvs) $+$ text "}"
+type2C (RecordType tvs union) = text "{" $+$ (nest 4 . vcat . map (tvar2C False) $ tvs) $+$ text "}"
 type2C (RangeType r) = text "<<range type>>"
 type2C (Sequence ids) = text "<<sequence type>>"
 type2C (ArrayDecl r t) = text "<<array type>>"