summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: ece4a4f)
raw | patch | inline | side by side (parent: ece4a4f)
author | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Mon, 21 Aug 2017 23:58:26 +0000 (02:58 +0300) | ||
committer | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Mon, 21 Aug 2017 23:59:15 +0000 (02:59 +0300) |
src/game/g_basic.pas | patch | blob | history | |
src/game/g_gfx.pas | patch | blob | history | |
src/game/g_grid.pas | patch | blob | history | |
src/game/g_map.pas | patch | blob | history |
diff --git a/src/game/g_basic.pas b/src/game/g_basic.pas
index 1f3add5d538fe6837f5ca0d3a942207da171fcb2..a5790239f616380501b8e33b29ce7a19d0d7954d 100644 (file)
--- a/src/game/g_basic.pas
+++ b/src/game/g_basic.pas
Result := True;
*)
- //result := false;
+ result := false;
if g_Map_traceToNearestWall(x1, y1, x2, y2, @wallHitX, @wallHitY) then
begin
// check distance
diff --git a/src/game/g_gfx.pas b/src/game/g_gfx.pas
index d6244b7561687a9bcea64545a8adde9873ef0ccc..44a9db46fc7adcc63d9c3b734a55f55bbab9d275 100644 (file)
--- a/src/game/g_gfx.pas
+++ b/src/game/g_gfx.pas
interface
uses
- g_textures;
+ e_log, g_textures;
const
BLOOD_NORMAL = 0;
CurrentParticle: Integer;
-function isBlockedAt (x, y: Integer; w: Integer=1; h: Integer=1): Boolean; inline;
+function isBlockedAt (x, y: Integer): Boolean; inline;
begin
- result := g_Map_CollidePanel(x, y, w, h, (PANEL_WALL or PANEL_CLOSEDOOR or PANEL_STEP));
+ result := g_Map_HasAnyPanelAtPoint(x, y, (PANEL_WALL or PANEL_CLOSEDOOR or PANEL_STEP));
end;
// ???
-function isWallAt (x, y: Integer; w: Integer=1; h: Integer=1): Boolean; inline;
+function isWallAt (x, y: Integer): Boolean; inline;
begin
- result := g_Map_CollidePanel(x, y, w, h, (PANEL_WALL or PANEL_STEP));
+ result := g_Map_HasAnyPanelAtPoint(x, y, (PANEL_WALL or PANEL_STEP));
end;
-function isLiftUpAt (x, y: Integer; w: Integer=1; h: Integer=1): Boolean; inline;
+function isLiftUpAt (x, y: Integer): Boolean; inline;
begin
- result := g_Map_CollidePanel(x, y, w, h, PANEL_LIFTUP);
+ result := g_Map_HasAnyPanelAtPoint(x, y, PANEL_LIFTUP);
end;
-function isLiftDownAt (x, y: Integer; w: Integer=1; h: Integer=1): Boolean; inline;
+function isLiftDownAt (x, y: Integer): Boolean; inline;
begin
- result := g_Map_CollidePanel(x, y, w, h, PANEL_LIFTDOWN);
+ result := g_Map_HasAnyPanelAtPoint(x, y, PANEL_LIFTDOWN);
end;
-function isLiftLeftAt (x, y: Integer; w: Integer=1; h: Integer=1): Boolean; inline;
+function isLiftLeftAt (x, y: Integer): Boolean; inline;
begin
- result := g_Map_CollidePanel(x, y, w, h, PANEL_LIFTLEFT);
+ result := g_Map_HasAnyPanelAtPoint(x, y, PANEL_LIFTLEFT);
end;
-function isLiftRightAt (x, y: Integer; w: Integer=1; h: Integer=1): Boolean; inline;
+function isLiftRightAt (x, y: Integer): Boolean; inline;
begin
- result := g_Map_CollidePanel(x, y, w, h, PANEL_LIFTRIGHT);
+ result := g_Map_HasAnyPanelAtPoint(x, y, PANEL_LIFTRIGHT);
end;
-function isLiquidAt (x, y: Integer; w: Integer=1; h: Integer=1): Boolean; inline;
+function isLiquidAt (x, y: Integer): Boolean; inline;
begin
- result := g_Map_CollidePanel(x, y, w, h, (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2));
+ result := g_Map_HasAnyPanelAtPoint(x, y, (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2));
end;
-function isAnythingAt (x, y: Integer; w: Integer=1; h: Integer=1): Boolean; inline;
+function isAnythingAt (x, y: Integer): Boolean; inline;
begin
- result := g_Map_CollidePanel(x, y, w, h, (PANEL_WALL or PANEL_CLOSEDOOR or PANEL_OPENDOOR or PANEL_WATER or PANEL_ACID1 or PANEL_ACID2 or PANEL_STEP or PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT));
+ result := g_Map_HasAnyPanelAtPoint(x, y, (PANEL_WALL or PANEL_CLOSEDOOR or PANEL_OPENDOOR or PANEL_WATER or PANEL_ACID1 or PANEL_ACID2 or PANEL_STEP or PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT));
end;
len := High(Particles);
for a := 0 to len do
- if Particles[a].State <> 0 then
+ begin
+ if Particles[a].State <> STATE_FREE then
+ begin
with Particles[a] do
begin
- if Time = LiveTime then
- State := STATE_FREE;
- if (X+1 >= w) or (Y+1 >= h) or (X <= 0) or (Y <= 0) then
- State := STATE_FREE;
- if State = STATE_FREE then
- Continue;
+ if Time = LiveTime then State := STATE_FREE;
+ if (X+1 >= w) or (Y+1 >= h) or (X <= 0) or (Y <= 0) then State := STATE_FREE;
+ if State = STATE_FREE then Continue;
+ //e_WriteLog(Format('particle #%d: %d', [State, ParticleType]), MSG_NOTIFY);
case ParticleType of
PARTICLE_BLOOD:
end; // case
CorrectOffsets(a);
- end;
+ end; // with
+ end; // if
+ end; // for
end; // Particles <> nil
if OnceAnims <> nil then
diff --git a/src/game/g_grid.pas b/src/game/g_grid.pas
index 661e341866708dcc7874ec9dedf7ad0721626d7f..da26a5fa58c6d3606488ff50e4803c9893b13069 100644 (file)
--- a/src/game/g_grid.pas
+++ b/src/game/g_grid.pas
mUData: TBodyProxyId; // for inserter/remover
mTagMask: Integer; // for iterator
mItCB: TGridQueryCB; // for iterator
- mQueryInProcess: Boolean;
private
function allocCell: Integer;
function inserter (grida: Integer): Boolean;
function remover (grida: Integer): Boolean;
- function iterator (grida: Integer): Boolean;
public
constructor Create (aMinPixX, aMinPixY, aPixWidth, aPixHeight: Integer; aTileSize: Integer=GridDefaultTileSize);
//WARNING: can't do recursive queries
function forEachInAABB (x, y, w, h: Integer; cb: TGridQueryCB; tagmask: Integer=-1): Boolean;
+ //WARNING: can't do recursive queries
+ function forEachAtPoint (x, y: Integer; cb: TGridQueryCB; tagmask: Integer=-1): Boolean;
+
//WARNING: can't do recursive queries
// cb with `(nil)` will be called before processing new tile
function traceRay (x0, y0, x1, y1: Integer; cb: TGridRayQueryCB; tagmask: Integer=-1): Boolean; overload;
mUData := 0;
mTagMask := -1;
mItCB := nil;
- mQueryInProcess := false;
e_WriteLog(Format('created grid with size: %dx%d (tile size: %d); pix: %dx%d', [mWidth, mHeight, mTileSize, mWidth*mTileSize, mHeight*mTileSize]), MSG_NOTIFY);
end;
begin
if (gx < 0) then continue;
if (gx >= mWidth) then break;
- if (cb(gy*mWidth+gx)) then begin result := true; exit; end;
+ result := cb(gy*mWidth+gx);
+ if result then exit;
end;
end;
end;
+// ////////////////////////////////////////////////////////////////////////// //
+function TBodyGridBase.forEachAtPoint (x, y: Integer; cb: TGridQueryCB; tagmask: Integer=-1): Boolean;
+var
+ idx, ga, curci: Integer;
+ f: Integer;
+ cc: PGridCell = nil;
+ px: PBodyProxyRec;
+ lq: LongWord;
+begin
+ result := false;
+ if not assigned(cb) or (tagmask = 0) then exit;
+
+ Dec(x, mMinX);
+ Dec(y, mMinY);
+ if (x < 0) or (y < 0) or (x >= mWidth*mTileSize) or (y >= mHeight*mTileSize) then exit;
+
+ ga := (y div mTileSize)*mWidth+(x div mTileSize);
+ curci := mGrid[ga];
+ Inc(x, mMinX);
+ Inc(y, mMinY);
+
+ // increase query counter
+ Inc(mLastQuery);
+ if (mLastQuery = 0) then
+ begin
+ // just in case of overflow
+ mLastQuery := 1;
+ for idx := 0 to High(mProxies) do mProxies[idx].mQueryMark := 0;
+ end;
+ lq := mLastQuery;
+
+ while (curci <> -1) do
+ begin
+ cc := @mCells[curci];
+ for f := 0 to High(TGridCell.bodies) do
+ begin
+ if (cc.bodies[f] = -1) then break;
+ px := @mProxies[cc.bodies[f]];
+ if (px.mQueryMark <> lq) and ((px.mTag and tagmask) <> 0) then
+ begin
+ if (x >= px.mX) and (y >= px.mY) and (x < px.mX+px.mWidth) and (y < px.mY+px.mHeight) then
+ begin
+ px.mQueryMark := lq;
+ result := cb(px.mObj, px.mTag);
+ if result then exit;
+ end;
+ end;
+ end;
+ curci := cc.next;
+ end;
+end;
+
+
// ////////////////////////////////////////////////////////////////////////// //
function TBodyGridBase.traceRay (x0, y0, x1, y1: Integer; cb: TGridRayQueryCB; tagmask: Integer=-1): Boolean;
var
prevX, prevY: Integer;
minx, miny: Integer;
begin
- result := False;
+ result := false;
if (tagmask = 0) then exit;
function TBodyGridBase.insertBody (aObj: ITP; aX, aY, aWidth, aHeight: Integer; aTag: Integer=0): TBodyProxyId;
begin
- if mQueryInProcess then raise Exception.Create('grid doesn''t support recursive queries');
- mQueryInProcess := true;
result := allocProxy(aX, aY, aWidth, aHeight, aObj, aTag);
insert(result);
- mQueryInProcess := false;
end;
procedure TBodyGridBase.removeBody (aObj: TBodyProxyId);
begin
if (aObj < 0) or (aObj > High(mProxies)) then exit; // just in case
- if mQueryInProcess then raise Exception.Create('grid doesn''t support recursive queries');
- mQueryInProcess := true;
remove(aObj);
freeProxy(aObj);
- mQueryInProcess := false;
end;
begin
if (body < 0) or (body > High(mProxies)) then exit; // just in case
if ((dx = 0) and (dy = 0) and (sx = 0) and (sy = 0)) then exit;
- if mQueryInProcess then raise Exception.Create('grid doesn''t support recursive queries');
- mQueryInProcess := true;
remove(body);
px := @mProxies[body];
Inc(px.mX, dx);
Inc(px.mWidth, sx);
Inc(px.mHeight, sy);
insert(body);
- mQueryInProcess := false;
end;
procedure TBodyGridBase.moveBody (body: TBodyProxyId; dx, dy: Integer);
end;
-function TBodyGridBase.iterator (grida: Integer): Boolean;
+function TBodyGridBase.forEachInAABB (x, y, w, h: Integer; cb: TGridQueryCB; tagmask: Integer=-1): Boolean;
var
idx: Integer;
- px: PBodyProxyRec;
- {$IFDEF grid_use_buckets}
- pi: PGridCell;
+ gx, gy: Integer;
+ curci: Integer;
f: Integer;
- {$ENDIF}
+ cc: PGridCell = nil;
+ px: PBodyProxyRec;
+ lq: LongWord;
+ tsize, gw: Integer;
+ x0, y0: Integer;
begin
result := false;
- idx := mGrid[grida];
- while (idx >= 0) do
- begin
- {$IFDEF grid_use_buckets}
- pi := @mCells[idx];
- for f := 0 to High(TGridCell.bodies) do
- begin
- if (pi.bodies[f] = -1) then break;
- px := @mProxies[pi.bodies[f]];
- if (px.mQueryMark <> mLastQuery) and ((mTagMask = -1) or ((px.mTag and mTagMask) <> 0)) then
- begin
- //e_WriteLog(Format(' query #%d body hit: (%d,%d)-(%dx%d) tag:%d', [mLastQuery, mCells[idx].body.mX, mCells[idx].body.mY, mCells[idx].body.mWidth, mCells[idx].body.mHeight, mCells[idx].body.mTag]), MSG_NOTIFY);
- px.mQueryMark := mLastQuery;
- if (mItCB(px.mObj, px.mTag)) then begin result := true; exit; end;
- end;
- end;
- idx := pi.next;
- {$ELSE}
- if (mCells[idx].body <> -1) then
- begin
- px := @mProxies[mCells[idx].body];
- if (px.mQueryMark <> mLastQuery) and ((mTagMask = -1) or ((px.mTag and mTagMask) <> 0)) then
- begin
- //e_WriteLog(Format(' query #%d body hit: (%d,%d)-(%dx%d) tag:%d', [mLastQuery, mCells[idx].body.mX, mCells[idx].body.mY, mCells[idx].body.mWidth, mCells[idx].body.mHeight, mCells[idx].body.mTag]), MSG_NOTIFY);
- px.mQueryMark := mLastQuery;
- if (mItCB(px.mObj, px.mTag)) then begin result := true; exit; end;
- end;
- end;
- idx := mCells[idx].next;
- {$ENDIF}
- end;
-end;
+ if (w < 1) or (h < 1) or not assigned(cb) then exit;
-function TBodyGridBase.forEachInAABB (x, y, w, h: Integer; cb: TGridQueryCB; tagmask: Integer=-1): Boolean;
-var
- idx: Integer;
-begin
- result := false;
- if not assigned(cb) then exit;
+ x0 := x;
+ y0 := y;
+
+ // fix coords
+ Dec(x, mMinX);
+ Dec(y, mMinY);
+
+ gw := mWidth;
+ tsize := mTileSize;
- if mQueryInProcess then raise Exception.Create('grid doesn''t support recursive queries');
- mQueryInProcess := true;
+ if (x+w <= 0) or (y+h <= 0) then exit;
+ if (x >= gw*tsize) or (y >= mHeight*tsize) then exit;
// increase query counter
Inc(mLastQuery);
for idx := 0 to High(mProxies) do mProxies[idx].mQueryMark := 0;
end;
//e_WriteLog(Format('grid: query #%d: (%d,%d)-(%dx%d)', [mLastQuery, minx, miny, maxx, maxy]), MSG_NOTIFY);
+ lq := mLastQuery;
- mTagMask := tagmask;
- mItCB := cb;
- result := forGridRect(x, y, w, h, iterator);
- mQueryInProcess := false;
+ // go on
+ for gy := y div tsize to (y+h-1) div tsize do
+ begin
+ if (gy < 0) then continue;
+ if (gy >= mHeight) then break;
+ for gx := x div tsize to (x+w-1) div tsize do
+ begin
+ if (gx < 0) then continue;
+ if (gx >= gw) then break;
+ // process cells
+ curci := mGrid[gy*gw+gx];
+ while (curci <> -1) do
+ begin
+ cc := @mCells[curci];
+ for f := 0 to High(TGridCell.bodies) do
+ begin
+ if (cc.bodies[f] = -1) then break;
+ px := @mProxies[cc.bodies[f]];
+ if (px.mQueryMark <> lq) and ((px.mTag and tagmask) <> 0) then
+ begin
+ if (x0 >= px.mX+px.mWidth) or (y0 >= px.mY+px.mHeight) then continue;
+ if (x0+w <= px.mX) or (y0+h <= px.mY) then continue;
+ px.mQueryMark := lq;
+ result := cb(px.mObj, px.mTag);
+ if result then exit;
+ end;
+ end;
+ curci := cc.next;
+ end;
+ end;
+ end;
end;
diff --git a/src/game/g_map.pas b/src/game/g_map.pas
index ae230c2292dfb483875b2c03468d20fde04bbbb5..bd8acf8ef1904f4e322fb628b431814e42961064 100644 (file)
--- a/src/game/g_map.pas
+++ b/src/game/g_map.pas
function g_Map_ForEachPanelAt (x, y: Integer; cb: TForEachPanelCB; panelType: Word): Boolean;
+function g_Map_HasAnyPanelAtPoint (x, y: Integer; panelType: Word): Boolean;
+
procedure g_Map_ProfilersBegin ();
procedure g_Map_ProfilersEnd ();
end;
+function g_Map_HasAnyPanelAtPoint (x, y: Integer; panelType: Word): Boolean;
+
+ function checker (pan: TPanel; tag: Integer): Boolean;
+ begin
+ result := false; // don't stop, ever
+
+ if ((tag and (GridTagWall or GridTagDoor)) <> 0) then
+ begin
+ if not pan.Enabled then exit;
+ end;
+
+ result := (x >= pan.X) and (y >= pan.Y) and (x < pan.X+pan.Width) and (y < pan.Y+pan.Height);
+ if not result then exit;
+
+ if ((tag and GridTagLift) <> 0) then
+ begin
+ result :=
+ ((WordBool(PanelType and PANEL_LIFTUP) and (pan.LiftType = 0)) or
+ (WordBool(PanelType and PANEL_LIFTDOWN) and (pan.LiftType = 1)) or
+ (WordBool(PanelType and PANEL_LIFTLEFT) and (pan.LiftType = 2)) or
+ (WordBool(PanelType and PANEL_LIFTRIGHT) and (pan.LiftType = 3)));
+ end;
+ end;
+
+var
+ tagmask: Integer = 0;
+begin
+ result := false;
+
+ if WordBool(PanelType and (PANEL_WALL or PANEL_CLOSEDOOR or PANEL_OPENDOOR)) then tagmask := tagmask or (GridTagWall or GridTagDoor);
+ if WordBool(PanelType and PANEL_WATER) then tagmask := tagmask or GridTagWater;
+ if WordBool(PanelType and PANEL_ACID1) then tagmask := tagmask or GridTagAcid1;
+ if WordBool(PanelType and PANEL_ACID2) then tagmask := tagmask or GridTagAcid2;
+ if WordBool(PanelType and PANEL_STEP) then tagmask := tagmask or GridTagStep;
+ if WordBool(PanelType and (PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT)) then tagmask := tagmask or GridTagLift;
+ if WordBool(PanelType and PANEL_BLOCKMON) then tagmask := tagmask or GridTagBlockMon;
+
+ if (tagmask = 0) then exit;// just in case
+ result := gMapGrid.forEachAtPoint(x, y, checker, tagmask);
+end;
+
+
function g_Map_IsSpecialTexture(Texture: String): Boolean;
begin
Result := (Texture = TEXTURE_NAME_WATER) or