Add an extra pass in FindPlace for AI resurrection mode to try to make it unwinnable, add DeleteGear, DeleteVisualGear, AddVisualGear, GetVisualGearValues, SetVisualGearValues to Lua
authornemo
Thu, 02 Dec 2010 18:45:16 -0500
changeset 4443 d393b9ccd328
parent 4442 f8424e1bc936
child 4447 76c12e4649e1
Add an extra pass in FindPlace for AI resurrection mode to try to make it unwinnable, add DeleteGear, DeleteVisualGear, AddVisualGear, GetVisualGearValues, SetVisualGearValues to Lua
hedgewars/GSHandlers.inc
hedgewars/uGears.pas
hedgewars/uScript.pas
hedgewars/uVisualGears.pas
--- a/hedgewars/GSHandlers.inc	Wed Dec 01 22:06:23 2010 +0300
+++ b/hedgewars/GSHandlers.inc	Thu Dec 02 18:45:16 2010 -0500
@@ -1885,13 +1885,12 @@
 
         if ((GameTicks mod 100) = 0) then
             begin
-            vgt:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFire);
+            vgt:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFire, gstTmpFlag);
             if vgt <> nil then
                 begin
                 vgt^.dx:= 0;
                 vgt^.dy:= 0;
                 vgt^.FrameTicks:= 1800 div (Gear^.Tag mod 3 + 2);
-                vgt^.State:= gstTmpFlag;
                 end;
             end;
 
--- a/hedgewars/uGears.pas	Wed Dec 01 22:06:23 2010 +0300
+++ b/hedgewars/uGears.pas	Thu Dec 02 18:45:16 2010 -0500
@@ -40,7 +40,8 @@
 procedure InsertGearToList(Gear: PGear);
 procedure RemoveGearFromList(Gear: PGear);
 function  ModifyDamage(dmg: Longword; Gear: PGear): Longword;
-procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt);
+procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean = false);
+procedure DeleteGear(Gear: PGear); 
 
 
 implementation
@@ -49,7 +50,6 @@
      uCommands, uUtils, uTextures, uRenderUtils, uGearsRender, uCaptions, uDebug;
 
 
-procedure DeleteGear(Gear: PGear); forward;
 procedure doMakeExplosion(X, Y, Radius: LongInt; Mask: LongWord); forward;
 procedure doMakeExplosion(X, Y, Radius: LongInt; Mask, Tint: LongWord); forward;
 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt); forward;
@@ -1459,7 +1459,7 @@
     end;
     tempTeam := gear^.Hedgehog^.Team;
     DeleteCI(gear);
-    FindPlace(gear, false, 0, LAND_WIDTH); 
+    FindPlace(gear, false, 0, LAND_WIDTH, true); 
     if gear <> nil then begin
         RenderHealth(gear^.Hedgehog^);
         ScriptCall('onGearResurrect', gear^.uid);
@@ -1589,7 +1589,7 @@
     end
 end;
 
-procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt);
+procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean = false);
 
     function CountNonZeroz(x, y, r, c: LongInt): LongInt;
     var i: LongInt;
@@ -1611,57 +1611,66 @@
     ar2: array[0..1023] of TPoint;
     cnt, cnt2: Longword;
     delta: LongInt;
+    reallySkip, tryAgain: boolean;
 begin
-delta:= 250;
-cnt2:= 0;
-repeat
-    x:= Left + LongInt(GetRandom(Delta));
+reallySkip:= false; // try not skipping proximity at first
+tryAgain:= true;
+while tryAgain do
+    begin
+    delta:= 250;
+    cnt2:= 0;
     repeat
-        inc(x, Delta);
-        cnt:= 0;
-        y:= min(1024, topY) - 2 * Gear^.Radius;
-        while y < cWaterLine do
-            begin
-            repeat
-                inc(y, 2);
-            until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) = 0);
+        x:= Left + LongInt(GetRandom(Delta));
+        repeat
+            inc(x, Delta);
+            cnt:= 0;
+            y:= min(1024, topY) - 2 * Gear^.Radius;
+            while y < cWaterLine do
+                begin
+                repeat
+                    inc(y, 2);
+                until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) = 0);
 
-            sy:= y;
+                sy:= y;
 
-            repeat
-                inc(y);
-            until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) <> 0);
+                repeat
+                    inc(y);
+                until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) <> 0);
 
