@@ -61,14 +61,10 @@ public static class Loader
6161 {
6262 if ( duringEnumCacheCreation )
6363 {
64- UnitData . Type unitPrefabType = UnitData . Type . Scout ;
6564 if ( token [ "prefab" ] != null )
6665 {
67- string prefabId = CultureInfo . CurrentCulture . TextInfo . ToTitleCase ( token [ "prefab" ] ! . ToString ( ) ) ;
68- if ( Enum . TryParse ( prefabId , out UnitData . Type parsedType ) )
69- unitPrefabType = parsedType ;
66+ Registry . prefabNames . Add ( ( int ) ( UnitData . Type ) Registry . autoidx , CultureInfo . CurrentCulture . TextInfo . ToTitleCase ( token [ "prefab" ] ! . ToString ( ) ) ) ;
7067 }
71- PrefabManager . units . TryAdd ( ( int ) ( UnitData . Type ) Registry . autoidx , PrefabManager . units [ ( int ) unitPrefabType ] ) ;
7268 }
7369 else
7470 {
@@ -458,6 +454,119 @@ public static void LoadAudioFile(Mod mod, Mod.File file)
458454 // TODO: issue #71
459455 }
460456
457+ public static void LoadPrefabInfoFile ( Mod mod , Mod . File file )
458+ {
459+ try
460+ {
461+ var prefab = JsonSerializer . Deserialize < Visual . PrefabInfo > ( file . bytes , new JsonSerializerOptions
462+ {
463+ Converters = { new Vector2Json ( ) } ,
464+ PropertyNameCaseInsensitive = true ,
465+ } ) ;
466+ if ( prefab == null || prefab . type != Visual . PrefabType . Unit )
467+ return ;
468+
469+ var baseUnit = PrefabManager . GetPrefab ( UnitData . Type . Warrior , TribeData . Type . Imperius , SkinType . Default ) ;
470+ if ( baseUnit == null )
471+ return ;
472+
473+ var unitInstance = GameObject . Instantiate ( baseUnit ) ;
474+ if ( unitInstance == null )
475+ return ;
476+
477+ var spriteContainer = unitInstance . transform . GetChild ( 0 ) ;
478+ var material = ClearExistingPartsAndExtractMaterial ( spriteContainer ) ;
479+
480+ var visualParts = ApplyVisualParts ( prefab . visualParts , spriteContainer , material ) ;
481+
482+ var svr = unitInstance . GetComponent < SkinVisualsReference > ( ) ;
483+ svr . visualParts = visualParts . ToArray ( ) ;
484+
485+ GameObject . DontDestroyOnLoad ( unitInstance . gameObject ) ;
486+ Registry . unitPrefabs . Add ( prefab , unitInstance . GetComponent < Unit > ( ) ) ;
487+
488+ Plugin . logger . LogInfo ( $ "Registered prefab info from { mod . id } mod") ;
489+ }
490+ catch ( Exception e )
491+ {
492+ Plugin . logger . LogError ( $ "Error on loading prefab info from { mod . id } mod: { e . Message } ") ;
493+ }
494+ }
495+
496+ private static Material ? ClearExistingPartsAndExtractMaterial ( Transform spriteContainer )
497+ {
498+ Material ? material = null ;
499+ for ( int i = 0 ; i < spriteContainer . childCount ; i ++ )
500+ {
501+ var child = spriteContainer . GetChild ( i ) ;
502+ if ( child . gameObject . name == "Head" )
503+ {
504+ var renderer = child . GetComponent < SpriteRenderer > ( ) ;
505+ if ( renderer != null )
506+ material = renderer . material ;
507+ }
508+ GameObject . Destroy ( child . gameObject ) ;
509+ }
510+ return material ;
511+ }
512+
513+ private static List < SkinVisualsReference . VisualPart > ApplyVisualParts (
514+ List < Visual . VisualPartInfo > partInfos ,
515+ Transform spriteContainer ,
516+ Material ? material )
517+ {
518+ List < SkinVisualsReference . VisualPart > parts = new ( ) ;
519+
520+ foreach ( var info in partInfos )
521+ {
522+ parts . Add ( CreateVisualPart ( info , spriteContainer , material ) ) ;
523+ }
524+
525+ return parts ;
526+ }
527+
528+ private static SkinVisualsReference . VisualPart CreateVisualPart (
529+ Visual . VisualPartInfo info ,
530+ Transform parent ,
531+ Material ? material )
532+ {
533+ var visualPartObj = new GameObject ( info . gameObjectName ) ;
534+ visualPartObj . transform . SetParent ( parent ) ;
535+ visualPartObj . transform . position = info . coordinates ;
536+ visualPartObj . transform . localScale = info . scale ;
537+ visualPartObj . transform . rotation = Quaternion . Euler ( 0f , 0f , info . rotation ) ;
538+
539+ var outlineObj = new GameObject ( "Outline" ) ;
540+ outlineObj . transform . SetParent ( visualPartObj . transform ) ;
541+ outlineObj . transform . position = info . coordinates ;
542+ outlineObj . transform . localScale = info . scale ;
543+ outlineObj . transform . rotation = Quaternion . Euler ( 0f , 0f , info . rotation ) ;
544+
545+ var visualPart = new SkinVisualsReference . VisualPart
546+ {
547+ DefaultSpriteName = info . baseName ,
548+ visualPart = visualPartObj ,
549+ outline = outlineObj ,
550+ tintable = info . tintable
551+ } ;
552+
553+ var renderer = visualPartObj . AddComponent < SpriteRenderer > ( ) ;
554+ renderer . material = material ;
555+ renderer . sortingLayerName = "Units" ;
556+ renderer . sortingOrder = info . tintable ? 0 : 1 ;
557+
558+ visualPart . renderer = new SkinVisualsReference . RendererUnion { spriteRenderer = renderer } ;
559+
560+ var outlineRenderer = outlineObj . AddComponent < SpriteRenderer > ( ) ;
561+ outlineRenderer . material = material ;
562+ outlineRenderer . sortingLayerName = "Units" ;
563+ outlineRenderer . sortingOrder = - 1 ;
564+
565+ visualPart . outlineRenderer = new SkinVisualsReference . RendererUnion { spriteRenderer = outlineRenderer } ;
566+
567+ return visualPart ;
568+ }
569+
461570 public static void LoadGameLogicDataPatch ( Mod mod , JObject gld , JObject patch )
462571 {
463572 try
0 commit comments