diff --git a/src/game/g_map.pas b/src/game/g_map.pas
index 29ece6fafd845f590715a7502689b9fc1dc2630a..e99d47b19186dd65974751d9a2dd3e90539e3439 100644 (file)
--- a/src/game/g_map.pas
+++ b/src/game/g_map.pas
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, version 3 of the License ONLY.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
GridTagLift = 1 shl 8; // gLifts
GridTagBlockMon = 1 shl 9; // gBlockMon
+ GridTagSolid = (GridTagWall or GridTagDoor);
GridTagObstacle = (GridTagStep or GridTagWall or GridTagDoor);
GridTagLiquid = (GridTagAcid1 or GridTagAcid2 or GridTagWater);
gLiftMap: array of array of DWORD;
gWADHash: TMD5Digest;
BackID: DWORD = DWORD(-1);
- gExternalResources: TStringList;
+ gExternalResources: array of TDiskFileInfo = nil;
gMovingWallIds: array of Integer = nil;
gdbg_map_use_accel_render: Boolean = true;
implementation
uses
- e_input, g_main, e_log, e_texture, g_items, g_gfx, g_console,
- GL, GLExt, g_weapons, g_game, g_sound, e_sound, CONFIG,
+ {$INCLUDE ../nogl/noGLuses.inc}
+ e_input, g_main, e_log, e_texture, e_res, g_items, g_gfx, g_console,
+ g_weapons, g_game, g_sound, e_sound, CONFIG,
g_options, g_triggers, g_player,
Math, g_monsters, g_saveload, g_language, g_netmsg,
sfs, xstreams, hashtable, wadreader,
ImagingTypes, Imaging, ImagingUtility,
- ImagingGif, ImagingNetworkGraphics;
+ ImagingGif, ImagingNetworkGraphics,
+ g_res_downloader;
const
FLAGRECT: TRectWH = (X:15; Y:12; Width:33; Height:52);
try
e_LogWritefln('parsing "mapdef.txt"...', []);
- st := openDiskFileRO(DataDir+'mapdef.txt');
- e_LogWritefln('found local "%smapdef.txt"', [DataDir]);
+ st := e_OpenResourceRO(DataDirs, 'mapdef.txt');
+ e_LogWritefln('found local "mapdef.txt"', []);
except
st := nil;
end;
// ////////////////////////////////////////////////////////////////////////// //
var
NNF_PureName: String; // Èìÿ òåêñòóðû áåç öèôð â êîíöå
+ NNF_PureExt: String; // extension postfix
NNF_FirstNum: Integer; // ×èñëî ó íà÷àëüíîé òåêñòóðû
NNF_CurrentNum: Integer; // Ñëåäóþùåå ÷èñëî ó òåêñòóðû
function g_Texture_NumNameFindStart(name: String): Boolean;
var
- i: Integer;
+ i, j: Integer;
begin
Result := False;
NNF_PureName := '';
+ NNF_PureExt := '';
NNF_FirstNum := -1;
NNF_CurrentNum := -1;
end
else
begin
+ j := i + 1;
+ while (j <= Length(name)) and (name[j] <> '.') do inc(j);
NNF_PureName := Copy(name, 1, i);
- Delete(name, 1, i);
+ NNF_PureExt := Copy(name, j);
+ name := Copy(name, i + 1, j - i - 1);
Break;
end;
end;
Exit;
end;
- newName := NNF_PureName + IntToStr(NNF_CurrentNum);
+ newName := NNF_PureName + IntToStr(NNF_CurrentNum) + NNF_PureExt;
if NNF_CurrentNum < NNF_FirstNum then
Result := NNF_NAME_BEFORE
procedure g_Map_ProfilersBegin ();
begin
if (profMapCollision = nil) then profMapCollision := TProfiler.Create('COLSOLID', g_profile_history_size);
- profMapCollision.mainBegin(g_profile_collision);
+ if (profMapCollision <> nil) then profMapCollision.mainBegin(g_profile_collision);
// create sections
- if g_profile_collision then
+ if g_profile_collision and (profMapCollision <> nil) then
begin
profMapCollision.sectionBegin('*solids');
profMapCollision.sectionEnd();
var
ex, ey: Integer;
begin
- result := mapGrid.traceRay(ex, ey, x0, y0, x1, y1, nil, (GridTagWall or GridTagDoor));
+ result := mapGrid.traceRay(ex, ey, x0, y0, x1, y1, (GridTagWall or GridTagDoor));
if (result <> nil) then
begin
if (hitx <> nil) then hitx^ := ex;
@@ -580,7 +587,7 @@ function g_Map_traceToNearest (x0, y0, x1, y1: Integer; tag: Integer; hitx: PInt
var
ex, ey: Integer;
begin
- result := mapGrid.traceRay(ex, ey, x0, y0, x1, y1, nil, tag);
+ result := mapGrid.traceRay(ex, ey, x0, y0, x1, y1, tag);
if (result <> nil) then
begin
if (hitx <> nil) then hitx^ := ex;
begin
// stop if the lift of the right type
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)));
+ ((WordBool(PanelType and PANEL_LIFTUP) and (pan.LiftType = LIFTTYPE_UP)) or
+ (WordBool(PanelType and PANEL_LIFTDOWN) and (pan.LiftType = LIFTTYPE_DOWN)) or
+ (WordBool(PanelType and PANEL_LIFTLEFT) and (pan.LiftType = LIFTTYPE_LEFT)) or
+ (WordBool(PanelType and PANEL_LIFTRIGHT) and (pan.LiftType = LIFTTYPE_RIGHT)));
exit;
end;
result := true; // otherwise, stop anyway, 'cause `forEachAtPoint()` is guaranteed to call this only for correct panels
end;
function g_Map_HasAnyPanelAtPoint (x, y: Integer; panelType: Word): Boolean;
-
- function checker (pan: TPanel; tag: Integer): Boolean;
- begin
- {
- if ((tag and (GridTagWall or GridTagDoor)) <> 0) then
- begin
- result := pan.Enabled; // stop if wall is enabled
- exit;
- end;
- }
-
- if ((tag and GridTagLift) <> 0) then
- begin
- // stop if the lift of the right type
- 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)));
- exit;
- end;
-
- result := true; // otherwise, stop anyway, 'cause `forEachAtPoint()` is guaranteed to call this only for correct panels
- end;
-
var
tagmask: Integer = 0;
- pmark: PoolMark;
- hitcount: Integer;
- ppan: PPanel;
+ mwit: PPanel;
+ it: TPanelGrid.Iter;
begin
result := false;
if (tagmask = 0) then exit;// just in case
- pmark := framePool.mark();
if ((tagmask and GridTagLift) <> 0) then
begin
// slow
- hitcount := mapGrid.forEachAtPoint(x, y, tagmask);
- ppan := PPanel(framePool.getPtr(pmark));
- while (hitcount > 0) do
- begin
- if (xxPanAtPointChecker(ppan^, PanelType)) then begin result := true; break; end;
- Inc(ppan);
- Dec(hitcount);
- end;
+ it := mapGrid.forEachAtPoint(x, y, tagmask);
+ for mwit in it do if (xxPanAtPointChecker(mwit^, PanelType)) then begin result := true; break; end;
end
else
begin
// fast
- result := (mapGrid.forEachAtPoint(x, y, tagmask, false, true) <> 0); // firsthit
+ it := mapGrid.forEachAtPoint(x, y, tagmask, false, true);
+ result := (it.length <> 0); // firsthit
end;
- framePool.release(pmark);
+ it.release();
end;
function g_Map_PanelAtPoint (x, y: Integer; tagmask: Integer=-1): TPanel;
var
- pmark: PoolMark;
- hitcount: Integer;
+ it: TPanelGrid.Iter;
begin
result := nil;
if (tagmask = 0) then exit;
- //result := mapGrid.forEachAtPoint(x, y, nil, tagmask);
- pmark := framePool.mark();
- hitcount := mapGrid.forEachAtPoint(x, y, tagmask, false, true); // firsthit
- if (hitcount <> 0) then result := PPanel(framePool.getPtr(pmark))^;
- framePool.release(pmark);
+ it := mapGrid.forEachAtPoint(x, y, tagmask, false, true); // firsthit
+ if (it.length <> 0) then result := it.first^;
+ it.release();
end;
end;
-function CreateTexture(RecName: AnsiString; Map: string; log: Boolean): Integer;
+function extractWadName (resourceName: string): string;
+var
+ posN: Integer;
+begin
+ posN := Pos(':', resourceName);
+ if posN > 0 then
+ Result:= Copy(resourceName, 0, posN-1)
+ else
+ Result := '';
+end;
+
+
+procedure addResToExternalResList (res: AnsiString);
+var
+ uname: AnsiString;
+ f: Integer;
+ fi: TDiskFileInfo;
+begin
+ if g_Game_IsClient or not g_Game_IsNet then exit;
+ if (length(res) = 0) then exit; // map wad
+ //res := extractWadName(res);
+ //if (length(res) = 0) then exit; // map wad
+ uname := toLowerCase1251(res);
+ // do not add duplicates
+ for f := 0 to High(gExternalResources) do
+ begin
+ if (gExternalResources[f].userName = uname) then exit;
+ end;
+ //writeln('***(000) addResToExternalResList: res=[', res, ']');
+ // add new resource
+ fi.userName := uname;
+ if not findFileCI(res) then exit;
+ //writeln('***(001) addResToExternalResList: res=[', res, ']');
+ fi.diskName := res;
+ if (not GetDiskFileInfo(res, fi)) then
+ begin
+ fi.tag := -1;
+ end
+ else
+ begin
+ //writeln('***(002) addResToExternalResList: res=[', res, ']');
+ fi.tag := 0; // non-zero means "cannot caclucate hash"
+ try
+ fi.hash := MD5File(fi.diskName);
+ except
+ fi.tag := -1;
+ end;
+ end;
+ //e_LogWritefln('addext: res=[%s]; uname=[%s]; diskName=[%s]', [res, fi.userName, fi.diskName]);
+ SetLength(gExternalResources, length(gExternalResources)+1);
+ gExternalResources[High(gExternalResources)] := fi;
+end;
+
+
+procedure compactExtResList ();
+var
+ src, dest: Integer;
+begin
+ src := 0;
+ dest := 0;
+ for src := 0 to High(gExternalResources) do
+ begin
+ if (gExternalResources[src].tag = 0) then
+ begin
+ // copy it
+ if (dest <> src) then gExternalResources[dest] := gExternalResources[src];
+ Inc(dest);
+ end;
+ end;
+ if (dest <> length(gExternalResources)) then SetLength(gExternalResources, dest);
+end;
+
+
+function GetReplacementWad (WadName: AnsiString): AnsiString;
+begin
+ result := '';
+ if WadName <> '' then
+ begin
+ result := WadName;
+ if g_Game_IsClient then result := g_Res_FindReplacementWad(WadName);
+ if (result = WadName) then result := e_FindWad(WadDirs, result)
+ end;
+end;
+
+
+procedure generateExternalResourcesList (map: TDynRecord);
+begin
+ SetLength(gExternalResources, 0);
+ addResToExternalResList(GetReplacementWad(g_ExtractWadName(map.MusicName)));
+ addResToExternalResList(GetReplacementWad(g_ExtractWadName(map.SkyName)));
+end;
+
+
+function CreateTexture (RecName: AnsiString; Map: string; log: Boolean): Integer;
var
WAD: TWADFile;
TextureData: Pointer;
end;
// Çàãðóæàåì ðåñóðñ òåêñòóðû â ïàìÿòü èç WAD'à:
- WADName := g_ExtractWadName(RecName);
+ WADName := GetReplacementWad(g_ExtractWadName(RecName));
+ if (WADName <> '') then addResToExternalResList(WADName);
+ if WADName = '' then WADName := Map; //WADName := GameDir+'/wads/'+WADName else
WAD := TWADFile.Create();
-
- if WADName <> '' then WADName := GameDir+'/wads/'+WADName else WADName := Map;
-
WAD.ReadFile(WADName);
//txname := RecName;
end;
// ×èòàåì WAD-ðåñóðñ àíèì.òåêñòóðû èç WAD'à â ïàìÿòü:
- WADName := g_ExtractWadName(RecName);
+ WADName := GetReplacementWad(g_ExtractWadName(RecName));
+ if (WADName <> '') then addResToExternalResList(WADName);
+ if WADName = '' then WADName := Map; //WADName := GameDir+'/wads/'+WADName else
WAD := TWADFile.Create();
try
- if WADName <> '' then WADName := GameDir+'/wads/'+WADName else WADName := Map;
+ //if WADName <> '' then WADName := GameDir+'/wads/'+WADName else WADName := Map;
WAD.ReadFile(WADName);
end;
// ýòî ïòèöà? ýòî ñàìîë¸ò?
- if (TextureWAD[0] = 'D') and (TextureWAD[1] = 'F') and
- (TextureWAD[2] = 'W') and (TextureWAD[3] = 'A') and (TextureWAD[4] = 'D') then
+ if isWadData(TextureWAD, ResLength) then
begin
// íåò, ýòî ñóïåðìåí!
if not WAD.ReadMemory(TextureWAD, ResLength) then
function CreateTrigger (amapIdx: Integer; Trigger: TDynRecord; atpanid, atrigpanid: Integer): Integer;
var
_trigger: TTrigger;
+ tp: TPanel;
begin
result := -1;
if g_Game_IsClient and not (Trigger.TriggerType in [TRIGGER_SOUND, TRIGGER_MUSIC]) then Exit;
ActivateType := Trigger.ActivateType;
Keys := Trigger.Keys;
trigPanelGUID := atrigpanid;
+ // HACK: used in TPanel.CanChangeTexture. maybe there's a better way?
+ if TexturePanelGUID <> -1 then
+ begin
+ tp := g_Map_PanelByGUID(TexturePanelGUID);
+ if (tp <> nil) then tp.hasTexTrigger := True;
+ end;
end;
result := Integer(g_Triggers_Create(_trigger, Trigger));
g_Mons_ForEach(monsDieTrig);
end;
-function extractWadName(resourceName: string): string;
-var
- posN: Integer;
-begin
- posN := Pos(':', resourceName);
- if posN > 0 then
- Result:= Copy(resourceName, 0, posN-1)
- else
- Result := '';
-end;
-
-procedure addResToExternalResList(res: string);
-begin
- res := extractWadName(res);
- if (res <> '') and (gExternalResources.IndexOf(res) = -1) then
- gExternalResources.Add(res);
-end;
-
-procedure generateExternalResourcesList({mapReader: TMapReader_1}map: TDynRecord);
-//var
- //textures: TTexturesRec1Array;
- //textures: TDynField;
- //trec: TDynRecord;
- //mapHeader: TMapHeaderRec_1;
- //i: integer;
- //resFile: String = '';
-begin
- if gExternalResources = nil then
- gExternalResources := TStringList.Create;
-
- gExternalResources.Clear;
-
- (*
- {
- textures := GetTextures(map);
- for i := 0 to High(textures) do
- begin
- addResToExternalResList(resFile);
- end;
- }
-
- textures := map['texture'];
- if (textures <> nil) then
- begin
- for trec in textures do
- begin
- addResToExternalResList(resFile);
- end;
- end;
-
- textures := nil;
- *)
-
- //mapHeader := GetMapHeader(map);
-
- addResToExternalResList(map.MusicName);
- addResToExternalResList(map.SkyName);
-end;
-
-
procedure mapCreateGrid ();
var
mapX0: Integer = $3fffffff;
if (gCurrentMap = nil) then
begin
FileName := g_ExtractWadName(Res);
- e_WriteLog('Loading map WAD: '+FileName, TMsgType.Notify);
+ e_LogWritefln('Loading map WAD [%s] (res=[%s])', [FileName, Res], TMsgType.Notify);
g_Game_SetLoadingText(_lc[I_LOAD_WAD_FILE], 0, False);
WAD := TWADFile.Create();
begin
e_WriteLog(' Loading sky: ' + gMapInfo.SkyName, TMsgType.Notify);
g_Game_SetLoadingText(_lc[I_LOAD_SKY], 0, False);
- FileName := g_ExtractWadName(gMapInfo.SkyName);
-
- if (FileName <> '') then FileName := GameDir+'/wads/'+FileName else FileName := g_ExtractWadName(Res);
-
if gTextureFilter then TEXTUREFILTER := GL_LINEAR else TEXTUREFILTER := GL_NEAREST;
try
- s := FileName+':'+g_ExtractFilePathName(gMapInfo.SkyName);
+ s := e_GetResourcePath(WadDirs, gMapInfo.SkyName, g_ExtractWadName(Res));
if g_Texture_CreateWAD(BackID, s) then
- begin
- g_Game_SetupScreenSize();
- end
+ g_Game_SetupScreenSize
else
- begin
- g_FatalError(Format(_lc[I_GAME_ERROR_SKY], [s]));
- end;
+ g_FatalError(Format(_lc[I_GAME_ERROR_SKY], [s]))
finally
TEXTUREFILTER := GL_NEAREST;
end;
begin
e_WriteLog(' Loading music: ' + gMapInfo.MusicName, TMsgType.Notify);
g_Game_SetLoadingText(_lc[I_LOAD_MUSIC], 0, False);
- FileName := g_ExtractWadName(gMapInfo.MusicName);
-
- if FileName <> '' then
- FileName := GameDir+'/wads/'+FileName
- else
- begin
- FileName := g_ExtractWadName(Res);
- end;
- s := FileName+':'+g_ExtractFilePathName(gMapInfo.MusicName);
+ s := e_GetResourcePath(WadDirs, gMapInfo.MusicName, g_ExtractWadName(Res));
if g_Sound_CreateWADEx(gMapInfo.MusicName, s, True) then
ok := True
else
finally
sfsGCEnable(); // enable releasing unused volumes
//mapReader.Free();
- e_ClearInputBuffer(); // why not?
+ e_UnpressAllKeys; // why not?
if not mapOk then
begin
gCurrentMap.Free();
end;
end;
+ compactExtResList();
e_WriteLog('Done loading map.', TMsgType.Notify);
Result := True;
end;
a, d, j: Integer;
m: Word;
s: String;
+ b: Byte;
procedure UpdatePanelArray(var panels: TPanelArray);
var
s := _lc[I_PLAYER_FLAG_BLUE];
g_Game_Message(Format(_lc[I_MESSAGE_FLAG_RETURN], [AnsiUpperCase(s)]), 144);
+ if (((gPlayer1 <> nil) and (((gPlayer1.Team = TEAM_RED) and (a = FLAG_RED)) or ((gPlayer1.Team = TEAM_BLUE) and (a = FLAG_BLUE))))
+ or ((gPlayer2 <> nil) and (((gPlayer2.Team = TEAM_RED) and (a = FLAG_RED)) or ((gPlayer2.Team = TEAM_BLUE) and (a = FLAG_BLUE))))) then
+ b := 0
+ else
+ b := 1;
+
+ if not sound_ret_flag[b].IsPlaying() then
+ sound_ret_flag[b].Play();
+
if g_Game_IsNet then
MH_SEND_FlagEvent(FLAG_STATE_RETURNED, a, 0);
Continue;
// new algo
procedure g_Map_CollectDrawPanels (x0, y0, wdt, hgt: Integer);
- (*
- function checker (pan: TPanel; tag: Integer): Boolean;
- begin
- result := false; // don't stop, ever
- if ((tag and GridTagDoor) <> 0) <> pan.Door then exit;
- gDrawPanelList.insert(pan);
- end;
- *)
var
- pmark: PoolMark;
- phit: PPanel;
- hitcount: Integer;
+ mwit: PPanel;
+ it: TPanelGrid.Iter;
begin
dplClear();
- //tagmask := panelTypeToTag(PanelType);
- //mapGrid.forEachInAABB(x0, y0, wdt, hgt, checker, GridDrawableMask);
- pmark := framePool.mark();
- hitcount := mapGrid.forEachInAABB(x0, y0, wdt, hgt, GridDrawableMask);
- if (hitcount = 0) then exit;
- phit := PPanel(framePool.getPtr(pmark));
- while (hitcount > 0) do
- begin
- if ((phit^.tag and GridTagDoor) <> 0) <> phit^.Door then
- begin
- end
- else
- begin
- gDrawPanelList.insert(phit^);
- end;
- Inc(phit);
- Dec(hitcount);
- end;
- framePool.release(pmark);
+ it := mapGrid.forEachInAABB(x0, y0, wdt, hgt, GridDrawableMask);
+ for mwit in it do if (((mwit^.tag and GridTagDoor) <> 0) = mwit^.Door) then gDrawPanelList.insert(mwit^);
+ it.release();
// list will be rendered in `g_game.DrawPlayer()`
end;
procedure g_Map_DrawPanelShadowVolumes (lightX: Integer; lightY: Integer; radius: Integer);
- (*
- function checker (pan: TPanel; tag: Integer): Boolean;
- begin
- result := false; // don't stop, ever
- pan.DrawShadowVolume(lightX, lightY, radius);
- end;
- *)
var
- pmark: PoolMark;
- phit: PPanel;
- hitcount: Integer;
-begin
- //mapGrid.forEachInAABB(lightX-radius, lightY-radius, radius*2, radius*2, checker, (GridTagWall or GridTagDoor));
- pmark := framePool.mark();
- hitcount := mapGrid.forEachInAABB(lightX-radius, lightY-radius, radius*2, radius*2, (GridTagWall or GridTagDoor));
- if (hitcount = 0) then exit;
- phit := PPanel(framePool.getPtr(pmark));
- while (hitcount > 0) do
- begin
- phit^.DrawShadowVolume(lightX, lightY, radius);
- Inc(phit);
- Dec(hitcount);
- end;
- framePool.release(pmark);
+ mwit: PPanel;
+ it: TPanelGrid.Iter;
+begin
+ it := mapGrid.forEachInAABB(lightX-radius, lightY-radius, radius*2, radius*2, (GridTagWall or GridTagDoor));
+ for mwit in it do mwit^.DrawShadowVolume(lightX, lightY, radius);
+ it.release();
end;
h := High(gLifts);
for a := 0 to h do
- if ((WordBool(PanelType and (PANEL_LIFTUP)) and (gLifts[a].LiftType = 0)) or
- (WordBool(PanelType and (PANEL_LIFTDOWN)) and (gLifts[a].LiftType = 1)) or
- (WordBool(PanelType and (PANEL_LIFTLEFT)) and (gLifts[a].LiftType = 2)) or
- (WordBool(PanelType and (PANEL_LIFTRIGHT)) and (gLifts[a].LiftType = 3))) and
+ if ((WordBool(PanelType and (PANEL_LIFTUP)) and (gLifts[a].LiftType = LIFTTYPE_UP)) or
+ (WordBool(PanelType and (PANEL_LIFTDOWN)) and (gLifts[a].LiftType = LIFTTYPE_DOWN)) or
+ (WordBool(PanelType and (PANEL_LIFTLEFT)) and (gLifts[a].LiftType = LIFTTYPE_LEFT)) or
+ (WordBool(PanelType and (PANEL_LIFTRIGHT)) and (gLifts[a].LiftType = LIFTTYPE_RIGHT))) and
g_Collide(X, Y, Width, Height,
gLifts[a].X, gLifts[a].Y,
gLifts[a].Width, gLifts[a].Height) then
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))) {and
+ ((WordBool(PanelType and PANEL_LIFTUP) and (pan.LiftType = LIFTTYPE_UP)) or
+ (WordBool(PanelType and PANEL_LIFTDOWN) and (pan.LiftType = LIFTTYPE_DOWN)) or
+ (WordBool(PanelType and PANEL_LIFTLEFT) and (pan.LiftType = LIFTTYPE_LEFT)) or
+ (WordBool(PanelType and PANEL_LIFTRIGHT) and (pan.LiftType = LIFTTYPE_RIGHT))) {and
g_Collide(X, Y, Width, Height, pan.X, pan.Y, pan.Width, pan.Height)};
exit;
end;
var
tagmask: Integer = 0;
- pmark: PoolMark;
- phit: PPanel;
- hitcount: Integer;
+ mwit: PPanel;
+ it: TPanelGrid.Iter;
pan: TPanel;
begin
result := false;
if (profMapCollision <> nil) then profMapCollision.sectionBeginAccum('*solids');
if gdbg_map_use_accel_coldet then
begin
- {if (Width = 1) and (Height = 1) then
- begin
- if ((tagmask and SlowMask) <> 0) then
- begin
- // slow
- result := (mapGrid.forEachAtPoint(X, Y, checker, tagmask) <> nil);
- end
- else
- begin
- // fast
- result := (mapGrid.forEachAtPoint(X, Y, nil, tagmask) <> nil);
- end;
- end
- else}
+ if ((tagmask and SlowMask) <> 0) then
begin
- pmark := framePool.mark();
- if ((tagmask and SlowMask) <> 0) then
+ // slow
+ it := mapGrid.forEachInAABB(X, Y, Width, Height, tagmask);
+ for mwit in it do
begin
- // slow
- //result := (mapGrid.forEachInAABB(X, Y, Width, Height, checker, tagmask) <> nil);
- hitcount := mapGrid.forEachInAABB(X, Y, Width, Height, tagmask);
- //if (hitcount = 0) then exit;
- phit := PPanel(framePool.getPtr(pmark));
- while (hitcount > 0) do
+ pan := mwit^;
+ if ((pan.tag and GridTagLift) <> 0) then
begin
- pan := phit^;
- if ((pan.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))) {and
- g_Collide(X, Y, Width, Height, pan.X, pan.Y, pan.Width, pan.Height)};
- end
- else if ((pan.tag and GridTagBlockMon) <> 0) then
- begin
- result := ((not b1x3) or (pan.Width+pan.Height >= 64)); //and g_Collide(X, Y, Width, Height, pan.X, pan.Y, pan.Width, pan.Height);
- end
- else
- begin
- // other shit
- result := true; // i found her!
- end;
- if (result) then break;
- Inc(phit);
- Dec(hitcount);
+ result :=
+ ((WordBool(PanelType and PANEL_LIFTUP) and (pan.LiftType = LIFTTYPE_UP)) or
+ (WordBool(PanelType and PANEL_LIFTDOWN) and (pan.LiftType = LIFTTYPE_DOWN)) or
+ (WordBool(PanelType and PANEL_LIFTLEFT) and (pan.LiftType = LIFTTYPE_LEFT)) or
+ (WordBool(PanelType and PANEL_LIFTRIGHT) and (pan.LiftType = LIFTTYPE_RIGHT))) {and
+ g_Collide(X, Y, Width, Height, pan.X, pan.Y, pan.Width, pan.Height)};
+ end
+ else if ((pan.tag and GridTagBlockMon) <> 0) then
+ begin
+ result := ((not b1x3) or (pan.Width+pan.Height >= 64)); //and g_Collide(X, Y, Width, Height, pan.X, pan.Y, pan.Width, pan.Height);
+ end
+ else
+ begin
+ // other shit
+ result := true; // i found her!
end;
- end
- else
- begin
- // fast
- //result := (mapGrid.forEachInAABB(X, Y, Width, Height, nil, tagmask) <> nil);
- hitcount := mapGrid.forEachInAABB(X, Y, Width, Height, tagmask, false, true); // return first hit
- result := (hitcount > 0);
+ if (result) then break;
end;
- framePool.release(pmark);
+ end
+ else
+ begin
+ // fast
+ it := mapGrid.forEachInAABB(X, Y, Width, Height, tagmask, false, true); // return first hit
+ result := (it.length > 0);
end;
+ it.release();
end
else
begin
function g_Map_CollideLiquid_Texture(X, Y: Integer; Width, Height: Word): DWORD;
var
cctype: Integer = 3; // priority: 0: water was hit, 1: acid1 was hit, 2: acid2 was hit; 3: nothing was hit
- //texid: DWORD;
-
- (*
- // slightly different from the old code, but meh...
- function checker (pan: TPanel; tag: Integer): Boolean;
- begin
- result := false; // don't stop, ever
- //if ((tag and (GridTagWater or GridTagAcid1 or GridTagAcid2)) = 0) then exit;
- // check priorities
- case cctype of
- 0: if ((tag and GridTagWater) = 0) then exit; // allowed: water
- 1: if ((tag and (GridTagWater or GridTagAcid1)) = 0) then exit; // allowed: water, acid1
- //2: if ((tag and (GridTagWater or GridTagAcid1 or GridTagAcid2) = 0) then exit; // allowed: water, acid1, acid2
- end;
- // collision?
- //if not g_Collide(X, Y, Width, Height, pan.X, pan.Y, pan.Width, pan.Height) then exit;
- // yeah
- texid := pan.GetTextureID();
- // water? water has the highest priority, so stop right here
- if ((tag and GridTagWater) <> 0) then begin cctype := 0; result := true; exit; end;
- // acid2?
- if ((tag and GridTagAcid2) <> 0) then cctype := 2;
- // acid1?
- if ((tag and GridTagAcid1) <> 0) then cctype := 1;
- end;
- *)
-var
- pmark: PoolMark;
- phit: PPanel;
- hitcount: Integer;
- pan: TPanel;
+ mwit: PPanel;
+ it: TPanelGrid.Iter;
begin
if (profMapCollision <> nil) then profMapCollision.sectionBeginAccum('liquids');
if gdbg_map_use_accel_coldet then
begin
- {texid}result := LongWord(TEXTURE_NONE);
- {
- if (Width = 1) and (Height = 1) then
- begin
- mapGrid.forEachAtPoint(X, Y, checker, (GridTagWater or GridTagAcid1 or GridTagAcid2));
- end
- else
- begin
- mapGrid.forEachInAABB(X, Y, Width, Height, checker, (GridTagWater or GridTagAcid1 or GridTagAcid2));
- end;
- }
- pmark := framePool.mark();
- hitcount := mapGrid.forEachInAABB(X, Y, Width, Height, (GridTagWater or GridTagAcid1 or GridTagAcid2));
- if (hitcount = 0) then exit;
- phit := PPanel(framePool.getPtr(pmark));
- while (hitcount > 0) do
- begin
- pan := phit^;
- Inc(phit);
- Dec(hitcount);
- if (liquidChecker(pan, result, cctype)) then break;
- end;
- framePool.release(pmark);
- //result := texid;
+ result := LongWord(TEXTURE_NONE);
+ it := mapGrid.forEachInAABB(X, Y, Width, Height, (GridTagWater or GridTagAcid1 or GridTagAcid2));
+ for mwit in it do if (liquidChecker(mwit^, result, cctype)) then break;
+ it.release();
end
else
begin
//TODO: make separate lift tags, and change tag here
case LiftType of
- 0: g_Mark(X, Y, Width, Height, MARK_LIFTUP);
- 1: g_Mark(X, Y, Width, Height, MARK_LIFTDOWN);
- 2: g_Mark(X, Y, Width, Height, MARK_LIFTLEFT);
- 3: g_Mark(X, Y, Width, Height, MARK_LIFTRIGHT);
+ LIFTTYPE_UP: g_Mark(X, Y, Width, Height, MARK_LIFTUP);
+ LIFTTYPE_DOWN: g_Mark(X, Y, Width, Height, MARK_LIFTDOWN);
+ LIFTTYPE_LEFT: g_Mark(X, Y, Width, Height, MARK_LIFTLEFT);
+ LIFTTYPE_RIGHT: g_Mark(X, Y, Width, Height, MARK_LIFTRIGHT);
end;
//if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(pguid);