diff --git a/src/Digitalroot.Valheim.Common.Extensions/Digitalroot.Valheim.Common.Extensions.csproj b/src/Digitalroot.Valheim.Common.Extensions/Digitalroot.Valheim.Common.Extensions.csproj index a98a5ee..c06bd1b 100644 --- a/src/Digitalroot.Valheim.Common.Extensions/Digitalroot.Valheim.Common.Extensions.csproj +++ b/src/Digitalroot.Valheim.Common.Extensions/Digitalroot.Valheim.Common.Extensions.csproj @@ -3,7 +3,7 @@ Digitalroot.Valheim.Common.Extensions net462 - 9 + 10 Digitalroot.Valheim.Common.Extensions Digitalroot.Valheim.Common.Extensions false @@ -44,8 +44,8 @@ - - + + all diff --git a/src/Digitalroot.Valheim.Common.Extensions/FloatExtensions.cs b/src/Digitalroot.Valheim.Common.Extensions/FloatExtensions.cs new file mode 100644 index 0000000..8163ef1 --- /dev/null +++ b/src/Digitalroot.Valheim.Common.Extensions/FloatExtensions.cs @@ -0,0 +1,8 @@ +using System; + +namespace Digitalroot.Valheim.Common.Extensions; + +public static class FloatExtensions +{ + public static int ToInt32(this float value) => Convert.ToInt32(value); +} diff --git a/src/Digitalroot.Valheim.Common.Extensions/GameObjectExtensions.cs b/src/Digitalroot.Valheim.Common.Extensions/GameObjectExtensions.cs new file mode 100644 index 0000000..91dd5f9 --- /dev/null +++ b/src/Digitalroot.Valheim.Common.Extensions/GameObjectExtensions.cs @@ -0,0 +1,305 @@ +using JetBrains.Annotations; +using System.Collections.Generic; +using System.Text; +using UnityEngine; +using Random = UnityEngine.Random; + +// ReSharper disable InconsistentNaming + +namespace Digitalroot.Valheim.Common.Extensions +{ + public static class GameObjectExtensions + { + public static GameObject AddLedgeJumping(this GameObject prefab) + { + prefab.GetOrAddMonoBehaviour(); + return prefab; + } + + public static bool HasParent(this GameObject prefab) => prefab.transform.GetParent() != null; + + public static GameObject GetParent(this GameObject prefab) => prefab.HasParent() ? prefab.transform.GetParent().gameObject : null; + + public static bool IsBoss(this GameObject prefab) => prefab.GetComponent()?.IsBoss() ?? false; + + private static Vector3 GetScale(string itemName, Vector3 currentScale) + { + List names = new() + { + "shield" + , "axe" + , "mace" + }; + + if (names.Contains(itemName.ToLowerInvariant())) + { + return Vector3.one * 2; + } + + return Vector3.one; + } + + public static string GetUniqueName(this GameObject prefab) + { + List paths = new(); + + var parent = prefab.transform.GetParent(); + + while (parent != null) + { + paths.Add(parent.name); + parent = parent.GetParent(); + } + + var sb = new StringBuilder(); + for (var i = paths.Count; i > 0; i--) + { + sb.Append(paths[i - 1]).Append('.'); + } + + sb.Append(prefab.name); + return sb.ToString(); + } + + /// + /// Sets De-spawn In Day to false; + /// + /// MonsterAI + /// + public static GameObject AsDayWalker(this GameObject prefab) + { + var monsterAI = prefab.GetComponent(); + if (monsterAI == null) return prefab; + + monsterAI.SetDespawnInDay(false); + return prefab; + } + + /// + /// Sets De-spawn In Day to true; + /// + /// MonsterAI + /// + public static GameObject AsNightStalker(this GameObject prefab) + { + var monsterAI = prefab.GetComponent(); + if (monsterAI == null) return prefab; + + monsterAI.SetDespawnInDay(true); + return prefab; + } + + /// + /// Configure MonsterAI to patrol spawn point. + /// + /// MonsterAI + /// + public static GameObject AsSpawnPointPatroler(this GameObject prefab) + { + var monsterAI = prefab.GetComponent(); + if (monsterAI == null) return prefab; + + if (prefab.HasParent()) + { + prefab.AsSpawnPointPatroler(prefab.transform.parent.transform.position); + } + else + { + monsterAI.SetPatrolPoint(); + } + + return prefab; + } + + /// + /// Configure MonsterAI to patrol spawn point. + /// + /// MonsterAI + /// + public static GameObject AsSpawnPointPatroler(this GameObject prefab, Vector3 point) + { + var monsterAI = prefab.GetComponent(); + if (monsterAI == null) return prefab; + + monsterAI.SetPatrolPoint(point); + + return prefab; + } + + /// + /// Configure MonsterAI to jump randomly. + /// + /// MonsterAI + /// Min random range. + /// Max random range. + /// + public static GameObject AsRandomJumper(this GameObject prefab, float min = 5f, float max = 9f) + { + var monsterAI = prefab.GetComponent(); + if (monsterAI == null) return prefab; + if (monsterAI.m_randomFly) return prefab; + monsterAI.m_jumpInterval = Random.Range(min, max); + return prefab; + } + + /// + /// Configure the base AI to not flee + /// + /// MonsterAI + /// + public static GameObject AsNoFleeing(this GameObject prefab) + { + var monsterAI = prefab.GetComponent(); + if (monsterAI == null) return prefab; + monsterAI.m_fleeIfLowHealth = 0f; + return prefab; + } + + /// + /// Sets Path Agent Type + /// + /// MonsterAI + /// + /// + public static GameObject SetPathAgentType(this GameObject prefab, Pathfinding.AgentType agentType) + { + var monsterAI = prefab.GetComponent(); + if (monsterAI == null) return prefab; + if (monsterAI.m_randomFly) return prefab; + + monsterAI.m_pathAgentType = agentType; + + return prefab; + } + + /// + /// Set the level of the prefab. + /// + /// Character + /// + /// + /// + public static GameObject SetLevel(this GameObject prefab, int levelMin, int levelMax) + { + var level = levelMin == levelMax ? levelMax : Random.Range(levelMin, levelMax + 1); + var character = prefab.GetComponent(); + character?.SetLevel(level); + character?.SetupMaxHealth(); + + // prefab.SendMessage("SetLevel", level, SendMessageOptions.RequireReceiver); + return prefab; + } + + /// + /// Set prefab's local position. + /// + /// + /// + /// + public static GameObject SetLocalPosition(this GameObject prefab, int i) + { + switch (i) + { + case 1: + prefab.transform.localPosition += Vector3.left * 2.5f; + break; + + case 2: + prefab.transform.localPosition += Vector3.right * 2.5f; + break; + + case 3: + prefab.transform.localPosition += Vector3.forward * 2.5f; + break; + + case 4: + prefab.transform.localPosition += Vector3.back * 2.5f; + break; + } + + return prefab; + } + + /// + /// Set prefab's local scale + /// + /// + /// + /// + [UsedImplicitly] + public static GameObject SetLocalScale(this GameObject prefab, float scaleSize) + { + prefab.SetLocalScale(new Vector3(scaleSize, scaleSize, scaleSize)); + return prefab; + } + + /// + /// Set prefab's local scale + /// + /// + /// + /// + [UsedImplicitly] + public static GameObject SetLocalScale(this GameObject prefab, Vector3 scaleSize) + { + var zNetView = prefab.GetComponent(); + zNetView.m_syncInitialScale = true; + zNetView.SetLocalScale(scaleSize); + return prefab; + } + + /// + /// Set prefab's local scale + /// + /// + /// + /// + public static GameObject SetLocalRotation(this GameObject prefab, Quaternion quaternion) + { + prefab.transform.rotation = quaternion; + return prefab; + } + + public static GameObject ScaleEquipment(this GameObject prefab) + { + var visEquipment = prefab.GetComponent(); + if (visEquipment == null) return prefab; + if (visEquipment.m_leftItemInstance != null) + { + for (var i = 0; i < visEquipment.m_leftItemInstance.transform.childCount; i++) + { + var item = visEquipment.m_leftItemInstance.transform.GetChild(i); + item.localScale = GetScale(item.gameObject.name, item.localScale); + } + } + + if (visEquipment.m_rightItemInstance != null) + { + for (var i = 0; i < visEquipment.m_rightItemInstance.transform.childCount; i++) + { + var item = visEquipment.m_rightItemInstance.transform.GetChild(i); + item.localScale = GetScale(item.gameObject.name, item.localScale); + } + } + + return prefab; + } + + /// + /// Returns the component of Type type. If one doesn't already exist on the GameObject it will be added. + /// + /// + /// Inspired by Jotunn JVL + /// Source: https://wiki.unity3d.com/index.php/GetOrAddComponent + /// + /// The type of Component to return. + /// The GameObject the Component is attached to. + /// Returns the component of Type T + [UsedImplicitly] + public static T GetOrAddMonoBehaviour([NotNull] this GameObject gameObject) + where T : MonoBehaviour + { + return gameObject.GetComponent() ?? gameObject.AddComponent(); + } + } +} diff --git a/src/Digitalroot.Valheim.Common.Extensions/Int32Extensions.cs b/src/Digitalroot.Valheim.Common.Extensions/Int32Extensions.cs new file mode 100644 index 0000000..9ffd3a6 --- /dev/null +++ b/src/Digitalroot.Valheim.Common.Extensions/Int32Extensions.cs @@ -0,0 +1,8 @@ +using System; + +namespace Digitalroot.Valheim.Common.Extensions; + +public static class Int32Extensions +{ + public static float ToFloat(this int value) => Convert.ToSingle(value); +} diff --git a/src/Digitalroot.Valheim.Common.Extensions/packages.lock.json b/src/Digitalroot.Valheim.Common.Extensions/packages.lock.json index ed6e933..02013c8 100644 --- a/src/Digitalroot.Valheim.Common.Extensions/packages.lock.json +++ b/src/Digitalroot.Valheim.Common.Extensions/packages.lock.json @@ -4,15 +4,15 @@ ".NETFramework,Version=v4.6.2": { "Digitalroot.Valheim.Common.References": { "type": "Direct", - "requested": "[0.204.5, )", - "resolved": "0.204.5", - "contentHash": "5+E+7FDWDKAYzL8A1GfBFWmxu2p6LLbd+D5PR79RCAVmJTn/b2cPXdTCiNNe5/msrcpdyaGT3GFra1AjY/V+aA==" + "requested": "[0.205.7, )", + "resolved": "0.205.7", + "contentHash": "iUIYAsg5HXZj3S4yhUECEuZJk98X8RG75wkJrlmIvfriwIZgV57wt4S6ym3KQNHvx87sxSbU3raSPMPTSfi0hw==" }, "UnityEngine.Modules": { "type": "Direct", - "requested": "[2019.4.32, 2019.4.32]", - "resolved": "2019.4.32", - "contentHash": "7KmS0Nz+s89igz/tDBRk9PEmWqlwReQZf9E6tl6/uV5DndbaR5WInqis4y6Fwq1B++2leamS7qPffnW5+WQwUw==" + "requested": "[2019.4.31, 2019.4.31]", + "resolved": "2019.4.31", + "contentHash": "xZjdfGGzZw6nnrn4auRNis6WnAlsvqY1XXioEGJnSku+CylESgEt/sTLYlrbrQ0srnLfSCfx80vR8z4SsI1EuQ==" } } }