Support Near reference, proper same cell detection
This commit is contained in:
parent
7378a8de90
commit
718cf89351
@ -16,7 +16,7 @@ unit ESMify_Plugins;
|
||||
|
||||
var
|
||||
refsChecked, recordsCounted, flaggedCount, persLocSkipped: integer;
|
||||
pluginAnnounced: boolean;
|
||||
pluginShown: boolean;
|
||||
|
||||
function IsReferencedByNonLocation(rec: IwbMainRecord): boolean;
|
||||
var
|
||||
@ -50,9 +50,7 @@ begin
|
||||
// Does not cover long chains of linked refs.
|
||||
if (ReferencedByCount(referencingRecord) = 0) then begin
|
||||
if (sig = 'REFR') then begin
|
||||
if Equals(LinksTo(ElementByPath(rec, 'Cell')), LinksTo(ElementByPath(referencingRecord, 'Cell'))) then begin
|
||||
continue;
|
||||
end;
|
||||
if InSameCell(rec, referencingRecord) then continue;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -66,6 +64,61 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function InSameCell(ref: IwbMainRecord; otherRef: IwbMainRecord): boolean;
|
||||
var
|
||||
cell, otherCell, worldspace, otherWorldspace: IwbMainRecord;
|
||||
coords, otherCoords: TwbGridCell;
|
||||
begin
|
||||
cell := LinksTo(ElementByPath(ref, 'Cell'));
|
||||
otherCell := LinksTo(ElementByPath(otherRef, 'Cell'));
|
||||
|
||||
if not Assigned(otherCell) then exit;
|
||||
|
||||
// Interior cell
|
||||
if (GetElementNativeValues(cell, 'DATA') and 1) > 0 then begin
|
||||
result := Equals(cell, otherCell);
|
||||
exit;
|
||||
end;
|
||||
|
||||
worldspace := LinksTo(ElementByPath(cell, 'Worldspace'));
|
||||
otherWorldspace := LinksTo(ElementByPath(otherCell, 'Worldspace'));
|
||||
|
||||
if not Equals(worldspace, otherWorldspace) then begin
|
||||
result := false;
|
||||
exit;
|
||||
end;
|
||||
|
||||
// Consider small world a cell
|
||||
if (GetElementNativeValues(worldspace, 'DATA') and 1) > 0 then begin
|
||||
result := true;
|
||||
exit;
|
||||
end;
|
||||
|
||||
// Persistent refs are located in 0,0 so we detect their original grid position via their position
|
||||
coords := wbPositionToGridCell(GetPosition(ref));
|
||||
otherCoords := wbPositionToGridCell(GetPosition(otherRef));
|
||||
|
||||
result := (coords.x = otherCoords.x) and (coords.y = otherCoords.y);
|
||||
end;
|
||||
|
||||
function HasScripts(e: IwbMainRecord; targetScripts: string): boolean;
|
||||
var
|
||||
scripts, currentItem: IwbElement;
|
||||
linkedCount, i: integer;
|
||||
begin
|
||||
if not ElementExists(e, 'VMAD') then exit;
|
||||
|
||||
scripts := ElementByPath(e, 'VMAD\Scripts');
|
||||
for i := 0 to Pred(ElementCount(scripts)) do begin
|
||||
currentItem := ElementByIndex(scripts, i);
|
||||
|
||||
if Pos(GetElementEditValues(currentItem, 'ScriptName'), targetScripts) <> 0 then begin
|
||||
result := true;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function MarkPersistent(e: IwbMainRecord): boolean;
|
||||
begin
|
||||
AddMessage(' + Marking as persistent: ' + GetElementEditValues(e, 'NAME') + ' - (' + Name(e) + ')');
|
||||
@ -113,6 +166,33 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function IsLinkedRefRemote(e: IwbMainRecord; linkedRefKeyword: IwbMainRecord): boolean;
|
||||
var
|
||||
linkedRef: IwbMainRecord;
|
||||
begin
|
||||
result := true;
|
||||
if Assigned(linkedRefKeyword) then begin
|
||||
linkedRef := GetLinkedRef(e, linkedRefKeyword);
|
||||
end
|
||||
else begin
|
||||
linkedRef := GetLinkedRefNull(e);
|
||||
end;
|
||||
|
||||
if Assigned(linkedRef) then begin
|
||||
if InSameCell(e, linkedRef) then begin
|
||||
//AddMessage(' Skipping actor, staying in one cell with his linked ref: ' + GetElementEditValues(e, 'NAME') + ' - (' + Name(e) + ')');
|
||||
result := false;
|
||||
end
|
||||
else if not GetIsPersistent(linkedRef) then begin
|
||||
MarkPersistent(linkedRef);
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
// Missing linked ref. Usually, package checks for its presence. Sometimes, it's just missing. The outcome is the same, this package is not doing anything.
|
||||
result := false;
|
||||
end;
|
||||
end;
|
||||
|
||||
function Process(e: IInterface): integer;
|
||||
var
|
||||
currentPlugin: IwbFile;
|
||||
@ -122,10 +202,10 @@ var
|
||||
sig, baseSig, packageLoc, packageType: string;
|
||||
isREFR, isACHR, skip: boolean;
|
||||
begin
|
||||
if not pluginAnnounced then begin
|
||||
if not pluginShown then begin
|
||||
currentPlugin := GetFile(e);
|
||||
AddMessage(#13#10 + '* Processing ' + Name(currentPlugin));
|
||||
pluginAnnounced := true;
|
||||
AddMessage(#13#10 + '# Processing ' + Name(currentPlugin));
|
||||
pluginShown := true;
|
||||
refsChecked := 0;
|
||||
recordsCounted := 0;
|
||||
flaggedCount := 0;
|
||||
@ -139,7 +219,7 @@ begin
|
||||
AddMessage(' ' + IntToStr(refsChecked) + ' references checked.');
|
||||
AddMessage(' ' + IntToStr(persLocSkipped) + ' actors with Persistent Location skipped.');
|
||||
AddMessage(' ' + IntToStr(flaggedCount) + ' references have been marked as persistent.' + #13#10);
|
||||
pluginAnnounced := false;
|
||||
pluginShown := false;
|
||||
exit;
|
||||
end;
|
||||
|
||||
@ -156,7 +236,7 @@ begin
|
||||
|
||||
if GetIsDeleted(e) then begin
|
||||
if GetIsPersistent(e) then begin
|
||||
AddMessage(' Removing persistence flag from deleted record: ' + ShortName(e));
|
||||
AddMessage(' ! Removing persistence flag from deleted record: ' + ShortName(e));
|
||||
SetIsPersistent(e, False);
|
||||
end;
|
||||
exit;
|
||||
@ -224,62 +304,52 @@ begin
|
||||
if packageCount = 0 then
|
||||
exit;
|
||||
|
||||
skip := false;
|
||||
skip := true;
|
||||
|
||||
for i := 0 to Pred(packageCount) do begin
|
||||
package := LinksTo(ElementByIndex(packages, i));
|
||||
|
||||
if not Assigned(package) then begin
|
||||
skip := true;
|
||||
AddMessage(' ! WARNING: Invalid package entry: ' + GetElementEditValues(e, 'NAME') + ' - (' + Name(e) + ')');
|
||||
continue;
|
||||
end;
|
||||
|
||||
packageLoc := GetElementEditValues(ElementByIndex(ElementByPath(package, 'Package Data\Data Input Values'), 0), 'PLDT\Type');
|
||||
|
||||
if (packageLoc = 'Near editor location') or (packageLoc = 'Near self') then begin
|
||||
AddMessage(' Skipping editor location actor: ' + GetElementEditValues(e, 'NAME') + ' - (' + Name(e) + ')');
|
||||
skip := true;
|
||||
continue;
|
||||
end;
|
||||
if packageLoc <> '' then begin
|
||||
|
||||
if (packageLoc = 'In cell') then begin
|
||||
refCell := LinksTo(ElementByPath(ElementByIndex(ElementByPath(package, 'Package Data\Data Input Values'), 0), 'PLDT\Cell'));
|
||||
if Assigned(refCell) then begin
|
||||
if Equals(refCell, LinksTo(ElementByPath(e, 'Cell'))) then begin
|
||||
AddMessage(' Skipping actor, staying in one cell: ' + GetElementEditValues(e, 'NAME') + ' - (' + Name(e) + ')');
|
||||
skip := true;
|
||||
continue;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
if (GetElementEditValues(ElementByIndex(ElementByPath(package, 'Package Data\Data Input Values'), 0), 'PTDA\Target Data\Type') = 'Linked Reference') then begin
|
||||
|
||||
linkedRefKeyword := LinksTo(ElementByPath(ElementByIndex(ElementByPath(package, 'Package Data\Data Input Values'), 0), 'PTDA\Target Data\Reference'));
|
||||
|
||||
if Assigned(linkedRefKeyword) then begin
|
||||
linkedRef := GetLinkedRef(e, linkedRefKeyword);
|
||||
if (packageLoc = 'Near editor location') or (packageLoc = 'Near self') then begin
|
||||
//AddMessage(' Skipping editor location actor: ' + GetElementEditValues(e, 'NAME') + ' - (' + Name(e) + ')');
|
||||
continue;
|
||||
end
|
||||
else begin
|
||||
linkedRef := GetLinkedRefNull(e);
|
||||
end;
|
||||
|
||||
if Assigned(linkedRef) then begin
|
||||
if Equals(LinksTo(ElementByPath(linkedRef, 'Cell')), LinksTo(ElementByPath(e, 'Cell'))) then begin
|
||||
AddMessage(' Skipping actor, staying in one cell with his linked ref: ' + GetElementEditValues(e, 'NAME') + ' - (' + Name(e) + ')');
|
||||
skip := true;
|
||||
continue;
|
||||
else if (packageLoc = 'In cell') then begin
|
||||
refCell := LinksTo(ElementByPath(ElementByIndex(ElementByPath(package, 'Package Data\Data Input Values'), 0), 'PLDT\Cell'));
|
||||
if Assigned(refCell) then begin
|
||||
if Equals(refCell, LinksTo(ElementByPath(e, 'Cell'))) then continue;
|
||||
end;
|
||||
end
|
||||
else if (packageLoc = 'Near linked reference') then begin
|
||||
linkedRefKeyword := LinksTo(ElementByPath(ElementByIndex(ElementByPath(package, 'Package Data\Data Input Values'), 0), 'PLDT\Keyword'));
|
||||
if not IsLinkedRefRemote(e, linkedRefKeyword) then continue;
|
||||
end
|
||||
else if (packageLoc = 'Near reference') then begin
|
||||
if InSameCell(e, LinksTo(ElementByPath(ElementByIndex(ElementByPath(package, 'Package Data\Data Input Values'), 0), 'PLDT\Reference'))) then continue;
|
||||
end;
|
||||
|
||||
|
||||
end
|
||||
else if (GetElementEditValues(ElementByIndex(ElementByPath(package, 'Package Data\Data Input Values'), 0), 'PTDA\Target Data\Type') = 'Linked Reference') then begin
|
||||
linkedRefKeyword := LinksTo(ElementByPath(ElementByIndex(ElementByPath(package, 'Package Data\Data Input Values'), 0), 'PTDA\Target Data\Reference'));
|
||||
if not IsLinkedRefRemote(e, linkedRefKeyword) then continue;
|
||||
end;
|
||||
|
||||
skip := false;
|
||||
|
||||
end;
|
||||
|
||||
if skip then exit;
|
||||
if skip then begin
|
||||
//AddMessage(' Skipping actor, staying in one cell: ' + GetElementEditValues(e, 'NAME') + ' - (' + Name(e) + ')');
|
||||
exit;
|
||||
end;
|
||||
|
||||
MarkPersistent(e);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user