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,288 @@
//
// 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.Diagnostics;
using UnityEngine;
using UnityEngine.Scripting;
using Debug = UnityEngine.Debug;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.SceneManagement;
#endif
namespace TinyGoose.Tremble
{
[Serializable]
public struct IDMapping
{
[SerializeField] private string m_ID;
[SerializeField] private GameObject[] m_Objects;
public string ID => m_ID;
public GameObject[] Objects => m_Objects;
public static IDMapping Create(string name, GameObject[] objects) => new()
{
m_ID = name,
m_Objects = objects,
};
}
/// <summary>
/// The root of a map file.
/// Provides a way to connect entities in maps to MonoBehaviours outside of the map.
/// </summary>
[DefaultExecutionOrder(-1000), Preserve, ExecuteInEditMode, AddComponentMenu("")]
public class MapDocument : MonoBehaviour
{
// -----------------------------------------------------------------------------------------------------------------------------
// Exposed
// -----------------------------------------------------------------------------------------------------------------------------
[SerializeField, HideInInspector] private string m_BspName;
[SerializeField, HideInInspector] private IDMapping[] m_EntityIDs;
[SerializeField, HideInInspector] private string m_OriginalAssetGuid;
[SerializeField, HideInInspector] private GameObject m_WorldspawnObject;
[SerializeField, HideInInspector] private ulong m_MapImportedTime;
private Q3Map2Result m_Result = Q3Map2Result.Succeeded;
private string m_ResultReason;
// -----------------------------------------------------------------------------------------------------------------------------
// Properties
// -----------------------------------------------------------------------------------------------------------------------------
public string BspName => m_BspName;
public TWorldspawn GetWorldspawn<TWorldspawn>() where TWorldspawn : Worldspawn => m_WorldspawnObject.GetComponent<TWorldspawn>();
public bool TryGetWorldspawn<TWorldspawn>(out TWorldspawn worldspawn) where TWorldspawn : Worldspawn
{
worldspawn = GetWorldspawn<TWorldspawn>();
return worldspawn;
}
public Q3Map2Result Result => m_Result;
public string ResultReason => m_ResultReason;
#if UNITY_EDITOR
public IDMapping[] EntityIDs => m_EntityIDs;
public string OriginalAssetGuid => m_OriginalAssetGuid;
public GameObject WorldspawnObject => m_WorldspawnObject;
public ulong MapImportedTime => m_MapImportedTime;
#endif
[Conditional("UNITY_EDITOR")]
private void OnEnable()
{
#if UNITY_EDITOR
TrembleSyncSettings syncSettings = TrembleSyncSettings.Get();
if (syncSettings.PrefabOverrideHandling != PrefabOverrideHandling.AllowOverrides)
{
bool hasAnyOverrides = PrefabUtility.HasPrefabInstanceAnyOverrides(gameObject, true);
List<AddedComponent> addedComponents = PrefabUtility.IsAnyPrefabInstanceRoot(gameObject) ? PrefabUtility.GetAddedComponents(gameObject) : new();
List<RemovedComponent> removedComponents = PrefabUtility.IsAnyPrefabInstanceRoot(gameObject) ? PrefabUtility.GetRemovedComponents(gameObject) : new();
int numChangedItems = addedComponents.Count + removedComponents.Count;
#if UNITY_2022_1_OR_NEWER
List<RemovedGameObject> removedGOs = PrefabUtility.IsAnyPrefabInstanceRoot(gameObject) ? PrefabUtility.GetRemovedGameObjects(gameObject) : new();
numChangedItems += removedGOs.Count;
#endif
if (hasAnyOverrides || numChangedItems > 0)
{
bool needsRevert = false;
foreach (PropertyModification propChanged in PrefabUtility.GetPropertyModifications(gameObject))
{
if (!propChanged.target)
continue;
if (propChanged.propertyPath.EqualsInvariant("name", caseSensitive: false) ||
propChanged.propertyPath.EqualsInvariant("m_Name", caseSensitive: false))
continue;
// TextMeshPro adds a hidden MeshFilter with overriden props, and then hides it. We can ignore this
// one since the user can't see it!
if ((propChanged.target.hideFlags & HideFlags.HideInHierarchy) != 0)
continue;
string niceName = propChanged.propertyPath.Split('.')[0].ToNamingConvention(NamingConvention.HumanFriendly);
GameObject changedInstance = gameObject.Find_Recursive(propChanged.target.name);
needsRevert = true;
if (syncSettings.PrefabOverrideHandling == PrefabOverrideHandling.WarnOnOverridesFound)
{
Debug.LogWarning($"Property override found: '{niceName}' ({propChanged.propertyPath}) on '{propChanged.target.name}' ({propChanged.target.GetType().Name}) - please change this value in TrenchBroom instead of Unity!", changedInstance);
}
else if (syncSettings.PrefabOverrideHandling == PrefabOverrideHandling.AutomaticallyRevert)
{
Debug.LogWarning($"Auto-reverted overridden property '{niceName}' ({propChanged.propertyPath}) on '{propChanged.target.name}' ({propChanged.target.GetType().Name}) - please change this value in TrenchBroom instead of Unity!", changedInstance);
}
}
foreach (AddedComponent addedComponent in addedComponents)
{
if (addedComponent.instanceComponent.GetType().Name.EqualsInvariant("UniversalAdditionalLightData", caseSensitive: true) ||
addedComponent.instanceComponent.GetType().Name.EqualsInvariant("HDAdditionalLightData", caseSensitive: true))
{
numChangedItems--;
continue;
}
if (syncSettings.PrefabOverrideHandling == PrefabOverrideHandling.WarnOnOverridesFound)
{
Debug.LogWarning($"Added component found: '{addedComponent.instanceComponent.GetType().Name}' on '{addedComponent.instanceComponent.name}' - please change this value in TrenchBroom instead of Unity!", addedComponent.instanceComponent);
}
else if (syncSettings.PrefabOverrideHandling == PrefabOverrideHandling.AutomaticallyRevert)
{
Debug.LogWarning($"Auto-reverted added component '{addedComponent.instanceComponent.GetType().Name}' on '{addedComponent.instanceComponent.name}' - please change this value in TrenchBroom instead of Unity!", addedComponent.instanceComponent);
addedComponent.Revert(InteractionMode.AutomatedAction);
}
}
foreach (RemovedComponent removedComponent in removedComponents)
{
if (syncSettings.PrefabOverrideHandling == PrefabOverrideHandling.WarnOnOverridesFound)
{
Debug.LogWarning($"Removed component found: '{removedComponent.assetComponent.GetType().Name}' on '{removedComponent.assetComponent.name}' - please change this value in TrenchBroom instead of Unity!", removedComponent.containingInstanceGameObject);
}
else if (syncSettings.PrefabOverrideHandling == PrefabOverrideHandling.AutomaticallyRevert)
{
Debug.LogWarning($"Auto-reverted removed component '{removedComponent.assetComponent.GetType().Name}' on '{removedComponent.assetComponent.name}' - please change this value in TrenchBroom instead of Unity!", removedComponent.containingInstanceGameObject);
removedComponent.Revert(InteractionMode.AutomatedAction);
}
}
#if UNITY_2022_1_OR_NEWER
foreach (RemovedGameObject removedGO in removedGOs)
{
if (syncSettings.PrefabOverrideHandling == PrefabOverrideHandling.WarnOnOverridesFound)
{
Debug.LogWarning($"Removed GameObject found: '{removedGO.assetGameObject.name}' - please change this value in TrenchBroom instead of Unity!", removedGO.parentOfRemovedGameObjectInInstance);
}
else if (syncSettings.PrefabOverrideHandling == PrefabOverrideHandling.AutomaticallyRevert)
{
Debug.LogWarning($"Auto-reverted removed GameObject '{removedGO.assetGameObject.name}' - please change this value in TrenchBroom instead of Unity!", removedGO.parentOfRemovedGameObjectInInstance);
removedGO.Revert(InteractionMode.AutomatedAction);
}
}
#endif
if (needsRevert && syncSettings.PrefabOverrideHandling == PrefabOverrideHandling.AutomaticallyRevert)
{
PrefabUtility.RevertPrefabInstance(gameObject, InteractionMode.AutomatedAction);
}
}
}
#endif
}
internal void INTERNAL_SetResult(Q3Map2Result result, string reason)
{
m_Result = result;
m_ResultReason = reason;
}
internal void INTERNAL_SetData(string bspName, IDMapping[] ids, string originalAssetGuid, GameObject worldspawnObject, ulong mapImportedTime)
{
m_BspName = bspName;
m_EntityIDs = ids;
m_OriginalAssetGuid = originalAssetGuid;
m_WorldspawnObject = worldspawnObject;
m_MapImportedTime = mapImportedTime;
}
// Find a list of entities with a given id
public bool Q(string id, out GameObject[] foundObjects)
{
if (m_EntityIDs == null || m_EntityIDs.Length == 0)
{
foundObjects = null;
return false;
}
foreach (IDMapping mapping in m_EntityIDs)
{
if (!mapping.ID.EqualsInvariant(id))
continue;
foundObjects = mapping.Objects;
return true;
}
foundObjects = Array.Empty<GameObject>();
return false;
}
// Find a list of components from entities with a given id
public bool Q<TComponent>(string id, out List<TComponent> foundComponents)
where TComponent : Component
{
foundComponents = new();
if (!Q(id, out GameObject[] foundObjects))
{
return false;
}
foreach (GameObject foundObject in foundObjects)
{
foundComponents.AddRange(foundObject.GetComponentsInChildren<TComponent>());
}
return foundComponents.Count > 0;
}
// Find a single entity with a id
public bool Q(string id, out GameObject foundObject)
{
bool wasFound = Q(id, out GameObject[] foundObjects);
foundObject = wasFound ? foundObjects[0] : null;
return wasFound;
}
// Find a component on a single entity with a id
public bool Q<TComponent>(string id, out TComponent foundComponent)
where TComponent : Component
{
bool wasFound = Q(id, out List<TComponent> foundComponents);
foundComponent = wasFound ? foundComponents[0] : null;
return wasFound;
}
// Find a list of components from entities with a given id
public bool Q(string id, Type componentType, out List<Component> foundComponents)
{
foundComponents = new();
if (!Q(id, out GameObject[] foundObjects))
{
return false;
}
foreach (GameObject foundObject in foundObjects)
{
foundComponents.AddRange(foundObject.GetComponentsInChildren(componentType));
}
return foundComponents.Count > 0;
}
// Find a component on a single entity with a id
public bool Q(string id, Type componentType, out Component foundComponent)
{
bool wasFound = Q(id, componentType, out List<Component> foundComponents);
foundComponent = wasFound ? foundComponents[0] : null;
return wasFound;
}
}
}
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 40181e5341c64b86bf8f57109d47ebce
timeCreated: 1706952539
AssetOrigin:
serializedVersion: 1
productId: 277805
packageName: Tremble - Map Importer
packageVersion: 1.11.1
assetPath: Assets/Tremble/MonoBehaviours/MapDocument.cs
uploadId: 939664
@@ -0,0 +1,18 @@
//
// This file is part of the Tremble package by Tiny Goose.
// Copyright (c) 2024-2026 TinyGoose Ltd., All Rights Reserved.
//
using UnityEngine;
namespace TinyGoose.Tremble
{
/// <summary>
/// Disconnects arbitrary brushes from the main worldspawn.
/// </summary>
[BrushEntity("separate", category: "misc")]
[AddComponentMenu("")]
public class SeparateMesh : MonoBehaviour
{
}
}
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 47ad5647e26f4839a384fedd97611250
timeCreated: 1706712777
AssetOrigin:
serializedVersion: 1
productId: 277805
packageName: Tremble - Map Importer
packageVersion: 1.11.1
assetPath: Assets/Tremble/MonoBehaviours/SeparateMesh.cs
uploadId: 939664
@@ -0,0 +1,25 @@
//
// This file is part of the Tremble package by Tiny Goose.
// Copyright (c) 2024-2026 TinyGoose Ltd., All Rights Reserved.
//
using UnityEngine;
namespace TinyGoose.Tremble
{
/// <summary>
/// Add this component to an existing Prefab which doesn't contain a
/// MonoBehaviour to allow it to be placed in TrenchBroom easily.
/// </summary>
[PrefabEntity]
public sealed class TrembleSpawnablePrefab : MonoBehaviour
{
[SerializeField, NoTremble] private string m_Category;
[SerializeField, NoTremble] private Texture2D m_OverrideSprite;
[SerializeField, NoTremble] private bool m_OnlyVariants;
public string Category => m_Category;
public Texture2D OverrideSprite => m_OverrideSprite;
public bool OnlyVariants => m_OnlyVariants;
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 3770c55e1e67e4805bcf322ae01885f3
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/MonoBehaviours/TrembleSpawnablePrefab.cs
uploadId: 939664
@@ -0,0 +1,15 @@
//
// This file is part of the Tremble package by Tiny Goose.
// Copyright (c) 2024-2026 TinyGoose Ltd., All Rights Reserved.
//
using UnityEngine;
namespace TinyGoose.Tremble
{
[DefaultExecutionOrder(-50)]
public class Worldspawn : MonoBehaviour
{
}
}
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 78f4dd27e14848d793e71189be81527b
timeCreated: 1710154074
AssetOrigin:
serializedVersion: 1
productId: 277805
packageName: Tremble - Map Importer
packageVersion: 1.11.1
assetPath: Assets/Tremble/MonoBehaviours/Worldspawn.cs
uploadId: 939664