summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 6eab64d)
raw | patch | inline | side by side (parent: 6eab64d)
author | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Mon, 21 Aug 2017 20:11:19 +0000 (23:11 +0300) | ||
committer | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Mon, 21 Aug 2017 21:02:16 +0000 (00:02 +0300) |
diff --git a/src/game/g_basic.pas b/src/game/g_basic.pas
index 98cebcce846067023ff07b3fa558f1c9ddba0797..8e1ae926769f02fa83676e5a685bd9274417d124 100644 (file)
--- a/src/game/g_basic.pas
+++ b/src/game/g_basic.pas
X2, Y2: Integer; Width2, Height2: Word): Boolean;
function g_CollidePlayer(X, Y: Integer; Width, Height: Word): Boolean;
function g_PatchLength(X1, Y1, X2, Y2: Integer): Word;
-function g_TraceVector(X1, Y1, X2, Y2: Integer): Boolean;
+function g_TraceVector(X1, Y1, X2, Y2: Integer): Boolean; // `true`: no wall hit
function g_GetAcidHit(X, Y: Integer; Width, Height: Word): Byte;
function g_Look(a, b: PObj; d: TDirection): Boolean;
procedure IncMax(var A: Integer; B, Max: Integer); overload;
end;
end;
+
function g_TraceVector(X1, Y1, X2, Y2: Integer): Boolean;
var
+ wallHitX: Integer = 0;
+ wallHitY: Integer = 0;
+(*
i: Integer;
dx, dy: Integer;
Xerr, Yerr, d: LongWord;
incX, incY: Integer;
x, y: Integer;
+*)
begin
- Result := False;
+ (*
+ result := False;
Assert(gCollideMap <> nil, 'g_TraceVector: gCollideMap = nil');
end;
Result := True;
+ *)
+
+ if (g_Map_traceToNearestWall(x1, y1, x2, y2, @wallHitX, @wallHitY) >= 0) then
+ begin
+ // check distance
+ //result := ((wallHitX-x1)*(wallHitX-x1)+(wallHitY-y1)*(wallHitY-y1) > (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
+ result := false;
+ end
+ else
+ begin
+ result := true; // no obstacles
+ end;
end;
+
function g_CreateUID(UIDType: Byte): Word;
var
ok: Boolean;
diff --git a/src/game/g_gfx.pas b/src/game/g_gfx.pas
index 17bbe920be07ac8843548777c9ed53878c498c80..37036278d08175ca4dbf3a93c88e724ac32995f7 100644 (file)
--- a/src/game/g_gfx.pas
+++ b/src/game/g_gfx.pas
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*)
{$INCLUDE ../shared/a_modes.inc}
+{.$DEFINE HAS_COLLIDE_BITMAP}
unit g_gfx;
interface
procedure g_GFX_Update();
procedure g_GFX_Draw();
+
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
var
gCollideMap: Array of Array of Byte;
+{$ENDIF}
+
implementation
CurrentParticle: Integer;
procedure g_Mark(x, y, Width, Height: Integer; t: Byte; st: Boolean);
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
var
yy, y2, xx, x2: Integer;
+{$ENDIF}
begin
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
if x < 0 then
begin
Width := Width + x;
for xx := x to x2 do
gCollideMap[yy][xx] := gCollideMap[yy][xx] and t;
end;
+{$ENDIF}
end;
procedure CreateCollideMap();
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
var
a: Integer;
+{$ENDIF}
begin
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
g_Game_SetLoadingText(_lc[I_LOAD_COLLIDE_MAP]+' 1/6', 0, False);
SetLength(gCollideMap, gMapInfo.Height+1);
for a := 0 to High(gCollideMap) do
g_Mark(X, Y, Width, Height, MARK_WALL, True);
end;
end;
+{$ENDIF}
end;
procedure g_GFX_Init();
OnceAnims := nil;
end;
+ {$IF DEFINED(HAS_COLLIDE_BITMAP)}
gCollideMap := nil;
+ {$ENDIF}
end;
+
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
procedure CorrectOffsets(id: Integer);
begin
with Particles[id] do
offsetX := 0;
end;
end;
+{$ENDIF}
+
procedure g_GFX_SparkVel(fX, fY: Integer; Count: Word; VX, VY: Integer; DevX, DevY: Byte);
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
var
a: Integer;
DevX1, DevX2,
DevY1, DevY2: Byte;
l: Integer;
+{$ENDIF}
begin
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
l := Length(Particles);
if l = 0 then
Exit;
else
CurrentParticle := CurrentParticle+1;
end;
+{$ENDIF}
end;
procedure g_GFX_Blood(fX, fY: Integer; Count: Word; vx, vy: Integer;
DevX, DevY: Word; CR, CG, CB: Byte; Kind: Byte = BLOOD_NORMAL);
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
var
a: Integer;
DevX1, DevX2,
l: Integer;
CRnd: Byte;
CC: SmallInt;
+{$ENDIF}
begin
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
if Kind = BLOOD_SPARKS then
begin
g_GFX_SparkVel(fX, fY, 2 + Random(2), -VX div 2, -VY div 2, DevX, DevY);
else
CurrentParticle := CurrentParticle+1;
end;
+{$ENDIF}
end;
procedure g_GFX_Spark(fX, fY: Integer; Count: Word; Angle: SmallInt; DevX, DevY: Byte);
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
var
a: Integer;
b: Single;
DevY1, DevY2: Byte;
BaseVelX, BaseVelY: Single;
l: Integer;
+{$ENDIF}
begin
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
l := Length(Particles);
if l = 0 then
Exit;
else
CurrentParticle := CurrentParticle+1;
end;
+{$ENDIF}
end;
procedure g_GFX_Water(fX, fY: Integer; Count: Word; fVelX, fVelY: Single; DevX, DevY, Color: Byte);
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
var
a: Integer;
DevX1, DevX2,
DevY1, DevY2: Byte;
l: Integer;
+{$ENDIF}
begin
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
l := Length(Particles);
if l = 0 then
Exit;
else
CurrentParticle := CurrentParticle+1;
end;
+{$ENDIF}
end;
procedure g_GFX_SimpleWater(fX, fY: Integer; Count: Word; fVelX, fVelY: Single; DefColor, CR, CG, CB: Byte);
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
var
a: Integer;
l: Integer;
+{$ENDIF}
begin
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
l := Length(Particles);
if l = 0 then
Exit;
else
CurrentParticle := CurrentParticle+1;
end;
+{$ENDIF}
end;
procedure g_GFX_Bubbles(fX, fY: Integer; Count: Word; DevX, DevY: Byte);
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
var
a: Integer;
DevX1, DevX2,
DevY1, DevY2: Byte;
l: Integer;
+{$ENDIF}
begin
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
l := Length(Particles);
if l = 0 then
Exit;
else
CurrentParticle := CurrentParticle+1;
end;
+{$ENDIF}
end;
procedure g_GFX_SetMax(Count: Integer);
procedure g_GFX_Update();
var
a: Integer;
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
w, h: Integer;
dX, dY: SmallInt;
b, len: Integer;
s: ShortInt;
c: Byte;
+{$ENDIF}
begin
+{$IF DEFINED(HAS_COLLIDE_BITMAP)}
if Particles <> nil then
begin
w := gMapInfo.Width;
CorrectOffsets(a);
end;
end; // Particles <> nil
+{$ENDIF}
if OnceAnims <> nil then
begin
diff --git a/src/game/g_map.pas b/src/game/g_map.pas
index 36ac9072a2fc315286abddb31042cba92eb9e053..a73434b9b8c6632bd41dbe63a194dd5376885def 100644 (file)
--- a/src/game/g_map.pas
+++ b/src/game/g_map.pas
// wall index in `gWalls` or -1
function g_Map_traceToNearestWall (x0, y0, x1, y1: Integer; hitx: PInteger=nil; hity: PInteger=nil): Integer;
+var
+ maxDistSq: Single;
function sqchecker (pan: TPanel; var ray: Ray2D): Single;
var
if not aabb.valid then exit;
if aabb.intersects(ray, @tmin) then
begin
+ //if (tmin*tmin > maxDistSq) then exit;
if (tmin >= 0.0) then
begin
//e_WriteLog(Format('sqchecker(%d,%d,%d,%d): panel #%d (%d,%d)-(%d,%d); tmin=%f', [x0, y0, x1, y1, pan.arrIdx, pan.X, pan.Y, pan.Width, pan.Height, tmin]), MSG_NOTIFY);
begin
result := -1;
if (mapTree = nil) then exit;
+ maxDistSq := (x1-x0)*(x1-x0)+(y1-y0)*(y1-y0);
if mapTree.segmentQuery(qr, x0, y0, x1, y1, sqchecker, (GridTagWall or GridTagDoor)) then
begin
- if (qr.flesh <> nil) then
+ if (qr.flesh <> nil) and (qr.time*qr.time <= maxDistSq) then
begin
result := qr.flesh.arrIdx;
if (hitx <> nil) or (hity <> nil) then
diff --git a/src/game/g_weapons.pas b/src/game/g_weapons.pas
index c55931b540dd1e4055a949fb29799e0e83fd2c09..d52abc5fb519b33ed746296c632eae8a64cc6a3f 100644 (file)
--- a/src/game/g_weapons.pas
+++ b/src/game/g_weapons.pas
end;
+(*
procedure g_Weapon_gunOld(const x, y, xd, yd, v, dmg: Integer; SpawnerUID: Word; CheckTrigger: Boolean);
var
a: Integer;
if CheckTrigger and g_Game_IsServer then
g_Triggers_PressL(X, Y, xx-xi, yy-yi, SpawnerUID, ACTIVATE_SHOT);
end;
+*)
(*
stt: UInt64;
{$ENDIF}
begin
+ (*
if not gwep_debug_fast_trace then
begin
g_Weapon_gunOld(x, y, xd, yd, v, dmg, SpawnerUID, CheckTrigger);
exit;
end;
+ *)
wgunMonHash.reset(); //FIXME: clear hash on level change
wgunHitHeap.clear();
index 86e05680340dfa2af06d8c4fee175a4f48e80083..72206539078e070e414dfdf5e1b7794b1624d475 100644 (file)
--- a/src/game/z_aabbtree.pas
+++ b/src/game/z_aabbtree.pas
chkAABB: AABB2D; // for checkers
qSRes: PSegmentQueryResult; // for queries
// for segment query
- maxFraction: Single;
curax, curay: Single;
curbx, curby: Single;
dirx, diry: Single;
function TDynAABBTreeBase.checkerRay (node: PTreeNode): Boolean;
-var
- tmin: Single = 0;
+//var tmin: Single = 0;
begin
{$IF FALSE}
result := node.aabb.intersects(curax, curay, curbx, curby, @tmin);
Integer(result),
]), MSG_NOTIFY);
{$ELSE}
- result := node.aabb.intersects(traceRay, maxFraction, @tmin);
+ result := false;
+ if (node.aabb.maxX < minSingle(curax, curbx)) or (node.aabb.maxY < minSingle(curay, curby)) then exit;
+ if (node.aabb.minX > maxSingle(curax, curbx)) or (node.aabb.minY > maxSingle(curay, curby)) then exit;
+ result := node.aabb.intersects(traceRay, qSRes.time{, @tmin});
{
e_WriteLog(Format('intersect: (%f,%f)-(%f,%f) (%d,%d)-(%d,%d) tmin=%f res=%d frac=%f', [
curax, curay, curbx, curby,
node.aabb.maxX, node.aabb.maxY,
tmin,
Integer(result),
- maxFraction
+ qSRes.time
]), MSG_NOTIFY);
}
{$ENDIF}
if (hitFraction > 0.0) then
begin
// we update the maxFraction value and the ray AABB using the new maximum fraction
- if (hitFraction < maxFraction) then
+ if (hitFraction < qSRes.time) then
begin
- maxFraction := hitFraction;
qSRes.time := hitFraction;
qSRes.flesh := flesh;
// fix curb here
// segment querying method
function TDynAABBTreeBase.segmentQuery (out qr: TSegmentQueryResult; ax, ay, bx, by: TreeNumber; cb: TSegQueryCallback; tagmask: Integer=-1): Boolean;
var
- oldmaxFraction: Single;
oldcurax, oldcuray: Single;
oldcurbx, oldcurby: Single;
olddirx, olddiry: Single;
if (ax = bx) and (ay = by) then begin result := false; exit; end;
- oldmaxFraction := maxFraction;
oldcurax := curax;
oldcuray := curay;
oldcurbx := curbx;
olddiry := diry;
oldray := traceRay;
- maxFraction := 1.0e100; // infinity
+ qr.time := 1.0e100; // infinity
+ //qr.time := sqrt((bx-ax)*(bx-ax)+(by-ay)*(by-ay))+1.0;
curax := ax;
curay := ay;
curbx := bx;
curby := oldcurby;
dirx := olddirx;
diry := olddiry;
- maxFraction := oldmaxFraction;
traceRay := oldray;
result := qr.valid;