-            if (y - sy > Gear^.Radius * 2) and
-               (((Gear^.Kind = gtExplosives)
-                   and (y < cWaterLine)
-                   and (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 60, 60) = nil)
-                   and (CountNonZeroz(x, y+1, Gear^.Radius - 1, Gear^.Radius+1) > Gear^.Radius))
-               or
-                 ((Gear^.Kind <> gtExplosives)
-                   and (y < cWaterLine)
-                   and (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 110, 110) = nil))) then
-                begin
-                ar[cnt].X:= x;
-                if withFall then ar[cnt].Y:= sy + Gear^.Radius
-                            else ar[cnt].Y:= y - Gear^.Radius;
-                inc(cnt)
+                if (y - sy > Gear^.Radius * 2) and
+                   (((Gear^.Kind = gtExplosives)
+                       and (y < cWaterLine)
+                       and (reallySkip or (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 60, 60) = nil))
+                       and (CountNonZeroz(x, y+1, Gear^.Radius - 1, Gear^.Radius+1) > Gear^.Radius))
+                   or
+                     ((Gear^.Kind <> gtExplosives)
+                       and (y < cWaterLine)
+                       and (reallySkip or (CheckGearsNear(x, y - Gear^.Radius, [gtFlame, gtHedgehog, gtMine, gtCase, gtExplosives], 110, 110) = nil)))) then
+                    begin
+                    ar[cnt].X:= x;
+                    if withFall then ar[cnt].Y:= sy + Gear^.Radius
+                                else ar[cnt].Y:= y - Gear^.Radius;
+                    inc(cnt)
+                    end;
+
+                inc(y, 45)
                 end;
 
-            inc(y, 45)
-            end;
+            if cnt > 0 then
+                with ar[GetRandom(cnt)] do
+                    begin
+                    ar2[cnt2].x:= x;
+                    ar2[cnt2].y:= y;
+                    inc(cnt2)
+                    end
+        until (x + Delta > Right);
 
-        if cnt > 0 then
-            with ar[GetRandom(cnt)] do
-                begin
-                ar2[cnt2].x:= x;
-                ar2[cnt2].y:= y;
-                inc(cnt2)
-                end
-    until (x + Delta > Right);
-
-    dec(Delta, 60)
-until (cnt2 > 0) or (Delta < 70);
+        dec(Delta, 60)
+    until (cnt2 > 0) or (Delta < 70);
+    if (cnt2 = 0) and skipProximity and not reallySkip then tryAgain:= true
+    else tryAgain:= false;
+    reallySkip:= true;
+    end;
 
 if cnt2 > 0 then
     with ar2[GetRandom(cnt2)] do
--- a/hedgewars/uScript.pas	Wed Dec 01 22:06:23 2010 +0300
+++ b/hedgewars/uScript.pas	Thu Dec 02 18:45:16 2010 -0500
@@ -228,6 +228,118 @@
     lc_addgear:= 1; // 1 return value
 end;
 
