@@ -1510,45 +1510,45 @@ fn applyIniDeinliningRulesRecursivelyFolder(allocator: Allocator, file_tree: *In
15101510}
15111511
15121512fn applyIniDeinliningRulesRecursivelyNode (allocator : Allocator , node : * Node , property : []const u8 , file : * IniFile , rootParent : Node , moduleSpace : * ModuleSpace ) ! bool {
1513- // If this has a property, and:
1514- if (node .property ) | node_property | {
1515- // If it matches the property given, and:
1516- if (strEql (node_property , property )) {
1517- // If this node has children, then:
1518- if (node .children .items .len > 0 ) {
1519- // This is a currently inlined constant reference, so:
1520-
1521- // Find if this is a copy and the name of it's copy reference, and if this is a preset and it's preset name.
1522- var copyOfNameOptional : ? []const u8 = null ;
1523- var presetNameOptional : ? []const u8 = null ;
1524-
1525- for (node .children .items ) | * child | {
1526- if (child .property ) | child_property | {
1527- if (strEql (child_property , "CopyOf" )) {
1528- copyOfNameOptional = child .value ;
1529- } else if (strEql (child_property , "PresetName" )) {
1530- presetNameOptional = child .value ;
1513+ if (node .property ) | nodeProperty | {
1514+ if (node .value ) | nodeValue | {
1515+ if (strEql (nodeProperty , property )) {
1516+ if (node .children .items .len > 0 ) {
1517+ const className : []const u8 = nodeValue ;
1518+ var moduleName : []const u8 = "Base.rte" ;
1519+ var presetNameOptional : ? []const u8 = null ;
1520+
1521+ var isOriginalPreset : bool = false ;
1522+ var isCopyOf : bool = false ;
1523+
1524+ // If we read a CopyOf, then whatever preset name we were going with is invalidated.
1525+ for (node .children .items ) | * child | {
1526+ if (child .property ) | childProperty | {
1527+ const readingCopyOf : bool = strEql (childProperty , "CopyOf" );
1528+ const readingOriginalPreset : bool = strEql (childProperty , "PresetName" );
1529+ isCopyOf = isCopyOf or readingCopyOf ;
1530+ isOriginalPreset = ! readingCopyOf and (isOriginalPreset or readingOriginalPreset );
1531+
1532+ if (readingCopyOf or readingOriginalPreset ) {
1533+ presetNameOptional = child .value ;
1534+ }
15311535 }
15321536 }
1533- }
15341537
1535- // Class name is given, module name is assumed, and probably wrong, but might be conveniently specified already.
1536- const className = node .value orelse "None" ;
1537- var moduleName : []const u8 = "Base.rte" ;
1538-
1539- // Find out if it's conveniently specified.
1540- if (copyOfNameOptional ) | nameWithPossibleModulePrefix | {
1541- if (indexOf (u8 , nameWithPossibleModulePrefix , "/" )) | modulePrefixEnd | {
1542- moduleName = nameWithPossibleModulePrefix [0.. modulePrefixEnd ];
1543- copyOfNameOptional = nameWithPossibleModulePrefix [modulePrefixEnd + 1 .. ];
1538+ // Sometimes both CopyOfs and PresetNames list the module name with the preset name, detect this.
1539+ // This lets it respect when well written mods intentionally reference non-Base data entities.
1540+ if (presetNameOptional ) | presetName | {
1541+ if (indexOf (u8 , presetName , "/" )) | modulePrefixEnd | {
1542+ moduleName = presetName [0.. modulePrefixEnd ];
1543+ presetNameOptional = presetName [modulePrefixEnd + 1 .. ];
1544+ }
15441545 }
1545- }
15461546
1547- // Assume that nothing is invalidated.
1548- var invalidationFlag = false ;
1549- if ( presetNameOptional ) | presetName | {
1550- // Special case Loadouts
1551- if (! strEql ( rootParent . property .? , "AddLoadout" ) ) {
1547+ // If this is an original preset, unless it's in a loadout, where all sorts of things seem to go wrong,
1548+ // then we're going to deinline it.
1549+ const deinliningFlag = isOriginalPreset and ! strEql ( rootParent . property .? , "AddLoadout" );
1550+
1551+ if (deinliningFlag ) {
15521552 moduleName = moduleSpace .moduleName ;
15531553
15541554 const duplicateNode = Node {
@@ -1560,36 +1560,29 @@ fn applyIniDeinliningRulesRecursivelyNode(allocator: Allocator, node: *Node, pro
15601560
15611561 const determinedIndex = index_of (Node , file .ast .items , rootParent ) orelse 0 ;
15621562 try file .ast .insert (determinedIndex , duplicateNode );
1563+ }
15631564
1564- invalidationFlag = true ;
1565- } else {
1566- if (moduleSpace .entityDefinitions .get (className )) | presetNameSpace | {
1567- if (presetNameSpace .get (presetName ) != null ) {
1568- moduleName = moduleSpace .moduleName ;
1565+ if (presetNameOptional ) | presetName | {
1566+ // If this was copied from something, and it isn't an original preset,
1567+ // then check if it is pointing to something within this module.
1568+ if (isCopyOf and ! isOriginalPreset ) {
1569+ if (moduleSpace .entityDefinitions .get (className )) | presetNameSpace | {
1570+ if (presetNameSpace .get (presetName ) != null ) {
1571+ moduleName = moduleSpace .moduleName ;
1572+ }
15691573 }
15701574 }
1571- }
15721575
1573- node .value = try allocPrint (allocator , "{s}/{s}/{s}" , .{ className , moduleName , presetName });
1574- } else if (copyOfNameOptional ) | copyOfName | {
1575- if (moduleSpace .entityDefinitions .get (className )) | presetNameSpace | {
1576- if (presetNameSpace .get (copyOfName ) != null ) {
1577- moduleName = moduleSpace .moduleName ;
1578- }
1576+ node .value = try allocPrint (allocator , "{s}/{s}/{s}" , .{ className , moduleName , presetName });
1577+ } else {
1578+ node .value = "None" ;
15791579 }
15801580
1581- node .value = try allocPrint (allocator , "{s}/{s}/{s}" , .{ className , moduleName , copyOfName });
1582- } else {
1583- node .value = "None" ;
1584- }
1581+ node .children .clearRetainingCapacity ();
1582+ node .comments .clearRetainingCapacity ();
15851583
1586- // If comments or children are needed, they belong to the duplicate, in it's definition.
1587- node .children .clearRetainingCapacity ();
1588- node .comments .clearRetainingCapacity ();
1589-
1590- // This was, in any case, a constant reference, it shouldn't have children, not here.
1591- // Return, and clarify to caller whether we had to deinline anything.
1592- return invalidationFlag ;
1584+ return deinliningFlag ;
1585+ }
15931586 }
15941587 }
15951588 }
0 commit comments