Expanded the list of always persistent form types
This commit is contained in:
parent
76af8d0a4a
commit
ce2345d7aa
@ -17,6 +17,8 @@ unit ESMify_Plugins;
|
|||||||
var
|
var
|
||||||
refsChecked, recordsCounted, flaggedCount, persLocSkipped: integer;
|
refsChecked, recordsCounted, flaggedCount, persLocSkipped: integer;
|
||||||
pluginShown: boolean;
|
pluginShown: boolean;
|
||||||
|
hardcodedStatForms: TStringList;
|
||||||
|
dragonCZMarker, dragonLZMarker: IwbMainRecord;
|
||||||
|
|
||||||
function IsReferencedByNonLocation(rec: IwbMainRecord): boolean;
|
function IsReferencedByNonLocation(rec: IwbMainRecord): boolean;
|
||||||
var
|
var
|
||||||
@ -179,18 +181,77 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function Initialize: integer;
|
function IsSameCellPackage(package: IwbMainRecord): boolean;
|
||||||
|
var
|
||||||
|
packageLoc, packageType: string;
|
||||||
|
refCell, linkedRefKeyword, linkedRef: IwbMainRecord;
|
||||||
begin
|
begin
|
||||||
AddMessage('All done.');
|
packageLoc := GetElementEditValues(ElementByIndex(ElementByPath(package, 'Package Data\Data Input Values'), 0), 'PLDT\Type');
|
||||||
|
|
||||||
|
if packageLoc <> '' then begin
|
||||||
|
|
||||||
|
if (packageLoc = 'Near editor location') or (packageLoc = 'Near self') then begin
|
||||||
|
//AddMessage(' Skipping editor location actor: ' + GetElementEditValues(e, 'NAME') + ' - (' + Name(e) + ')');
|
||||||
|
continue;
|
||||||
|
end
|
||||||
|
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 SameRecord(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 begin
|
||||||
|
packageLoc := GetElementEditValues(ElementByIndex(ElementByPath(package, 'Package Data\Data Input Values'), 0), 'PTDA\Target Data\Type');
|
||||||
|
|
||||||
|
if (packageLoc = '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
|
||||||
|
else if (packageLoc = 'Specific Reference') then begin
|
||||||
|
linkedRef := LinksTo(ElementByPath(ElementByIndex(ElementByPath(package, 'Package Data\Data Input Values'), 0), 'PTDA\Target Data\Reference'));
|
||||||
|
if InSameCell(e, linkedRef) then continue;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function Initialize: integer;
|
||||||
|
var dobj: IwbMainRecord;
|
||||||
|
begin
|
||||||
|
AddMessage('ESMify Plugins is starting...');
|
||||||
|
|
||||||
|
hardcodedStatForms := TStringList.Create;
|
||||||
|
hardcodedStatForms.Add($5); // DivineMarker
|
||||||
|
hardcodedStatForms.Add($6); // TempleMarker
|
||||||
|
hardcodedStatForms.Add($10); // MapMarker
|
||||||
|
hardcodedStatForms.Add($12); // HorseMarker
|
||||||
|
hardcodedStatForms.Add($15); // MultiBoundMarker
|
||||||
|
hardcodedStatForms.Add($1F); // RoomMarker
|
||||||
|
hardcodedStatForms.Add($34); // XMarkerHeading
|
||||||
|
hardcodedStatForms.Add($3B); // XMarker
|
||||||
|
|
||||||
|
// DLZM and DCZM Default Objects.
|
||||||
|
// For simplicity sake, I assume they are unchanged, which is true in 99.999% cases.
|
||||||
|
// If you ever find a mod, changing these objects, I will update this to retrieve actual values.
|
||||||
|
hardcodedStatForms.Add($138C0); // DragonMarker
|
||||||
|
hardcodedStatForms.Add($3DF55); // DragonMarkerCrashStrip
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function Process(e: IInterface): integer;
|
function Process(e: IInterface): integer;
|
||||||
var
|
var
|
||||||
currentPlugin: IwbFile;
|
currentPlugin: IwbFile;
|
||||||
baseRefRecord, package, refCell, actorLocation, linkedRef, linkedRefKeyword: IwbMainRecord;
|
baseRefRecord, package, actorLocation: IwbMainRecord;
|
||||||
packages: IwbElement;
|
packages: IwbElement;
|
||||||
i, baseID, packageCount, typeId: integer;
|
i, baseID, packageCount, typeId: integer;
|
||||||
sig, baseSig, packageLoc, packageType: string;
|
sig, baseSig: string;
|
||||||
isREFR, isACHR, skip: boolean;
|
isREFR, isACHR, skip: boolean;
|
||||||
begin
|
begin
|
||||||
if not pluginShown then begin
|
if not pluginShown then begin
|
||||||
@ -240,18 +301,43 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
if isREFR then begin
|
if isREFR then begin
|
||||||
// Water, texture sets, and markers always get flagged by CK
|
// Certain types of references are always flagged as persistent by the CK. See DavidJCobb's post:
|
||||||
|
// https://discord.com/channels/535508975626747927/535530099475480596/1129026688077013084
|
||||||
baseID := FormID(baseRefRecord);
|
|
||||||
if (baseID = $3B) or (baseID = $4) or (baseID = $34) or (baseID = $1F) or (baseID = $15) or (baseID = $12) or (baseID = $10) or (baseID = $6) or (baseID = $5) or (baseID = $138C0) or (baseID = $3DF55) then begin
|
|
||||||
MarkPersistent(e);
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
baseSig := Signature(baseRefRecord);
|
baseSig := Signature(baseRefRecord);
|
||||||
if (baseSig = 'TXST') or ((baseSig = 'ACTI') and ElementExists(baseRefRecord, 'WNAM')) then begin
|
|
||||||
|
if baseSig = 'TXST' then begin
|
||||||
|
// Flag texture sets
|
||||||
MarkPersistent(e);
|
MarkPersistent(e);
|
||||||
exit;
|
exit;
|
||||||
|
end
|
||||||
|
else if baseSig = 'STAT' then begin
|
||||||
|
// Flag hardcoded static forms (markers)
|
||||||
|
if hardcodedStatForms.indexOf(FormID(baseRefRecord)) > -1 then begin
|
||||||
|
MarkPersistent(e);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else if baseSig = 'ACTI' then begin
|
||||||
|
// Flag water activators
|
||||||
|
if ElementExists(baseRefRecord, 'WNAM')) then begin
|
||||||
|
MarkPersistent(e);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else if baseSig = 'LIGH' then begin
|
||||||
|
// Flag Never Fades lights
|
||||||
|
if (GetElementNativeValues(e, 'Record Header\Record Flags\Never Fades') > 0) then begin
|
||||||
|
MarkPersistent(e);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else if baseSig = 'DOOR' then begin
|
||||||
|
// Flag PrisonMarker refs and any doors with teleport data
|
||||||
|
if (FormID(baseRefRecord) = $4) or (ElementExists(e, 'XTEL')) then begin // PrisonMarker
|
||||||
|
MarkPersistent(e);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -267,9 +353,16 @@ begin
|
|||||||
// This NPC uses Persistent Location, should work fine if the location was assigned correctly
|
// This NPC uses Persistent Location, should work fine if the location was assigned correctly
|
||||||
if ElementExists(e, 'XLCN') then begin
|
if ElementExists(e, 'XLCN') then begin
|
||||||
actorLocation := LinksTo(ElementByPath(e, 'XLCN'));
|
actorLocation := LinksTo(ElementByPath(e, 'XLCN'));
|
||||||
|
|
||||||
|
// CK flags refs with the PersistAll location
|
||||||
|
if FormID(actorLocation) = $216A7 then begin // PersistAll
|
||||||
|
MarkPersistent(e);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
if ReferencedByCount(actorLocation) > 1 then begin
|
if ReferencedByCount(actorLocation) > 1 then begin
|
||||||
Inc(persLocSkipped);
|
Inc(persLocSkipped);
|
||||||
//AddMessage(' Skipping actor with Persistent Location: ' + GetElementEditValues(e, 'NAME') + ' - (' + Name(e) + ')');
|
AddMessage(' Skipping actor with Persistent Location: ' + GetElementEditValues(e, 'NAME') + ' - (' + Name(e) + ')');
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -285,8 +378,8 @@ begin
|
|||||||
if packageCount = 0 then
|
if packageCount = 0 then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
// Scan packages and try to determine if their range extends beyond the NPC's starting cell.
|
||||||
skip := true;
|
skip := true;
|
||||||
|
|
||||||
for i := 0 to Pred(packageCount) do begin
|
for i := 0 to Pred(packageCount) do begin
|
||||||
package := LinksTo(ElementByIndex(packages, i));
|
package := LinksTo(ElementByIndex(packages, i));
|
||||||
|
|
||||||
@ -295,48 +388,14 @@ begin
|
|||||||
continue;
|
continue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
packageLoc := GetElementEditValues(ElementByIndex(ElementByPath(package, 'Package Data\Data Input Values'), 0), 'PLDT\Type');
|
if (IsSameCellPackage(package)) then continue;
|
||||||
|
|
||||||
if packageLoc <> '' then begin
|
|
||||||
|
|
||||||
if (packageLoc = 'Near editor location') or (packageLoc = 'Near self') then begin
|
|
||||||
//AddMessage(' Skipping editor location actor: ' + GetElementEditValues(e, 'NAME') + ' - (' + Name(e) + ')');
|
|
||||||
continue;
|
|
||||||
end
|
|
||||||
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 SameRecord(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 begin
|
|
||||||
packageLoc := GetElementEditValues(ElementByIndex(ElementByPath(package, 'Package Data\Data Input Values'), 0), 'PTDA\Target Data\Type');
|
|
||||||
|
|
||||||
if (packageLoc = '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
|
|
||||||
else if (packageLoc = 'Specific Reference') then begin
|
|
||||||
linkedRef := LinksTo(ElementByPath(ElementByIndex(ElementByPath(package, 'Package Data\Data Input Values'), 0), 'PTDA\Target Data\Reference'));
|
|
||||||
if InSameCell(e, linkedRef) then continue;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
skip := false;
|
skip := false;
|
||||||
|
break;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if skip then begin
|
if skip then begin
|
||||||
//AddMessage(' Skipping actor, staying in one cell: ' + GetElementEditValues(e, 'NAME') + ' - (' + Name(e) + ')');
|
AddMessage(' Skipping actor, staying in the same cell: ' + GetElementEditValues(e, 'NAME') + ' - (' + Name(e) + ')');
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -346,6 +405,7 @@ end;
|
|||||||
|
|
||||||
function Finalize: integer;
|
function Finalize: integer;
|
||||||
begin
|
begin
|
||||||
|
hardcodedStatForms.Clear;
|
||||||
AddMessage('All done.');
|
AddMessage('All done.');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user