Skip to content

Commit

Permalink
Merge pull request #47 from Alexejhero/misc-stuff
Browse files Browse the repository at this point in the history
Ency paths and Coordinated spawns
  • Loading branch information
Govorunb authored Nov 6, 2023
2 parents bc386d0 + cd04700 commit 98f8aa5
Show file tree
Hide file tree
Showing 38 changed files with 499 additions and 179 deletions.
6 changes: 3 additions & 3 deletions SCHIZO/Creatures/UnityCreaturePrefab.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Diagnostics.CodeAnalysis;
using ECCLibrary;
using Nautilus.Handlers;
Expand Down Expand Up @@ -27,9 +27,9 @@ protected override void SetItemProperties()
if (UnityData.acidImmune) CreatureDataUtils.SetAcidImmune(ModItem);
if (UnityData.bioReactorCharge > 0) CreatureDataUtils.SetBioreactorCharge(ModItem, UnityData.bioReactorCharge);

if (UnityData.PDAEncyclopediaInfo)
if (UnityData.pdaEncyInfo)
{
PDAHandler.AddCustomScannerEntry(ModItem, UnityData.PDAEncyclopediaInfo.scanTime, encyclopediaKey: PrefabInfo.ClassID);
PDAHandler.AddCustomScannerEntry(ModItem, UnityData.pdaEncyInfo.scanTime, encyclopediaKey: PrefabInfo.ClassID);
}

if (UnityData.isPickupable)
Expand Down
1 change: 0 additions & 1 deletion SCHIZO/Items/Data/ItemData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ partial class ItemData
public string[] CraftTreePath => RetargetHelpers.Pick(craftTreePathSN, craftTreePathBZ).Split('/');
public TechGroup TechGroup => (TechGroup) RetargetHelpers.Pick(techGroupSN, techGroupBZ);
public TechCategory TechCategory => (TechCategory) RetargetHelpers.Pick(techCategorySN, techCategoryBZ);
public PDAEncyclopediaInfo PDAEncyclopediaInfo => RetargetHelpers.Pick(pdaEncyclopediaInfoSN, pdaEncyclopediaInfoBZ);
public KnownTechInfo KnownTechInfo => RetargetHelpers.Pick(knownTechInfoSN, knownTechInfoBZ);
public bool UnlockAtStart => RetargetHelpers.Pick(unlockAtStartSN, unlockAtStartBZ);
public TechType RequiredForUnlock => RetargetHelpers.Pick(requiredForUnlockSN, requiredForUnlockBZ).GetTechType();
Expand Down
7 changes: 4 additions & 3 deletions SCHIZO/Items/UnityPrefab.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,12 @@ protected virtual void SetItemProperties()
CraftDataHandler.AddToGroup(ModItem.ItemData.TechGroup, ModItem.ItemData.TechCategory, ModItem);
}

