
Freaky Eyes
Adds freaky eyes to Blind Pest, Blind Vermin and Lemurians.Details
Created using https://thunderstore.io/package/Brynzananas/Body_Model_Additions_API/
All source code here because I am lazy to create another repo:
using System.Security.Permissions;
using System.Security;
using static BodyModelAdditionsAPI.Main;
using UnityEngine;
using RoR2;
using UnityEngine.AddressableAssets;
using System.Collections.Generic;
using Newtonsoft.Json.Utilities;
using System.Linq;
using UnityEngine.PlayerLoop;
using RoR2.CharacterAI;
using BepInEx.Configuration;
using RiskOfOptions.Options;
using RiskOfOptions;
using System;
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: HG.Reflection.SearchableAttribute.OptIn]
[assembly: HG.Reflection.SearchableAttribute.OptInAttribute]
[module: UnverifiableCode]
#pragma warning disable CS0618
#pragma warning restore CS0618
namespace FreakyEyes
{
[BepInPlugin(ModGuid, ModName, ModVer)]
[BepInDependency("com.brynzananas.bodymodeladditionsapi")]
[BepInDependency(RiskOfOptionsCompatimility.riskOfOptionsGUID, BepInDependency.DependencyFlags.SoftDependency)]
[System.Serializable]
public class Main : BaseUnityPlugin
{
public const string ModGuid = "com.brynzananas.freakyeyes";
public const string ModName = "Freaky Eyes";
public const string ModVer = "1.3.1";
private static bool riskOfOptionsEnabled;
public static AssetBundle assetBundle;
public static BepInEx.PluginInfo PInfo { get; private set; }
public static GameObject freakyEye;
public void Awake()
{
PInfo = Info;
assetBundle = AssetBundle.LoadFromFile(System.IO.Path.Combine(System.IO.Path.GetDirectoryName(PInfo.Location), "assetbundles", "freakyeye"));
riskOfOptionsEnabled = BepInEx.Bootstrap.Chainloader.PluginInfos.ContainsKey(RiskOfOptionsCompatimility.riskOfOptionsGUID);
List<Material> materials = new List<Material>();
materials.AddRange(assetBundle.LoadAllAssets<Material>());
foreach (Material material in materials)
{
if (!material.shader.name.StartsWith("StubbedRoR2"))
{
continue;
}
string shaderName = material.shader.name.Replace("StubbedRoR2", "RoR2") + ".shader";
Shader replacementShader = Addressables.LoadAssetAsync<Shader>(shaderName).WaitForCompletion();
if (replacementShader)
{
material.shader = replacementShader;
}
}
freakyEye = assetBundle.LoadAsset<GameObject>("Assets/CosmeticsMod/googlyeye.prefab");
freakyEye.AddComponent<TrackingEye>();
ConfigEntry<bool> config1 = CreateConfig("Blind Pest");
ModelPartInfo modelPartInfo = new ModelPartInfo
{
bodyName = "FlyingVerminBody",
gameObject = freakyEye,
inputString = "Body",
codeAfterApplying = PlaceIt,
customCondition = Config1,
};
bool Config1(CharacterModel characterModel)
{
return config1.Value;
}
new ModelPart(modelPartInfo);
void PlaceIt(GameObject modelObject, ChildLocator childLocator, CharacterModel characterModel, ActivePartsComponent activePartsComponent)
{
ApplyFreakyTracking(modelObject, characterModel);
modelObject.transform.localPosition = new Vector3(-0.45f, 0.641f, .89f);
modelObject.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
}
modelPartInfo = new ModelPartInfo
{
bodyName = "FlyingVerminBody",
gameObject = freakyEye,
inputString = "Body",
codeAfterApplying = PlaceIt2,
customCondition = Config1,
};
new ModelPart(modelPartInfo);
ConfigEntry<bool> config2 = CreateConfig("Blind Vermin");
void PlaceIt2(GameObject modelObject, ChildLocator childLocator, CharacterModel characterModel, ActivePartsComponent activePartsComponent)
{
ApplyFreakyTracking(modelObject, characterModel);
modelObject.transform.localPosition = new Vector3(0.45f, 0.641f, .89f);
modelObject.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
}
modelPartInfo = new ModelPartInfo
{
bodyName = "VerminBody",
gameObject = freakyEye,
inputString = "Head",
codeAfterApplying = PlaceIt3,
customCondition = Config2,
};
bool Config2(CharacterModel characterModel)
{
return config2.Value;
}
new ModelPart(modelPartInfo);
void PlaceIt3(GameObject modelObject, ChildLocator childLocator, CharacterModel characterModel, ActivePartsComponent activePartsComponent)
{
ApplyFreakyTracking(modelObject, characterModel);
modelObject.transform.localPosition = new Vector3(-0.312f, 0.999f, -0.308f);
modelObject.transform.localEulerAngles = new Vector3(-127.928f, 0, 0);
modelObject.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
}
modelPartInfo = new ModelPartInfo
{
bodyName = "VerminBody",
gameObject = freakyEye,
inputString = "Head",
codeAfterApplying = PlaceIt4,
customCondition = Config2,
};
new ModelPart(modelPartInfo);
void PlaceIt4(GameObject modelObject, ChildLocator childLocator, CharacterModel characterModel, ActivePartsComponent activePartsComponent)
{
ApplyFreakyTracking(modelObject, characterModel);
modelObject.transform.localPosition = new Vector3(0.312f, 0.999f, -0.308f);
modelObject.transform.localEulerAngles = new Vector3(-127.928f, 0, 0);
modelObject.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
}
ConfigEntry<bool> config3 = CreateConfig("Lemurian");
modelPartInfo = new ModelPartInfo
{
bodyName = "LemurianBody",
gameObject = freakyEye,
inputString = "Head",
codeAfterApplying = PlaceIt5,
customCondition = Config3,
};
bool Config3(CharacterModel characterModel)
{
return config3.Value;
}
new ModelPart(modelPartInfo);
void PlaceIt5(GameObject modelObject, ChildLocator childLocator, CharacterModel characterModel, ActivePartsComponent activePartsComponent)
{
ApplyFreakyTracking(modelObject, characterModel);
modelObject.transform.localPosition = new Vector3(1.47f, 1.86f, -0.33f);
modelObject.transform.localEulerAngles = new Vector3(-70f, 90, 0);
modelObject.transform.localScale = new Vector3(0.6f, 0.6f, 0.6f);
}
modelPartInfo = new ModelPartInfo
{
bodyName = "LemurianBody",
gameObject = freakyEye,
inputString = "Head",
codeAfterApplying = PlaceIt6,
customCondition = Config3,
};
new ModelPart(modelPartInfo);
void PlaceIt6(GameObject modelObject, ChildLocator childLocator, CharacterModel characterModel, ActivePartsComponent activePartsComponent)
{
ApplyFreakyTracking(modelObject, characterModel);
modelObject.transform.localPosition = new Vector3(-1.47f, 1.86f, -0.33f);
modelObject.transform.localEulerAngles = new Vector3(250f, 90, 0);
modelObject.transform.localScale = new Vector3(0.6f, 0.6f, 0.6f);
}
ConfigEntry<bool> config4 = CreateConfig("Elder Lemurian");
modelPartInfo = new ModelPartInfo
{
bodyName = "LemurianBruiserBody",
gameObject = freakyEye,
inputString = "Head",
codeAfterApplying = PlaceIt7,
customCondition = Config4,
};
bool Config4(CharacterModel characterModel)
{
return config4.Value;
}
new ModelPart(modelPartInfo);
void PlaceIt7(GameObject modelObject, ChildLocator childLocator, CharacterModel characterModel, ActivePartsComponent activePartsComponent)
{
ApplyFreakyTracking(modelObject, characterModel);
modelObject.transform.localPosition = new Vector3(1.7f, 2f, -0.2f);
modelObject.transform.localEulerAngles = new Vector3(-75f, 90, 0);
modelObject.transform.localScale = new Vector3(0.7f, 0.7f, 0.7f);
}
modelPartInfo = new ModelPartInfo
{
bodyName = "LemurianBruiserBody",
gameObject = freakyEye,
inputString = "Head",
codeAfterApplying = PlaceIt8,
customCondition = Config4,
};
new ModelPart(modelPartInfo);
void PlaceIt8(GameObject modelObject, ChildLocator childLocator, CharacterModel characterModel, ActivePartsComponent activePartsComponent)
{
ApplyFreakyTracking(modelObject, characterModel);
modelObject.transform.localPosition = new Vector3(-1.7f, 2f, -0.2f);
modelObject.transform.localEulerAngles = new Vector3(255f, 90, 0);
modelObject.transform.localScale = new Vector3(0.7f, 0.7f, 0.7f);
}
void ApplyFreakyTracking(GameObject gameObject, CharacterModel characterModel)
{
if (characterModel && characterModel.body && characterModel.body.master)
{
BaseAI baseAI = characterModel.body.master.GetComponent<BaseAI>();
if (baseAI != null)
{
TrackingEye trackingEye = gameObject.GetComponent<TrackingEye>();
trackingEye.baseAI = baseAI;
}
}
}
ConfigEntry<bool> CreateConfig(string bodyName)
{
ConfigEntry<bool> configEntry = Config.Bind("Main", bodyName, true, "Enable freaky eyes for " + bodyName + "?");
if (riskOfOptionsEnabled) configEntry.AddBoolConfig();
return configEntry;
}
}
public class TrackingEye : MonoBehaviour
{
public Transform eyeBone;
public Transform eyeTarget;
public BaseAI baseAI;
public PlayerCharacterMasterController characterMasterController;
public bool freakier = false;
public void Start()
{
if (baseAI == null)
{
Destroy(this);
return;
}
eyeBone = transform;
if(eyeBone == null)
{
Destroy(this);
return;
}
freakier = Util.CheckRoll(5f);
}
public void FixedUpdate()
{
if (baseAI && baseAI.enemySearch != null && baseAI.enemySearch.candidatesEnumerable != null && baseAI.enemySearch.candidatesEnumerable.Count > 0)
{
HurtBox hurtBox = baseAI.enemySearch.candidatesEnumerable.FirstOrDefault().hurtBox;
if(hurtBox != null)
eyeTarget = hurtBox.transform;
if (freakier && hurtBox && hurtBox.healthComponent.body && hurtBox.healthComponent.body.master && hurtBox.healthComponent.body.master.playerCharacterMasterController)
{
characterMasterController = hurtBox.healthComponent.body.master.playerCharacterMasterController;
eyeTarget = characterMasterController.networkUser.cameraRigController.sceneCam.transform;
}
}
}
public void LateUpdate()
{
if (eyeTarget && eyeBone)
{
eyeBone.rotation = Quaternion.LookRotation((eyeTarget.transform.position - eyeBone.position).normalized);
}
}
}
}
public static class RiskOfOptionsCompatimility
{
public const string riskOfOptionsGUID = "com.rune580.riskofoptions";
public static void AddFloatConfig(this ConfigEntry<float> configEntry)
{
ModSettingsManager.AddOption(new FloatFieldOption(configEntry));
}
public static void AddIntConfig(this ConfigEntry<int> configEntry)
{
ModSettingsManager.AddOption(new IntFieldOption(configEntry));
}
public static void AddBoolConfig(this ConfigEntry<bool> configEntry)
{
ModSettingsManager.AddOption(new CheckBoxOption(configEntry));
}
}
}