summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 6dd20e0)
raw | patch | inline | side by side (parent: 6dd20e0)
author | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Tue, 29 Aug 2017 15:42:35 +0000 (18:42 +0300) | ||
committer | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Tue, 29 Aug 2017 15:43:10 +0000 (18:43 +0300) |
diff --git a/src/game/g_grid.pas b/src/game/g_grid.pas
index b4b0e32795cddfaa38864fa8154c2f260e903328..346770246cfd96eb4bb196e9471360ef95763d13 100644 (file)
--- a/src/game/g_grid.pas
+++ b/src/game/g_grid.pas
mProxyFree: TBodyProxyId; // free
mProxyCount: Integer; // currently used
mProxyMaxCount: Integer;
+ mInQuery: Boolean;
public
dbgShowTraceLog: Boolean;
if (x+w <= 0) or (y+h <= 0) then exit;
if (x >= gw*tsize) or (y >= mHeight*tsize) then exit;
+ if mInQuery then raise Exception.Create('recursive queries aren''t supported');
+ mInQuery := true;
+
// increase query counter
Inc(mLastQuery);
if (mLastQuery = 0) then
if (x0+w <= px.mX) or (y0+h <= px.mY) then continue;
if assigned(cb) then
begin
- if cb(px.mObj, ptag) then begin result := px.mObj; exit; end;
+ if cb(px.mObj, ptag) then begin result := px.mObj; mInQuery := false; exit; end;
end
else
begin
result := px.mObj;
+ mInQuery := false;
exit;
end;
end;
end;
end;
end;
+
+ mInQuery := false;
end;
//if (dbgShowTraceLog) then e_WriteLog(Format('raycast start: (%d,%d)-(%d,%d); xptr^=%d; yptr^=%d', [ax0, ay0, ax1, ay1, xptr^, yptr^]), MSG_NOTIFY);
+ if mInQuery then raise Exception.Create('recursive queries aren''t supported');
+ mInQuery := true;
+
// increase query counter
Inc(mLastQuery);
if (mLastQuery = 0) then
result := px.mObj;
ex := x;
ey := y;
+ mInQuery := false;
exit;
end;
end
ex := x;
ey := y;
result := px.mObj;
+ mInQuery := false;
exit;
end;
end;
result := px.mObj;
ex := prevx;
ey := prevy;
+ mInQuery := false;
exit;
end;
end
// next cell
ccidx := cc.next;
end;
- if wasHit and not assigned(cb) then begin result := lastObj; exit; end;
- if assigned(cb) and cb(nil, 0, x, y, x, y) then begin result := lastObj; exit; end;
+ if wasHit and not assigned(cb) then begin result := lastObj; mInQuery := false; exit; end;
+ if assigned(cb) and cb(nil, 0, x, y, x, y) then begin result := lastObj; mInQuery := false; exit; end;
end;
// skip to next tile
if hopt then
end;
// we can travel less than one cell
if wasHit and not assigned(cb) then result := lastObj else begin ex := ax1; ey := ay1; end;
+ mInQuery := false;
exit;
end;
{$ENDIF}
// signal cell completion
if assigned(cb) then
begin
- if cb(nil, 0, xptr^+minx, yptr^+miny, prevx, prevy) then begin result := lastObj; exit; end;
+ if cb(nil, 0, xptr^+minx, yptr^+miny, prevx, prevy) then begin result := lastObj; mInQuery := false; exit; end;
end
else if wasHit then
begin
result := lastObj;
+ mInQuery := false;
exit;
end;
end;
result := px.mObj;
ex := prevx;
ey := prevy;
+ mInQuery := false;
exit;
end;
end
ccidx := -1;
if assigned(cb) then
begin
- if cb(nil, 0, x, y, prevx, prevy) then begin result := lastObj; exit; end;
+ if cb(nil, 0, x, y, prevx, prevy) then begin result := lastObj; mInQuery := false; exit; end;
end
else if wasHit then
begin
result := lastObj;
+ mInQuery := false;
exit;
end;
end;
ex := ax1; // why not?
ey := ay1; // why not?
end;
+
+ mInQuery := false;
end;
//lastGA := (yptr^ div tsize)*gw+(xptr^ div tsize);
//ccidx := mGrid[lastGA];
+ if mInQuery then raise Exception.Create('recursive queries aren''t supported');
+ mInQuery := true;
+
// increase query counter
Inc(mLastQuery);
if (mLastQuery = 0) then
px.mQueryMark := lq; // mark as processed
if assigned(cb) then
begin
- if cb(px.mObj, ptag) then begin result := px.mObj; exit; end;
+ if cb(px.mObj, ptag) then begin result := px.mObj; mInQuery := false; exit; end;
end
else
begin
result := px.mObj;
+ mInQuery := false;
exit;
end;
end;
end;
Dec(wklen, wkstep);
end;
+ mInQuery := false;
exit;
end;
{$ENDIF}
px.mQueryMark := lq; // mark as processed
if assigned(cb) then
begin
- if cb(px.mObj, ptag) then begin result := px.mObj; exit; end;
+ if cb(px.mObj, ptag) then begin result := px.mObj; mInQuery := false; exit; end;
end
else
begin
result := px.mObj;
+ mInQuery := false;
exit;
end;
end;
if (e >= 0) then begin yd += sty; e -= dx2; end else e += dy2;
xd += stx;
end;
+
+ mInQuery := false;
end;
diff --git a/src/game/g_items.pas b/src/game/g_items.pas
index dffeb96096c08d34d753150f155a2f86cfb2e057..672e4810e78d496f275fed809a7355b6b15e0381 100644 (file)
--- a/src/game/g_items.pas
+++ b/src/game/g_items.pas
it := @ggItems[f];
if not it.Live then continue;
case it.ItemType of
- ITEM_KEY_RED: g_AddDynLight(it.Obj.X+(it.Obj.Rect.Width div 2), it.Obj.Y+(it.Obj.Rect.Height div 2), 32, 1.0, 0.0, 0.0, 0.6);
- ITEM_KEY_GREEN: g_AddDynLight(it.Obj.X+(it.Obj.Rect.Width div 2), it.Obj.Y+(it.Obj.Rect.Height div 2), 32, 0.0, 1.0, 0.0, 0.6);
- ITEM_KEY_BLUE: g_AddDynLight(it.Obj.X+(it.Obj.Rect.Width div 2), it.Obj.Y+(it.Obj.Rect.Height div 2), 32, 0.0, 0.0, 1.0, 0.6);
+ ITEM_KEY_RED: g_AddDynLight(it.Obj.X+(it.Obj.Rect.Width div 2), it.Obj.Y+(it.Obj.Rect.Height div 2), 24, 1.0, 0.0, 0.0, 0.6);
+ ITEM_KEY_GREEN: g_AddDynLight(it.Obj.X+(it.Obj.Rect.Width div 2), it.Obj.Y+(it.Obj.Rect.Height div 2), 24, 0.0, 1.0, 0.0, 0.6);
+ ITEM_KEY_BLUE: g_AddDynLight(it.Obj.X+(it.Obj.Rect.Width div 2), it.Obj.Y+(it.Obj.Rect.Height div 2), 24, 0.0, 0.0, 1.0, 0.6);
ITEM_ARMOR_GREEN: g_AddDynLight(it.Obj.X+(it.Obj.Rect.Width div 2), it.Obj.Y+(it.Obj.Rect.Height div 2), 42, 0.0, 1.0, 0.0, 0.6);
ITEM_ARMOR_BLUE: g_AddDynLight(it.Obj.X+(it.Obj.Rect.Width div 2), it.Obj.Y+(it.Obj.Rect.Height div 2), 42, 0.0, 0.0, 1.0, 0.6);
ITEM_SPHERE_BLUE: g_AddDynLight(it.Obj.X+(it.Obj.Rect.Width div 2), it.Obj.Y+(it.Obj.Rect.Height div 2), 32, 0.0, 1.0, 0.0, 0.6);
ITEM_SPHERE_WHITE: g_AddDynLight(it.Obj.X+(it.Obj.Rect.Width div 2), it.Obj.Y+(it.Obj.Rect.Height div 2), 32, 1.0, 1.0, 1.0, 0.6);
ITEM_INVUL: g_AddDynLight(it.Obj.X+(it.Obj.Rect.Width div 2), it.Obj.Y+(it.Obj.Rect.Height div 2), 32, 1.0, 0.0, 0.0, 0.6);
ITEM_INVIS: g_AddDynLight(it.Obj.X+(it.Obj.Rect.Width div 2), it.Obj.Y+(it.Obj.Rect.Height div 2), 32, 1.0, 1.0, 0.0, 0.6);
- ITEM_BOTTLE: g_AddDynLight(it.Obj.X+(it.Obj.Rect.Width div 2), it.Obj.Y+(it.Obj.Rect.Height div 2), 32, 0.0, 0.0, 1.0, 0.6);
+ ITEM_BOTTLE: g_AddDynLight(it.Obj.X+(it.Obj.Rect.Width div 2), it.Obj.Y+(it.Obj.Rect.Height div 2), 16, 0.0, 0.0, 0.8, 0.6);
+ ITEM_HELMET: g_AddDynLight(it.Obj.X+(it.Obj.Rect.Width div 2), it.Obj.Y+(it.Obj.Rect.Height div 2), 16, 0.0, 0.8, 0.0, 0.6);
end;
end;
end;
diff --git a/src/game/g_map.pas b/src/game/g_map.pas
index 681e182d7b1583834630e5a8fd7999ac4b65cbf9..4f86e9b0d3f14ddc3f21e097756080f4996e2e12 100644 (file)
--- a/src/game/g_map.pas
+++ b/src/game/g_map.pas
SetLength(s, 64);
CopyMemory(@s[1], @_textures[a].Resource[0], 64);
for b := 1 to Length(s) do
+ begin
if s[b] = #0 then
begin
SetLength(s, b-1);
Break;
end;
+ end;
+ {$IF DEFINED(D2F_DEBUG)}
e_WriteLog(Format(' Loading texture #%d: %s', [a, s]), MSG_NOTIFY);
+ {$ENDIF}
//if g_Map_IsSpecialTexture(s) then e_WriteLog(' SPECIAL!', MSG_NOTIFY);
// Àíèìèðîâàííàÿ òåêñòóðà:
if ByteBool(_textures[a].Anim) then
index e39b8c66a3dfdd7b6a2491f85087cae51e119ddb..3b1f911bf133db08b97b0c1f50da8e5a1732fed1 100644 (file)
--- a/src/game/g_triggers.pas
+++ b/src/game/g_triggers.pas
g_player, g_map, Math, g_gfx, g_game, g_textures,
g_console, g_monsters, g_items, g_phys, g_weapons,
wadreader, g_main, SysUtils, e_log, g_language,
- g_options, g_net, g_netmsg;
+ g_options, g_net, g_netmsg, utils;
const
TRIGGER_SIGNATURE = $52475254; // 'TRGR'
Result := find_id;
end;
+
+// sorry; grid doesn't support recursive queries, so we have to do this
+type
+ TSimpleMonsterList = specialize TSimpleList<TMonster>;
+
+var
+ tgMonsList: TSimpleMonsterList = nil;
+
procedure g_Triggers_Update();
var
a, b, i: Integer;
Affected: array of Integer;
- {function monsNear (mon: TMonster): Boolean;
- begin
- result := false; // don't stop
- if mon.Collide(gTriggers[a].X, gTriggers[a].Y, gTriggers[a].Width, gTriggers[a].Height) then
- begin
- gTriggers[a].ActivateUID := mon.UID;
- ActivateTrigger(gTriggers[a], ACTIVATE_MONSTERCOLLIDE);
- end;
- end;}
-
function monsNear (mon: TMonster): Boolean;
begin
result := false; // don't stop
+ {
gTriggers[a].ActivateUID := mon.UID;
ActivateTrigger(gTriggers[a], ACTIVATE_MONSTERCOLLIDE);
+ }
+ tgMonsList.append(mon);
end;
+var
+ mon: TMonster;
begin
+ if (tgMonsList = nil) then tgMonsList := TSimpleMonsterList.Create();
+
if gTriggers = nil then
Exit;
SetLength(Affected, 0);
begin
//g_Mons_ForEach(monsNear);
//Alive?!
+ tgMonsList.reset();
g_Mons_ForEachAt(gTriggers[a].X, gTriggers[a].Y, gTriggers[a].Width, gTriggers[a].Height, monsNear);
+ for mon in tgMonsList do
+ begin
+ gTriggers[a].ActivateUID := mon.UID;
+ ActivateTrigger(gTriggers[a], ACTIVATE_MONSTERCOLLIDE);
+ end;
+ tgMonsList.reset(); // just in case
end;
// "Ìîíñòðîâ íåò"
diff --git a/src/shared/utils.pas b/src/shared/utils.pas
index c182da196a11ed57a1e61716031f8b033ad76424..49408d77a7ac88ab8481e9b1e7bb5e3d8be19e8a 100644 (file)
--- a/src/shared/utils.pas
+++ b/src/shared/utils.pas
function quoteStr (const s: AnsiString): AnsiString;
+type
+ generic TSimpleList<ItemT> = class
+ private
+ type PItemT = ^ItemT;
+
+ public
+ type
+ TEnumerator = record
+ private
+ mItems: PItemT;
+ mCount: Integer;
+ mCurrent: Integer;
+ public
+ constructor Create (aitems: PItemT; acount: Integer);
+ function MoveNext: Boolean;
+ function getCurrent (): ItemT;
+ property Current: ItemT read getCurrent;
+ end;
+
+ private
+ mItems: array of ItemT;
+ mCount: Integer; // can be less than `mItems` size
+
+ private
+ function getAt (idx: Integer): ItemT; inline;
+
+ public
+ constructor Create ();
+ destructor Destroy (); override;
+
+ function GetEnumerator (): TEnumerator;
+
+ procedure reset (); inline; // won't resize `mItems`
+ procedure clear (); inline;
+
+ procedure append (constref it: ItemT); inline;
+
+ public
+ property count: Integer read mCount;
+ property at[idx: Integer]: ItemT read getAt; default;
+ end;
+
+
implementation
+// ////////////////////////////////////////////////////////////////////////// //
+constructor TSimpleList.TEnumerator.Create (aitems: PItemT; acount: Integer);
+begin
+ mItems := aitems;
+ mCount := acount;
+ mCurrent := -1;
+end;
+
+function TSimpleList.TEnumerator.MoveNext: Boolean;
+begin
+ Inc(mCurrent);
+ result := (mCurrent < mCount);
+end;
+
+function TSimpleList.TEnumerator.getCurrent (): ItemT;
+begin
+ result := mItems[mCurrent];
+end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+constructor TSimpleList.Create ();
+begin
+ mItems := nil;
+ mCount := 0;
+end;
+
+
+destructor TSimpleList.Destroy ();
+begin
+ mItems := nil;
+ inherited;
+end;
+
+
+function TSimpleList.GetEnumerator (): TEnumerator;
+begin
+ if (Length(mItems) > 0) then result := TEnumerator.Create(@mItems[0], mCount)
+ else result := TEnumerator.Create(nil, -1);
+end;
+
+
+procedure TSimpleList.reset (); inline;
+begin
+ mCount := 0;
+end;
+
+
+procedure TSimpleList.clear (); inline;
+begin
+ mItems := nil;
+ mCount := 0;
+end;
+
+
+function TSimpleList.getAt (idx: Integer): ItemT; inline;
+begin
+ if (idx >= 0) and (idx < mCount) then result := mItems[idx] else result := Default(ItemT);
+end;
+
+
+procedure TSimpleList.append (constref it: ItemT); inline;
+begin
+ if (mCount = Length(mItems)) then
+ begin
+ if (mCount = 0) then SetLength(mItems, 128) else SetLength(mItems, mCount*2);
+ end;
+ mItems[mCount] := it;
+ Inc(mCount);
+end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
var
wc2shitmap: array[0..65535] of AnsiChar;
wc2shitmapInited: Boolean = false;