# HG changeset patch # User nemo # Date 1428551975 14400 # Node ID fbf6fbe66092274db36ace08483379a132ff5300 # Parent de52c2b8b77377e7bd2da082f4b85a6c438ea1d4 also erase diff -r de52c2b8b773 -r fbf6fbe66092 hedgewars/uLandGraphics.pas --- a/hedgewars/uLandGraphics.pas Wed Apr 08 15:10:44 2015 -0400 +++ b/hedgewars/uLandGraphics.pas Wed Apr 08 23:59:35 2015 -0400 @@ -51,6 +51,7 @@ function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; LandFlags: Word): boolean; inline; function ForcePlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; LandFlags: Word; Tint: LongWord; Behind, flipHoriz, flipVert: boolean): boolean; inline; function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, outOfMap, force, behind, flipHoriz, flipVert: boolean; LandFlags: Word; Tint: LongWord): boolean; +procedure EraseLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; LandFlags: Word; eraseOnLFMatch, flipHoriz, flipVert: boolean); function GetPlaceCollisionTex(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt): PTexture; implementation @@ -739,8 +740,8 @@ SDL_UnlockSurface(Image); exit end; - p:= PByteArray(@(p^[Image^.pitch])); - end; + p:= PByteArray(@(p^[Image^.pitch])) + end end; TryPlaceOnLand:= true; @@ -815,6 +816,88 @@ end; +procedure EraseLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; LandFlags: Word; eraseOnLFMatch, flipHoriz, flipVert: boolean); +var X, Y, bpp, h, w, row, col, gx, gy, numFramesFirstCol: LongInt; + p: PByteArray; + Image: PSDL_Surface; + pixel: LongWord; +begin +numFramesFirstCol:= SpritesData[Obj].imageHeight div SpritesData[Obj].Height; + +TryDo(SpritesData[Obj].Surface <> nil, 'Assert SpritesData[Obj].Surface failed', true); + +Image:= SpritesData[Obj].Surface; +w:= SpritesData[Obj].Width; +h:= SpritesData[Obj].Height; +if flipVert then flipSurface(Image, true); +if flipHoriz then flipSurface(Image, false); +row:= Frame mod numFramesFirstCol; +col:= Frame div numFramesFirstCol; + +if SDL_MustLock(Image) then + SDLTry(SDL_LockSurface(Image) >= 0, true); + +bpp:= Image^.format^.BytesPerPixel; +TryDo(bpp = 4, 'It should be 32 bpp sprite', true); +// Check that sprite fits free space +p:= PByteArray(@(PByteArray(Image^.pixels)^[ Image^.pitch * row * h + col * w * 4 ])); +case bpp of + 4: for y:= 0 to Pred(h) do + begin + for x:= 0 to Pred(w) do + if ((PLongword(@(p^[x * 4]))^) and AMask) <> 0 then + if ((cpY + y) <= Longint(topY)) or ((cpY + y) >= LAND_HEIGHT) or + ((cpX + x) <= Longint(leftX)) or ((cpX + x) >= Longint(rightX)) then + begin + if SDL_MustLock(Image) then + SDL_UnlockSurface(Image); + exit + end; + p:= PByteArray(@(p^[Image^.pitch])) + end + end; + +// Checked, now place +p:= PByteArray(@(PByteArray(Image^.pixels)^[ Image^.pitch * row * h + col * w * 4 ])); +case bpp of + 4: for y:= 0 to Pred(h) do + begin + for x:= 0 to Pred(w) do + if ((PLongword(@(p^[x * 4]))^) and AMask) <> 0 then + begin + if (cReducedQuality and rqBlurryLand) = 0 then + begin + gX:= cpX + x; + gY:= cpY + y; + end + else + begin + gX:= (cpX + x) div 2; + gY:= (cpY + y) div 2; + end; + if (not eraseOnLFMatch or (Land[cpY + y, cpX + x] and LandFlags <> 0)) and + (PLongword(@(p^[x * 4]))^ and AMask <> 0) then + begin + LandPixels[gY, gX]:= 0; + Land[cpY + y, cpX + x]:= 0 + end + end; + p:= PByteArray(@(p^[Image^.pitch])); + end; + end; +if SDL_MustLock(Image) then + SDL_UnlockSurface(Image); + +if flipVert then flipSurface(Image, true); +if flipHoriz then flipSurface(Image, false); + +x:= Max(cpX, leftX); +w:= Min(cpX + Image^.w, LAND_WIDTH) - x; +y:= Max(cpY, topY); +h:= Min(cpY + Image^.h, LAND_HEIGHT) - y; +UpdateLandTexture(x, w, y, h, true) +end; + function GetPlaceCollisionTex(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt): PTexture; var X, Y, bpp, h, w, row, col, numFramesFirstCol: LongInt; p, pt: PLongWordArray; diff -r de52c2b8b773 -r fbf6fbe66092 hedgewars/uScript.pas --- a/hedgewars/uScript.pas Wed Apr 08 15:10:44 2015 -0400 +++ b/hedgewars/uScript.pas Wed Apr 08 23:59:35 2015 -0400 @@ -2213,18 +2213,21 @@ if CheckAndFetchLuaParamMinCount(L, 4, call, params, n) then begin if not lua_isnoneornil(L, 5) then - tint := lua_tointeger(L, 5) + tint := lua_tointeger(L, 5) else tint := $FFFFFFFF; if not lua_isnoneornil(L, 6) then - flipHoriz := lua_toboolean(L, 6) + behind := lua_toboolean(L, 6) + else behind := false; + if not lua_isnoneornil(L, 7) then + flipHoriz := lua_toboolean(L, 7) else flipHoriz := false; - if not lua_isnoneornil(L, 7) then - flipVert := lua_toboolean(L, 7) + if not lua_isnoneornil(L, 8) then + flipVert := lua_toboolean(L, 8) else flipVert := false; lf:= 0; // accept any amount of landflags, loop is never executed if n>6 - for i:= 8 to n do + for i:= 9 to n do lf:= lf or lua_tointeger(L, i); n:= LuaToSpriteOrd(L, 3, call, params); @@ -2245,6 +2248,48 @@ lc_placesprite:= 1 end; +function lc_erasesprite(L : Plua_State) : LongInt; Cdecl; +var spr : TSprite; + lf : Word; + i, n : LongInt; + eraseOnLFMatch, flipHoriz, flipVert : boolean; +const + call = 'EraseSprite'; + params = 'x, y, sprite, frameIdx, eraseOnLFMatch, flipHoriz, flipVert, [, landFlag, ... ]'; +begin + if CheckAndFetchLuaParamMinCount(L, 4, call, params, n) then + begin + if not lua_isnoneornil(L, 5) then + eraseOnLFMatch := lua_toboolean(L, 5) + else eraseOnLFMatch := false; + if not lua_isnoneornil(L, 6) then + flipHoriz := lua_toboolean(L, 6) + else flipHoriz := false; + if not lua_isnoneornil(L, 7) then + flipVert := lua_toboolean(L, 7) + else flipVert := false; + lf:= 0; + + // accept any amount of landflags, loop is never executed if n>6 + for i:= 8 to n do + lf:= lf or lua_tointeger(L, i); + + n:= LuaToSpriteOrd(L, 3, call, params); + if n >= 0 then + begin + spr:= TSprite(n); + if SpritesData[spr].Surface = nil then + LuaError(call + ': ' + EnumToStr(spr) + ' cannot be placed! (required information not loaded)' ) + else + EraseLand( + lua_tointeger(L, 1) - SpritesData[spr].Width div 2, + lua_tointeger(L, 2) - SpritesData[spr].Height div 2, + spr, lua_tointeger(L, 4), lf, eraseOnLFMatch, flipHoriz, flipVert); + end; + end; + lc_erasesprite:= 0 +end; + function lc_placegirder(L : Plua_State) : LongInt; Cdecl; var placed: boolean; begin @@ -3166,6 +3211,7 @@ lua_register(luaState, _P'MapHasBorder', @lc_maphasborder); lua_register(luaState, _P'GetHogHat', @lc_gethoghat); lua_register(luaState, _P'SetHogHat', @lc_sethoghat); +lua_register(luaState, _P'EraseSprite', @lc_erasesprite); lua_register(luaState, _P'PlaceSprite', @lc_placesprite); lua_register(luaState, _P'PlaceGirder', @lc_placegirder); lua_register(luaState, _P'GetCurAmmoType', @lc_getcurammotype);