if (ModItem.ItemData.PDAEncyclopediaInfo)
if (ModItem.ItemData.pdaEncyInfo)
{
PDAEncyclopediaInfo i = ModItem.ItemData.PDAEncyclopediaInfo;
PDAEncyclopediaInfo i = ModItem.ItemData.pdaEncyInfo;
string encyPath = RetargetHelpers.Pick(i.encyPathSN, i.encyPathBZ);

PDAHandler.AddEncyclopediaEntry(ModItem.PrefabInfo.ClassID, i.encyPath, i.title, i.description.text, i.texture, i.unlockSprite,
PDAHandler.AddEncyclopediaEntry(ModItem.PrefabInfo.ClassID, encyPath, i.title, i.description.text, i.texture, i.unlockSprite,
i.isImportantUnlock ? PDAHandler.UnlockImportant : PDAHandler.UnlockBasic);

if (i.scanSounds) ScanSoundHandler.Register(ModItem, i.scanSounds);
Expand Down
21 changes: 21 additions & 0 deletions SCHIZO/Spawns/CoordinatedSpawns.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Nautilus.Handlers;
using NSpawnInfo = Nautilus.Handlers.SpawnInfo;

namespace SCHIZO.Spawns;

partial class CoordinatedSpawns
{
protected override void Register()
{
foreach (SpawnInfo spawnInfo in spawns)
{
if (!spawnInfo.game.HasFlag(GAME)) continue;

foreach (SpawnInfo.SpawnLocation location in spawnInfo.locations)
{
NSpawnInfo nSpawnInfo = new((TechType)spawnInfo.item.techType, location.position, location.rotation);
CoordinatedSpawnsHandler.RegisterCoordinatedSpawn(nSpawnInfo);
}
}
}
}
2 changes: 1 addition & 1 deletion Unity/Assets/Editor/Scripts/Editor.asmdef
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
}
8 changes: 8 additions & 0 deletions Unity/Assets/Editor/Scripts/Extensions.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions Unity/Assets/Editor/Scripts/Extensions/GameAttributeExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using SCHIZO.Helpers;
using SCHIZO.Registering;
using UnityEditor;

namespace Editor.Scripts.Extensions
{
public static class GameAttributeExtensions
{
public static bool TryGetGame(this GameAttribute attr, out Game game) => TryGetGame(attr, null, out game);
public static bool TryGetGame(this GameAttribute attr, SerializedProperty property, out Game game)
{
game = attr.game;
if (game > 0 || string.IsNullOrEmpty(attr.gameMember)) return true;
if (property == null) return false;

object target = property.GetParent().GetSerializedValue<object>();
game = ReflectionHelpers.GetMemberValue<Game>(target, attr.gameMember);
return true;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using SCHIZO.Helpers;
using UnityEditor;

namespace Editor.Scripts.Extensions
{
public static class SerializedPropertyExtensions
{
// most (all) of the code is adapted from this thread: https://forum.unity.com/threads/get-a-general-object-value-from-serializedproperty.327098/
private delegate FieldInfo GetFieldInfo(SerializedProperty prop, out Type type);
private static readonly GetFieldInfo fieldInfoGetter = Setup();

public static FieldInfo GetFieldInfoAndStaticType(this SerializedProperty prop, out Type type)
{
return fieldInfoGetter(prop, out type);
}

private static GetFieldInfo Setup()
{
Type t = Type.GetType("UnityEditor.ScriptAttributeUtility, UnityEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
MethodInfo mi = t.GetMethod("GetFieldInfoAndStaticTypeFromProperty", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
return (GetFieldInfo) Delegate.CreateDelegate(typeof(GetFieldInfo), mi);
}

public static T GetCustomAttribute<T>(this SerializedProperty prop) where T : Attribute
{
FieldInfo info = prop.GetFieldInfoAndStaticType(out _);
return info.GetCustomAttribute<T>();
}

public static bool TryGetAttributeInHierarchy<T>(this SerializedProperty prop, out T attribute, out SerializedProperty ancestorWithAttribute) where T : Attribute
{
attribute = null;
ancestorWithAttribute = null;
foreach (SerializedProperty ancestor in prop.WalkHierarchy())
{
attribute = ancestor.GetCustomAttribute<T>();
if (attribute != null)
{
ancestorWithAttribute = ancestor;
return true;
}
}
return false;
}

public static SerializedProperty GetParent(this SerializedProperty property)
{
int i = property.propertyPath.LastIndexOf('.');
return i < 0 ? null
: property.serializedObject.FindProperty(property.propertyPath.Substring(0, i));
}

public static IEnumerable<SerializedProperty> WalkHierarchy(this SerializedProperty prop)
{
for (SerializedProperty curr = prop; curr != null; curr = curr.GetParent())
yield return curr;
}

public static T GetSerializedValue<T>(this SerializedProperty property)
{
// adapted from https://github.com/lordofduct/spacepuppy-unity-framework-4.0/blob/679088a9fca826764de39390b4e08c6feaa06b52/Framework/com.spacepuppy.core/Editor/src/EditorHelper.cs#L278
string path = property.propertyPath.Replace(".Array.data[", "[");
object obj = property.serializedObject.targetObject;

foreach (string elem in path.Split('.'))
{
if (elem[elem.Length - 1] == ']')
{
string memberName = elem.Substring(0, elem.LastIndexOf('['));
string indexer = elem.Substring(memberName.Length, elem.Length - memberName.Length);
int index = int.Parse(indexer.Substring(1, indexer.Length - 2));
IList valueList = ReflectionHelpers.GetMemberValue<IList>(obj, memberName);
obj = valueList[index];
}
else
{
obj = ReflectionHelpers.GetMemberValue<object>(obj, elem);
}
}

return (T)obj;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Editor.Scripts.Extensions;
using Editor.Scripts.PropertyDrawers.Utilities;
using SCHIZO.Registering;
using UnityEditor;
Expand All @@ -12,16 +13,35 @@ namespace Editor.Scripts.PropertyDrawers.Enums
public abstract class GameSpecificEnumDrawer<T> : PropertyDrawer where T : Enum
{
protected static readonly List<string> SubnauticaValues = typeof(T).GetEnumNames()
.Where(n => typeof(T).GetField(n).GetCustomAttribute<GameAttribute>().game.HasFlag(Game.Subnautica)).ToList();
.Where(n => typeof(T).GetField(n).GetCustomAttribute<GameAttribute>().TryGetGame(out Game game) && game.HasFlag(Game.Subnautica))
.ToList();

protected static readonly List<string> BelowZeroValues = typeof(T).GetEnumNames()
.Where(n => typeof(T).GetField(n).GetCustomAttribute<GameAttribute>().game.HasFlag(Game.BelowZero)).ToList();
.Where(n => typeof(T).GetField(n).GetCustomAttribute<GameAttribute>().TryGetGame(out Game game) && game.HasFlag(Game.BelowZero)).ToList();

protected virtual bool IsValueAcceptable(string entry, string propertyPath)
protected bool? hasGameAttr;
protected GameAttribute gameAttribute;
protected SerializedProperty parentWithGameAttribute;
protected virtual bool IsValueAcceptable(SerializedProperty property, string entry)
{
if (propertyPath.ToLower().Contains("sn")) return SubnauticaValues.Contains(entry);
if (propertyPath.ToLower().Contains("bz")) return BelowZeroValues.Contains(entry);
return SubnauticaValues.Contains(entry) || BelowZeroValues.Contains(entry);
Game game = default;
if (!hasGameAttr.HasValue)
{
hasGameAttr = property.TryGetAttributeInHierarchy(out gameAttribute, out parentWithGameAttribute);
}

gameAttribute?.TryGetGame(parentWithGameAttribute, out game);
// todo replace with attributes to be explicit?
if (property.propertyPath.EndsWith("SN")) game = Game.Subnautica;
if (property.propertyPath.EndsWith("BZ")) game = Game.BelowZero;

return IsValueAcceptable(entry, game);
}

protected bool IsValueAcceptable(string value, Game game)
{
return (!game.HasFlag(Game.Subnautica) || SubnauticaValues.Contains(value))
&& (!game.HasFlag(Game.BelowZero) || BelowZeroValues.Contains(value));
}

public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
Expand All @@ -45,11 +65,11 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
protected void DrawDropdownButton(SerializedProperty property, int controlid, Rect position)
{
Color oldColor = GUI.backgroundColor;
if (!IsValueAcceptable(property.enumNames[property.enumValueIndex], property.propertyPath)) GUI.backgroundColor = Color.red;
if (!IsValueAcceptable(property, property.enumNames[property.enumValueIndex])) GUI.backgroundColor = Color.red;

if (DropdownButton(controlid, position, new GUIContent(property.enumDisplayNames[property.enumValueIndex])))
{
SearchablePopup.Show(position, property.enumDisplayNames, property.enumNames, property.enumValueIndex, property.propertyPath, IsValueAcceptable, i =>
SearchablePopup.Show(position, property, IsValueAcceptable, i =>
{
property.enumValueIndex = i;
property.serializedObject.ApplyModifiedProperties();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using SCHIZO.Interop.Subnautica.Enums;
using Editor.Scripts.Extensions;
using SCHIZO.Helpers;
using SCHIZO.Interop.Subnautica.Enums;
using SCHIZO.Registering;
using UnityEditor;
using UnityEngine;
Expand All @@ -8,32 +10,21 @@ namespace Editor.Scripts.PropertyDrawers.Enums
[CustomPropertyDrawer(typeof(TechType_All))]
public sealed class TechType_AllDrawer : GameSpecificEnumDrawer<TechType_All>
{
public static Game TargetGame = 0;
public static Game TargetGame;

protected override bool IsValueAcceptable(string entry, string propertyPath)
protected override bool IsValueAcceptable(SerializedProperty property, string entry)
{
switch (TargetGame)
{
case 0:
return base.IsValueAcceptable(entry, propertyPath);

case Game.Subnautica:
return SubnauticaValues.Contains(entry);

case Game.BelowZero:
return BelowZeroValues.Contains(entry);

case Game.Subnautica | Game.BelowZero:
return SubnauticaValues.Contains(entry) && BelowZeroValues.Contains(entry);

default:
return false;
}
return TargetGame != default
? IsValueAcceptable(entry, TargetGame)
: base.IsValueAcceptable(property, entry);
}

public static void DrawDropdownButtonStatic(SerializedProperty property, int controlid, Rect position)
{
new TechType_AllDrawer().DrawDropdownButton(property, controlid, position);
TechType_AllDrawer drawer = new();
ReflectionCache.GetField(typeof(PropertyDrawer), "m_FieldInfo")
.SetValue(drawer, property.GetFieldInfoAndStaticType(out _));
drawer.DrawDropdownButton(property, controlid, position);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ private static bool IsOk(SerializedProperty property)

Recipe recipe = (Recipe) property.objectReferenceValue;

if (property.propertyPath.ToLower().Contains("sn") && !recipe.game.HasFlag(Game.Subnautica)) return false;
if (property.propertyPath.ToLower().Contains("bz") && !recipe.game.HasFlag(Game.BelowZero)) return false;
if (property.propertyPath.EndsWith("SN") && !recipe.game.HasFlag(Game.Subnautica)) return false;
if (property.propertyPath.EndsWith("BZ") && !recipe.game.HasFlag(Game.BelowZero)) return false;
return true;
}

Expand Down
Loading

0 comments on commit 98f8aa5

Please sign in to comment.