diff --git a/ESMify_Plugins.pas b/ESMify_Plugins.pas index 67e0596..2d9e525 100644 --- a/ESMify_Plugins.pas +++ b/ESMify_Plugins.pas @@ -66,7 +66,7 @@ begin end; end; -function MarkPersistent(e: IInterface): boolean; +function MarkPersistent(e: IwbMainRecord): boolean; begin AddMessage(' + Marking as persistent: ' + GetElementEditValues(e, 'NAME') + ' - (' + Name(e) + ')'); Inc(flaggedCount); @@ -74,20 +74,53 @@ begin CheckNonPersistentOverride(e); end; -function CheckNonPersistentOverride(e: IInterface): integer; +function CheckNonPersistentOverride(e: IwbMainRecord): integer; begin if IsWinningOverride(e) then exit; if not GetIsPersistent(WinningOverride(e)) then AddMessage(' ! WARNING: the highest override of ' + ShortName(e) + ' is not persistent: ' + PathName(WinningOverride(e))); end; +function GetLinkedRefNull(rec: IwbMainRecord): IwbMainRecord; +var + linkedRefs, currentItem: IwbElement; + linkedCount, i: integer; +begin + linkedRefs := ElementByPath(rec, 'Linked References'); + linkedCount := ElementCount(linkedRefs); + for i := 0 to Pred(linkedCount) do begin + currentItem := ElementByIndex(linkedRefs, i); + if not Assigned(LinksTo(ElementByPath(currentItem, 'Keyword/Ref'))) then begin + result := LinksTo(ElementByPath(currentItem, 'Ref')); + break; + end; + end; +end; + +function GetLinkedRef(rec: IwbMainRecord; keyword: IwbMainRecord): IwbMainRecord; +var + linkedRefs, currentItem: IwbElement; + linkedCount, i: integer; +begin + linkedRefs := ElementByPath(rec, 'Linked References'); + linkedCount := ElementCount(linkedRefs); + for i := 0 to Pred(linkedCount) do begin + currentItem := ElementByIndex(linkedRefs, i); + if Equals(LinksTo(ElementByPath(currentItem, 'Keyword/Ref')), keyword) then begin + result := LinksTo(ElementByPath(currentItem, 'Ref')); + break; + end; + end; +end; + function Process(e: IInterface): integer; var currentPlugin: IwbFile; - baseRefRecord, package, refCell, actorLocation: IwbMainRecord; - i, baseID, packageCount: integer; - sig, baseSig, packageLoc: string; - isREFR, isACHR: boolean; + baseRefRecord, package, refCell, actorLocation, linkedRef, linkedRefKeyword: IwbMainRecord; + packages: IwbElement; + i, baseID, packageCount, typeId: integer; + sig, baseSig, packageLoc, packageType: string; + isREFR, isACHR, skip: boolean; begin if not pluginAnnounced then begin currentPlugin := GetFile(e); @@ -176,10 +209,6 @@ begin end; end; - // Skip non-persistent, non-unique actors. Multi-package bandits will probably be late on their schedules. - if GetElementNativeValues(baseRefRecord, 'ACBS\Flags\Unique') = 0 then - exit; - // Skip Starts Dead NPCs if GetElementNativeValues(e, 'Record Header\Record Flags\Starts Dead') <> 0 then exit; @@ -188,25 +217,30 @@ begin if GetElementNativeValues(baseRefRecord, 'ACBS\Flags\Simple Actor') <> 0 then exit; - packageCount := ElementCount(ElementByPath(baseRefRecord, 'Packages')); + packages := ElementByPath(baseRefRecord, 'Packages'); + packageCount := ElementCount(packages); - // Skip unique actors without packages (probably, flagged erroneously) + // Skip actors without packages if packageCount = 0 then exit; - if packageCount = 1 then begin + skip := false; - // Skip actors, having a single package revolving around their editor location or themselves - package := LinksTo(ElementByIndex(ElementByPath(baseRefRecord, 'Packages'), 0)); + 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; - if not Assigned(package) then - exit; - packageLoc := GetElementEditValues(ElementByIndex(ElementByPath(package, 'Package Data\Data Input Values'), 0), 'PLDT\Type'); - if (Pos(packageLoc, 'Near editor location|Near self') <> 0) then begin + if (packageLoc = 'Near editor location') or (packageLoc = 'Near self') then begin AddMessage(' Skipping editor location actor: ' + GetElementEditValues(e, 'NAME') + ' - (' + Name(e) + ')'); - exit; + skip := true; + continue; end; if (packageLoc = 'In cell') then begin @@ -214,13 +248,39 @@ begin 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) + ')'); - exit; + 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); + 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; + end; + end; + + end; + + skip := false; + end; + if skip then exit; + MarkPersistent(e); end;