ДОБАВЛЯТОР ВЫДЕЛЕННЫХ ЛОКАЦИЙ В ЗАДАВАЕМЫЙ ЗАГРУЗОЧНЫЙ ЭКРАН.pas #
Hellow peep! Nyse to meat yu! Я решил основать проект GPT-xEdit.pas -- писать скрипты для Эдита с помощью чатжпт по запросам Магнума. Можете посмотреть, это уже второй скрипт написанный Chat-GPT по моим наводкам.
- Скрипт не копирует записи которые НЕ WRLD / CELL
- пропускает дубли
- умеет работать с внешними мастерами либо с собственными (плагина) записями
- спрашивает бэйс-форм загрузочного экрана
- там проверка, что введённый айдишник, это экран загрузки
- добавляет в LSCR все выделенные локации
- и не делает ошибок
- СДЕЛАНО ПО ПРОСЬБЕ МАГНУМА
{
Filename: AddLocationsToLSCR.pas
Author: ChatGPT (OpenAI)
License: MIT
Description:
Adds selected CELL and WRLD records to a specified LSCR (Loading Screen).
Supports both external masters and same-file (self) locations.
Prevents duplicates and provides detailed logging.
}
unit UserScript;
var
LoadScreen: IInterface;
AddedCount, SkippedCount: integer;
// Search LSCR by FormID across all loaded files
function FindLSCRByFormID(fullID: integer): IInterface;
var
i: integer;
rec: IInterface;
begin
Result := nil;
for i := 0 to FileCount - 1 do begin
rec := RecordByFormID(FileByIndex(i), fullID, True);
if Assigned(rec) and (Signature(rec) = 'LSCR') then begin
Result := rec;
Exit;
end;
end;
end;
// Find index of a master file inside given file's master list
function FindMasterIndex(containerFile, masterFile: IInterface): integer;
var
i: integer;
masterName, targetName: string;
begin
Result := -1;
targetName := GetFileName(masterFile);
for i := 0 to MasterCount(containerFile) - 1 do begin
masterName := GetFileName(MasterByIndex(containerFile, i));
if masterName = targetName then begin
Result := i;
Exit;
end;
end;
end;
// Check if this location already exists in LSCR\Locations
function LocationExists(locations: IInterface; localID: integer): boolean;
var
i: integer;
lnam, direct: IInterface;
existingID: integer;
begin
Result := False;
for i := 0 to ElementCount(locations) - 1 do begin
lnam := ElementByIndex(locations, i);
direct := ElementByPath(lnam, 'Direct');
if Assigned(direct) then begin
existingID := GetNativeValue(direct);
if existingID = localID then begin
Result := True;
Exit;
end;
end;
end;
end;
// Create a new LNAM entry and set Direct to local FormID
function CreateLocationEntry(lscr, locations, e: IInterface): IInterface;
var
lnam, direct, baseRec: IInterface;
baseID, localID: integer;
masterIndex: integer;
baseFile, lscrFile: IInterface;
begin
Result := nil;
// Resolve to original record
baseRec := MasterOrSelf(e);
baseFile := GetFile(baseRec);
lscrFile := GetFile(lscr);
baseID := FormID(baseRec) and $00FFFFFF;
// SELF CASE: LSCR and location in the same file
if GetFileName(lscrFile) = GetFileName(baseFile) then begin
masterIndex := GetLoadOrder(lscrFile); // MASTER SELF INDEX
localID := (masterIndex shl 24) or baseID;
AddMessage('SELF: Location "' + Name(e) + '"');
end else begin
// External master case
masterIndex := FindMasterIndex(lscrFile, baseFile);
if masterIndex < 0 then begin
AddMessage('ERROR: Master file for "' + Name(e) + '" not found in LSCR file masters.');
Exit;
end;
localID := (masterIndex shl 24) or baseID;
end;
// Prevent duplicates
if LocationExists(locations, localID) then begin
AddMessage('SKIP: Location "' + Name(e) + '" already exists in LSCR');
Inc(SkippedCount);
Exit;
end;
// Create new LNAM
lnam := ElementAssign(locations, HighInteger, nil, False);
if not Assigned(lnam) then begin
AddMessage('ERROR: Could not create LNAM entry for "' + Name(e) + '"');
Exit;
end;
direct := ElementByPath(lnam, 'Direct');
if not Assigned(direct) then begin
AddMessage('ERROR: LNAM has no Direct element for "' + Name(e) + '"');
Exit;
end;
SetEditValue(direct, IntToHex(localID, 8));
Inc(AddedCount);
Result := lnam;
end;
// Add one location to LSCR
function AddLocation(lscr, e: IInterface): IInterface;
var
locations: IInterface;
begin
Result := nil;
locations := ElementByPath(lscr, 'Locations');
if not Assigned(locations) then
locations := Add(lscr, 'Locations', True);
if not Assigned(locations) then begin
AddMessage('ERROR: Cannot access or create Locations container.');
Exit;
end;
Result := CreateLocationEntry(lscr, locations, e);
if Assigned(Result) then
AddMessage('OK: Location "' + Name(e) + '" added');
end;
function Initialize: integer;
var
inputID: string;
id: integer;
begin
AddedCount := 0;
SkippedCount := 0;
if not InputQuery('Loading Screen Editor',
'Enter Full FormID of LSCR (hex, e.g. 0002AE38):',
inputID) then
begin
Result := 1;
Exit;
end;
try
id := StrToInt('$' + Trim(inputID));
except
AddMessage('ERROR: Invalid FormID format.');
Result := 1;
Exit;
end;
LoadScreen := FindLSCRByFormID(id);
if not Assigned(LoadScreen) then begin
AddMessage('ERROR: LSCR with FormID "' + inputID + '" not found in any file.');
Result := 1;
Exit;
end;
AddMessage('INFO: Selected LSCR = ' + Name(LoadScreen));
end;
function Process(e: IInterface): integer;
begin
if not Assigned(LoadScreen) then Exit;
if (Signature(e) <> 'CELL') and (Signature(e) <> 'WRLD') then Exit;
AddLocation(LoadScreen, e);
end;
function Finalize: integer;
begin
AddMessage('=== Finished adding locations ===');
AddMessage('Total added: ' + IntToStr(AddedCount));
AddMessage('Total skipped (duplicates): ' + IntToStr(SkippedCount));
end;
end.