1- using System ;
1+ using HarmonyLib ;
2+ using System ;
23using System . Collections . Generic ;
34using System . Reflection ;
45using System . Security . AccessControl ;
@@ -60,8 +61,7 @@ private static Action<object> CreateMutator(ConfigNode.Value configValue, Type o
6061 return null ;
6162 }
6263
63-
64- private static void CreateMutators ( ConfigNode configNode , Type objectType , List < Action < object > > mutators )
64+ private static void CreateObjectMutators ( ConfigNode configNode , Type objectType , List < Action < object > > mutators )
6565 {
6666 foreach ( ConfigNode . Value configValue in configNode . values . values )
6767 {
@@ -71,12 +71,81 @@ private static void CreateMutators(ConfigNode configNode, Type objectType, List<
7171 mutators . Add ( mutator ) ;
7272 }
7373 }
74+
75+ var customNodeHandlers = x_customNodeHandlers . GetValueOrDefault ( objectType ) ;
76+
77+ foreach ( ConfigNode childNode in configNode . nodes . nodes )
78+ {
79+ // TODO: support arbitrary nested objects
80+
81+ if ( customNodeHandlers != null && customNodeHandlers . TryGetValue ( childNode . name , out var customNodeHandler ) )
82+ {
83+ customNodeHandler . Invoke ( childNode , objectType , mutators ) ;
84+ }
85+ }
86+ }
87+
88+ static Dictionary < Type , Dictionary < string , Action < ConfigNode , Type , List < Action < object > > > > > x_customNodeHandlers = new ( )
89+ {
90+ {
91+ typeof ( GameObject ) , new Dictionary < string , Action < ConfigNode , Type , List < Action < object > > > >
92+ {
93+ { "Components" , CreateComponentMutators } ,
94+ }
95+ } ,
96+ } ;
97+
98+ private static void CreateComponentMutators ( ConfigNode configNode , Type type , List < Action < object > > mutators )
99+ {
100+ foreach ( ConfigNode componentNode in configNode . nodes . nodes )
101+ {
102+ string componentTypeName = componentNode . name ;
103+ Type componentType = typeof ( Component ) . GetSubclassNamed ( componentTypeName ) ;
104+
105+ if ( componentType == null ) continue ;
106+
107+ bool createNew = false ;
108+ if ( componentNode . TryGetValue ( "create" , ref createNew ) )
109+ {
110+ componentNode . RemoveValue ( "create" ) ;
111+ }
112+
113+ Action < object > [ ] componentMutators = CreateMutators ( componentNode , componentType ) ;
114+
115+ mutators . Add ( obj =>
116+ {
117+ GameObject gameObject = ( GameObject ) obj ;
118+ var component = gameObject . GetComponent ( componentType ) ;
119+ if ( component == null )
120+ {
121+ if ( createNew )
122+ {
123+ component = gameObject . AddComponent ( componentType ) ;
124+ }
125+ else
126+ {
127+ Log . Error ( $ "Component { componentTypeName } not found on GameObject { gameObject . name } ") ;
128+ return ;
129+ }
130+ }
131+ else if ( createNew )
132+ {
133+ // maybe we should still add a new one?
134+ Log . Warning ( $ "Component { componentTypeName } already existed on Gamebject { gameObject . name } ") ;
135+ }
136+
137+ foreach ( var mutator in componentMutators )
138+ {
139+ mutator . Invoke ( component ) ;
140+ }
141+ } ) ;
142+ }
74143 }
75144
76145 private static Action < object > [ ] CreateMutators ( ConfigNode configNode , Type objectType )
77146 {
78147 List < Action < object > > mutators = new List < Action < object > > ( ) ;
79- CreateMutators ( configNode , objectType , mutators ) ;
148+ CreateObjectMutators ( configNode , objectType , mutators ) ;
80149 return mutators . ToArray ( ) ;
81150 }
82151
0 commit comments