diff --git a/src/openrct2-dll/Export/Tracks.cpp b/src/openrct2-dll/Export/Tracks.cpp new file mode 100644 index 0000000000..1b2b3a2b3c --- /dev/null +++ b/src/openrct2-dll/Export/Tracks.cpp @@ -0,0 +1,22 @@ +#include +#include + +#include "Openrct2-dll.h" + +extern "C" +{ + // Returns the amount of path nodes in the pathing route for the specified track type. + EXPORT int GetTrackElementRouteSize(int32_t trackVariant, int32_t typeAndDirection) + { + return gTrackVehicleInfo[trackVariant][typeAndDirection]->size; + } + + + // Returns the pathing route for the specified track element. + EXPORT void GetTrackElementRoute(int32_t trackVariant, int32_t typeAndDirection, rct_vehicle_info* nodes, int arraySize) + { + const rct_vehicle_info_list* list = gTrackVehicleInfo[trackVariant][typeAndDirection]; + + std::memcpy(nodes, list->info, sizeof(rct_vehicle_info) * arraySize); + } +} diff --git a/src/openrct2-dll/openrct2-dll.vcxproj b/src/openrct2-dll/openrct2-dll.vcxproj index 348e8912e0..748437b95a 100644 --- a/src/openrct2-dll/openrct2-dll.vcxproj +++ b/src/openrct2-dll/openrct2-dll.vcxproj @@ -67,6 +67,7 @@ xcopy /i /y /f "$(SolutionDir)bin\dll-export\*" "$(SolutionDir)src\openrct2-unit + diff --git a/src/openrct2-unity/Assets/Prefabs/GameObjects/Track.prefab b/src/openrct2-unity/Assets/Prefabs/GameObjects/Track.prefab index ba802f1b75..a01c6947ec 100644 --- a/src/openrct2-unity/Assets/Prefabs/GameObjects/Track.prefab +++ b/src/openrct2-unity/Assets/Prefabs/GameObjects/Track.prefab @@ -25,12 +25,106 @@ Transform: m_GameObject: {fileID: 3460111253241373034} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0.25, y: 0.25, z: 0.25} + m_LocalScale: {x: 0.05, y: 0.05, z: 0.05} m_Children: - {fileID: 3676241976214955814} + - {fileID: 8931575796167162921} m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &5548823012095227079 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8931575796167162921} + - component: {fileID: 3552024548040068515} + - component: {fileID: 3049426981837551801} + - component: {fileID: 2258461748174447842} + m_Layer: 0 + m_Name: Cube (1) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 4294967295 + m_IsActive: 1 +--- !u!4 &8931575796167162921 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5548823012095227079} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 2.5, y: 0.5, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 7165131111595459873} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &3552024548040068515 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5548823012095227079} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &3049426981837551801 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5548823012095227079} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: ce68aa93eb4498b4fa6a2a58f04c2bfb, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!65 &2258461748174447842 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5548823012095227079} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} --- !u!1 &6000070329163251540 GameObject: m_ObjectHideFlags: 0 @@ -58,7 +152,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 6000070329163251540} m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0.5, z: 0} + m_LocalPosition: {x: -2.5, y: 0.5, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 7165131111595459873} diff --git a/src/openrct2-unity/Assets/Scenes/ParkScene.unity b/src/openrct2-unity/Assets/Scenes/ParkScene.unity index f0dcf47bbf..7645c5ce81 100644 --- a/src/openrct2-unity/Assets/Scenes/ParkScene.unity +++ b/src/openrct2-unity/Assets/Scenes/ParkScene.unity @@ -98,7 +98,7 @@ LightmapSettings: m_TrainingDataDestination: TrainingData m_LightProbeSampleCountMultiplier: 4 m_LightingDataAsset: {fileID: 0} - m_UseShadowmask: 0 + m_UseShadowmask: 1 --- !u!196 &4 NavMeshSettings: serializedVersion: 2 @@ -464,7 +464,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 79be679884da2154dacd80be9669d5dc, type: 3} m_Name: m_EditorClassIdentifier: - selectedPark: Blackpool.sv6 + selectedPark: Dynamite Dunes.sv6 --- !u!4 &1347800243 Transform: m_ObjectHideFlags: 0 @@ -514,7 +514,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 8f4353bcde699fe4dbc7f9641bcd509e, type: 3} m_Name: m_EditorClassIdentifier: - generationFlags: 125 + generationFlags: -1 surfaceGenerator: id: 0 pathGenerator: @@ -552,7 +552,7 @@ MonoBehaviour: prefab: {fileID: 6681454114598486694, guid: d5e4b199bf0e87b47b14b43c86d8c12f, type: 3} 00000002: - type: {class: PrefabGenerator, ns: Generation, asm: Assembly-CSharp} + type: {class: TrackGenerator, ns: Generation.Retro, asm: Assembly-CSharp} data: prefab: {fileID: 3460111253241373034, guid: ac7c5b20c9776c2458a7c5f077e645f0, type: 3} diff --git a/src/openrct2-unity/Assets/Scripts/Generation/IElementGenerator.cs b/src/openrct2-unity/Assets/Scripts/Generation/IElementGenerator.cs index 67223b9cb9..849b8cb16d 100644 --- a/src/openrct2-unity/Assets/Scripts/Generation/IElementGenerator.cs +++ b/src/openrct2-unity/Assets/Scripts/Generation/IElementGenerator.cs @@ -1,4 +1,4 @@ -using OpenRCT; +using Lib; namespace Generation { @@ -8,7 +8,7 @@ namespace Generation public interface IElementGenerator { /// - /// Creates a tile element at the specified position. + /// Creates a tile element at the specified tile position. /// void CreateElement(int x, int y, ref TileElement tile); diff --git a/src/openrct2-unity/Assets/Scripts/Generation/Miscellaneous/PrefabGenerator.cs b/src/openrct2-unity/Assets/Scripts/Generation/Miscellaneous/PrefabGenerator.cs index 272f6d63df..bd8e9b6229 100644 --- a/src/openrct2-unity/Assets/Scripts/Generation/Miscellaneous/PrefabGenerator.cs +++ b/src/openrct2-unity/Assets/Scripts/Generation/Miscellaneous/PrefabGenerator.cs @@ -1,4 +1,4 @@ -using OpenRCT; +using Lib; using UnityEngine; namespace Generation diff --git a/src/openrct2-unity/Assets/Scripts/Generation/Retro/SmallSceneryGenerator.cs b/src/openrct2-unity/Assets/Scripts/Generation/Retro/SmallSceneryGenerator.cs index 1b1f6eab33..3dfe529bbf 100644 --- a/src/openrct2-unity/Assets/Scripts/Generation/Retro/SmallSceneryGenerator.cs +++ b/src/openrct2-unity/Assets/Scripts/Generation/Retro/SmallSceneryGenerator.cs @@ -1,4 +1,4 @@ -using OpenRCT; +using Lib; using UnityEngine; namespace Generation.Retro @@ -8,7 +8,6 @@ namespace Generation.Retro /// public class SmallSceneryGenerator : IElementGenerator { - [Header("Meshes")] [SerializeField] GameObject crossShape; Map map; diff --git a/src/openrct2-unity/Assets/Scripts/Generation/Retro/SurfaceGenerator.Textures.cs b/src/openrct2-unity/Assets/Scripts/Generation/Retro/SurfaceGenerator.Textures.cs index 9585899683..c96e614c19 100644 --- a/src/openrct2-unity/Assets/Scripts/Generation/Retro/SurfaceGenerator.Textures.cs +++ b/src/openrct2-unity/Assets/Scripts/Generation/Retro/SurfaceGenerator.Textures.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using OpenRCT; +using Lib; using UnityEngine; namespace Generation.Retro diff --git a/src/openrct2-unity/Assets/Scripts/Generation/Retro/SurfaceGenerator.cs b/src/openrct2-unity/Assets/Scripts/Generation/Retro/SurfaceGenerator.cs index 6d84b976af..af9cab6568 100644 --- a/src/openrct2-unity/Assets/Scripts/Generation/Retro/SurfaceGenerator.cs +++ b/src/openrct2-unity/Assets/Scripts/Generation/Retro/SurfaceGenerator.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using MeshBuilding; -using OpenRCT; +using Lib; using UnityEngine; namespace Generation.Retro diff --git a/src/openrct2-unity/Assets/Scripts/Generation/Retro/TrackGenerator.cs b/src/openrct2-unity/Assets/Scripts/Generation/Retro/TrackGenerator.cs new file mode 100644 index 0000000000..fb5d36050e --- /dev/null +++ b/src/openrct2-unity/Assets/Scripts/Generation/Retro/TrackGenerator.cs @@ -0,0 +1,74 @@ +using System.Collections.Generic; +using Lib; +using UnityEngine; + +namespace Generation.Retro +{ + public class TrackGenerator : IElementGenerator + { + static Dictionary trackNodesCache = new Dictionary(); + + + [SerializeField] GameObject prefab; + + Map map; + + + /// + public void StartGenerator(Map map) + { + this.map = map; + } + + + /// + public void FinishGenerator() + { + map = null; + } + + + + /// + public void CreateElement(int x, int y, ref TileElement tile) + { + TrackElement track = tile.AsTrack(); + + if (track.PartIndex != 0) + return; + + int trackType = track.TrackType; + + if (!trackNodesCache.TryGetValue(trackType, out TrackNode[] nodes)) + { + nodes = OpenRCT2.GetTrackElementRoute(trackType); + trackNodesCache.Add(trackType, nodes); + } + + const float trackOffset = -0.5f; + + GameObject parent = new GameObject($"[{x}, {y}] rot: {tile.Rotation}, type: {trackType}") + { + isStatic = true + }; + + Transform tfParent = parent.transform; + tfParent.parent = map.transform; + tfParent.localPosition = Map.TileCoordsToUnity(x, tile.baseHeight, y); + tfParent.localRotation = Quaternion.Euler(0, tile.Rotation * 90f, 0); + + for (int i = 0; i < nodes.Length; i++) + { + TrackNode node = nodes[i]; + + GameObject obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, tfParent); + obj.name = $"#{i} = dir: {node.direction}, bank: {node.bankRotation}, sprite: {node.vehicleSprite}"; + + Vector3 local = node.LocalPosition; + Transform tf = obj.transform; + tf.localPosition = new Vector3(local.x + trackOffset, local.y, local.z + trackOffset); + tf.localRotation = Quaternion.Euler(0, ((360f / 32f) * node.direction) + 270f, 0); + } + } + } +} diff --git a/src/openrct2-unity/Assets/Scripts/Generation/Retro/TrackGenerator.cs.meta b/src/openrct2-unity/Assets/Scripts/Generation/Retro/TrackGenerator.cs.meta new file mode 100644 index 0000000000..772cae7e53 --- /dev/null +++ b/src/openrct2-unity/Assets/Scripts/Generation/Retro/TrackGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b626c25729c8694a9b1b122fdc92b0f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/openrct2-unity/Assets/Scripts/Generation/Retro/WallGenerator.cs b/src/openrct2-unity/Assets/Scripts/Generation/Retro/WallGenerator.cs index 69ce68c097..c0c480d776 100644 --- a/src/openrct2-unity/Assets/Scripts/Generation/Retro/WallGenerator.cs +++ b/src/openrct2-unity/Assets/Scripts/Generation/Retro/WallGenerator.cs @@ -1,4 +1,4 @@ -using OpenRCT; +using Lib; using UnityEngine; namespace Generation.Retro diff --git a/src/openrct2-unity/Assets/Scripts/MeshBuilding/MeshBuilder.cs b/src/openrct2-unity/Assets/Scripts/MeshBuilding/MeshBuilder.cs index 120ff9e91a..ea2c92f2e7 100644 --- a/src/openrct2-unity/Assets/Scripts/MeshBuilding/MeshBuilder.cs +++ b/src/openrct2-unity/Assets/Scripts/MeshBuilding/MeshBuilder.cs @@ -6,18 +6,89 @@ namespace MeshBuilding /// /// Small class to easily create meshes through C#. /// - public class MeshBuilder + public partial class MeshBuilder { + /// + /// Returns all vertices currently added to the builder. + /// + public IReadOnlyCollection Vertices + => vertices.Keys; + + + /// + /// Returns all vertices currently added to the builder. + /// + public Bounds Bounds + => CalculateBounds(); + + // Dictionary of vertices and their indexes. - public readonly Dictionary vertices = new Dictionary(64); + readonly Dictionary vertices; // List of triangles per submesh. - readonly List> triangles = new List>(1); + readonly List> triangles; Mesh mesh = null; + #region Constructors + + /// + /// Creates a regular mesh builder. + /// + public MeshBuilder() + { + vertices = new Dictionary(64); + triangles = new List>(1); + } + + + /// + /// Creates a mesh builder from an existing mesh. + /// + public MeshBuilder(Mesh mesh) + { + // Load vertices + Vector3[] meshVerts = mesh.vertices; + Vector3[] meshNormals = mesh.normals; + Vector2[] meshUvs = mesh.uv; + + int vertexCount = mesh.vertexCount; + vertices = new Dictionary(vertexCount); + + int index = 0; + for (int v = 0; v < vertexCount; v++) + { + Vertex vertex = new Vertex( + pos: meshVerts[v], + nor: meshNormals[v], + uvs: meshUvs[v] + ); + + if (vertices.ContainsKey(vertex)) + continue; + + vertices.Add(vertex, index); + index++; + } + + // Load triangles + int submeshCount = mesh.subMeshCount; + triangles = new List>(submeshCount); + + for (int s = 0; s < submeshCount; s++) + { + List buffer = new List(0); + mesh.GetTriangles(buffer, s); + + triangles[s] = buffer; + } + } + + #endregion + + /// /// Add a vertex to the mesh. Returns the index of this vertex. /// @@ -117,6 +188,36 @@ namespace MeshBuilding return mesh; } - } + + + /// + /// Returns the bounds of all vertices. + /// + Bounds CalculateBounds() + { + float min_x = float.MaxValue, min_y = float.MaxValue, min_z = float.MaxValue, + max_x = float.MinValue, max_y = float.MinValue, max_z = float.MinValue; + + foreach (Vertex vertex in vertices.Keys) + { + Vector3 pos = vertex.position; + + if (min_x > pos.x) min_x = pos.x; + if (min_y > pos.y) min_y = pos.y; + if (min_z > pos.z) min_x = pos.z; + + if (max_x < pos.x) max_x = pos.x; + if (max_y < pos.y) max_y = pos.y; + if (max_z < pos.z) max_x = pos.z; + } + + Vector3 min = new Vector3(min_x, min_y, min_z); + Vector3 max = new Vector3(max_x, max_y, max_z); + + Bounds bounds = new Bounds(); + bounds.SetMinMax(min, max); + return bounds; + } + } } diff --git a/src/openrct2-unity/Assets/Scripts/MeshBuilding/MeshBuilderExtensions.cs b/src/openrct2-unity/Assets/Scripts/MeshBuilding/MeshBuilderExtensions.cs index cab894551f..4f27afdfbf 100644 --- a/src/openrct2-unity/Assets/Scripts/MeshBuilding/MeshBuilderExtensions.cs +++ b/src/openrct2-unity/Assets/Scripts/MeshBuilding/MeshBuilderExtensions.cs @@ -44,7 +44,6 @@ namespace MeshBuilding for (int p = 0; p < 4; p++) { - //innerVerts[p] = new Vertex(matrix[p] * a.position + matrix[(p+1)%4] * b.position + matrix[(p+2)%4] * c.position + matrix[(p+3)%4] * d.position); innerVerts[p] = new Vertex( CalculateMatrix(matrix, p, a.position, b.position, c.position, d.position), Vector3.up, diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Configuration.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Configuration.cs index 0f39374ad7..c7a6df8677 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Configuration.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Configuration.cs @@ -1,6 +1,6 @@ using UnityEngine; -namespace OpenRCT +namespace Lib { /// /// Static class to access OpenRCT2-Unity configuration. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Editor/OpenRCT2Editor.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Editor/OpenRCT2Editor.cs index 3ed37d44d0..59e497a261 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Editor/OpenRCT2Editor.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Editor/OpenRCT2Editor.cs @@ -4,7 +4,7 @@ using System.Linq; using UnityEditor; using UnityEngine; -namespace OpenRCT +namespace Lib { /// /// An editor that helps configuring OpenRCT2 settings in Unity, for example diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Editor/ScriptSelectorDrawer.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Editor/ScriptSelectorDrawer.cs new file mode 100644 index 0000000000..0da64db497 --- /dev/null +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Editor/ScriptSelectorDrawer.cs @@ -0,0 +1,179 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using Utilities; + +namespace Lib +{ + /// + /// Property drawer for the . + /// + [CustomPropertyDrawer(typeof(ScriptSelectorAttribute))] + public class ScriptSelectorDrawer : PropertyDrawer + { + // Cache for the drawer, because the same drawer can be used for multiple properties. + static readonly Dictionary cache = new Dictionary(); + + + // The settings for the drawer per property. + struct DrawerData + { + public bool foldout; + public MonoScript script; + } + + + /// + /// Draws the GUI for a property with a . + /// + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + float fieldSpacing = EditorGUIUtility.standardVerticalSpacing; + float singleLineHeight = EditorGUIUtility.singleLineHeight; + + string cacheKey = GetCacheKey(property); + cache.TryGetValue(cacheKey, out DrawerData settings); + + Rect rect = position; + rect.height = singleLineHeight; + + if ((settings.foldout = EditorGUI.Foldout(rect, settings.foldout, label, toggleOnLabelClick: true))) + { + rect.y += (singleLineHeight + fieldSpacing); + EditorGUI.indentLevel++; + + // Script + if (!TryFindManagedType(property.managedReferenceFullTypename, out Type managedType)) + return; + + MonoScript script; + + if (settings.script != null) + script = settings.script; + else if (TryFindMonoScriptAsset(managedType.Name, out script)) + settings.script = script; + else return; + + GUIContent scriptLabel = new GUIContent(fieldInfo.FieldType.Name); + MonoScript selected = (MonoScript)EditorGUI.ObjectField(rect, scriptLabel, script, typeof(MonoScript), allowSceneObjects: false); + + if (selected != script && ValidateSelectedScript(selected, fieldInfo, out object instance)) + { + property.serializedObject.Update(); + property.managedReferenceValue = instance; + property.serializedObject.ApplyModifiedProperties(); + } + + rect.y += (singleLineHeight + fieldSpacing); + + // Serialized fields + SerializedProperty end = property.GetEndProperty(); + bool any = property.NextVisible(true); + + while (any && property.propertyPath != end.propertyPath) + { + float propertyHeight = EditorGUI.GetPropertyHeight(property); + rect.height = propertyHeight; + + EditorGUI.PropertyField(rect, property, label, includeChildren: true); + + rect.y += (propertyHeight + fieldSpacing); + any = property.NextVisible(false); + } + EditorGUI.indentLevel--; + } + cache[cacheKey] = settings; + } + + + /// + /// Gets the height of the property. + /// + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + cache.TryGetValue(GetCacheKey(property), out DrawerData settings); + + if (!settings.foldout) + return EditorGUIUtility.singleLineHeight; + + float editorHeight = EditorGUI.GetPropertyHeight(property, label, includeChildren: true); + return (editorHeight + EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing); + } + + + /// + /// Try to find the managed type from the Unity provided type name. + /// + static bool TryFindManagedType(string fullUnityTypeName, out Type managedType) + { + string[] parts = fullUnityTypeName.Split(' '); + + if (parts.Length == 2) + { + managedType = Type.GetType($"{parts[1]}, {parts[0]}"); + return true; + } + + Debug.LogWarning($"Could not find managed type '{fullUnityTypeName}'!"); + managedType = null; + return false; + } + + + /// + /// Try to find the asset that contains the specified class. + /// + static bool TryFindMonoScriptAsset(string className, out MonoScript script) + { + string[] assetGuids = AssetDatabase.FindAssets($"{className} t:MonoScript"); + + if (assetGuids.Length > 0) + { + string path = AssetDatabase.GUIDToAssetPath(assetGuids[0]); + + script = AssetDatabase.LoadAssetAtPath(path); + return true; + } + + Debug.LogWarning($"Could not find MonoScript asset '{className}'!"); + script = null; + return false; + } + + + /// + /// Validate the selected to see whether it can + /// produce a valid instance for the specified property. + /// + static bool ValidateSelectedScript(MonoScript selected, FieldInfo fieldInfo, out object instance) + { + Type classType = selected.GetClass(); + if (classType == null) + { + Debug.LogError($"The selected MonoScript '{selected.name}' does not have a matching class!"); + instance = null; + return false; + } + + Type fieldType = fieldInfo.FieldType; + if (!fieldType.IsAssignableFrom(classType)) + { + Debug.LogError($"Cannot use script '{classType.Name}'! Only scripts that implement '{fieldType.Name}' are allowed."); + instance = null; + return false; + } + + instance = Activator.CreateInstance(classType); + return true; + } + + + /// + /// Gets the key (path) of the cache. + /// + static string GetCacheKey(SerializedProperty property) + => $"{property.propertyPath}<{property.serializedObject.targetObject}>"; + } +} diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Editor/ScriptSelectorDrawer.cs.meta b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Editor/ScriptSelectorDrawer.cs.meta new file mode 100644 index 0000000000..6784da5f96 --- /dev/null +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Editor/ScriptSelectorDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 739e17dce77728a4abc4e39d3c2812f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/Ownership.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/Ownership.cs index 99b105a05b..bf165f0cd2 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/Ownership.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/Ownership.cs @@ -1,6 +1,6 @@ using System; -namespace OpenRCT +namespace Lib { /// /// Flags of ownership of a specific tile. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepAction.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepAction.cs index a62384b937..30efc3b8b7 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepAction.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepAction.cs @@ -1,4 +1,4 @@ -namespace OpenRCT +namespace Lib { public enum PeepAction : byte { diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepActionSprite.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepActionSprite.cs index 220d8eb09e..69fcce4f94 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepActionSprite.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepActionSprite.cs @@ -1,4 +1,4 @@ -namespace OpenRCT +namespace Lib { public enum PeepActionSprite : byte { diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepSpriteType.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepSpriteType.cs index 5a60505b62..aa3259433a 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepSpriteType.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepSpriteType.cs @@ -1,4 +1,4 @@ -namespace OpenRCT +namespace Lib { public enum PeepSpriteType : byte { diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepState.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepState.cs index e922b09226..f13572019a 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepState.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepState.cs @@ -1,4 +1,4 @@ -namespace OpenRCT +namespace Lib { public enum PeepState : byte { diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepSubState.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepSubState.cs index e92423e40c..ba61a78bcc 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepSubState.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepSubState.cs @@ -1,4 +1,4 @@ -namespace OpenRCT +namespace Lib { public enum PeepSubState : byte { diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepType.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepType.cs index 0918bbaed1..1cbecb80bf 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepType.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/PeepType.cs @@ -1,4 +1,4 @@ -namespace OpenRCT +namespace Lib { public enum PeepType : byte { diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/SmallSceneryFlags.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/SmallSceneryFlags.cs index 526024e0d4..74e12d7a33 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/SmallSceneryFlags.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/SmallSceneryFlags.cs @@ -1,6 +1,6 @@ using System; -namespace OpenRCT +namespace Lib { /// /// Flags that can be set on a small scenery. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/SpriteType.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/SpriteType.cs index b202c579ba..5f476557ca 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/SpriteType.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/SpriteType.cs @@ -1,4 +1,4 @@ -namespace OpenRCT +namespace Lib { public enum SpriteType { diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/SurfaceSlope.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/SurfaceSlope.cs index 01a9616cde..e66c4c323a 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/SurfaceSlope.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/SurfaceSlope.cs @@ -1,6 +1,6 @@ using System; -namespace OpenRCT +namespace Lib { [Flags] public enum SurfaceSlope : byte diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/TerrainEdgeStyle.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/TerrainEdgeStyle.cs index 70e31e74ad..66e197c1b1 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/TerrainEdgeStyle.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/TerrainEdgeStyle.cs @@ -1,4 +1,4 @@ -namespace OpenRCT +namespace Lib { public enum TerrainEdgeStyle : byte { diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/TerrainSurfaceStyle.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/TerrainSurfaceStyle.cs index d3920d33ee..5568ecb30d 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/TerrainSurfaceStyle.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/TerrainSurfaceStyle.cs @@ -1,4 +1,4 @@ -namespace OpenRCT +namespace Lib { public enum TerrainSurfaceStyle : byte { diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/TileElementType.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/TileElementType.cs index 4097789876..eb46c24c74 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/TileElementType.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Enums/TileElementType.cs @@ -1,6 +1,6 @@ using System; -namespace OpenRCT +namespace Lib { /// /// The type of element. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Graphics/Graphic.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Graphics/Graphic.cs index 8db8a123b9..e97cd95913 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Graphics/Graphic.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Graphics/Graphic.cs @@ -1,6 +1,6 @@ using System; -namespace OpenRCT +namespace Lib { /// /// A small struct that contains RCT graphic information. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Graphics/GraphicExtensions.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Graphics/GraphicExtensions.cs index 995de49447..c245a6eda8 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Graphics/GraphicExtensions.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Graphics/GraphicExtensions.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using UnityEngine; -namespace OpenRCT +namespace Lib { /// /// Extensions for the Graphic struct. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Graphics/GraphicsFactory.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Graphics/GraphicsFactory.cs index 36b0c7a7e4..983b673df2 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Graphics/GraphicsFactory.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Graphics/GraphicsFactory.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using UnityEngine; -namespace OpenRCT +namespace Lib { /// /// Factory for graphics related things in OpenRCT2. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Graphics/PaletteEntry.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Graphics/PaletteEntry.cs index 63001a0039..a99a8dde6a 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Graphics/PaletteEntry.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Graphics/PaletteEntry.cs @@ -1,7 +1,7 @@ using System.Runtime.InteropServices; using UnityEngine; -namespace OpenRCT +namespace Lib { [StructLayout(LayoutKind.Sequential, Size = 4)] public struct PaletteEntry diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Game.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Game.cs index fffcf2a5a4..6ca3a0970a 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Game.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Game.cs @@ -3,7 +3,7 @@ using System.Runtime.InteropServices; #pragma warning disable CA2101 // Specify marshaling for P/Invoke string arguments -> this is deliberate -namespace OpenRCT +namespace Lib { public partial class OpenRCT2 { diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Graphics.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Graphics.cs index 9620241aca..aa8f399aec 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Graphics.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Graphics.cs @@ -1,6 +1,6 @@ using System.Runtime.InteropServices; -namespace OpenRCT +namespace Lib { public partial class OpenRCT2 { diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Map.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Map.cs index 637f09cec3..5ccde8a9c0 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Map.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Map.cs @@ -1,6 +1,6 @@ using System.Runtime.InteropServices; -namespace OpenRCT +namespace Lib { public partial class OpenRCT2 { diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Sprites.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Sprites.cs index 67a14b9562..58fc1811d4 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Sprites.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Sprites.cs @@ -1,7 +1,7 @@ using System.Runtime.InteropServices; using UnityEngine; -namespace OpenRCT +namespace Lib { public partial class OpenRCT2 { diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Tracks.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Tracks.cs new file mode 100644 index 0000000000..cc5b9842f7 --- /dev/null +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Tracks.cs @@ -0,0 +1,58 @@ +using System.Runtime.InteropServices; + + +namespace Lib +{ + public partial class OpenRCT2 + { + /// + /// Returns the amount of path nodes in the pathing route for the specified track type. + /// + [DllImport(PluginFile, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + static extern int GetTrackElementRouteSize(int trackVariant, int typeAndDirection); + + + /// + /// Writes all the path nodes up to size into the array. + /// + [DllImport(PluginFile, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + static extern void GetTrackElementRoute(int trackVariant, int typeAndDirection, [Out] TrackNode[] nodes, int size); + + + /// + /// Gets the path nodes in the pathing route for the specified track type. + /// + /// + /// The track type to retrieve. + /// + /// + /// The pathing information table to use. + /// + /// 0Regular tracks. + /// 1-4Custom routing for chairlifts. + /// 5-8Custom routing for go karts. + /// 9-14Custom routing for mini golf. + /// 15-16Custom routing for reversers. + /// + /// + public static TrackNode[] GetTrackElementRoute(int trackType, int trackVariant) + { + int typeAndDirection = trackType << 2; // direction right now is defaulted to 0; + int size = GetTrackElementRouteSize(trackVariant, typeAndDirection); + + TrackNode[] nodes = new TrackNode[size]; + GetTrackElementRoute(trackVariant, typeAndDirection, nodes, size); + return nodes; + } + + + /// + /// Gets the path nodes in the pathing route for the specified track type. + /// + /// + /// The track type to retrieve. + /// + public static TrackNode[] GetTrackElementRoute(int trackType) + => GetTrackElementRoute(trackType, 0); + } +} diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Tracks.cs.meta b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Tracks.cs.meta new file mode 100644 index 0000000000..25f0478d52 --- /dev/null +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.Tracks.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3304ed262b42d7d4cad57e62abdbcd67 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.cs index 981c1c1e8f..49f92ab57e 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/OpenRCT2.cs @@ -1,7 +1,7 @@ using System.IO; using UnityEngine; -namespace OpenRCT +namespace Lib { public partial class OpenRCT2 : MonoBehaviour { diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/Ptr.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/Ptr.cs index 72f6398fa1..653130108c 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/Ptr.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Imports/Ptr.cs @@ -1,4 +1,4 @@ -namespace OpenRCT +namespace Lib { /// /// Static helper class for pointer information. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/Map.Generation.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/Map.Generation.cs index 3befea178b..95d8b4f0ad 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/Map.Generation.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/Map.Generation.cs @@ -2,8 +2,9 @@ using System; using Generation; using Generation.Retro; using UnityEngine; +using Utilities; -namespace OpenRCT +namespace Lib { public partial class Map { @@ -26,15 +27,14 @@ namespace OpenRCT [SerializeField] TileElementFlags generationFlags = TileElementFlags.All; - [Header("Generators")] - [SerializeReference] IElementGenerator surfaceGenerator = new SurfaceGenerator(); - [SerializeReference] IElementGenerator pathGenerator = new PrefabGenerator(); - [SerializeReference] IElementGenerator trackGenerator = new PrefabGenerator(); - [SerializeReference] IElementGenerator smallSceneryGenerator = new SmallSceneryGenerator(); - [SerializeReference] IElementGenerator entranceGenerator = new PrefabGenerator(); - [SerializeReference] IElementGenerator wallGenerator = new WallGenerator(); - [SerializeReference] IElementGenerator largeSceneryGenerator = new PrefabGenerator(); - [SerializeReference] IElementGenerator bannerGenerator = new PrefabGenerator(); + [SerializeReference, ScriptSelector] IElementGenerator surfaceGenerator = new SurfaceGenerator(); + [SerializeReference, ScriptSelector] IElementGenerator pathGenerator = new PrefabGenerator(); + [SerializeReference, ScriptSelector] IElementGenerator trackGenerator = new TrackGenerator(); + [SerializeReference, ScriptSelector] IElementGenerator smallSceneryGenerator = new SmallSceneryGenerator(); + [SerializeReference, ScriptSelector] IElementGenerator entranceGenerator = new PrefabGenerator(); + [SerializeReference, ScriptSelector] IElementGenerator wallGenerator = new WallGenerator(); + [SerializeReference, ScriptSelector] IElementGenerator largeSceneryGenerator = new PrefabGenerator(); + [SerializeReference, ScriptSelector] IElementGenerator bannerGenerator = new PrefabGenerator(); /// diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/Map.Helpers.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/Map.Helpers.cs index e652412006..dc06209d67 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/Map.Helpers.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/Map.Helpers.cs @@ -1,7 +1,7 @@ using System; using UnityEngine; -namespace OpenRCT +namespace Lib { /// /// The map of the park. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/Map.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/Map.cs index 91760af400..afe6157bec 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/Map.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/Map.cs @@ -1,7 +1,6 @@ -using System; using UnityEngine; -namespace OpenRCT +namespace Lib { /// /// The map of the park. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/MapTile.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/MapTile.cs index e47bb63f57..355304f6c6 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/MapTile.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/MapTile.cs @@ -1,6 +1,6 @@ using System; -namespace OpenRCT +namespace Lib { /// /// A tile struct containing multiple elements. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/PeepController.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/PeepController.cs index 4dce1dc8e1..85dd0b1bfd 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/PeepController.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/PeepController.cs @@ -1,7 +1,7 @@ using System.Linq; using UnityEngine; -namespace OpenRCT +namespace Lib { /// /// Controller which moves and updates all the peeps in the park. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/SpriteController.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/SpriteController.cs index f4d5859595..43cf5773ee 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/SpriteController.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/SpriteController.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using UnityEngine; -namespace OpenRCT +namespace Lib { /// /// Abstract base class for shared code in moving sprites around. @@ -74,7 +74,7 @@ namespace OpenRCT /// protected virtual SpriteObject AddSprite(int index, ref TSprite sprite) { - Vector3 position = Map.CoordsToVector3(sprite.Position); + Vector3 position = sprite.Position; GameObject peepObj = Instantiate(spritePrefab, position, Quaternion.identity, transform); SpriteObject instance = new SpriteObject @@ -108,7 +108,7 @@ namespace OpenRCT obj.lastUpdate = currentUpdateTick; - Vector3 target = Map.CoordsToVector3(sprite.Position); + Vector3 target = sprite.Position; if (obj.towards != target) { diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/VehicleController.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/VehicleController.cs index c1e26e6708..4fd17c8a7b 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/VehicleController.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Map/VehicleController.cs @@ -1,4 +1,4 @@ -namespace OpenRCT +namespace Lib { /// /// Controller which moves and updates all ride vehicles in the park. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/ISprite.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/ISprite.cs index c2f267233d..a522086ad8 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/ISprite.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/ISprite.cs @@ -1,13 +1,21 @@ using UnityEngine; -namespace OpenRCT +namespace Lib { /// /// Generic sprite information. /// public interface ISprite { + /// + /// Returns the sprite id. + /// ushort Id { get; } + + + /// + /// Returns the position of the sprite in Unity coordinates. + /// Vector3 Position { get; } } } diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/Peep.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/Peep.cs index 997b61467e..4ce98ba55b 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/Peep.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/Peep.cs @@ -2,7 +2,7 @@ using System; using System.Runtime.InteropServices; using UnityEngine; -namespace OpenRCT +namespace Lib { /// /// The struct of a peep, which can be either a guest or a staff member. @@ -95,9 +95,9 @@ namespace OpenRCT /// - /// Returns the peep's position in RCT2 coordinates. + /// Returns the peep's position in Unity coordinates. /// public Vector3 Position - => new Vector3(sprite.x, sprite.z, sprite.y); + => Map.CoordsToVector3(sprite.x, sprite.z, sprite.y); } } diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/SpriteBase.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/SpriteBase.cs index d4f3570b75..8e4df28b6e 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/SpriteBase.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/SpriteBase.cs @@ -1,6 +1,6 @@ using System.Runtime.InteropServices; -namespace OpenRCT +namespace Lib { [StructLayout(LayoutKind.Sequential, Size = 31)] public struct SpriteBase diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/SpriteSize.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/SpriteSize.cs index 5c5e25ad69..8afe2c64c5 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/SpriteSize.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/SpriteSize.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; -namespace OpenRCT +namespace Lib { [StructLayout(LayoutKind.Sequential, Size = 4)] public struct SpriteSize diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/Vehicle.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/Vehicle.cs index 67a535db90..dcd90a3b2a 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/Vehicle.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/Sprites/Vehicle.cs @@ -1,7 +1,7 @@ using System.Runtime.InteropServices; using UnityEngine; -namespace OpenRCT +namespace Lib { /// /// The struct of a ride vehicle. @@ -13,7 +13,7 @@ namespace OpenRCT public int x; public int y; public int z; - public byte direction; // 0-31 to indicate direction, 0 = negative x axis + public byte direction; // 0-31 to indicate direction, 0 = negative x axis direction public byte bankRotation; public byte pitchRotation; // this is a index describing what sprite should be used; maybe useless for pitch? @@ -26,10 +26,10 @@ namespace OpenRCT /// - /// Returns the vehicle's position in RCT2 coordinates. + /// Returns the vehicle's position in Unity coordinates. /// public Vector3 Position - => new Vector3(x, z, y); + => Map.CoordsToVector3(x, z, y); /// diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/Data.meta b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/Data.meta new file mode 100644 index 0000000000..80fb6b6644 --- /dev/null +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/Data.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7e8dded0fd3047245a43b019689de347 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/Data/TrackNode.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/Data/TrackNode.cs new file mode 100644 index 0000000000..60b0942d8a --- /dev/null +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/Data/TrackNode.cs @@ -0,0 +1,24 @@ +using System.Runtime.InteropServices; +using UnityEngine; + +namespace Lib +{ + [StructLayout(LayoutKind.Sequential)] + public struct TrackNode + { + public short x; + public short y; + public short z; + public byte direction; // 0-31 to indicate direction, 0 = negative x axis direction + public byte vehicleSprite; + public byte bankRotation; + + + /// + /// The local position of the track node in Unity coordinates, relative + /// to the start of the track element. + /// + public Vector3 LocalPosition + => Map.CoordsToVector3(x, z, y); + } +} diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/Data/TrackNode.cs.meta b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/Data/TrackNode.cs.meta new file mode 100644 index 0000000000..69a2b08823 --- /dev/null +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/Data/TrackNode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6ecf0197a2ffb454a80713ae5e32d883 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/Entries/SmallSceneryEntry.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/Entries/SmallSceneryEntry.cs index 5085244ce7..36cb49435e 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/Entries/SmallSceneryEntry.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/Entries/SmallSceneryEntry.cs @@ -1,6 +1,6 @@ using System.Runtime.InteropServices; -namespace OpenRCT +namespace Lib { /// /// A small scenery entry struct. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/PathElement.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/PathElement.cs index 56bcf84935..69dc9498b2 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/PathElement.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/PathElement.cs @@ -1,4 +1,4 @@ -namespace OpenRCT +namespace Lib { /// /// An element representing a piece of path. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/SmallSceneryElement.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/SmallSceneryElement.cs index e0da983ef0..84a7873060 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/SmallSceneryElement.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/SmallSceneryElement.cs @@ -1,4 +1,4 @@ -namespace OpenRCT +namespace Lib { /// /// An element representing a small scenery piece. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/SurfaceElement.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/SurfaceElement.cs index 31f01f3cdd..519b44a318 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/SurfaceElement.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/SurfaceElement.cs @@ -1,4 +1,4 @@ -namespace OpenRCT +namespace Lib { /// /// An element representing the surface of the map. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/TileElement.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/TileElement.cs index 45f3175b01..7d83db12e2 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/TileElement.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/TileElement.cs @@ -1,9 +1,10 @@ +using System; using System.Runtime.InteropServices; -namespace OpenRCT +namespace Lib { [StructLayout(LayoutKind.Sequential, Size = 16)] - public struct TileElement + public struct TileElement : IEquatable { public byte type; public byte flags; @@ -46,5 +47,77 @@ namespace OpenRCT /// public byte Rotation => (byte)(type & RotationMask); + + + #region Equality overrides + + /// + /// Compares two tile elements to see whether they are equal. + /// + public static bool Equals(ref TileElement left, ref TileElement right) + => (left.type == right.type) + && (left.flags == right.flags) + && (left.baseHeight == right.baseHeight) + && (left.clearanceHeight == right.clearanceHeight) + && (left.slot0x1 == right.slot0x1) + && (left.slot0x2 == right.slot0x2) + && (left.slot0x3 == right.slot0x3) + && (left.slot0x4 == right.slot0x4) + && (left.slot0x5 == right.slot0x5) + && (left.slot0x6 == right.slot0x6) + && (left.slot0x7 == right.slot0x7) + && (left.slot0x8 == right.slot0x8) + && (left.slot0x9 == right.slot0x9) + && (left.slot0xA == right.slot0xA) + && (left.slot0xB == right.slot0xB) + && (left.slot0xC == right.slot0xC); + + + /// + public override bool Equals(object obj) + => (obj is TileElement tile && Equals(ref this, ref tile)); + + + /// + public bool Equals(TileElement other) + => (Equals(ref this, ref other)); + + + /// + public static bool operator ==(TileElement left, TileElement right) + => (Equals(ref left, ref right)); + + + /// + public static bool operator !=(TileElement left, TileElement right) + => (!Equals(ref left, ref right)); + + + /// + /// Autogenerated hash function. + /// + public override int GetHashCode() + { + int hashCode = 437187081; + hashCode = hashCode * -1521134295 + type.GetHashCode(); + hashCode = hashCode * -1521134295 + flags.GetHashCode(); + hashCode = hashCode * -1521134295 + baseHeight.GetHashCode(); + hashCode = hashCode * -1521134295 + clearanceHeight.GetHashCode(); + hashCode = hashCode * -1521134295 + slot0x1.GetHashCode(); + hashCode = hashCode * -1521134295 + slot0x2.GetHashCode(); + hashCode = hashCode * -1521134295 + slot0x3.GetHashCode(); + hashCode = hashCode * -1521134295 + slot0x4.GetHashCode(); + hashCode = hashCode * -1521134295 + slot0x5.GetHashCode(); + hashCode = hashCode * -1521134295 + slot0x6.GetHashCode(); + hashCode = hashCode * -1521134295 + slot0x7.GetHashCode(); + hashCode = hashCode * -1521134295 + slot0x8.GetHashCode(); + hashCode = hashCode * -1521134295 + slot0x9.GetHashCode(); + hashCode = hashCode * -1521134295 + slot0xA.GetHashCode(); + hashCode = hashCode * -1521134295 + slot0xB.GetHashCode(); + hashCode = hashCode * -1521134295 + slot0xC.GetHashCode(); + return hashCode; + } + + #endregion } } diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/TileElementExtensions.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/TileElementExtensions.cs index d74e7972c8..a80d9f46b4 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/TileElementExtensions.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/TileElementExtensions.cs @@ -1,7 +1,7 @@ using System; using UnityEngine; -namespace OpenRCT +namespace Lib { /// /// Extensions for a tile element struct. diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/TrackElement.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/TrackElement.cs index 5aa919e5ec..397f2b5d36 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/TrackElement.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/TrackElement.cs @@ -1,25 +1,68 @@ -namespace OpenRCT +namespace Lib { /// /// An element representing a trackpiece of a ride, or a stall. /// public readonly ref struct TrackElement { + // Mask to get the bits for the scenery quadrant/wall side. + const byte ChainliftMask = 0b10000000; + + + /// + /// The type of the element. In this case a track element. + /// public TileElementType Type => element.Type; + /// + /// Returns true of the track element has a chainlift. + /// + public bool HasChainlift => (element.type & ChainliftMask) != 0; + + + /// + /// Returns the track type index of this track element. + /// + public short TrackType => (short)((element.slot0x2 << 8) + element.slot0x1); + + + /// + /// Returns the index of the tile part of this track element. A multi-tile + /// track-piece will have multiple parts, one for each tile. Also called + /// 'sequence' in OpenRCT2 source code. + /// + public byte PartIndex => element.slot0x3; + + + /// + /// Returns the index of which colour scheme this track element uses. + /// + public byte ColourScheme => element.slot0x4; + + + /// + /// Returns the track type index of this track element. + /// + public short RideIndex => (short)((element.slot0x9 << 8) + element.slot0x8); + + /* 0x1 = TrackType * 0x2 = TrackType * 0x3 = Sequence / Maze - * 0x4 = Sequence / Maze + * 0x4 = ColourScheme / Maze * 0x5 = OnRidePhoto / BrakeBoosterSpeed * 0x6 = StationIndex * 0x7 = Flags2 * 0x8 = RideIndex + * 0x9 = RideIndex */ readonly TileElement element; + /// + /// Wraps the tile element to access the track element information. + /// public TrackElement(ref TileElement element) { this.element = element; diff --git a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/WallElement.cs b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/WallElement.cs index 78812a2079..ea624fc07b 100644 --- a/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/WallElement.cs +++ b/src/openrct2-unity/Assets/Scripts/OpenRCT2/TileElements/WallElement.cs @@ -1,4 +1,4 @@ -namespace OpenRCT +namespace Lib { /// /// An element representing a piece of wall. diff --git a/src/openrct2-unity/Assets/Scripts/Tools/SelectionTool.cs b/src/openrct2-unity/Assets/Scripts/Tools/SelectionTool.cs index 6f8fd73b26..9411aebd52 100644 --- a/src/openrct2-unity/Assets/Scripts/Tools/SelectionTool.cs +++ b/src/openrct2-unity/Assets/Scripts/Tools/SelectionTool.cs @@ -1,4 +1,4 @@ -using OpenRCT; +using Lib; using UI; using UnityEngine; diff --git a/src/openrct2-unity/Assets/Scripts/UI/PeepWindow.cs b/src/openrct2-unity/Assets/Scripts/UI/PeepWindow.cs index a0806d7866..586aceae06 100644 --- a/src/openrct2-unity/Assets/Scripts/UI/PeepWindow.cs +++ b/src/openrct2-unity/Assets/Scripts/UI/PeepWindow.cs @@ -1,4 +1,4 @@ -using OpenRCT; +using Lib; using UnityEngine; using UnityEngine.UI; diff --git a/src/openrct2-unity/Assets/Scripts/UI/WindowManager.cs b/src/openrct2-unity/Assets/Scripts/UI/WindowManager.cs index f4d3b1d28d..0c74115466 100644 --- a/src/openrct2-unity/Assets/Scripts/UI/WindowManager.cs +++ b/src/openrct2-unity/Assets/Scripts/UI/WindowManager.cs @@ -1,4 +1,4 @@ -using OpenRCT; +using Lib; using UnityEngine; diff --git a/src/openrct2-unity/Assets/Scripts/Utilities.meta b/src/openrct2-unity/Assets/Scripts/Utilities.meta new file mode 100644 index 0000000000..57391eeb93 --- /dev/null +++ b/src/openrct2-unity/Assets/Scripts/Utilities.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6753d33824cebd84080a9ca1a7fe9f41 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/openrct2-unity/Assets/Scripts/Maths.cs b/src/openrct2-unity/Assets/Scripts/Utilities/Maths.cs similarity index 100% rename from src/openrct2-unity/Assets/Scripts/Maths.cs rename to src/openrct2-unity/Assets/Scripts/Utilities/Maths.cs diff --git a/src/openrct2-unity/Assets/Scripts/Maths.cs.meta b/src/openrct2-unity/Assets/Scripts/Utilities/Maths.cs.meta similarity index 100% rename from src/openrct2-unity/Assets/Scripts/Maths.cs.meta rename to src/openrct2-unity/Assets/Scripts/Utilities/Maths.cs.meta diff --git a/src/openrct2-unity/Assets/Scripts/Utilities/ScriptSelectorAttribute.cs b/src/openrct2-unity/Assets/Scripts/Utilities/ScriptSelectorAttribute.cs new file mode 100644 index 0000000000..774b7fe413 --- /dev/null +++ b/src/openrct2-unity/Assets/Scripts/Utilities/ScriptSelectorAttribute.cs @@ -0,0 +1,14 @@ +using System; +using UnityEngine; + +namespace Utilities +{ + /// + /// Put this on attributes alongside the -attribute + /// to draw a script selector box and property fields for all its values. + /// + [AttributeUsage(AttributeTargets.Field)] + public sealed class ScriptSelectorAttribute : PropertyAttribute + { + } +} diff --git a/src/openrct2-unity/Assets/Scripts/Utilities/ScriptSelectorAttribute.cs.meta b/src/openrct2-unity/Assets/Scripts/Utilities/ScriptSelectorAttribute.cs.meta new file mode 100644 index 0000000000..2c9b3c1690 --- /dev/null +++ b/src/openrct2-unity/Assets/Scripts/Utilities/ScriptSelectorAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 015154ac7feb23d41a7ebf58a3775021 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/openrct2-unity/Parks/Three Monkeys Park.sv6 b/src/openrct2-unity/Parks/Three Monkeys Park.sv6 new file mode 100644 index 0000000000..9527c44587 Binary files /dev/null and b/src/openrct2-unity/Parks/Three Monkeys Park.sv6 differ diff --git a/src/openrct2-unity/ProjectSettings/QualitySettings.asset b/src/openrct2-unity/ProjectSettings/QualitySettings.asset index cab35ccc42..a45c679e5d 100644 --- a/src/openrct2-unity/ProjectSettings/QualitySettings.asset +++ b/src/openrct2-unity/ProjectSettings/QualitySettings.asset @@ -95,7 +95,7 @@ QualitySettings: skinWeights: 2 textureQuality: 0 anisotropicTextures: 1 - antiAliasing: 0 + antiAliasing: 2 softParticles: 0 softVegetation: 1 realtimeReflectionProbes: 1