+function lc_deletegear(L : Plua_State) : LongInt; Cdecl;
+var gear : PGear;
+begin
+    if lua_gettop(L) <> 1 then
+        begin
+        LuaError('Lua: Wrong number of parameters passed to DeleteGear!');
+        end
+    else
+        begin
+        gear:= GearByUID(lua_tointeger(L, 1));
+        if gear <> nil then DeleteGear(gear);
+        end;
+    lc_deletegear:= 0
+end;
+
+function lc_addvisualgear(L : Plua_State) : LongInt; Cdecl;
+var vg : PVisualGear;
+    x, y, s: LongInt;
+    c: Boolean;
+    vgt: TVisualGearType;
+begin
+    if lua_gettop(L) <> 5 then
+        begin
+        LuaError('Lua: Wrong number of parameters passed to AddVisualGear!');
+        lua_pushnil(L); // return value on stack (nil)
+        end
+    else
+        begin
+        x:= lua_tointeger(L, 1);
+        y:= lua_tointeger(L, 2);
+        vgt:= TVisualGearType(lua_tointeger(L, 3));
+        s:= lua_tointeger(L, 4);
+        c:= lua_toboolean(L, 5);
+
+        vg:= AddVisualGear(x, y, vgt, s, c); 
+        lua_pushnumber(L, vg^.uid)
+        end;
+    lc_addvisualgear:= 1; // 1 return value
+end;
+
+function lc_deletevisualgear(L : Plua_State) : LongInt; Cdecl;
+var vg : PVisualGear;
+begin
+    if lua_gettop(L) <> 1 then
+        begin
+        LuaError('Lua: Wrong number of parameters passed to DeleteVisualGear!');
+        end
+    else
+        begin
+        vg:= VisualGearByUID(lua_tointeger(L, 1));
+        if vg <> nil then DeleteVisualGear(vg);
+        end;
+    lc_deletevisualgear:= 0
+end;
+
+function lc_getvisualgearvalues(L : Plua_State) : LongInt; Cdecl;
+var vg: PVisualGear;
+begin
+    if lua_gettop(L) <> 1 then
+        begin
+        LuaError('Lua: Wrong number of parameters passed to GetVisualGearValues!');
+        lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
+        lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L)
+        end
+    else
+        begin
+        vg:= VisualGearByUID(lua_tointeger(L, 1));
+        if vg <> nil then
+            begin
+            lua_pushinteger(L, round(vg^.X));
+            lua_pushinteger(L, round(vg^.Y));
+            lua_pushnumber(L, vg^.dX);
+            lua_pushnumber(L, vg^.dY);
+            lua_pushnumber(L, vg^.Angle);
+            lua_pushinteger(L, vg^.Frame);
+            lua_pushinteger(L, vg^.FrameTicks);
+            lua_pushinteger(L, vg^.State);
+            lua_pushinteger(L, vg^.Timer);
+            lua_pushinteger(L, vg^.Tint);
+            end
+        end;
+    lc_getvisualgearvalues:= 10;
+end;
+
+function lc_setvisualgearvalues(L : Plua_State) : LongInt; Cdecl;
+var vg : PVisualGear;
+begin
+    if lua_gettop(L) <> 10 then
+        begin
+        LuaError('Lua: Wrong number of parameters passed to SetVisualGearValues!');
+        lua_pushnil(L); // return value on stack (nil)
+        end
+    else
+        begin
+        vg:= VisualGearByUID(lua_tointeger(L, 1));
+        if vg <> nil then
+            begin
+            vg^.X:= lua_tointeger(L, 1);
+            vg^.Y:= lua_tointeger(L, 2);
+            vg^.dX:= lua_tonumber(L, 3);
+            vg^.dY:= lua_tonumber(L, 4);
+            vg^.Angle:= lua_tonumber(L, 5);
+            vg^.Frame:= lua_tointeger(L, 6);
+            vg^.FrameTicks:= lua_tointeger(L, 7);
+            vg^.State:= lua_tointeger(L, 8);
+            vg^.Timer:= lua_tointeger(L, 9);
+            vg^.Tint:= lua_tointeger(L, 10);
+            end
+        end;
+    lc_setvisualgearvalues:= 0;
+end;
+
 function lc_getfollowgear(L : Plua_State) : LongInt; Cdecl;
 begin
     if lua_gettop(L) <> 0 then
@@ -1186,6 +1298,11 @@
 
 // register functions
 lua_register(luaState, 'AddGear', @lc_addgear);
+lua_register(luaState, 'DeleteGear', @lc_deletegear);
+lua_register(luaState, 'AddVisualGear', @lc_addvisualgear);
+lua_register(luaState, 'DeleteVisualGear', @lc_deletevisualgear);
+lua_register(luaState, 'GetVisualGearValues', @lc_getvisualgearvalues);
+lua_register(luaState, 'SetVisualGearValues', @lc_setvisualgearvalues);
 lua_register(luaState, 'SpawnHealthCrate', @lc_spawnhealthcrate);
 lua_register(luaState, 'SpawnAmmoCrate', @lc_spawnammocrate);
 lua_register(luaState, 'SpawnUtilityCrate', @lc_spawnutilitycrate);
--- a/hedgewars/uVisualGears.pas	Wed Dec 01 22:06:23 2010 +0300
+++ b/hedgewars/uVisualGears.pas	Thu Dec 02 18:45:16 2010 -0500
@@ -30,6 +30,7 @@
 procedure KickFlakes(Radius, X, Y: LongInt);
 procedure DrawVisualGears(Layer: LongWord);
 procedure DeleteVisualGear(Gear: PVisualGear);
+function  VisualGearByUID(uid : Longword) : PVisualGear;
 procedure AddClouds;
 procedure AddDamageTag(X, Y, Damage, Color: LongWord);
 
@@ -480,6 +481,22 @@
     end
 end;
 
+function  VisualGearByUID(uid : Longword) : PVisualGear;
+var vg: PVisualGear;
+begin
+VisualGearByUID:= nil;
+vg:= VisualGearsList;
+while vg <> nil do
+    begin
+    if vg^.uid = uid then
+        begin
+            VisualGearByUID:= vg;
+            exit
+        end;
+    vg:= vg^.NextGear
+    end
+end;
+
 procedure AddClouds;
 var i: LongInt;
 begin