Second commit

This commit is contained in:
ThomasCharester committed 2026-09-20 15:26:03 +03:00
commit 36840f3ad4
999 files changed
+61364

No files matched your search

@@ -0,0 +1,94 @@
//
// This file is part of the Tremble package by Tiny Goose.
// Copyright (c) 2024-2026 TinyGoose Ltd., All Rights Reserved.
//
using System;
using System.Collections.Generic;
using System.Reflection;
namespace TinyGoose.Tremble
{
public class MapTypeLookup
{
public MapTypeLookup(TrembleSyncSettings syncSettings)
{
m_TypeNamingConvention = syncSettings.TypeNamingConvention;
GenerateLookup();
}
// -----------------------------------------------------------------------------------------------------------------------------
// Setup
// -----------------------------------------------------------------------------------------------------------------------------
private readonly NamingConvention m_TypeNamingConvention;
// -----------------------------------------------------------------------------------------------------------------------------
// State
// -----------------------------------------------------------------------------------------------------------------------------
private readonly Dictionary<string, Type> m_MapNameToClass = new();
private readonly Dictionary<string, EntityType> m_MapNameToEntityType = new();
private readonly Dictionary<Type, string> m_TypeToMapName = new();
public IEnumerable<Type> AllTypes => m_TypeToMapName.Keys;
public bool TryGetClassFromMapName(string mapName, out Type foundType)
{
return m_MapNameToClass.TryGetValue(mapName, out foundType);
}
public bool TryGetEntityTypeFromMapName(string mapName, out EntityType foundType)
{
return m_MapNameToEntityType.TryGetValue(mapName, out foundType);
}
public bool TryGetMapNameFromClass(Type type, out string foundName)
{
return m_TypeToMapName.TryGetValue(type, out foundName);
}
private void GenerateLookup()
{
foreach (Type type in TypeDatabase.GetTypesWithAttribute<EntityAttributeBase>())
{
if (type == typeof(TrembleSpawnablePrefab))
continue;
EntityAttributeBase attribute = type.GetCustomAttribute<EntityAttributeBase>();
string baseName = attribute.TrenchBroomName ?? type.Name.ToNamingConvention(m_TypeNamingConvention);
if (attribute is BrushEntityAttribute { BrushType: BrushType.Trigger }
&& !baseName.ContainsInvariant("trigger")
&& (attribute.Category == null || !attribute.Category.ContainsInvariant("trigger")))
{
UnityEngine.Debug.LogWarning($"Brush Entity of type '{type.Name}' is marked as a trigger. Consider adding 'trigger' into the name '{baseName}' so that TrenchBroom renders it appropriately.");
}
try
{
switch (attribute)
{
case PointEntityAttribute:
string pointPrefix = attribute.Category ?? FgdConsts.POINT_PREFIX;
string fullPointName = (pointPrefix.Length == 0) ? baseName : $"{pointPrefix}_{baseName}";
m_MapNameToClass.Add(fullPointName, type);
m_MapNameToEntityType.Add(fullPointName, EntityType.Point);
m_TypeToMapName.Add(type, fullPointName);
break;
case BrushEntityAttribute:
string brushPrefix = attribute.Category ?? FgdConsts.BRUSH_PREFIX;
string fullBrushName = (brushPrefix.Length == 0) ? baseName : $"{brushPrefix}_{baseName}";
m_MapNameToClass.Add(fullBrushName, type);
m_MapNameToEntityType.Add(fullBrushName, EntityType.Brush);
m_TypeToMapName.Add(type, fullBrushName);
break;
}
}
catch (ArgumentException)
{
UnityEngine.Debug.LogError($"Type '{type.Name}' or name '{baseName}' already used!}}");
}
}
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: e34c8bfb658a448d8979c62b58a61b90
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 277805
packageName: Tremble - Map Importer
packageVersion: 1.11.1
assetPath: Assets/Tremble/TypeLookups/MapTypeLookup.cs
uploadId: 939664
@@ -0,0 +1,107 @@
//
// This file is part of the Tremble package by Tiny Goose.
// Copyright (c) 2024-2026 TinyGoose Ltd., All Rights Reserved.
//
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace TinyGoose.Tremble
{
public class MaterialNameLookup
{
public MaterialNameLookup(TrembleSyncSettings syncSettings)
{
m_NamingConvention = syncSettings.MaterialNamingConvention;
#if UNITY_EDITOR
GenerateLookup(syncSettings);
#endif
}
// -----------------------------------------------------------------------------------------------------------------------------
// State
// -----------------------------------------------------------------------------------------------------------------------------
private readonly NamingConvention m_NamingConvention;
private readonly TwoWayDictionary<string, string> m_MapNameToMaterialPath = new();
public IEnumerable<string> AllMaterialPaths => m_MapNameToMaterialPath.Values;
public bool TryGetMaterialPathFromMapName(string mapName, out string foundMaterialPath)
{
#if !UNITY_EDITOR
if (TrembleAssetLoader.TryGetAssetDataFromMapName(mapName, out AssetMetadata data))
{
foundMaterialPath = data.Path;
return true;
}
foundMaterialPath = mapName;
return false;
#else
Debug.Assert(m_MapNameToMaterialPath != null, nameof(m_MapNameToMaterialPath) + " != null");
return m_MapNameToMaterialPath.TryGetValue(mapName, out foundMaterialPath);
#endif
}
public bool TryGetMapNameFromMaterialPath(string materialPath, out string foundName)
{
Debug.Assert(m_MapNameToMaterialPath != null, nameof(m_MapNameToMaterialPath) + " != null");
return m_MapNameToMaterialPath.TryGetKey(materialPath, out foundName);
}
public string GetPrefabNameFromMaterialPath(string materialPath)
{
string mapName = Path.GetFileNameWithoutExtension(materialPath);
if (m_NamingConvention != NamingConvention.PreserveExact && mapName.StartsWith("M_"))
{
mapName = mapName.Substring(2);
}
return mapName.ToNamingConvention(m_NamingConvention);
}
#if UNITY_EDITOR
private void GenerateLookup(TrembleSyncSettings syncSettings)
{
foreach (MaterialGroup mg in syncSettings.GetMaterialGroupsOrDefault())
{
foreach (Material mat in mg.Materials)
{
if (!mat)
continue;
string materialPath = TrembleAssetLoader.GetPath(mat);
string mapName = mat.name;
if (m_NamingConvention != NamingConvention.PreserveExact && mapName.StartsWith("M_"))
{
if (mapName.StartsWith("M_"))
{
mapName = mapName.Substring(2);
}
}
mapName = mapName.ToNamingConvention(m_NamingConvention);
// Replace spaces with underscores
mapName = mapName.Sanitise(new() { ' ' }, '_');
// Prepend group name
mapName = mg.Name + "/" + mapName;
// Already seen, and this is not a .mat - skip
if (m_MapNameToMaterialPath.ContainsValue(mapName) && !materialPath.EndsWith(".mat"))
{
continue;
}
m_MapNameToMaterialPath[mapName] = materialPath;
}
}
}
#endif
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 4e4e764a2eb96413e95877bace55f05d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 277805
packageName: Tremble - Map Importer
packageVersion: 1.11.1
assetPath: Assets/Tremble/TypeLookups/MaterialNameLookup.cs
uploadId: 939664
@@ -0,0 +1,177 @@
//
// This file is part of the Tremble package by Tiny Goose.
// Copyright (c) 2024-2026 TinyGoose Ltd., All Rights Reserved.
//
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
#if UNITY_EDITOR
using System.Text;
using UnityEditor;
#endif
namespace TinyGoose.Tremble
{
public class PrefabNameLookup
{
public PrefabNameLookup(TrembleSyncSettings syncSettings)
{
m_SyncSettings = syncSettings;
#if UNITY_EDITOR
GenerateLookup();
#endif
}
// -----------------------------------------------------------------------------------------------------------------------------
// Setup
// -----------------------------------------------------------------------------------------------------------------------------
private readonly TrembleSyncSettings m_SyncSettings;
// -----------------------------------------------------------------------------------------------------------------------------
// State
// -----------------------------------------------------------------------------------------------------------------------------
private readonly TwoWayDictionary<string, string> m_PrefabPathToMapName = new();
public bool TryGetPrefabPathFromMapName(string mapName, out string foundName)
{
#if !UNITY_EDITOR
if (TrembleAssetLoader.TryGetAssetDataFromMapName(mapName, out AssetMetadata data))
{
foundName = data.Path;
return true;
}
foundName = mapName;
return false;
#else
Debug.Assert(m_PrefabPathToMapName != null, nameof(m_PrefabPathToMapName) + " != null");
return m_PrefabPathToMapName.TryGetKey(mapName, out foundName);
#endif
}
public bool TryGetMapNameFromPrefabPath(string prefabPath, out string foundName)
{
Debug.Assert(m_PrefabPathToMapName != null, nameof(m_PrefabPathToMapName) + " != null");
return m_PrefabPathToMapName.TryGetValue(prefabPath, out foundName);
}
public bool IsValidAsset(string mapName)
{
return TrembleAssetLoader.TryGetAssetDataFromMapName(mapName, out _);
}
public List<string> AllPrefabPaths => m_PrefabPathToMapName.Keys.ToList();
#if UNITY_EDITOR
private void GenerateLookup()
{
foreach (string prefabEntityPath in TrembleAssetLoader.FindAssetPaths<GameObject>())
{
GameObject asset = TrembleAssetLoader.LoadPrefabByPath(prefabEntityPath);
if (!asset)
continue;
// Work out prefix/name for this prefab
string prefix = FgdConsts.PREFAB_PREFIX;
string mapName = Path.GetFileNameWithoutExtension(prefabEntityPath);
mapName = mapName.Sanitise(new() { '{', '}', ' ', '[', ']', '"', '\'', '.', ',' });
if (m_SyncSettings.TypeNamingConvention != NamingConvention.PreserveExact && mapName.StartsWithInvariant("P_", caseSensitive: true))
{
mapName = mapName.Substring(2);
}
mapName = mapName.ToNamingConvention(m_SyncSettings.TypeNamingConvention);
bool isExportedType = false;
if (asset.TryGetComponent(out TrembleSpawnablePrefab spawnablePrefab))
{
if (!spawnablePrefab.Category.IsNullOrEmpty())
{
prefix = spawnablePrefab.Category;
}
isExportedType = !spawnablePrefab.OnlyVariants || EDITOR_IsVariant(asset);
}
else
{
foreach (MonoBehaviour component in asset.GetComponents<MonoBehaviour>())
{
if (!component)
{
Debug.LogWarning($"Missing component on prefab {asset.name}!", asset);
continue;
}
if (!component.GetType().TryGetCustomAttribute(out PrefabEntityAttribute pea))
continue;
if (pea.Category != null)
{
prefix = pea.Category;
}
if (pea.TrenchBroomName != null)
{
mapName = pea.TrenchBroomName;
}
isExportedType = !pea.OnlyVariants || EDITOR_IsVariant(asset);
break;
}
}
if (!isExportedType)
continue;
if (!mapName.StartsWithInvariant(prefix, caseSensitive: true))
{
mapName = prefix + "_" + mapName;
}
try
{
m_PrefabPathToMapName.Add(prefabEntityPath, mapName);
}
catch (ArgumentException)
{
Debug.LogError($"Prefab path '{prefabEntityPath}' or map name '{mapName}' already used!}}");
}
}
}
#endif
#if UNITY_EDITOR
private bool EDITOR_IsVariant(GameObject asset)
{
// Not a variant - don't export!
if (PrefabUtility.GetPrefabAssetType(asset) != PrefabAssetType.Variant)
return false;
// It's a variant - check first if the parent is a regular prefab or
// a variant of a prefab... i.e. NOT a model prefab.
GameObject parent = PrefabUtility.GetCorrespondingObjectFromSource(asset);
if (parent)
{
PrefabAssetType parentType = PrefabUtility.GetPrefabAssetType(parent);
return parentType switch
{
PrefabAssetType.Regular => true,
PrefabAssetType.Variant => true,
_ => false
};
}
return true;
}
#endif
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 8632018739db74abc82c2fc22b75b1c6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 277805
packageName: Tremble - Map Importer
packageVersion: 1.11.1
assetPath: Assets/Tremble/TypeLookups/PrefabNameLookup.cs
uploadId: 939664