r2mods/ilspy_dump/ror2_csproj/RoR2/SkinDef.cs

334 lines
9.8 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
namespace RoR2;
[CreateAssetMenu(menuName = "RoR2/SkinDef")]
public class SkinDef : ScriptableObject
{
[Serializable]
public struct GameObjectActivation
{
[PrefabReference]
public GameObject gameObject;
public bool shouldActivate;
}
[Serializable]
public struct MeshReplacement
{
[PrefabReference]
public Renderer renderer;
public Mesh mesh;
}
[Serializable]
public struct ProjectileGhostReplacement
{
public GameObject projectilePrefab;
public GameObject projectileGhostReplacementPrefab;
}
[Serializable]
public struct MinionSkinReplacement
{
public GameObject minionBodyPrefab;
public SkinDef minionSkin;
}
private struct RendererInfoTemplate
{
public string path;
public CharacterModel.RendererInfo data;
}
private struct GameObjectActivationTemplate
{
public string path;
public bool shouldActivate;
}
private struct MeshReplacementTemplate
{
public string path;
public Mesh mesh;
}
private class RuntimeSkin
{
public RendererInfoTemplate[] rendererInfoTemplates;
public GameObjectActivationTemplate[] gameObjectActivationTemplates;
public MeshReplacementTemplate[] meshReplacementTemplates;
private static readonly List<CharacterModel.RendererInfo> rendererInfoBuffer = new List<CharacterModel.RendererInfo>();
public void Apply(GameObject modelObject)
{
Transform transform = modelObject.transform;
for (int i = 0; i < rendererInfoTemplates.Length; i++)
{
ref RendererInfoTemplate reference = ref rendererInfoTemplates[i];
CharacterModel.RendererInfo data = reference.data;
Transform transform2 = transform.Find(reference.path);
if ((bool)transform2)
{
Renderer component = transform2.GetComponent<Renderer>();
if ((bool)component)
{
data.renderer = component;
rendererInfoBuffer.Add(data);
}
else
{
Debug.LogWarningFormat("No renderer at {0}/{1}", transform.name, reference.path);
}
}
else
{
Debug.LogWarningFormat("Could not find transform \"{0}\" relative to \"{1}\".", reference.path, transform.name);
}
}
CharacterModel component2 = modelObject.GetComponent<CharacterModel>();
component2.baseRendererInfos = rendererInfoBuffer.ToArray();
component2.forceUpdate = true;
rendererInfoBuffer.Clear();
foreach (Transform gameObjectActivationTransform in component2.gameObjectActivationTransforms)
{
if ((bool)gameObjectActivationTransform.gameObject)
{
gameObjectActivationTransform.gameObject.SetActive(value: false);
}
}
component2.gameObjectActivationTransforms.Clear();
for (int j = 0; j < gameObjectActivationTemplates.Length; j++)
{
ref GameObjectActivationTemplate reference2 = ref gameObjectActivationTemplates[j];
bool shouldActivate = reference2.shouldActivate;
Transform transform3 = transform.Find(reference2.path);
transform3.gameObject.SetActive(shouldActivate);
component2.gameObjectActivationTransforms.Add(transform3);
}
for (int k = 0; k < meshReplacementTemplates.Length; k++)
{
ref MeshReplacementTemplate reference3 = ref meshReplacementTemplates[k];
Mesh mesh = reference3.mesh;
Renderer component3 = transform.Find(reference3.path).GetComponent<Renderer>();
if (component3 is MeshRenderer)
{
component3.GetComponent<MeshFilter>().sharedMesh = mesh;
}
else if (component3 is SkinnedMeshRenderer skinnedMeshRenderer)
{
skinnedMeshRenderer.sharedMesh = mesh;
}
}
}
}
[Tooltip("The skins which will be applied before this one.")]
public SkinDef[] baseSkins;
[ShowThumbnail]
public Sprite icon;
public string nameToken;
[Obsolete("Use 'unlockableDef' instead.")]
public string unlockableName;
public UnlockableDef unlockableDef;
[PrefabReference]
public GameObject rootObject;
public CharacterModel.RendererInfo[] rendererInfos = Array.Empty<CharacterModel.RendererInfo>();
public GameObjectActivation[] gameObjectActivations = Array.Empty<GameObjectActivation>();
public MeshReplacement[] meshReplacements = Array.Empty<MeshReplacement>();
public ProjectileGhostReplacement[] projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>();
public MinionSkinReplacement[] minionSkinReplacements = Array.Empty<MinionSkinReplacement>();
private RuntimeSkin runtimeSkin;
public SkinIndex skinIndex { get; set; } = SkinIndex.None;
private void Bake()
{
if (runtimeSkin != null)
{
return;
}
runtimeSkin = new RuntimeSkin();
List<RendererInfoTemplate> rendererInfoTemplates = new List<RendererInfoTemplate>();
List<GameObjectActivationTemplate> gameObjectActivationTemplates = new List<GameObjectActivationTemplate>();
List<MeshReplacementTemplate> meshReplacementTemplates = new List<MeshReplacementTemplate>();
SkinDef[] array = baseSkins;
foreach (SkinDef skinDef in array)
{
if (!skinDef)
{
continue;
}
skinDef.Bake();
if (skinDef.runtimeSkin == null)
{
continue;
}
if (skinDef.runtimeSkin.rendererInfoTemplates != null)
{
RendererInfoTemplate[] rendererInfoTemplates2 = skinDef.runtimeSkin.rendererInfoTemplates;
for (int j = 0; j < rendererInfoTemplates2.Length; j++)
{
AddRendererInfoTemplate(rendererInfoTemplates2[j]);
}
}
if (skinDef.runtimeSkin.gameObjectActivationTemplates != null)
{
GameObjectActivationTemplate[] gameObjectActivationTemplates2 = skinDef.runtimeSkin.gameObjectActivationTemplates;
for (int j = 0; j < gameObjectActivationTemplates2.Length; j++)
{
AddGameObjectActivationTemplate(gameObjectActivationTemplates2[j]);
}
}
if (skinDef.runtimeSkin.meshReplacementTemplates != null)
{
MeshReplacementTemplate[] meshReplacementTemplates2 = skinDef.runtimeSkin.meshReplacementTemplates;
for (int j = 0; j < meshReplacementTemplates2.Length; j++)
{
AddMeshReplacementTemplate(meshReplacementTemplates2[j]);
}
}
}
for (int k = 0; k < rendererInfos.Length; k++)
{
ref CharacterModel.RendererInfo reference = ref rendererInfos[k];
if (!reference.renderer)
{
Debug.LogErrorFormat("Skin {0} has an empty renderer field in its rendererInfos at index {1}.", this, k);
}
else
{
RendererInfoTemplate rendererInfoTemplate2 = default(RendererInfoTemplate);
rendererInfoTemplate2.data = reference;
rendererInfoTemplate2.path = Util.BuildPrefabTransformPath(rootObject.transform, reference.renderer.transform);
AddRendererInfoTemplate(rendererInfoTemplate2);
}
}
runtimeSkin.rendererInfoTemplates = rendererInfoTemplates.ToArray();
for (int l = 0; l < gameObjectActivations.Length; l++)
{
ref GameObjectActivation reference2 = ref gameObjectActivations[l];
if (!reference2.gameObject)
{
Debug.LogErrorFormat("Skin {0} has an empty gameObject field in its gameObjectActivations at index {1}.", this, l);
}
else
{
GameObjectActivationTemplate gameObjectActivationTemplate2 = default(GameObjectActivationTemplate);
gameObjectActivationTemplate2.shouldActivate = reference2.shouldActivate;
gameObjectActivationTemplate2.path = Util.BuildPrefabTransformPath(rootObject.transform, reference2.gameObject.transform);
AddGameObjectActivationTemplate(gameObjectActivationTemplate2);
}
}
runtimeSkin.gameObjectActivationTemplates = gameObjectActivationTemplates.ToArray();
for (int m = 0; m < meshReplacements.Length; m++)
{
ref MeshReplacement reference3 = ref meshReplacements[m];
if (!reference3.renderer)
{
Debug.LogErrorFormat("Skin {0} has an empty renderer field in its meshReplacements at index {1}.", this, m);
}
else
{
MeshReplacementTemplate meshReplacementTemplate2 = default(MeshReplacementTemplate);
meshReplacementTemplate2.mesh = reference3.mesh;
meshReplacementTemplate2.path = Util.BuildPrefabTransformPath(rootObject.transform, reference3.renderer.transform);
AddMeshReplacementTemplate(meshReplacementTemplate2);
}
}
runtimeSkin.meshReplacementTemplates = meshReplacementTemplates.ToArray();
void AddGameObjectActivationTemplate(GameObjectActivationTemplate gameObjectActivationTemplate)
{
int num = 0;
for (int count2 = gameObjectActivationTemplates.Count; num < count2; num++)
{
if (gameObjectActivationTemplates[num].path == gameObjectActivationTemplate.path)
{
gameObjectActivationTemplates[num] = gameObjectActivationTemplate;
return;
}
}
gameObjectActivationTemplates.Add(gameObjectActivationTemplate);
}
void AddMeshReplacementTemplate(MeshReplacementTemplate meshReplacementTemplate)
{
int n = 0;
for (int count = meshReplacementTemplates.Count; n < count; n++)
{
if (meshReplacementTemplates[n].path == meshReplacementTemplate.path)
{
meshReplacementTemplates[n] = meshReplacementTemplate;
return;
}
}
meshReplacementTemplates.Add(meshReplacementTemplate);
}
void AddRendererInfoTemplate(RendererInfoTemplate rendererInfoTemplate)
{
int num2 = 0;
for (int count3 = rendererInfoTemplates.Count; num2 < count3; num2++)
{
if (rendererInfoTemplates[num2].path == rendererInfoTemplate.path)
{
rendererInfoTemplates[num2] = rendererInfoTemplate;
return;
}
}
rendererInfoTemplates.Add(rendererInfoTemplate);
}
}
public void Apply(GameObject modelObject)
{
Bake();
runtimeSkin.Apply(modelObject);
}
private void Awake()
{
if (Application.IsPlaying(this))
{
Bake();
}
}
[ContextMenu("Upgrade unlockableName to unlockableDef")]
public void UpgradeUnlockableNameToUnlockableDef()
{
if (!string.IsNullOrEmpty(unlockableName) && !this.unlockableDef)
{
UnlockableDef unlockableDef = LegacyResourcesAPI.Load<UnlockableDef>("UnlockableDefs/" + unlockableName);
if ((bool)unlockableDef)
{
this.unlockableDef = unlockableDef;
unlockableName = null;
}
}
EditorUtil.SetDirty(this);
}
}