Add an extra pass in FindPlace for AI resurrection mode to try to make it unwinnable, add DeleteGear, DeleteVisualGear, AddVisualGear, GetVisualGearValues, SetVisualGearValues to Lua
--- 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