Brynzananas-Freaky_Eyes icon

Freaky Eyes

Adds freaky eyes to Blind Pest, Blind Vermin and Lemurians.

Last updated 3 months ago
Total downloads 5297
Total rating 4 
Categories Mods Skins Seekers of the Storm Update
Dependency string Brynzananas-Freaky_Eyes-1.3.1
Dependants 0 other packages depend on this package

This mod requires the following mods to function

Brynzananas-Body_Model_Additions_API-1.4.3 icon
Brynzananas-Body_Model_Additions_API

Adds a system for developers to load custom objects onto characters in game and in lobby. Model additions can require selected skins, skills, skins and skills or custom condition.

Preferred version: 1.4.3

README

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));
        }
    }
}