@@ -103,6 +103,7 @@ public static IEnumerable<string> GenerateModList(IEnumerable<ModAddedByAssembly
103103 mods . Add ( assemblyName . Name ) ;
104104 }
105105
106+ Dictionary < string , List < UrlDir . UrlConfig > > forneedsConflict = new Dictionary < string , List < UrlDir . UrlConfig > > ( ) ;
106107 modListInfo . Append ( "Non-DLL mods added (:FOR[xxx]):\n " ) ;
107108 foreach ( UrlDir . UrlConfig cfgmod in GameDatabase . Instance . root . AllConfigs )
108109 {
@@ -117,21 +118,34 @@ public static IEnumerable<string> GenerateModList(IEnumerable<ModAddedByAssembly
117118 {
118119 string dependency = name . Substring ( name . IndexOf ( ":FOR[" ) + 5 ) ;
119120 dependency = dependency . Substring ( 0 , dependency . IndexOf ( ']' ) ) ;
120- if ( ! mods . Contains ( dependency , StringComparer . OrdinalIgnoreCase ) )
121- {
122- // found one, now add it to the list.
123- mods . Add ( dependency ) ;
124- modListInfo . AppendFormat ( " {0}\n " , dependency ) ;
125- }
126121
127122 if ( name . Contains ( ":NEEDS[" ) )
128123 {
124+ // If an assembly was already declared a modname with this tag, there's no possible harm on
125+ // using :NEEDS[foo] on :FOR[foo] and so it would be wiser to prevent flagging a non problem just
126+ // because it looked like one. So we only consider a conflict when there's no Assembly declaring
127+ // such tag as a modName.
129128 string needs = ( name . Substring ( name . IndexOf ( ":NEEDS[" ) + 7 ) ) ;
130129 needs = needs . Substring ( 0 , needs . IndexOf ( ']' ) ) ;
131130 needs = needs . Replace ( "!" , "" ) . Replace ( '&' , ',' ) . Replace ( '|' , ',' ) ;
132- foreach ( string s in needs . Split ( ',' ) ) if ( dependency . Equals ( s ) )
133- progress . ForWithInvalidNeedsWarning ( dependency , cfgmod ) ;
131+
132+ // That's the deal - once the dependency is flagged as a conflict, every single :FOR mentining it
133+ // (as long there's a :NEEDS) should be flagged too.
134+ if ( ! mods . Contains ( dependency ) || forneedsConflict . ContainsKey ( dependency ) )
135+ foreach ( string s in needs . Split ( ',' ) ) if ( string . Equals ( dependency , s , StringComparison . OrdinalIgnoreCase ) )
136+ {
137+ if ( ! forneedsConflict . ContainsKey ( dependency ) )
138+ forneedsConflict . Add ( dependency , new List < UrlDir . UrlConfig > ( ) ) ;
139+ forneedsConflict [ dependency ] . Add ( cfgmod ) ;
140+ }
134141 }
142+
143+ if ( ! mods . Contains ( dependency , StringComparer . OrdinalIgnoreCase ) )
144+ {
145+ // found one, now add it to the list.
146+ mods . Add ( dependency ) ;
147+ modListInfo . AppendFormat ( " {0}\n " , dependency ) ;
148+ }
135149 }
136150 catch ( ArgumentOutOfRangeException )
137151 {
@@ -143,18 +157,30 @@ public static IEnumerable<string> GenerateModList(IEnumerable<ModAddedByAssembly
143157 }
144158 }
145159 }
160+
146161 modListInfo . Append ( "Mods by directory (sub directories of GameData):\n " ) ;
147162 UrlDir gameData = GameDatabase . Instance . root . children . First ( dir => dir . type == UrlDir . DirectoryType . GameData ) ;
148163 foreach ( UrlDir subDir in gameData . children )
149164 {
150165 string cleanName = subDir . name . RemoveWS ( ) ;
166+
167+ // Since the :FOR[foo]:NEEDS[foo] is only really a problem when nothing else had declared the
168+ // name as a modname, if a tag created by a directory is found we remove the conflict from the dictionary
169+ // as it's now harmless and it's not the best of ideas to warn users for things that "look" like problems
170+ // without really being one - unless we could not tell one from another, what we can do here.
171+ if ( forneedsConflict . ContainsKey ( cleanName ) )
172+ forneedsConflict . Remove ( cleanName ) ;
173+
151174 if ( ! mods . Contains ( cleanName , StringComparer . OrdinalIgnoreCase ) )
152175 {
153176 mods . Add ( cleanName ) ;
154177 modListInfo . AppendFormat ( " {0}\n " , cleanName ) ;
155178 }
156179 }
157180
181+ foreach ( string dependency in forneedsConflict . Keys ) foreach ( UrlDir . UrlConfig faultyNode in forneedsConflict [ dependency ] )
182+ progress . ForWithInvalidNeedsWarning ( dependency , faultyNode ) ;
183+
158184 modListInfo . Append ( "Mods added by assemblies:\n " ) ;
159185 foreach ( ModAddedByAssembly mod in modsAddedByAssemblies )
160186 {
0 commit comments