@@ -184,7 +184,6 @@ TModConfig = class (TBaseConfig)
184184
185185 property Disabled:Boolean read FDisabled write FDisabled;
186186 property ID: TModId read FID write SetID;
187- // realtive (to mod root) mod path
188187 property Path: String read FPath write SetPath;
189188 procedure MayBeSetDefaultFSConfig ;
190189
@@ -294,9 +293,12 @@ TFSManager = class (TComponent, IResourceLoader)
294293
295294 procedure OnFileFound (FileIterator: TFileIterator);
296295 procedure OnDirectoryFound (FileIterator: TFileIterator);
296+ procedure OnTopLevelDirectoryFound (FileIterator: TFileIterator);
297+
297298 procedure OnArchiveFound (FileIterator: TFileIterator);
298299
299300 procedure ScanDir (const RelDir: string; ARootPath: TStrings);
301+ procedure ScanContentDir (const RelDir: string; ARootPath: TStrings);
300302
301303 procedure ScanMap (MapPath: string; ARootPath: TStrings);
302304
@@ -336,6 +338,7 @@ TFSManager = class (TComponent, IResourceLoader)
336338 procedure Load (AProgress: IProgressCallback);
337339
338340 procedure LoadResource (AResource: IResource; AResType: TResourceType; AName: string);
341+ procedure LoadResourceCombined (AResource: IResource; AResType: TResourceType; AName: string);
339342
340343 function TryLoadResource (AResource: IResource; AResType: TResourceType; AName: string): boolean;
341344
@@ -349,6 +352,10 @@ TFSManager = class (TComponent, IResourceLoader)
349352 property DataPath: TStringListUTF8 read FDataPath;
350353 end ;
351354
355+ EResourceNotFound = class (Exception)
356+
357+ end ;
358+
352359
353360implementation
354361uses
@@ -602,7 +609,7 @@ procedure TModConfig.MayBeSetDefaultFSConfig;
602609 cur_path := Filesystem.Add;
603610 cur_path.Identifier := ' ' ;
604611
605- item := cur_path.Items.Add;
612+ item := cur_path.Items.Add;
606613 item.&Type := ' dir' ;
607614 item.Path := MOD_ROOT;
608615 end ;
@@ -734,7 +741,7 @@ procedure TFSManager.ProcessModConfig(AParentModID: AnsiString;
734741 try
735742 mod_config := TModConfig.Create;
736743 mod_config.ID := AModID;
737- mod_config.Path := ExtractFileNameOnly(ExcludeTrailingBackslash( ExtractFilePath(mod_path)) );
744+ mod_config.Path := ExtractFilePath(mod_path);
738745 destreamer.JSONStreamToObject(stm, mod_config,' ' );
739746 mod_config.MayBeSetDefaultFSConfig;
740747
@@ -775,7 +782,30 @@ procedure TFSManager.OnDirectoryFound(FileIterator: TFileIterator);
775782 srch.OnDirectoryFound:=@OnDirectoryFound;
776783 try
777784 p := IncludeTrailingPathDelimiter(FileIterator.FileName);
778- srch.Search(p);
785+ srch.Search(p, ' ' , False);
786+ finally
787+ srch.Free;
788+ end ;
789+ end ;
790+
791+ procedure TFSManager.OnTopLevelDirectoryFound (FileIterator: TFileIterator);
792+ var
793+ srch: TFileSearcher;
794+ p, tld_name: string;
795+ begin
796+ srch := TFileSearcher.Create;
797+ srch.OnFileFound := @OnFileFound;
798+ srch.OnDirectoryFound:=@OnDirectoryFound;
799+ try
800+ p := IncludeTrailingPathDelimiter(FileIterator.FileName);
801+
802+ tld_name := ExtractFileNameOnly(ExcludeTrailingPathDelimiter(FileIterator.FileName));
803+
804+ if UpperCase(tld_name) <> ' MODS' then
805+ begin
806+ DebugLn(' TLD :' , p);
807+ srch.Search(p, ' ' , False);
808+ end ;
779809 finally
780810 srch.Free;
781811 end ;
@@ -993,10 +1023,62 @@ procedure TFSManager.LoadResource(AResource: IResource; AResType: TResourceType;
9931023begin
9941024 if not TryLoadResource(AResource, AResType, AName) then
9951025 begin
996- raise Exception .Create(' Resource not found: ' +AName);
1026+ raise EResourceNotFound .Create(' Resource not found: ' +AName);
9971027 end ;
9981028end ;
9991029
1030+ procedure TFSManager.LoadResourceCombined (AResource: IResource;
1031+ AResType: TResourceType; AName: string);
1032+ var
1033+ it : TResIDToLocationMap.TIterator;
1034+
1035+ last_location: TResLocation;
1036+ order: Integer;
1037+ begin
1038+ AName := NormalizeResourceName(AName);
1039+ it := SelectResource(AResType, AName);
1040+ if not Assigned(it) then
1041+ begin
1042+ raise EResourceNotFound.Create(' Resource not found: ' +AName);
1043+ end ;
1044+
1045+ last_location := it.Value ;
1046+ order := it.Key.ModOrder;
1047+
1048+ case last_location.lt of
1049+ TLocationType.InLod: last_location.lod.LoadResource(AResource,last_location.FileHeader);
1050+ TLocationType.InFile: LoadFileResource(AResource,last_location.path);
1051+ TLocationType.InArchive: LoadArchiveResource(AResource, last_location.archive, last_location.entry);
1052+ end ;
1053+
1054+ while it.Next do
1055+ begin
1056+ if (it.Key.VFSPath = AName) and (it.Key.Typ = AResType) then
1057+ begin
1058+ last_location := it.Value ;
1059+
1060+ if not (order < it.Key.ModOrder) then
1061+ begin
1062+ raise Exception.CreateFmt(' [Internal error] wrong order %d for %s' , [it.Key.ModOrder, AName]);
1063+ end ;
1064+
1065+ case last_location.lt of
1066+ TLocationType.InLod: last_location.lod.LoadResource(AResource,last_location.FileHeader) ;
1067+ TLocationType.InFile: LoadFileResource(AResource,last_location.path);
1068+ TLocationType.InArchive: LoadArchiveResource(AResource, last_location.archive, last_location.entry);
1069+ end ;
1070+
1071+ order := it.Key.ModOrder;
1072+ end
1073+ else
1074+ begin
1075+ Break;
1076+ end ;
1077+ end ;
1078+
1079+ FreeAndNil(it);
1080+ end ;
1081+
10001082function TFSManager.TryLoadResource (AResource: IResource; AResType: TResourceType; AName: string): boolean;
10011083var
10021084 it : TResIDToLocationMap.TIterator;
@@ -1132,15 +1214,9 @@ procedure TFSManager.ScanMods;
11321214 FCurrentLoadOrder:=load_order;
11331215 mod_paths.Clear;
11341216
1135- for APath in mod_roots do
1136- begin
1137- mod_paths.Append( IncludeTrailingPathDelimiter(APath) + AMod.Path);
1138- end ;
1217+ mod_paths.Append(AMod.Path);
11391218
1140- for APath in mod_roots do
1141- begin
1142- ProcessFSConfig(FModMap.Data[mod_idx].Filesystem,mod_paths);
1143- end ;
1219+ ProcessFSConfig(FModMap.Data[mod_idx].Filesystem,mod_paths);
11441220 end ;
11451221 end ;
11461222
@@ -1297,12 +1373,14 @@ procedure TFSManager.OnFileFound(FileIterator: TFileIterator);
12971373 file_name := ExtractFileNameOnly(FileIterator.FileName);
12981374
12991375 res_id.Typ := res_typ;
1300- res_id.VFSPath := SetDirSeparators(UpperCase(FCurrentVFSPath+ExtractFilePath(rel_path)+file_name));//
1376+ res_id.VFSPath := SetDirSeparators(UpperCase(FCurrentVFSPath+ExtractFilePath(rel_path)+file_name));
13011377 res_id.ModOrder:=FCurrentLoadOrder;
13021378
13031379 res_loc.SetFile(FileIterator.FileName);
13041380
13051381 FResMap.Insert(res_id,res_loc);
1382+
1383+ DebugLn(rel_path, ' => ' , res_id.VFSPath, ' => ' , FileIterator.FileName);
13061384end ;
13071385
13081386procedure TFSManager.OnLodItemFound (Alod: TLod; constref AItem: TLodItem);
@@ -1327,7 +1405,7 @@ procedure TFSManager.OnLodItemFound(Alod: TLod; constref AItem: TLodItem);
13271405 exit;
13281406
13291407 res_id.Typ := res_typ;
1330- res_id.VFSPath := FCurrentVFSPath+file_name;//
1408+ res_id.VFSPath := FCurrentVFSPath+file_name;
13311409 res_id.ModOrder:=FCurrentLoadOrder;
13321410
13331411 res_loc.SetLod(Alod, AItem);
@@ -1395,12 +1473,13 @@ procedure TFSManager.ProcessConfigItem(APath: TFilesystemConfigPath; ARootPath:
13951473 ScanLod(rel_path,ARootPath);
13961474 end ;
13971475 ' dir' :begin
1398- if item.Path = MOD_ROOT then
1476+ if UpperCase(rel_path) = UpperCase( MOD_ROOT) then
13991477 begin
14001478 ScanArchive(item, rel_path, ARootPath);
1401- ScanDir (rel_path,ARootPath);
1479+ ScanContentDir (rel_path,ARootPath);
14021480 end
1403- else begin
1481+ else if UpperCase(item.Path) <> ' MODS' then
1482+ begin
14041483 ScanDir(rel_path,ARootPath);
14051484 end ;
14061485 end ;
@@ -1431,12 +1510,35 @@ procedure TFSManager.ScanDir(const RelDir: string; ARootPath: TStrings);
14311510 begin
14321511 srch := TFileSearcher.Create;
14331512 srch.OnFileFound := @OnFileFound;
1434- // srch.OnDirectoryFound:=@OnDirectoryFound;
1513+ srch.OnDirectoryFound:=@OnDirectoryFound;
1514+ try
1515+ FCurrentRelPath := RelDir;
1516+ FCurrentRootPath := root_path;
1517+ p := IncludeTrailingPathDelimiter(MakeFullPath(root_path,RelDir));
1518+ srch.Search(p, ' ' , False);
1519+ finally
1520+ srch.Free;
1521+ end ;
1522+ end ;
1523+ end ;
1524+
1525+ procedure TFSManager.ScanContentDir (const RelDir: string; ARootPath: TStrings);
1526+ var
1527+ srch: TFileSearcher;
1528+ p: string;
1529+ root_path: String;
1530+ begin
1531+ for root_path in ARootPath do
1532+ begin
1533+ DebugLn(' ScanContentDir: ' , root_path, ' ' , RelDir);
1534+ srch := TFileSearcher.Create;
1535+ // srch.OnFileFound := @OnFileFound;
1536+ srch.OnDirectoryFound:=@OnTopLevelDirectoryFound;
14351537 try
14361538 FCurrentRelPath := RelDir;
14371539 FCurrentRootPath := root_path;
14381540 p := IncludeTrailingPathDelimiter(MakeFullPath(root_path,RelDir));
1439- srch.Search(p);
1541+ srch.Search(p, ' ' , False );
14401542 finally
14411543 srch.Free;
14421544 end ;
0 commit comments