# HG changeset patch # User nemo # Date 1291333516 18000 # Node ID d393b9ccd328632955ae42b388add8f67cc486fe # Parent f8424e1bc9361739370080506fcdfb53479a6360 Add an extra pass in FindPlace for AI resurrection mode to try to make it unwinnable, add DeleteGear, DeleteVisualGear, AddVisualGear, GetVisualGearValues, SetVisualGearValues to Lua diff -r f8424e1bc936 -r d393b9ccd328 hedgewars/GSHandlers.inc --- 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; diff -r f8424e1bc936 -r d393b9ccd328 hedgewars/uGears.pas --- 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 diff -r f8424e1bc936 -r d393b9ccd328 hedgewars/uScript.pas --- 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); diff -r f8424e1bc936 -r d393b9ccd328 hedgewars/uVisualGears.pas --- 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