From cd3ad220a3c6c2d1c4761c27a1e3e805656ca2bc Mon Sep 17 00:00:00 2001 From: ozonexo3 Date: Sat, 30 Dec 2017 08:54:53 +0100 Subject: [PATCH] v0.515 --- Assets/CielaSpike.meta | 10 + Assets/CielaSpike/Thread Ninja.meta | 10 + .../Thread Ninja/Code Documentation.pdf | Bin 0 -> 62326 bytes .../Thread Ninja/Code Documentation.pdf.meta | 8 + Assets/CielaSpike/Thread Ninja/Example.meta | 10 + .../Thread Ninja/Example/ExampleScene.unity | 366 +++++ .../Example/ExampleScene.unity.meta | 8 + .../Thread Ninja/Example/ExampleScript.cs | 97 ++ .../Example/ExampleScript.cs.meta | 12 + Assets/CielaSpike/Thread Ninja/Ninja.cs | 30 + Assets/CielaSpike/Thread Ninja/Ninja.cs.meta | 12 + Assets/CielaSpike/Thread Ninja/Task.cs | 266 ++++ Assets/CielaSpike/Thread Ninja/Task.cs.meta | 12 + Assets/CielaSpike/Thread Ninja/TaskState.cs | 36 + .../CielaSpike/Thread Ninja/TaskState.cs.meta | 12 + .../ThreadNinjaMonoBehaviourExtensions.cs | 32 + ...ThreadNinjaMonoBehaviourExtensions.cs.meta | 12 + Assets/Editor/BuildWithResources.cs | 18 +- Assets/GFX/Shaders/FaTerrainShader.shader | 29 +- Assets/GFX/Shaders/FaWater.shader | 2 +- Assets/GFX/Shaders/Skybox/FaSkybox.mat | 32 + Assets/GFX/Shaders/Skybox/FaSkybox.mat.meta | 10 + .../GFX/Shaders/Skybox/FaSkyboxShader.shader | 67 + .../Shaders/Skybox/FaSkyboxShader.shader.meta | 10 + Assets/GFX/Shaders/Skybox/RenderSkybox.mat | 79 ++ ...{Skybox.mat.meta => RenderSkybox.mat.meta} | 0 Assets/GFX/Shaders/Skybox/Skybox.mat | 157 --- Assets/GFX/Terrain/ScmapTerrain.asset | Bin 141960 -> 141960 bytes Assets/GFX/Terrain/TerrainShader.mat | 26 +- Assets/GFX/Terrain/WaterShader.mat | 4 +- Assets/GFX/UI/decal_cursor.png | Bin 0 -> 18203 bytes Assets/GFX/UI/decal_cursor.png.meta | 82 ++ Assets/GFX/UI/prop_cursor.png | Bin 0 -> 18559 bytes Assets/GFX/UI/prop_cursor.png.meta | 82 ++ Assets/MapEditor.unity | 1199 ++++++++++++++--- Assets/Scripts/Camera/CameraControlerCam.cs | 23 +- Assets/Scripts/Common/EditorVersion.cs | 2 +- .../Shader/OzoneDeferredDecal.shader | 2 + Assets/Scripts/HazardX SCMAP Code/Map.cs | 1 + .../Scripts/HazardX SCMAP Code/SkyboxData.cs | 8 + .../Scripts/Ozone SCMAP Code/MapLuaParser.cs | 1 + .../Scripts/Ozone SCMAP Code/ScmapEditor.cs | 37 +- Assets/Scripts/Ozone SCMAP Code/Skybox.meta | 10 + .../Skybox/ProceduralSkybox.cs | 103 ++ .../Skybox/ProceduralSkybox.cs.meta | 13 + .../Texture/GenerateControlTex.cs | 165 ++- Assets/Scripts/Painting/BrushGenerator.cs | 4 + Assets/Scripts/Placement/PlacementManager.cs | 136 +- .../Selection/SelectionManager_Symmetry.cs | 7 +- Assets/Scripts/UI/AppMenu/AppMenu.cs | 4 + Assets/Scripts/UI/Lists/ResourceObject.cs | 2 +- .../Scripts/UI/Tools/Decals/DecalSettings.cs | 76 +- .../UI/Tools/Decals/DecalsInfo_Selection.cs | 2 + .../Scripts/UI/Tools/Decals/DecalsInfo_UI.cs | 69 + Assets/Scripts/UI/Tools/LightingInfo.cs | 7 +- .../UI/Tools/Markers/NewMarkersInfo.cs | 17 + Assets/Scripts/UI/Tools/TerrainInfo.cs | 197 ++- Assets/Scripts/UI/Tools/WaterInfo.cs | 2 +- Assets/Scripts/UI/UiElements/UiTextField.cs | 24 +- Assets/Scripts/UI/Windows/ResourceBrowser.cs | 21 + .../HistoryObjects/HistoryTerrainHeight.cs | 1 + FAForeverMapEditor.Editor.Plugins.csproj | 1 + FAForeverMapEditor.Editor.csproj | 1 + FAForeverMapEditor.Plugins.csproj | 1 + FAForeverMapEditor.csproj | 7 + 65 files changed, 3088 insertions(+), 586 deletions(-) create mode 100644 Assets/CielaSpike.meta create mode 100644 Assets/CielaSpike/Thread Ninja.meta create mode 100644 Assets/CielaSpike/Thread Ninja/Code Documentation.pdf create mode 100644 Assets/CielaSpike/Thread Ninja/Code Documentation.pdf.meta create mode 100644 Assets/CielaSpike/Thread Ninja/Example.meta create mode 100644 Assets/CielaSpike/Thread Ninja/Example/ExampleScene.unity create mode 100644 Assets/CielaSpike/Thread Ninja/Example/ExampleScene.unity.meta create mode 100644 Assets/CielaSpike/Thread Ninja/Example/ExampleScript.cs create mode 100644 Assets/CielaSpike/Thread Ninja/Example/ExampleScript.cs.meta create mode 100644 Assets/CielaSpike/Thread Ninja/Ninja.cs create mode 100644 Assets/CielaSpike/Thread Ninja/Ninja.cs.meta create mode 100644 Assets/CielaSpike/Thread Ninja/Task.cs create mode 100644 Assets/CielaSpike/Thread Ninja/Task.cs.meta create mode 100644 Assets/CielaSpike/Thread Ninja/TaskState.cs create mode 100644 Assets/CielaSpike/Thread Ninja/TaskState.cs.meta create mode 100644 Assets/CielaSpike/Thread Ninja/ThreadNinjaMonoBehaviourExtensions.cs create mode 100644 Assets/CielaSpike/Thread Ninja/ThreadNinjaMonoBehaviourExtensions.cs.meta create mode 100644 Assets/GFX/Shaders/Skybox/FaSkybox.mat create mode 100644 Assets/GFX/Shaders/Skybox/FaSkybox.mat.meta create mode 100644 Assets/GFX/Shaders/Skybox/FaSkyboxShader.shader create mode 100644 Assets/GFX/Shaders/Skybox/FaSkyboxShader.shader.meta create mode 100644 Assets/GFX/Shaders/Skybox/RenderSkybox.mat rename Assets/GFX/Shaders/Skybox/{Skybox.mat.meta => RenderSkybox.mat.meta} (100%) delete mode 100644 Assets/GFX/Shaders/Skybox/Skybox.mat create mode 100644 Assets/GFX/UI/decal_cursor.png create mode 100644 Assets/GFX/UI/decal_cursor.png.meta create mode 100644 Assets/GFX/UI/prop_cursor.png create mode 100644 Assets/GFX/UI/prop_cursor.png.meta create mode 100644 Assets/Scripts/Ozone SCMAP Code/Skybox.meta create mode 100644 Assets/Scripts/Ozone SCMAP Code/Skybox/ProceduralSkybox.cs create mode 100644 Assets/Scripts/Ozone SCMAP Code/Skybox/ProceduralSkybox.cs.meta diff --git a/Assets/CielaSpike.meta b/Assets/CielaSpike.meta new file mode 100644 index 00000000..3cd94032 --- /dev/null +++ b/Assets/CielaSpike.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 142c089bb4b245a4e944cfdcdf8fa59b +folderAsset: yes +timeCreated: 1514375241 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/CielaSpike/Thread Ninja.meta b/Assets/CielaSpike/Thread Ninja.meta new file mode 100644 index 00000000..dbcfc2a2 --- /dev/null +++ b/Assets/CielaSpike/Thread Ninja.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a17e087d811c9ed499ee8b63149eb487 +folderAsset: yes +timeCreated: 1514375241 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/CielaSpike/Thread Ninja/Code Documentation.pdf b/Assets/CielaSpike/Thread Ninja/Code Documentation.pdf new file mode 100644 index 0000000000000000000000000000000000000000..321c7dd4f3599bffb014d623c655c3647500f3c4 GIT binary patch literal 62326 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 B5m5jD literal 0 HcmV?d00001 diff --git a/Assets/CielaSpike/Thread Ninja/Code Documentation.pdf.meta b/Assets/CielaSpike/Thread Ninja/Code Documentation.pdf.meta new file mode 100644 index 00000000..446fb19d --- /dev/null +++ b/Assets/CielaSpike/Thread Ninja/Code Documentation.pdf.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ea0c7cf2694656545a83fc2e65877958 +timeCreated: 18446744011573954816 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/CielaSpike/Thread Ninja/Example.meta b/Assets/CielaSpike/Thread Ninja/Example.meta new file mode 100644 index 00000000..c5d72f1e --- /dev/null +++ b/Assets/CielaSpike/Thread Ninja/Example.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 744b4212906e2ba4da9a36d855e2da2e +folderAsset: yes +timeCreated: 1514375241 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/CielaSpike/Thread Ninja/Example/ExampleScene.unity b/Assets/CielaSpike/Thread Ninja/Example/ExampleScene.unity new file mode 100644 index 00000000..e0d2c25a --- /dev/null +++ b/Assets/CielaSpike/Thread Ninja/Example/ExampleScene.unity @@ -0,0 +1,366 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 8 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.2, g: 0.2, b: 0.2, a: 1} + m_AmbientEquatorColor: {r: 0.2, g: 0.2, b: 0.2, a: 1} + m_AmbientGroundColor: {r: 0.2, g: 0.2, b: 0.2, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} +--- !u!196 &3 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!157 &4 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 9 + m_Resolution: 1 + m_BakeResolution: 50 + m_TextureWidth: 1024 + m_TextureHeight: 1024 + m_AO: 1 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 0 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 1 + m_BakeBackend: 0 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 0 +--- !u!1 &5 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 8} + - component: {fileID: 13} + - component: {fileID: 14} + - component: {fileID: 12} + - component: {fileID: 19} + m_Layer: 0 + m_Name: Cube + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &6 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 9} + - component: {fileID: 17} + m_Layer: 0 + m_Name: Point light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!1 &7 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 10} + - component: {fileID: 11} + - component: {fileID: 16} + - component: {fileID: 18} + - component: {fileID: 15} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 5} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &9 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 6} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 10} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!4 &10 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 7} + m_LocalRotation: {x: -0.28549448, y: 0.36395362, z: -0.118255705, w: -0.87866163} + m_LocalPosition: {x: 1, y: 1, z: -1} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 9} + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!20 &11 +Camera: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 7} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0.019607844} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 100 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!23 &12 +MeshRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 5} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_Materials: + - {fileID: 10302, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 0 + 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!33 &13 +MeshFilter: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 5} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!65 &14 +BoxCollider: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 5} + 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!81 &15 +AudioListener: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 7} + m_Enabled: 1 +--- !u!92 &16 +Behaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 7} + m_Enabled: 1 +--- !u!108 &17 +Light: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 6} + m_Enabled: 1 + serializedVersion: 8 + m_Type: 2 + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_Intensity: 1.6097561 + m_Range: 10 + m_SpotAngle: 30 + m_CookieSize: 10 + m_Shadows: + m_Type: 0 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_Lightmapping: 1 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!124 &18 +Behaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 7} + m_Enabled: 1 +--- !u!114 &19 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 5} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2bdc4c227df9cca48bf03fb1efb90211, type: 3} + m_Name: + m_EditorClassIdentifier: diff --git a/Assets/CielaSpike/Thread Ninja/Example/ExampleScene.unity.meta b/Assets/CielaSpike/Thread Ninja/Example/ExampleScene.unity.meta new file mode 100644 index 00000000..c0aff32c --- /dev/null +++ b/Assets/CielaSpike/Thread Ninja/Example/ExampleScene.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a8488491c7764e742b365a62b90d5d13 +timeCreated: 18446744011573954816 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/CielaSpike/Thread Ninja/Example/ExampleScript.cs b/Assets/CielaSpike/Thread Ninja/Example/ExampleScript.cs new file mode 100644 index 00000000..5e9fd748 --- /dev/null +++ b/Assets/CielaSpike/Thread Ninja/Example/ExampleScript.cs @@ -0,0 +1,97 @@ +using System; +using UnityEngine; +using System.Collections; +using CielaSpike; +using System.Threading; + +public class ExampleScript : MonoBehaviour { + + void Start() + { + StartCoroutine(StartExamples()); + } + + void Update() + { + // rotate cube to see if main thread has been blocked; + transform.Rotate(Vector3.up, Time.deltaTime * 180); + } + + IEnumerator StartExamples() + { + Task task; + LogExample("Blocking Thread"); + this.StartCoroutineAsync(Blocking(), out task); + yield return StartCoroutine(task.Wait()); + LogState(task); + + LogExample("Cancellation"); + this.StartCoroutineAsync(Cancellation(), out task); + yield return new WaitForSeconds(2.0f); + task.Cancel(); + LogState(task); + + LogExample("Error Handling"); + yield return this.StartCoroutineAsync(ErrorHandling(), out task); + LogState(task); + } + + IEnumerator Blocking() + { + LogAsync("Thread.Sleep(5000); -> See if cube rotates."); + Thread.Sleep(5000); + LogAsync("Jump to main thread."); + yield return Ninja.JumpToUnity; + LogSync("Thread.Sleep(5000); -> See if cube rotates."); + yield return new WaitForSeconds(0.1f); + Thread.Sleep(5000); + LogSync("Jump to background."); + yield return Ninja.JumpBack; + LogAsync("Yield WaitForSeconds on background."); + yield return new WaitForSeconds(3.0f); + } + + IEnumerator Cancellation() + { + LogAsync("Running heavy task..."); + for (int i = 0; i < int.MaxValue; i++) + { + // do some heavy ops; + // ... + } + + yield break; + } + + IEnumerator ErrorHandling() + { + LogAsync("Running heavy task..."); + for (int i = 0; i < int.MaxValue; i++) + { + if (i > int.MaxValue / 2) + throw new Exception("Some error from background thread..."); + } + + yield break; + } + + private void LogAsync(string msg) + { + Debug.Log("[Async]" + msg); + } + + private void LogState(Task task) + { + Debug.Log("[State]" + task.State); + } + + private void LogSync(string msg) + { + Debug.Log("[Sync]" + msg); + } + + private void LogExample(string msg) + { + Debug.Log("[Example]" + msg); + } +} diff --git a/Assets/CielaSpike/Thread Ninja/Example/ExampleScript.cs.meta b/Assets/CielaSpike/Thread Ninja/Example/ExampleScript.cs.meta new file mode 100644 index 00000000..f64acb23 --- /dev/null +++ b/Assets/CielaSpike/Thread Ninja/Example/ExampleScript.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2bdc4c227df9cca48bf03fb1efb90211 +timeCreated: 18446744011573954816 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/CielaSpike/Thread Ninja/Ninja.cs b/Assets/CielaSpike/Thread Ninja/Ninja.cs new file mode 100644 index 00000000..8c41f448 --- /dev/null +++ b/Assets/CielaSpike/Thread Ninja/Ninja.cs @@ -0,0 +1,30 @@ +using UnityEngine; + +using System.Linq; +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace CielaSpike +{ + /// + /// Ninja jumps between threads. + /// + public static class Ninja + { + /// + /// Yield return it to switch to Unity main thread. + /// + public static readonly object JumpToUnity; + /// + /// Yield return it to switch to background thread. + /// + public static readonly object JumpBack; + + static Ninja() + { + JumpToUnity = new object(); + JumpBack = new object(); + } + } +} \ No newline at end of file diff --git a/Assets/CielaSpike/Thread Ninja/Ninja.cs.meta b/Assets/CielaSpike/Thread Ninja/Ninja.cs.meta new file mode 100644 index 00000000..6ff9645f --- /dev/null +++ b/Assets/CielaSpike/Thread Ninja/Ninja.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ae3a816481baf5040ae16b5fb874b886 +timeCreated: 18446744011573954816 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/CielaSpike/Thread Ninja/Task.cs b/Assets/CielaSpike/Thread Ninja/Task.cs new file mode 100644 index 00000000..125deb55 --- /dev/null +++ b/Assets/CielaSpike/Thread Ninja/Task.cs @@ -0,0 +1,266 @@ +using UnityEngine; + +using System.Linq; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace CielaSpike +{ + /// + /// Represents an async task. + /// + public class Task : IEnumerator + { + // implements IEnumerator to make it usable by StartCoroutine; + #region IEnumerator Interface + /// + /// The current iterator yield return value. + /// + public object Current { get; private set; } + + /// + /// Runs next iteration. + /// + /// true for continue, otherwise false. + public bool MoveNext() + { + return OnMoveNext(); + } + + public void Reset() + { + // Reset method not supported by iterator; + throw new System.NotSupportedException( + "Not support calling Reset() on iterator."); + } + #endregion + + // inner running state used by state machine; + private enum RunningState + { + Init, + RunningAsync, + PendingYield, + ToBackground, + RunningSync, + CancellationRequested, + Done, + Error + } + + // routine user want to run; + private readonly IEnumerator _innerRoutine; + + // current running state; + private RunningState _state; + // last running state; + private RunningState _previousState; + // temporary stores current yield return value + // until we think Unity coroutine engine is OK to get it; + private object _pendingCurrent; + + /// + /// Gets state of the task. + /// + public TaskState State + { + get + { + switch (_state) + { + case RunningState.CancellationRequested: + return TaskState.Cancelled; + case RunningState.Done: + return TaskState.Done; + case RunningState.Error: + return TaskState.Error; + case RunningState.Init: + return TaskState.Init; + default: + return TaskState.Running; + } + } + } + + /// + /// Gets exception during running. + /// + public System.Exception Exception { get; private set; } + + public Task(IEnumerator routine) + { + _innerRoutine = routine; + // runs into background first; + _state = RunningState.Init; + } + + /// + /// Cancel the task till next iteration; + /// + public void Cancel() + { + if (State == TaskState.Running) + { + GotoState(RunningState.CancellationRequested); + } + } + + /// + /// A co-routine that waits the task. + /// + public IEnumerator Wait() + { + while (State == TaskState.Running) + yield return null; + } + + // thread safely switch running state; + private void GotoState(RunningState state) + { + if (_state == state) return; + + lock (this) + { + // maintainance the previous state; + _previousState = _state; + _state = state; + } + } + + // thread safely save yield returned value; + private void SetPendingCurrentObject(object current) + { + lock (this) + { + _pendingCurrent = current; + } + } + + // actual MoveNext method, controls running state; + private bool OnMoveNext() + { + // no running for null; + if (_innerRoutine == null) + return false; + + // set current to null so that Unity not get same yield value twice; + Current = null; + + // loops until the inner routine yield something to Unity; + while (true) + { + // a simple state machine; + switch (_state) + { + // first, goto background; + case RunningState.Init: + GotoState(RunningState.ToBackground); + break; + // running in background, wait a frame; + case RunningState.RunningAsync: + return true; + + // runs on main thread; + case RunningState.RunningSync: + MoveNextUnity(); + break; + + // need switch to background; + case RunningState.ToBackground: + GotoState(RunningState.RunningAsync); + // call the thread launcher; + MoveNextAsync(); + return true; + + // something was yield returned; + case RunningState.PendingYield: + if (_pendingCurrent == Ninja.JumpBack) + { + // do not break the loop, switch to background; + GotoState(RunningState.ToBackground); + } + else if (_pendingCurrent == Ninja.JumpToUnity) + { + // do not break the loop, switch to main thread; + GotoState(RunningState.RunningSync); + } + else + { + // not from the Ninja, then Unity should get noticed, + // Set to Current property to achieve this; + Current = _pendingCurrent; + + // yield from background thread, or main thread? + if (_previousState == RunningState.RunningAsync) + { + // if from background thread, + // go back into background in the next loop; + _pendingCurrent = Ninja.JumpBack; + } + else + { + // otherwise go back to main thread the next loop; + _pendingCurrent = Ninja.JumpToUnity; + } + + // end this iteration and Unity get noticed; + return true; + } + break; + + // done running, pass false to Unity; + case RunningState.Done: + case RunningState.CancellationRequested: + default: + return false; + } + } + } + + // background thread launcher; + private void MoveNextAsync() + { + ThreadPool.QueueUserWorkItem( + new WaitCallback(BackgroundRunner)); + } + + // background thread function; + private void BackgroundRunner(object state) + { + // just run the sync version on background thread; + MoveNextUnity(); + } + + // run next iteration on main thread; + private void MoveNextUnity() + { + try + { + // run next part of the user routine; + var result = _innerRoutine.MoveNext(); + + if (result) + { + // something has been yield returned, handle it; + SetPendingCurrentObject(_innerRoutine.Current); + GotoState(RunningState.PendingYield); + } + else + { + // user routine simple done; + GotoState(RunningState.Done); + } + } + catch (System.Exception ex) + { + // exception handling, save & log it; + this.Exception = ex; + Debug.LogError(string.Format("{0}\n{1}", ex.Message, ex.StackTrace)); + // then terminates the task; + GotoState(RunningState.Error); + } + } + } +} \ No newline at end of file diff --git a/Assets/CielaSpike/Thread Ninja/Task.cs.meta b/Assets/CielaSpike/Thread Ninja/Task.cs.meta new file mode 100644 index 00000000..8b021e98 --- /dev/null +++ b/Assets/CielaSpike/Thread Ninja/Task.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0620f67d7a00dd948afeb7d9187ccb8a +timeCreated: 18446744011573954816 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/CielaSpike/Thread Ninja/TaskState.cs b/Assets/CielaSpike/Thread Ninja/TaskState.cs new file mode 100644 index 00000000..7eee246f --- /dev/null +++ b/Assets/CielaSpike/Thread Ninja/TaskState.cs @@ -0,0 +1,36 @@ +using UnityEngine; + +using System.Linq; +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace CielaSpike +{ + /// + /// Running state of a task. + /// + public enum TaskState + { + /// + /// Task has been created, but has not begun. + /// + Init, + /// + /// Task is running. + /// + Running, + /// + /// Task has finished properly. + /// + Done, + /// + /// Task has been cancelled. + /// + Cancelled, + /// + /// Task terminated by errors. + /// + Error + } +} \ No newline at end of file diff --git a/Assets/CielaSpike/Thread Ninja/TaskState.cs.meta b/Assets/CielaSpike/Thread Ninja/TaskState.cs.meta new file mode 100644 index 00000000..ebed5ef1 --- /dev/null +++ b/Assets/CielaSpike/Thread Ninja/TaskState.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 66b22140171e51044805701223458fb0 +timeCreated: 18446744011573954816 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/CielaSpike/Thread Ninja/ThreadNinjaMonoBehaviourExtensions.cs b/Assets/CielaSpike/Thread Ninja/ThreadNinjaMonoBehaviourExtensions.cs new file mode 100644 index 00000000..6ab44605 --- /dev/null +++ b/Assets/CielaSpike/Thread Ninja/ThreadNinjaMonoBehaviourExtensions.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections; +using UnityEngine; + +namespace CielaSpike +{ + public static class ThreadNinjaMonoBehaviourExtensions + { + /// + /// Start a co-routine on a background thread. + /// + /// Gets a task object with more control on the background thread. + /// + public static Coroutine StartCoroutineAsync( + this MonoBehaviour behaviour, IEnumerator routine, + out Task task) + { + task = new Task(routine); + return behaviour.StartCoroutine(task); + } + + /// + /// Start a co-routine on a background thread. + /// + public static Coroutine StartCoroutineAsync( + this MonoBehaviour behaviour, IEnumerator routine) + { + Task t; + return StartCoroutineAsync(behaviour, routine, out t); + } + } +} \ No newline at end of file diff --git a/Assets/CielaSpike/Thread Ninja/ThreadNinjaMonoBehaviourExtensions.cs.meta b/Assets/CielaSpike/Thread Ninja/ThreadNinjaMonoBehaviourExtensions.cs.meta new file mode 100644 index 00000000..327bfb8f --- /dev/null +++ b/Assets/CielaSpike/Thread Ninja/ThreadNinjaMonoBehaviourExtensions.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5e4ae1c36bb70b94bb93ebc3a07bbde3 +timeCreated: 18446744011573954816 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Editor/BuildWithResources.cs b/Assets/Editor/BuildWithResources.cs index 296dcb8c..8c37e5a3 100644 --- a/Assets/Editor/BuildWithResources.cs +++ b/Assets/Editor/BuildWithResources.cs @@ -63,10 +63,22 @@ public static void ChangeModelVerts() [MenuItem("Build/Do Action")] public static void ChangeModelVerts() { - ScmapEditor From = UnityEditor.Selection.gameObjects[0].GetComponent(); - ScmapEditor To = UnityEditor.Selection.gameObjects[1].GetComponent(); + //ScmapEditor From = UnityEditor.Selection.gameObjects[0].GetComponent(); + //ScmapEditor To = UnityEditor.Selection.gameObjects[1].GetComponent(); - To.DefaultSkyboxData = From.DefaultSkyboxData; + //To.DefaultSkyboxData = From.DefaultSkyboxData; + + string path = EditorUtility.OpenFilePanel("Skybox", "", ""); + + + if (string.IsNullOrEmpty(path)) + return; + + string data = System.IO.File.ReadAllText(path); + ScmapEditor To = UnityEditor.Selection.activeGameObject.GetComponent(); + SkyboxData NewSkybox = UnityEngine.JsonUtility.FromJson(data); + To.DefaultSkyboxData = NewSkybox.Data; + EditorUtility.SetDirty(To); } } \ No newline at end of file diff --git a/Assets/GFX/Shaders/FaTerrainShader.shader b/Assets/GFX/Shaders/FaTerrainShader.shader index 034bdb25..d660934b 100644 --- a/Assets/GFX/Shaders/FaTerrainShader.shader +++ b/Assets/GFX/Shaders/FaTerrainShader.shader @@ -4,17 +4,13 @@ Shader "MapEditor/FaTerrainShader" { Properties { _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1) _Shininess ("Shininess", Range (0.03, 1)) = 0.078125 - [MaterialToggle] _Water("Has Water", Int) = 0 + //[MaterialToggle] _Water("Has Water", Int) = 0 [MaterialToggle] _Grid("Grid", Int) = 0 [MaterialToggle] _Slope("Slope", Int) = 0 [MaterialToggle] _UseSlopeTex("Use Slope Data", Int) = 0 _SlopeTex ("Slope data", 2D) = "black" {} [MaterialToggle] _TTerrainXP("_TTerrainXP", Int) = 0 - - _WaterLevel ("Water Level", float) = 0.078125 - _DepthLevel ("Depth Level", float) = 0.078125 - _AbyssLevel ("Abyss Level", float) = 0.078125 - + // set by terrain engine _Control ("Control (RGBA)", 2D) = "black" {} _ControlXP ("ControlXP (RGBA)", 2D) = "black" {} @@ -128,11 +124,10 @@ Properties { sampler2D _MyGrabTexture3; sampler2D _WaterRam; half _Shininess; - half _WaterLevel; - half _DepthLevel, _AbyssLevel; fixed4 _Abyss; fixed4 _Deep; int _Water; + float _WaterLevel; int _Slope, _UseSlopeTex; sampler2D _SlopeTex; @@ -199,7 +194,6 @@ Properties { float4 waterTexture = tex2D( _UtilitySamplerC, IN.uv_Control * float2(1, -1) + float2(1 / (_WaterScaleX * 1), 1 / (_WaterScaleZ * 1) + 1)); - //float WaterDepth = (_WaterLevel - IN.worldPos.y) / (_WaterLevel - _AbyssLevel); float WaterDepth = waterTexture.g; float2 UVCtrl = IN.uv_Control * fixed2(1, -1) + half2(0, 1); @@ -342,7 +336,8 @@ Properties { if(_Grid > 0){ - fixed4 GridColor = tex2D (_GridTexture, IN.uv_Control * _GridScale - float2(-0.00, -0.00)); + float2 GridUv = IN.uv_Control * _GridScale; + fixed4 GridColor = tex2D (_GridTexture, IN.uv_Control * _GridScale); fixed4 GridFinal = fixed4(0,0,0,GridColor.a); if(_GridCamDist < 1){ GridFinal.rgb = lerp(GridFinal.rgb, fixed3(1,1,1), GridColor.r * lerp(1, 0, _GridCamDist)); @@ -350,11 +345,19 @@ Properties { GridFinal.rgb = lerp(GridFinal.rgb, fixed3(0,1,0), GridColor.b * lerp(0, 1, _GridCamDist)); } else{ - GridFinal.rgb = lerp(GridFinal.rgb, fixed3(0,1,0), GridColor.b); + GridFinal.rgb = lerp(GridFinal.rgb, fixed3(0,1,0), GridColor.b); } - + + GridFinal *= GridColor.a; + + half CenterGridSize = lerp(0.005, 0.015, _GridCamDist) / _GridScale; + if(IN.uv_Control.x > 0.5 - CenterGridSize && IN.uv_Control.x < 0.5 + CenterGridSize) + GridFinal.rgb = fixed3(0.4,1,0); + else if(IN.uv_Control.y > 0.5 - CenterGridSize && IN.uv_Control.y < 0.5 + CenterGridSize) + GridFinal.rgb = fixed3(0.4,1,0); + //col.rgb = lerp(col.rgb, GridFinal.rgb, GridColor.a); - Emit += GridFinal * GridColor.a; + Emit += GridFinal; } if(_Brush > 0){ diff --git a/Assets/GFX/Shaders/FaWater.shader b/Assets/GFX/Shaders/FaWater.shader index 6fa4d4d8..993e3ff4 100644 --- a/Assets/GFX/Shaders/FaWater.shader +++ b/Assets/GFX/Shaders/FaWater.shader @@ -33,7 +33,7 @@ Shader "MapEditor/FaWater" { } Blend SrcAlpha OneMinusSrcAlpha - + Offset 0, -20000 CGPROGRAM diff --git a/Assets/GFX/Shaders/Skybox/FaSkybox.mat b/Assets/GFX/Shaders/Skybox/FaSkybox.mat new file mode 100644 index 00000000..87ccd0a2 --- /dev/null +++ b/Assets/GFX/Shaders/Skybox/FaSkybox.mat @@ -0,0 +1,32 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: FaSkybox + m_Shader: {fileID: 4800000, guid: 284e4a8023473e04bb9f05b4eba4631a, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _HorizonHeight: 1.5 + - _ZenithHeight: 4 + m_Colors: + - _Horizon: {r: 0.5, g: 0.5, b: 0.5, a: 1} + - _HorizonColor: {r: 1, g: 0, b: 0, a: 1} + - _Zenith: {r: 0.5, g: 0.5, b: 0.5, a: 1} + - _ZenithColor: {r: 0, g: 0.16666651, b: 1, a: 1} diff --git a/Assets/GFX/Shaders/Skybox/FaSkybox.mat.meta b/Assets/GFX/Shaders/Skybox/FaSkybox.mat.meta new file mode 100644 index 00000000..85cc1707 --- /dev/null +++ b/Assets/GFX/Shaders/Skybox/FaSkybox.mat.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f8f8ef8907eadd14a82038f7c09cf9fe +timeCreated: 1514552045 +licenseType: Free +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GFX/Shaders/Skybox/FaSkyboxShader.shader b/Assets/GFX/Shaders/Skybox/FaSkyboxShader.shader new file mode 100644 index 00000000..f5898b37 --- /dev/null +++ b/Assets/GFX/Shaders/Skybox/FaSkyboxShader.shader @@ -0,0 +1,67 @@ +// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' + +Shader "MapEditor/FaSkybox" +{ + Properties + { + _MainTex ("Texture", 2D) = "white" {} + _HorizonHeight ("Grid Scale", Float) = 0 + _HorizonColor ("Horizon Color", Color) = (0.5, 0.5, 0.5, 1) + _ZenithHeight ("Grid Scale", Float) = 256 + _ZenithColor ("Zenith Color", Color) = (0.5, 0.5, 0.5, 1) + } + SubShader + { + Tags { "RenderType"="Opaque" } + LOD 100 + ZTest Less + + Pass + { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + // make fog work + + #include "UnityCG.cginc" + + struct appdata + { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + }; + + struct v2f + { + float2 uv : TEXCOORD0; + float4 vertex : SV_POSITION; + float4 WorldPos : TEXCOORD1; + }; + + sampler2D _MainTex; + float4 _MainTex_ST; + half _HorizonHeight, _ZenithHeight; + fixed4 _HorizonColor, _ZenithColor; + + + v2f vert (appdata v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.WorldPos = mul(unity_ObjectToWorld, v.vertex); + o.uv = TRANSFORM_TEX(v.uv, _MainTex); + return o; + } + + fixed4 frag (v2f i) : SV_Target + { + fixed4 col = tex2D(_MainTex, i.uv); + + col = lerp(_HorizonColor, _ZenithColor, smoothstep(_HorizonHeight, _ZenithHeight, i.WorldPos.y)); + + return col; + } + ENDCG + } + } +} diff --git a/Assets/GFX/Shaders/Skybox/FaSkyboxShader.shader.meta b/Assets/GFX/Shaders/Skybox/FaSkyboxShader.shader.meta new file mode 100644 index 00000000..9e850a96 --- /dev/null +++ b/Assets/GFX/Shaders/Skybox/FaSkyboxShader.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 284e4a8023473e04bb9f05b4eba4631a +timeCreated: 1514551693 +licenseType: Free +ShaderImporter: + externalObjects: {} + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/GFX/Shaders/Skybox/RenderSkybox.mat b/Assets/GFX/Shaders/Skybox/RenderSkybox.mat new file mode 100644 index 00000000..d8ae5884 --- /dev/null +++ b/Assets/GFX/Shaders/Skybox/RenderSkybox.mat @@ -0,0 +1,79 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: RenderSkybox + m_Shader: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 1000 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Tex: + m_Texture: {fileID: 8900000, guid: 4462d82eabe117945b29ff9b909c5d44, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _Exposure: 1 + - _Glossiness: 0.5 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _Rotation: 0 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _Tint: {r: 0.5, g: 0.5, b: 0.5, a: 0.5} diff --git a/Assets/GFX/Shaders/Skybox/Skybox.mat.meta b/Assets/GFX/Shaders/Skybox/RenderSkybox.mat.meta similarity index 100% rename from Assets/GFX/Shaders/Skybox/Skybox.mat.meta rename to Assets/GFX/Shaders/Skybox/RenderSkybox.mat.meta diff --git a/Assets/GFX/Shaders/Skybox/Skybox.mat b/Assets/GFX/Shaders/Skybox/Skybox.mat deleted file mode 100644 index 7e0511b9..00000000 --- a/Assets/GFX/Shaders/Skybox/Skybox.mat +++ /dev/null @@ -1,157 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!21 &2100000 -Material: - serializedVersion: 6 - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_Name: Skybox - m_Shader: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0} - m_ShaderKeywords: - m_LightmapFlags: 5 - m_CustomRenderQueue: 1000 - stringTagMap: {} - m_SavedProperties: - serializedVersion: 2 - m_TexEnvs: - data: - first: - name: _MainTex - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _BumpMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _DetailNormalMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _Tex - second: - m_Texture: {fileID: 8900000, guid: 4462d82eabe117945b29ff9b909c5d44, type: 3} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _ParallaxMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _OcclusionMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _EmissionMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _DetailMask - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _DetailAlbedoMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - data: - first: - name: _MetallicGlossMap - second: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Floats: - data: - first: - name: _SrcBlend - second: 1 - data: - first: - name: _DstBlend - second: 0 - data: - first: - name: _Cutoff - second: .5 - data: - first: - name: _Exposure - second: 1 - data: - first: - name: _Parallax - second: .0199999996 - data: - first: - name: _ZWrite - second: 1 - data: - first: - name: _Glossiness - second: .5 - data: - first: - name: _BumpScale - second: 1 - data: - first: - name: _OcclusionStrength - second: 1 - data: - first: - name: _DetailNormalMapScale - second: 1 - data: - first: - name: _UVSec - second: 0 - data: - first: - name: _Mode - second: 0 - data: - first: - name: _Metallic - second: 0 - data: - first: - name: _Rotation - second: 0 - m_Colors: - data: - first: - name: _EmissionColor - second: {r: 0, g: 0, b: 0, a: 1} - data: - first: - name: _Color - second: {r: 1, g: 1, b: 1, a: 1} - data: - first: - name: _Tint - second: {r: .5, g: .5, b: .5, a: .5} diff --git a/Assets/GFX/Terrain/ScmapTerrain.asset b/Assets/GFX/Terrain/ScmapTerrain.asset index 18de13f46a2beeea5a602a4fa51bc14fcc6a903c..d20c91067426cb9211a34d891f69ab7deb1af1eb 100644 GIT binary patch literal 141960 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

Up1RG`*p4zp2{3f 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 d8jiC9QXlHhym@Qmzx~Qba`s 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.text = EditorBuildVersion; diff --git a/Assets/Scripts/GFX/OzoneDecals/Shader/OzoneDeferredDecal.shader b/Assets/Scripts/GFX/OzoneDecals/Shader/OzoneDeferredDecal.shader index 61c981c1..08b62975 100644 --- a/Assets/Scripts/GFX/OzoneDecals/Shader/OzoneDeferredDecal.shader +++ b/Assets/Scripts/GFX/OzoneDecals/Shader/OzoneDeferredDecal.shader @@ -51,6 +51,7 @@ Shader "Ozone/Deferred Decal" sampler2D _Glow; uniform sampler2D _WaterRam; uniform sampler2D _UtilitySamplerC; + uniform int _Water; uniform float _WaterScaleX, _WaterScaleZ; @@ -73,6 +74,7 @@ Shader "Ozone/Deferred Decal" float4 waterTexture = tex2D( _UtilitySamplerC, wpos.xz * half2(0.009765 / (_WaterScaleX / 1024.0), -0.009765 / (_WaterScaleZ / 1024.0))); + if(_Water > 0) color.rgb = ApplyWaterColor( waterTexture.g, color.rgb); color.a *= blend * tex2D(_Mask, texUV).r; diff --git a/Assets/Scripts/HazardX SCMAP Code/Map.cs b/Assets/Scripts/HazardX SCMAP Code/Map.cs index 5714e3b0..102b3ea4 100644 --- a/Assets/Scripts/HazardX SCMAP Code/Map.cs +++ b/Assets/Scripts/HazardX SCMAP Code/Map.cs @@ -719,6 +719,7 @@ public bool Load(string Filename) } else { + AdditionalSkyboxData.Data = new SkyboxData.SkyboxValues(ScmapEditor.Current.DefaultSkyboxData); //AdditionalSkyboxData.LoadDefaults(); } diff --git a/Assets/Scripts/HazardX SCMAP Code/SkyboxData.cs b/Assets/Scripts/HazardX SCMAP Code/SkyboxData.cs index 7f2b2226..013ff154 100644 --- a/Assets/Scripts/HazardX SCMAP Code/SkyboxData.cs +++ b/Assets/Scripts/HazardX SCMAP Code/SkyboxData.cs @@ -110,6 +110,14 @@ public void CopyFrom(SkyboxValues from) CirrusLayers = from.CirrusLayers; Clouds7 = from.Clouds7; + + UpdateSize(); + } + + public void UpdateSize() + { + Position = ScmapEditor.WorldPosToScmap( MapLuaParser.Current.MapCenterPoint); + Scale = Mathf.Max(ScmapEditor.Current.map.Width, ScmapEditor.Current.map.Height) * 2.288245f; } } #endregion diff --git a/Assets/Scripts/Ozone SCMAP Code/MapLuaParser.cs b/Assets/Scripts/Ozone SCMAP Code/MapLuaParser.cs index d21ac4a6..545ac761 100644 --- a/Assets/Scripts/Ozone SCMAP Code/MapLuaParser.cs +++ b/Assets/Scripts/Ozone SCMAP Code/MapLuaParser.cs @@ -98,6 +98,7 @@ public static bool IsMapLoaded public void ResetUI() { + EditMenu.ButtonFunction("Map"); EditMenu.gameObject.SetActive(false); Background.SetActive(true); diff --git a/Assets/Scripts/Ozone SCMAP Code/ScmapEditor.cs b/Assets/Scripts/Ozone SCMAP Code/ScmapEditor.cs index 27c52a05..da0c4c27 100644 --- a/Assets/Scripts/Ozone SCMAP Code/ScmapEditor.cs +++ b/Assets/Scripts/Ozone SCMAP Code/ScmapEditor.cs @@ -20,6 +20,7 @@ public class ScmapEditor : MonoBehaviour public Transform WaterLevel; public ResourceBrowser ResBrowser; public Light Sun; + public ProceduralSkybox Skybox; public Material TerrainMaterial; public Material WaterMaterial; public PostProcessingProfile PostProcessing; @@ -95,7 +96,6 @@ public void UpdateLighting() Shader.SetGlobalColor("_SunAmbience", new Color(map.SunAmbience.x * 0.5f, map.SunAmbience.y * 0.5f, map.SunAmbience.z * 0.5f, 1)); Shader.SetGlobalColor("_ShadowColor", new Color(map.ShadowFillColor.x * 0.5f, map.ShadowFillColor.y * 0.5f, map.ShadowFillColor.z * 0.5f, 1)); - Shader.SetGlobalColor("_SpecularColor", new Color(map.SpecularColor.x * 0.5f, map.SpecularColor.y * 0.5f, map.SpecularColor.z * 0.5f, map.SpecularColor.w * 0.5f)); } @@ -114,6 +114,7 @@ public IEnumerator LoadScmapFile() if (map.Load(path)) { UpdateLighting(); + Skybox.LoadSkybox(); } else { @@ -166,11 +167,6 @@ public IEnumerator LoadScmapFile() TerrainMaterial.SetTexture("_TerrainNormal", map.UncompressedNormalmapTex); Shader.SetGlobalTexture("_UtilitySamplerC", map.UncompressedWatermapTex); - //WaterMaterial.SetTexture("_UtilitySamplerC", map.UncompressedWatermapTex); - //WaterMaterial.SetFloat("_WaterScaleX", xRes); - //WaterMaterial.SetFloat("_WaterScaleZ", zRes); - //TerrainMaterial.SetFloat("_WaterScaleX", xRes); - //TerrainMaterial.SetFloat("_WaterScaleZ", zRes); Shader.SetGlobalFloat("_WaterScaleX", xRes); Shader.SetGlobalFloat("_WaterScaleZ", xRes); @@ -188,7 +184,7 @@ public IEnumerator LoadScmapFile() Teren.gameObject.name = "TERRAIN"; Teren.materialType = Terrain.MaterialType.Custom; Teren.materialTemplate = TerrainMaterial; - Teren.heightmapPixelError = 5f; + Teren.heightmapPixelError = 4f; Teren.basemapDistance = 10000; Teren.castShadows = false; Teren.drawTreesAndFoliage = false; @@ -343,10 +339,11 @@ public void SetWater() //Shader.SetGlobalVector("waterLerp", map.Water.WaveTextures); - TerrainMaterial.SetFloat("_WaterLevel", map.Water.Elevation / 10.0f); - TerrainMaterial.SetFloat("_DepthLevel", map.Water.ElevationDeep / 10.0f); - TerrainMaterial.SetFloat("_AbyssLevel", map.Water.ElevationAbyss / 10.0f); - TerrainMaterial.SetInt("_Water", map.Water.HasWater ? 1 : 0); + Shader.SetGlobalFloat("_WaterLevel", map.Water.Elevation / 10.0f); + //TerrainMaterial.SetFloat("_DepthLevel", map.Water.ElevationDeep / 10.0f); + //TerrainMaterial.SetFloat("_AbyssLevel", map.Water.ElevationAbyss / 10.0f); + //TerrainMaterial.SetInt("_Water", map.Water.HasWater ? 1 : 0); + Shader.SetGlobalInt("_Water", map.Water.HasWater ? 1 : 0); } public void SetWaterTextures() @@ -624,11 +621,7 @@ public void SaveScmapFile() map.VersionMinor = 60; - map.AdditionalSkyboxData.Data.Position = WorldPosToScmap(MapLuaParser.Current.MapCenterPoint); - - //map.AdditionalSkyboxData.Data.Position.y = Mathf.Clamp(LowestElevation - 1, 0, 128); - //map.AdditionalSkyboxData.Data.Scale.y = Mathf.Max(map.Width, map.Height) * 2.288245f; - + map.AdditionalSkyboxData.Data.UpdateSize(); } else if(map.VersionMinor >= 60) { @@ -636,6 +629,7 @@ public void SaveScmapFile() { map.AdditionalSkyboxData.Data.CopyFrom(DefaultSkyboxData); } + map.AdditionalSkyboxData.Data.UpdateSize(); map.VersionMinor = 56; } @@ -860,6 +854,14 @@ public static Vector3 SnapToSmallGrid(Vector3 Pos) return Pos; } + public static Vector3 SnapMarker(Vector3 Pos, int ID) + { + bool Water = ID == 1 || ID == 2 || ID == 3; + + return SnapToGridCenter(Pos, true, !Water); + + } + public static Vector3 SnapToGridCenter(Vector3 Pos, bool SampleHeight = false, bool MinimumWaterLevel = false) { Pos.x += 0.1f; @@ -885,7 +887,8 @@ public static Vector3 SnapToGridCenter(Vector3 Pos, bool SampleHeight = false, b public static Vector3 ClampToWater(Vector3 Pos) { - Pos.y = Mathf.Clamp(Pos.y, GetWaterLevel(), 10000); + if (Current.map.Water.HasWater) + Pos.y = Mathf.Clamp(Pos.y, GetWaterLevel(), 10000); return Pos; } diff --git a/Assets/Scripts/Ozone SCMAP Code/Skybox.meta b/Assets/Scripts/Ozone SCMAP Code/Skybox.meta new file mode 100644 index 00000000..310914fb --- /dev/null +++ b/Assets/Scripts/Ozone SCMAP Code/Skybox.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e4aa85dc6235d7047b7c31767b4a0cc1 +folderAsset: yes +timeCreated: 1514551570 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Ozone SCMAP Code/Skybox/ProceduralSkybox.cs b/Assets/Scripts/Ozone SCMAP Code/Skybox/ProceduralSkybox.cs new file mode 100644 index 00000000..cb5c2559 --- /dev/null +++ b/Assets/Scripts/Ozone SCMAP Code/Skybox/ProceduralSkybox.cs @@ -0,0 +1,103 @@ +//******************************** +// +// * Procedural skybox mesh generator for FAF Map Editor +// * Copyright ozonexo3 2017 +// +//******************************** + +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class ProceduralSkybox : MonoBehaviour { + + public MeshFilter Mf; + public Material Mat; + + SkyboxData SkyData; + public void LoadSkybox() + { + SkyData = ScmapEditor.Current.map.AdditionalSkyboxData; + + CreateMesh(); + + transform.position = ScmapEditor.ScmapPosToWorld(SkyData.Data.Position) + Vector3.up * (SkyData.Data.HorizonHeight * 0.1f); + transform.localScale = Vector3.one * (SkyData.Data.Scale * 0.1f); + + Mat.SetFloat("_HorizonHeight", SkyData.Data.HorizonHeight * 0.1f); + Mat.SetColor("_HorizonColor", SkyData.Data.HorizonColor); + Mat.SetFloat("_ZenithHeight", SkyData.Data.ZenithHeight * 0.1f); + Mat.SetColor("_ZenithColor", SkyData.Data.ZenithColor); + } + + void CreateMesh() + { + Mesh newMesh = new Mesh(); + List Verts = new List(); + List Uvs = new List(); + List Tris = new List(); + + float SphereLerp = 1f - ((SkyData.Data.SubtractHeight * 2) / Mathf.PI); + + Vector3[] Positions = new Vector3[SkyData.Data.SubdivisionsHeight]; + for (int h = 0; h < SkyData.Data.SubdivisionsHeight; h++) + { + float Lerp = h / ((float)SkyData.Data.SubdivisionsHeight - 1f); + Positions[h] = Vector3.Lerp( + new Vector3(1 - Lerp, 0, 0), + Quaternion.Euler(Vector3.forward * Lerp * 90) * Vector3.right, + SphereLerp); + + + } + + + for (int i = 0; i < SkyData.Data.SubdivisionsAxis; i++) + { + float AngleLerp = i / ((float)SkyData.Data.SubdivisionsAxis); + for (int h = 0; h < SkyData.Data.SubdivisionsHeight; h++) + { + float Lerp = h / ((float)SkyData.Data.SubdivisionsHeight - 1f); + + Verts.Add(Quaternion.Euler(Vector3.up * (360 * AngleLerp)) * Positions[h]); + Vector3 UvOffset = Quaternion.Euler(Vector3.forward * (360 * AngleLerp)) * (Vector3.right * (Lerp * 0.5f)); + Uvs.Add(new Vector2(0.5f + UvOffset.x, 0.5f + UvOffset.y)); + + if(i > 0 && h > 0) + { + int CountOffset = i * SkyData.Data.SubdivisionsHeight; + Tris.Add(CountOffset + h); + Tris.Add(CountOffset + h - 1); + Tris.Add(CountOffset + h - (SkyData.Data.SubdivisionsHeight + 1)); + + Tris.Add(CountOffset + h); + Tris.Add(CountOffset + h - (SkyData.Data.SubdivisionsHeight + 1)); + Tris.Add(CountOffset + h - (SkyData.Data.SubdivisionsHeight)); + } + } + } + + for (int h = 0; h < SkyData.Data.SubdivisionsHeight; h++) + { + if (h > 0) + { + int CountOffset = (SkyData.Data.SubdivisionsAxis - 1) * SkyData.Data.SubdivisionsHeight; + Tris.Add(CountOffset + h); + Tris.Add(CountOffset + h - (CountOffset + 1)); + Tris.Add(CountOffset + h - 1); + + + Tris.Add(CountOffset + h); + Tris.Add(CountOffset + h - (CountOffset)); + Tris.Add(CountOffset + h - (CountOffset + 1)); + + } + } + + + newMesh.SetVertices(Verts); + newMesh.SetTriangles(Tris, 0); + newMesh.RecalculateNormals(); + Mf.sharedMesh = newMesh; + } +} \ No newline at end of file diff --git a/Assets/Scripts/Ozone SCMAP Code/Skybox/ProceduralSkybox.cs.meta b/Assets/Scripts/Ozone SCMAP Code/Skybox/ProceduralSkybox.cs.meta new file mode 100644 index 00000000..6df16880 --- /dev/null +++ b/Assets/Scripts/Ozone SCMAP Code/Skybox/ProceduralSkybox.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 671c7432897376c4c87ae6caa26e1713 +timeCreated: 1514551578 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Ozone SCMAP Code/Texture/GenerateControlTex.cs b/Assets/Scripts/Ozone SCMAP Code/Texture/GenerateControlTex.cs index 246ff331..d1eccf1b 100644 --- a/Assets/Scripts/Ozone SCMAP Code/Texture/GenerateControlTex.cs +++ b/Assets/Scripts/Ozone SCMAP Code/Texture/GenerateControlTex.cs @@ -1,5 +1,7 @@ using UnityEngine; using System.Collections; +using CielaSpike; +using System.Threading; public class GenerateControlTex : MonoBehaviour { @@ -15,16 +17,23 @@ public static void StopAllTasks() { if (GeneratingNormalTex) Current.StopCoroutine(NormalCoroutine); - if(GeneratingWaterTex) + if (GeneratingWaterTex) Current.StopCoroutine(WaterCoroutine); } #region Water - static bool GeneratingWaterTex = false; + static bool GeneratingWaterTex + { + get + { + return WaterCoroutine != null; + } + } static bool BufforWaterTex = false; static Coroutine WaterCoroutine; - public static void GenerateWater(){ + public static void GenerateWater() + { if (GeneratingWaterTex) { BufforWaterTex = true; @@ -35,8 +44,22 @@ public static void GenerateWater(){ public IEnumerator GeneratingWater() { - GeneratingWaterTex = true; - Color[] AllColors = ScmapEditor.Current.map.UncompressedWatermapTex.GetPixels(); + Task task; + this.StartCoroutineAsync(GeneratingWaterTask(), out task); + yield return StartCoroutine(task.Wait()); + + WaterCoroutine = null; + yield return null; + + if (BufforWaterTex) + { + BufforWaterTex = false; + WaterCoroutine = Current.StartCoroutine(Current.GeneratingWater()); + } + } + + public IEnumerator GeneratingWaterTask() + { float WaterHeight = ScmapEditor.Current.map.Water.Elevation * 0.1f; if (WaterHeight == 0) @@ -45,47 +68,54 @@ public IEnumerator GeneratingWater() float DeepDifference = (WaterHeight - WaterDeep) / WaterHeight; - int Width = ScmapEditor.Current.map.UncompressedWatermapTex.width; - int Height = ScmapEditor.Current.map.UncompressedWatermapTex.height; + int i = 0; int x = 0; int y = 0; float WaterDepth = 0; - int counter = 0; + + yield return Ninja.JumpToUnity; + int Width = ScmapEditor.Current.map.UncompressedWatermapTex.width; + int Height = ScmapEditor.Current.map.UncompressedWatermapTex.height; + Color[] AllColors = ScmapEditor.Current.map.UncompressedWatermapTex.GetPixels(); + float[,] HeightmapPixels = ScmapEditor.Current.Teren.terrainData.GetHeights(0, 0, ScmapEditor.Current.Teren.terrainData.heightmapWidth, ScmapEditor.Current.Teren.terrainData.heightmapHeight); + int HeightmapWidth = ScmapEditor.Current.Teren.terrainData.heightmapWidth - 1; + int HeightmapHeight = ScmapEditor.Current.Teren.terrainData.heightmapHeight - 1; + + yield return Ninja.JumpBack; for (x = 0; x < Width; x++) { for (y = 0; y < Height; y++) { - i = x + y * Width; + i = y + x * Height; - WaterDepth = ScmapEditor.Current.Data.GetInterpolatedHeight((x + 0.5f) / (Width + 1f), 1f - (y + 0.5f) / (Height + 1f)); + //WaterDepth = ScmapEditor.Current.Data.GetInterpolatedHeight((x + 0.5f) / (Width + 1f), 1f - (y + 0.5f) / (Height + 1f)); + int LerpX = (int)(HeightmapWidth * (1f - (x) / ((float)Width))); + int LerpY = (int)(HeightmapHeight * ((y) / ((float)Height))); + + if (LerpX < 0) LerpX = 0; + else if (LerpX >= HeightmapWidth) + LerpX = HeightmapWidth - 1; + + if (LerpY < 0) LerpY = 0; + else if (LerpY >= HeightmapHeight) + LerpY = HeightmapHeight - 1; + + WaterDepth = HeightmapPixels[LerpX, LerpY] + HeightmapPixels[LerpX + 1, LerpY] + HeightmapPixels[LerpX, LerpY + 1] + HeightmapPixels[LerpX + 1, LerpY + 1]; + WaterDepth /= 4; + WaterDepth *= 16; WaterDepth = (WaterHeight - WaterDepth) / WaterHeight; WaterDepth /= DeepDifference; AllColors[i] = new Color(AllColors[i].r, Mathf.Clamp01(WaterDepth), (1f - Mathf.Clamp01(WaterDepth * 100f)), 0); - - counter++; - if (counter > 40000) - { - counter = 0; - yield return null; - } } } + yield return Ninja.JumpToUnity; ScmapEditor.Current.map.UncompressedWatermapTex.SetPixels(AllColors); ScmapEditor.Current.map.UncompressedWatermapTex.Apply(false); - - yield return null; - GeneratingWaterTex = false; - - if (BufforWaterTex) - { - BufforWaterTex = false; - Current.StartCoroutine(Current.GeneratingWater()); - } } #endregion @@ -106,12 +136,17 @@ public static void GenerateNormal() - static bool GeneratingNormalTex = false; + static bool GeneratingNormalTex + { + get + { + return NormalCoroutine != null; + } + } static bool BufforNormalTex = false; public IEnumerator GeneratingNormal() { - GeneratingNormalTex = true; ScmapEditor.Current.TerrainMaterial.SetFloat("_GeneratingNormal", 1); Color[] AllColors = ScmapEditor.Current.map.UncompressedNormalmapTex.GetPixels(); @@ -130,31 +165,28 @@ public IEnumerator GeneratingNormal() { i = x + y * ScmapEditor.Current.map.UncompressedNormalmapTex.width; Normal = ScmapEditor.Current.Data.GetInterpolatedNormal((x + 0.5f) / (Width), 1f - (y + 0.5f) / (Height)); - AllColors[i] = new Color(0, 1f - (Normal.z * 0.5f + 0.5f), 0, Normal.x * 0.5f + 0.5f); counter++; - if(counter > 40000) + if (counter > 40000) { counter = 0; yield return null; } } - } ScmapEditor.Current.map.UncompressedNormalmapTex.SetPixels(AllColors); ScmapEditor.Current.map.UncompressedNormalmapTex.Apply(false); yield return null; - GeneratingNormalTex = false; ScmapEditor.Current.TerrainMaterial.SetFloat("_GeneratingNormal", 0); if (BufforNormalTex) { BufforNormalTex = false; - Current.StartCoroutine(Current.GeneratingNormal()); + NormalCoroutine = Current.StartCoroutine(Current.GeneratingNormal()); } } @@ -164,7 +196,7 @@ public IEnumerator GeneratingNormal() public void GenerateSlopeTexture() { - if(SlopeData == null || SlopeData.width != ScmapEditor.Current.map.Width || SlopeData.height != ScmapEditor.Current.map.Height) + if (SlopeData == null || SlopeData.width != ScmapEditor.Current.map.Width || SlopeData.height != ScmapEditor.Current.map.Height) { SlopeData = new Texture2D(ScmapEditor.Current.map.Width, ScmapEditor.Current.map.Height, TextureFormat.RGB24, false); SlopeData.filterMode = FilterMode.Point; @@ -177,35 +209,55 @@ public void GenerateSlopeTexture() } else { - StartCoroutine(GeneratingSlope()); + SlopeTask = StartCoroutine(GeneratingSlope()); } } - static bool GeneratingSlopeTex = false; + static Coroutine SlopeTask; + static bool GeneratingSlopeTex + { + get + { + return SlopeTask != null; + } + } static bool BufforSlopeTex = false; public float FlatHeight = 0.000045f; public float NonFlatHeight = 0.0022f; public float UnpassableHeight = 0.005f; + static float[,] SlopeHeightmapPixels; + IEnumerator GeneratingSlope() { - GeneratingSlopeTex = true; //ScmapEditor.Current.TerrainMaterial.SetFloat("_UseSlopeTex", 0); + SlopeHeightmapPixels = ScmapEditor.Current.Teren.terrainData.GetHeights(0, 0, ScmapEditor.Current.Teren.terrainData.heightmapWidth, ScmapEditor.Current.Teren.terrainData.heightmapHeight); + Task task; + this.StartCoroutineAsync(GeneratingSlopeTask(), out task); + yield return StartCoroutine(task.Wait()); + + SlopeTask = null; + if (BufforSlopeTex) + { + BufforSlopeTex = false; + SlopeTask = StartCoroutine(GeneratingSlope()); + } + } + + IEnumerator GeneratingSlopeTask() + { Color Flat = new Color(0, 0.8f, 0, 1); Color LowAngle = new Color(0.3f, 0.89f, 0, 1); Color HighAngle = new Color(0.6f, 0.9f, 0, 1); Color Unpassable = new Color(0.9f, 0, 0, 1); Color[] Pixels = new Color[ScmapEditor.Current.map.Width * ScmapEditor.Current.map.Height]; - float[,] HeightmapPixels = ScmapEditor.Current.Teren.terrainData.GetHeights(0, 0, ScmapEditor.Current.Teren.terrainData.heightmapWidth, ScmapEditor.Current.Teren.terrainData.heightmapHeight); - int x = 0; int y = 0; int i = 0; - int counter = 0; for (x = 0; x < ScmapEditor.Current.map.Width; x++) @@ -214,19 +266,16 @@ IEnumerator GeneratingSlope() { i = y + x * ScmapEditor.Current.map.Height; - float Slope0 = HeightmapPixels[x, y]; - float Slope1 = HeightmapPixels[x + 1, y]; - float Slope2 = HeightmapPixels[x, y + 1]; - float Slope3 = HeightmapPixels[x + 1, y + 1]; + float Slope0 = SlopeHeightmapPixels[x, y]; + float Slope1 = SlopeHeightmapPixels[x + 1, y]; + float Slope2 = SlopeHeightmapPixels[x, y + 1]; + float Slope3 = SlopeHeightmapPixels[x + 1, y + 1]; float Min = Mathf.Min(Slope0, Slope1, Slope2, Slope3); float Max = Mathf.Max(Slope0, Slope1, Slope2, Slope3); float Slope = Mathf.Abs(Max - Min); - //Pixels[i] = Color.Lerp(Color.black, Color.white, Slope / 0.008f); - - if (Slope < FlatHeight) Pixels[i] = Flat; else if (Slope < NonFlatHeight) @@ -235,33 +284,17 @@ IEnumerator GeneratingSlope() Pixels[i] = HighAngle; else Pixels[i] = Unpassable; - - counter++; - if (counter > 80000) - { - counter = 0; - yield return null; - } } } + + yield return Ninja.JumpToUnity; SlopeData.SetPixels(Pixels); SlopeData.Apply(false); - ScmapEditor.Current.TerrainMaterial.SetTexture("_SlopeTex", SlopeData); ScmapEditor.Current.TerrainMaterial.SetFloat("_UseSlopeTex", 1); - yield return null; - GeneratingSlopeTex = false; - - - if (BufforSlopeTex) - { - BufforSlopeTex = false; - StartCoroutine(GeneratingSlope()); - } + //yield return null; } - - } diff --git a/Assets/Scripts/Painting/BrushGenerator.cs b/Assets/Scripts/Painting/BrushGenerator.cs index ee211721..af186e12 100644 --- a/Assets/Scripts/Painting/BrushGenerator.cs +++ b/Assets/Scripts/Painting/BrushGenerator.cs @@ -28,6 +28,10 @@ public class BrushGenerator : MonoBehaviour public int[] PaintImageWidths; public int[] PaintImageHeights; + public AnimationCurve HeightmapPaintStrength; + public AnimationCurve HeightmapBlurStrength; + public AnimationCurve HeightmapSharpenStrength; + public Color GetPixel(int id, int x, int y) { return Pixels[id][x + y]; diff --git a/Assets/Scripts/Placement/PlacementManager.cs b/Assets/Scripts/Placement/PlacementManager.cs index f6e4fefd..a86df0c5 100644 --- a/Assets/Scripts/Placement/PlacementManager.cs +++ b/Assets/Scripts/Placement/PlacementManager.cs @@ -29,6 +29,19 @@ private void Awake() public LayerMask RaycastMask; public Camera Cam; + static bool _SnapToWater = false; + public static bool SnapToWater + { + set + { + _SnapToWater = value; + } + get + { + return _SnapToWater; + } + } + int PlaceAngle = 0; @@ -50,6 +63,7 @@ public static void BeginPlacement(GameObject Prefab, System.Action PlaceAction, bool ResetTransform = true) + { + BeginPlacement(Prefab, PlaceAction, ResetTransform); + + Current.PlacementObject.transform.localPosition = Position; + Current.PlacementObject.transform.localRotation = OldRot; + Current.PlacementObject.transform.localScale = OldScale; + + Current.UpdateSymmetryObjects(); + + Current.Place(); + Clear(); + } + + + int LastSym = 0; //float LastTolerance; public Matrix4x4[] SymmetryMatrix; + public bool[] InvertRotation; public GameObject[] PlacementSymmetry; public void GenerateSymmetry() { @@ -239,51 +293,67 @@ public void GenerateSymmetry() { case 1: // X SymmetryMatrix = new Matrix4x4[1]; + InvertRotation = new bool[1]; SymmetryMatrix[0] = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(-1, 1, 1)); + InvertRotation[0] = true; break; case 2: // Z SymmetryMatrix = new Matrix4x4[1]; + InvertRotation = new bool[1]; SymmetryMatrix[0] = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1, 1, -1)); + InvertRotation[0] = true; break; case 3: // XZ SymmetryMatrix = new Matrix4x4[1]; + InvertRotation = new bool[1]; SymmetryMatrix[0] = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(-1, 1, -1)); + InvertRotation[0] = false; break; case 4: // X Z XZ SymmetryMatrix = new Matrix4x4[3]; + InvertRotation = new bool[3]; SymmetryMatrix[0] = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(-1, 1, 1)); + InvertRotation[0] = true; - SymmetryMatrix[1] = new Matrix4x4(); SymmetryMatrix[1] = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1, 1, -1)); + InvertRotation[1] = true; - SymmetryMatrix[2] = new Matrix4x4(); SymmetryMatrix[2] = SymmetryMatrix[0] * SymmetryMatrix[1]; + InvertRotation[2] = false; //SymmetryMatrix[2] = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(-1, 1, -1)); break; case 5:// Diagonal1 SymmetryMatrix = new Matrix4x4[1]; + InvertRotation = new bool[1]; SymmetryMatrix[0] = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(Vector3.up * 90), new Vector3(-1, 1, 1)); + InvertRotation[0] = true; break; case 6: // Diagonal 2 SymmetryMatrix = new Matrix4x4[1]; + InvertRotation = new bool[1]; SymmetryMatrix[0] = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(Vector3.down * 90), new Vector3(-1, 1, 1)); + InvertRotation[0] = true; break; case 7: // Diagonal 3 SymmetryMatrix = new Matrix4x4[3]; + InvertRotation = new bool[3]; SymmetryMatrix[0] = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(Vector3.up * 90), new Vector3(-1, 1, 1)); - + InvertRotation[0] = true; SymmetryMatrix[1] = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(Vector3.down * 90), new Vector3(-1, 1, 1)); - + InvertRotation[1] = true; SymmetryMatrix[2] = SymmetryMatrix[0] * SymmetryMatrix[1]; + InvertRotation[2] = false; break; case 8: // Rotation int RotCount = PlayerPrefs.GetInt("SymmetryAngleCount", 2) - 1; float angle = 360.0f / (float)(RotCount + 1); SymmetryMatrix = new Matrix4x4[RotCount]; + InvertRotation = new bool[RotCount]; for (int i = 0; i < RotCount; i++) { SymmetryMatrix[i] = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(Vector3.up * (angle * (i + 1))), Vector3.one); + InvertRotation[i] = false; } break; default: diff --git a/Assets/Scripts/Selection/SelectionManager_Symmetry.cs b/Assets/Scripts/Selection/SelectionManager_Symmetry.cs index 6a19c6cb..e1c80889 100644 --- a/Assets/Scripts/Selection/SelectionManager_Symmetry.cs +++ b/Assets/Scripts/Selection/SelectionManager_Symmetry.cs @@ -133,7 +133,12 @@ public void OffsetPosition(Vector3 Offset) Current.AffectedGameObjects[Ids[i]].transform.localPosition = ScmapEditor.SnapToGridCenter(Positions[i] + Offset, true, Current.SnapToWater); SelectionRings[i].transform.localPosition = Current.AffectedGameObjects[Ids[i]].transform.localPosition; }*/ - Vector3 NewPos = ScmapEditor.SnapToGridCenter(Positions[i] + Offset, true, Current.SnapToWater); + + Vector3 NewPos = Vector3.zero; + if (Current.LastControlType == SelectionControlTypes.Marker) + NewPos = ScmapEditor.SnapMarker(Positions[i] + Offset, Current.AffectedTypes[Ids[i]]); + else + NewPos = ScmapEditor.SnapToGridCenter(Positions[i] + Offset, true, Current.SnapToWater); SelectionRings[i].transform.localPosition = NewPos; if (CustomSnapAction != null) diff --git a/Assets/Scripts/UI/AppMenu/AppMenu.cs b/Assets/Scripts/UI/AppMenu/AppMenu.cs index 7dbdb371..cf02d68c 100644 --- a/Assets/Scripts/UI/AppMenu/AppMenu.cs +++ b/Assets/Scripts/UI/AppMenu/AppMenu.cs @@ -92,6 +92,9 @@ public void MenuButton(string func) case "Donate": Application.OpenURL("https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=LUYMTPBDH5V4E&lc=GB&item_name=FAF%20Map%20Editor¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"); break; + case "Shortcuts": + Application.OpenURL("https://wiki.faforever.com/index.php?title=FA_Forever_Map_Editor#Useful_shortuts"); + break; case "PlayMap": if (MapLuaParser.IsMapLoaded) { @@ -311,6 +314,7 @@ public void OpenRecentMapNo() MapLuaParser.Current.FolderName = PlayerPrefs.GetString(LoadRecentMaps.FolderPath + LoadRecentMaps.RecentMapSelected, ""); MapLuaParser.Current.FolderParentPath = PlayerPrefs.GetString(LoadRecentMaps.ParentPath + LoadRecentMaps.RecentMapSelected, ""); + MapLuaParser.Current.LoadFile(); } diff --git a/Assets/Scripts/UI/Lists/ResourceObject.cs b/Assets/Scripts/UI/Lists/ResourceObject.cs index 3e1599c3..4244555b 100644 --- a/Assets/Scripts/UI/Lists/ResourceObject.cs +++ b/Assets/Scripts/UI/Lists/ResourceObject.cs @@ -28,6 +28,6 @@ public void Clicked(){ public void OnBeginDrag(){ ResourceBrowser.DragedObject = this; //Cursor.SetCursor ((Texture2D)GetComponent ().texture, Vector2.zero, CursorMode.Auto); - Cursor.SetCursor(ResourceBrowser.Current.CursorImage, Vector2.zero, CursorMode.Auto); + Cursor.SetCursor(ResourceBrowser.Current.GetCursorImage(), Vector2.zero, CursorMode.Auto); } } diff --git a/Assets/Scripts/UI/Tools/Decals/DecalSettings.cs b/Assets/Scripts/UI/Tools/Decals/DecalSettings.cs index c68fa7f2..52484279 100644 --- a/Assets/Scripts/UI/Tools/Decals/DecalSettings.cs +++ b/Assets/Scripts/UI/Tools/Decals/DecalSettings.cs @@ -10,10 +10,19 @@ namespace EditMap { public class DecalSettings : MonoBehaviour { + public GameObject TextureObject; + public GameObject TypeObject; + public RawImage Texture1; public InputField Texture1Path; public RawImage Texture2; public InputField Texture2Path; + public Text Texture1Name; + public Text Texture2Name; + public Color TextureEmptyColor; + public Color TextureGoodColor; + public Color TextureUnusedColor; + public UiTextField CutOff; public UiTextField NearCutOff; public Dropdown DecalType; @@ -21,6 +30,8 @@ public class DecalSettings : MonoBehaviour public GameObject CreateSelected; public Button SelectAllBtn; + + static Decal.DecalSharedSettings Loaded; public static Decal.DecalSharedSettings GetLoaded @@ -56,6 +67,7 @@ public void Load(Decal.DecalSharedSettings DecalSettings) public void SwitchCreation() { PlacementManager.Clear(); + PlacementManager.SnapToWater = false; PlacementManager.BeginPlacement(GetCreationObject(), DecalsInfo.Current.Place, false); } @@ -76,6 +88,7 @@ void SetUI() CreateBtn.interactable = false; CreateSelected.SetActive(false); + UpdateTextureNames(); } else { @@ -123,10 +136,67 @@ void SetUI() DecalType.value = 9; break; } + + UpdateTextureNames(); } Loading = false; } + void UpdateTextureNames() + { + if(Loaded == null) + { + Texture1Name.text = "None"; + Texture2Name.text = "None"; + TextureObject.SetActive(false); + TypeObject.SetActive(false); + SelectAllBtn.gameObject.SetActive(false); + return; + } + + TextureObject.SetActive(true); + TypeObject.SetActive(true); + SelectAllBtn.gameObject.SetActive(true); + + bool NeedSecound = false; + switch (DecalType.value) + { + case 0: + Texture1Name.text = "Color"; + Texture2Name.text = "Specular"; + break; + case 1: + Texture1Name.text = "Normal"; + Texture2Name.text = "None"; + break; + case 2: + Texture1Name.text = "Normal"; + Texture2Name.text = "Alpha"; + NeedSecound = true; + break; + case 3: + Texture1Name.text = "Glow"; + Texture2Name.text = "None"; + break; + case 4: + Texture1Name.text = "Glow"; + Texture2Name.text = "Mask"; + NeedSecound = true; + break; + default: + Texture1Name.text = "Color"; + Texture2Name.text = "None"; + break; + } + + Texture1Name.color = (Loaded.Texture1 != null) ? TextureGoodColor : TextureEmptyColor; + + if (NeedSecound) + Texture2Name.color = (Loaded.Texture2 != null) ? TextureGoodColor : TextureEmptyColor; + else + Texture2Name.color = TextureUnusedColor; + } + public void SelectAll() { if (Loaded == null) @@ -233,7 +303,7 @@ public void OnTypeChanged() Undo.Current.RegisterDecalsSharedValuesChange(); Loaded.Type = TypeByDropdown(); - + UpdateTextureNames(); Loaded.UpdateMaterial(); } @@ -406,6 +476,7 @@ public void OnClickCreate(bool Value) Selection.SelectionManager.Current.ClearAffectedGameObjects(false); PlacementManager.InstantiateAction = CreatePrefabAction; PlacementManager.MinRotAngle = 0; + PlacementManager.SnapToWater = false; PlacementManager.BeginPlacement(GetCreationObject(), DecalsInfo.Current.Place); DecalsInfo.Current.DecalsList.UpdateSelection(); } @@ -427,6 +498,8 @@ public void OnClickCreate(bool Value) GameObject CreationGameObject; GameObject GetCreationObject() { + return CreationPrefab; + /* if (!CreationGameObject) { CreationGameObject = Instantiate(CreationPrefab); @@ -434,6 +507,7 @@ GameObject GetCreationObject() CreatePrefabAction(CreationGameObject); } return CreationGameObject; + */ } void CreatePrefabAction(GameObject InstancedPrefab) diff --git a/Assets/Scripts/UI/Tools/Decals/DecalsInfo_Selection.cs b/Assets/Scripts/UI/Tools/Decals/DecalsInfo_Selection.cs index 4d2fc6eb..65301966 100644 --- a/Assets/Scripts/UI/Tools/Decals/DecalsInfo_Selection.cs +++ b/Assets/Scripts/UI/Tools/Decals/DecalsInfo_Selection.cs @@ -12,6 +12,7 @@ public partial class DecalsInfo : MonoBehaviour private void OnEnable() { + PlacementManager.OnDropOnGameplay += DropAtGameplay; SelectionManager.Current.DisableLayer = 14; SelectionManager.Current.SetRemoveAction(DestroyDetails); SelectionManager.Current.SetSelectionChangeAction(SelectDetails); @@ -22,6 +23,7 @@ private void OnEnable() private void OnDisable() { + PlacementManager.OnDropOnGameplay -= DropAtGameplay; Selection.SelectionManager.Current.ClearAffectedGameObjects(); } diff --git a/Assets/Scripts/UI/Tools/Decals/DecalsInfo_UI.cs b/Assets/Scripts/UI/Tools/Decals/DecalsInfo_UI.cs index a52ccd06..cd920dd3 100644 --- a/Assets/Scripts/UI/Tools/Decals/DecalsInfo_UI.cs +++ b/Assets/Scripts/UI/Tools/Decals/DecalsInfo_UI.cs @@ -1,6 +1,7 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; +using UnityEngine.UI; using OzoneDecals; using Selection; @@ -12,6 +13,74 @@ public partial class DecalsInfo : MonoBehaviour public DecalSettings DecalSettingsUi; public DecalsList DecalsList; + public void DropAtDecals() { + if (ResourceBrowser.DragedObject == null) + return; + + if (!ResourceBrowser.IsDecal()) + return; + + string DropPath = ResourceBrowser.Current.LoadedPaths[ResourceBrowser.DragedObject.InstanceId]; + if (!DropPath.StartsWith("/")) + { + DropPath = DropPath.ToLower().Replace("env", "/env"); + } + Debug.Log(DropPath); + + foreach(Decal.DecalSharedSettings Shared in Decal.AllDecalsShared) + { + if (Shared.Tex1Path == DropPath) + { + SelectionManager.Current.CleanSelection(); + DecalSettingsUi.Load(Shared); + Debug.Log("Exist"); + return; + } + } + + // Decal does not exist. Create it + SelectionManager.Current.CleanSelection(); + GoToSelection(); + + Decal.DecalSharedSettings NewSharedDecal = new Decal.DecalSharedSettings(); + + if(DropPath.ToLower().Contains("normal")) + NewSharedDecal.Type = TerrainDecalType.TYPE_NORMALS; + else + NewSharedDecal.Type = TerrainDecalType.TYPE_ALBEDO; + + NewSharedDecal.Tex1Path = DropPath; + + NewSharedDecal.UpdateMaterial(); + Decal.AllDecalsShared.Add(NewSharedDecal); + + DecalSettingsUi.Load(NewSharedDecal); + DecalsList.GenerateTypes(); + } + + public void DropAtGameplay() + { + if (ResourceBrowser.DragedObject == null) + return; + + if (!ResourceBrowser.IsDecal()) + return; + + DropAtDecals(); + Decal.DecalSharedSettings Shared = DecalSettings.GetLoaded; + if (Shared == null) + { + Debug.Log("No deca setting loaded"); + return; + } + + Vector3 MouseWorldPos = CameraControler.BufforedGameplayCursorPos; + PlacementManager.PlaceAtPosition(MouseWorldPos, DecalSettingsUi.CreationPrefab, Place); + + GoToSelection(); + DecalSettingsUi.Load(Shared); + } + public void MoveUp() { diff --git a/Assets/Scripts/UI/Tools/LightingInfo.cs b/Assets/Scripts/UI/Tools/LightingInfo.cs index 22edbc14..881b4026 100644 --- a/Assets/Scripts/UI/Tools/LightingInfo.cs +++ b/Assets/Scripts/UI/Tools/LightingInfo.cs @@ -148,7 +148,7 @@ void UpdateLightingData() Scmap.map.FogEnd = FogEnd.value; Scmap.UpdateLighting(); - + Scmap.Skybox.LoadSkybox(); /* // Set light Scmap.Sun.transform.rotation = Quaternion.Euler(new Vector3(DA.value, -360 + RA.value, 0)); @@ -165,7 +165,7 @@ void UpdateLightingData() Shader.SetGlobalColor("_SunAmbience", new Color(Scmap.map.SunAmbience.x * 0.5f, Scmap.map.SunAmbience.y * 0.5f, Scmap.map.SunAmbience.z * 0.5f, 1)); Shader.SetGlobalColor("_ShadowColor", new Color(Scmap.map.ShadowFillColor.x * 0.5f, Scmap.map.ShadowFillColor.y * 0.5f, Scmap.map.ShadowFillColor.z * 0.5f, 1)); */ - } + } class LightingData{ @@ -281,6 +281,9 @@ public void ImportProceduralSkybox() string data = File.ReadAllText(paths[0]); Scmap.map.AdditionalSkyboxData = UnityEngine.JsonUtility.FromJson(data); + Scmap.map.AdditionalSkyboxData.Data.UpdateSize(); + + Scmap.Skybox.LoadSkybox(); } } } diff --git a/Assets/Scripts/UI/Tools/Markers/NewMarkersInfo.cs b/Assets/Scripts/UI/Tools/Markers/NewMarkersInfo.cs index 9d88df38..a5874b74 100644 --- a/Assets/Scripts/UI/Tools/Markers/NewMarkersInfo.cs +++ b/Assets/Scripts/UI/Tools/Markers/NewMarkersInfo.cs @@ -325,6 +325,7 @@ GameObject GetCreationObject() { if(CreationId == 5) { + PlacementManager.SnapToWater = false; return MarkerPresets[SpawnPressetDropdown.value]; } else @@ -332,6 +333,22 @@ GameObject GetCreationObject() LastCreationType = GetCreationType(); MarkersControler.MarkerPropGraphic Mpg = MarkersControler.GetPropByType(LastCreationType); + switch (LastCreationType) + { + case MapLua.SaveLua.Marker.MarkerTypes.BlankMarker: + PlacementManager.SnapToWater = false; + break; + case MapLua.SaveLua.Marker.MarkerTypes.Mass: + PlacementManager.SnapToWater = false; + break; + case MapLua.SaveLua.Marker.MarkerTypes.Hydrocarbon: + PlacementManager.SnapToWater = false; + break; + default: + PlacementManager.SnapToWater = true; + break; + } + MarkerNew NewMarkerObject = MarkerPrefab.GetComponent(); NewMarkerObject.Mf.sharedMesh = Mpg.SharedMesh; NewMarkerObject.Mr.sharedMaterial = Mpg.SharedMaterial; diff --git a/Assets/Scripts/UI/Tools/TerrainInfo.cs b/Assets/Scripts/UI/Tools/TerrainInfo.cs index 80ab6a0a..5d66c831 100644 --- a/Assets/Scripts/UI/Tools/TerrainInfo.cs +++ b/Assets/Scripts/UI/Tools/TerrainInfo.cs @@ -30,6 +30,7 @@ public class TerrainInfo : MonoBehaviour //public Slider BrushRotationSlider; public UiTextField BrushRotation; + public UiTextField BrushTarget; public UiTextField BrushMini; public UiTextField BrushMax; @@ -281,29 +282,15 @@ public void UpdateMenu(bool Slider = false) { if (Slider) { - //BrushSize.text = BrushSizeSlider.value.ToString(); - //BrushStrength.text = BrushStrengthSlider.value.ToString(); - //BrushRotation.text = BrushRotationSlider.value.ToString(); + } else { - //BrushSizeSlider.value = float.Parse(BrushSize.text); - //BrushStrengthSlider.value = int.Parse(BrushStrength.text); - //BrushRotationSlider.value = int.Parse(BrushRotation.text); - } - - //BrushSizeSlider.value = Mathf.Clamp(BrushSizeSlider.value, 1, 256); - //BrushStrengthSlider.value = (int)Mathf.Clamp(BrushStrengthSlider.value, 0, 100); - //BrushRotationSlider.value = (int)Mathf.Clamp(BrushStrengthSlider.value, -360, 360); - - //BrushSize.text = BrushSizeSlider.value.ToString(); - //BrushStrength.text = BrushStrengthSlider.value.ToString(); - //BrushRotation.text = BrushRotationSlider.value.ToString(); - //float TerrainHeight = ScmapEditor.Current.Data.size.y; + } - Min = BrushMini.intValue / ScmapEditor.Current.Data.size.y; - Max = BrushMax.intValue / ScmapEditor.Current.Data.size.y; + Min = BrushMini.value / ScmapEditor.Current.Data.size.y; + Max = BrushMax.value / ScmapEditor.Current.Data.size.y; Min /= 10f; Max /= 10f; @@ -416,6 +403,7 @@ public void ExportHeightmap() } } + public Texture2D ExportAs; public void ExportWithSizeHeightmap() { @@ -436,12 +424,14 @@ public void ExportWithSizeHeightmap() if (paths == null || string.IsNullOrEmpty(paths)) return; - int h = ScmapEditor.Current.Teren.terrainData.heightmapWidth; - int w = ScmapEditor.Current.Teren.terrainData.heightmapWidth; + float h = ScmapEditor.Current.Teren.terrainData.heightmapHeight; + float w = ScmapEditor.Current.Teren.terrainData.heightmapWidth; - float[,] data = ScmapEditor.Current.Teren.terrainData.GetHeights(0, 0, w, h); + float[,] data = ScmapEditor.Current.Teren.terrainData.GetHeights(0, 0, (int)w, (int)h); - Texture2D ExportAs = new Texture2D(ScmapEditor.Current.Teren.terrainData.heightmapWidth, ScmapEditor.Current.Teren.terrainData.heightmapWidth, TextureFormat.RGB24, false); + ExportAs = new Texture2D((int)w, (int)h, TextureFormat.RGB24, false, true); + + Debug.Log(w + ", " + h); float HeightValue = 1; HeightValue = float.Parse(TerrainScale_HeightValue.text); @@ -451,43 +441,51 @@ public void ExportWithSizeHeightmap() { for (int x = 0; x < w; x++) { - float Value = data[y, x] / HeightConversion; + float Value = data[y, x];// / HeightConversion; if (TerrainScale_Height.isOn) { Value *= HeightValue; } - float ColorR = (Mathf.Floor(Value) * (1f / 255f)); - float ColorG = (Value - Mathf.Floor(Value)); + //float ColorR = (Mathf.Floor(Value) * (1f / 255f)); + //float ColorG = (Value - Mathf.Floor(Value)); - ExportAs.SetPixel(h - (y + 1), x, new Color(ColorR, ColorG, 0)); + ExportAs.SetPixel((int)(h - (y + 1)), x, new Color(Value, 0, 0)); } } ExportAs.Apply(); - Debug.Log(ExportAs.GetPixel(128, 128).r + ", " + ExportAs.GetPixel(128, 128).g); - Debug.Log(ExportAs.GetPixel(128, 128).r + ExportAs.GetPixel(128, 128).g * (1f / 255f)); + //Debug.Log(ExportAs.GetPixel(128, 128).r + ", " + ExportAs.GetPixel(128, 128).g); + //Debug.Log(ExportAs.GetPixel(128, 128).r + ExportAs.GetPixel(128, 128).g * (1f / 255f)); + + //ExportAs = TextureScale.Bilinear(ExportAs, scale, scale); - TextureScale.Bilinear(ExportAs, scale, scale); + bool differentSize = w != scale || h != scale; h = scale; w = scale; using (BinaryWriter writer = new BinaryWriter(new System.IO.FileStream(paths, System.IO.FileMode.Create))) { + Color pixel = Color.black; + for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { - Color pixel = ExportAs.GetPixel(h - (y + 1), x); - float value = (pixel.r + pixel.g * (1f / 255f)); + if(differentSize) + pixel = ExportAs.GetPixelBilinear(y / h, x / w); + else + pixel = ExportAs.GetPixel(y, x); + //float value = (pixel.r + pixel.g * (1f / 255f)); + float value = pixel.r; uint ThisPixel = (uint)(value * HeightConversion); writer.Write(System.BitConverter.GetBytes(System.BitConverter.ToUInt16(System.BitConverter.GetBytes(ThisPixel), 0))); } } writer.Close(); } - ExportAs = null; + //ExportAs = null; } @@ -575,8 +573,7 @@ public void RegenerateMaps() { GenerateControlTex.GenerateWater(); GenerateControlTex.GenerateNormal(); - if (ScmapEditor.Current.Slope) - GenerateControlTex.Current.GenerateSlopeTexture(); + } #region Brush Update @@ -666,11 +663,13 @@ void SymmetryPaint() void Paint(Vector3 AtPosition, int id = 0) { - int BrushPaintType = 0; - if (Smooth || SelectedBrush == 2) - BrushPaintType = 1; // Smooth - else if (SelectedBrush == 3) - BrushPaintType = 2; + int BrushPaintType = SelectedBrush; + + + if (Smooth) + BrushPaintType = 2; // Smooth + + int hmWidth = ScmapEditor.Current.Teren.terrainData.heightmapWidth; int hmHeight = ScmapEditor.Current.Teren.terrainData.heightmapHeight; @@ -716,32 +715,71 @@ void Paint(Vector3 AtPosition, int id = 0) int i = 0; int j = 0; - - if (SelectedBrush == 3) + int x = 0; + int y = 0; + float SampleBrush = 0; + float PixelPower = 0; + + if (SelectedBrush == 1) + { + float Count = 0; + for (i = 0; i < (size - OffsetDown) - OffsetTop; i++) + { + for (j = 0; j < (size - OffsetLeft) - OffsetRight; j++) + { + x = (int)(((i + OffsetDown) / (float)size) * BrushGenerator.Current.PaintImageWidths[id]); + y = (int)(((j + OffsetLeft) / (float)size) * BrushGenerator.Current.PaintImageHeights[id]); + SampleBrush = Mathf.Clamp01(BrushGenerator.Current.Values[id][y + BrushGenerator.Current.PaintImageWidths[id] * x] - 0.0255f); + CenterHeight += heights[i, j] * SampleBrush; + Count += SampleBrush; + } + } + CenterHeight /= Count; + } + else if (SelectedBrush == 3) { + float Count = 0; for (i = 0; i < (size - OffsetDown) - OffsetTop; i++) { for (j = 0; j < (size - OffsetLeft) - OffsetRight; j++) { - CenterHeight += heights[i, j]; + x = (int)(((i + OffsetDown) / (float)size) * BrushGenerator.Current.PaintImageWidths[id]); + y = (int)(((j + OffsetLeft) / (float)size) * BrushGenerator.Current.PaintImageHeights[id]); + SampleBrush = Mathf.Clamp01(BrushGenerator.Current.Values[id][y + BrushGenerator.Current.PaintImageWidths[id] * x] - 0.5f) * 2f; + CenterHeight += heights[i, j] * SampleBrush; + Count += SampleBrush; } } - CenterHeight /= size * size; + CenterHeight /= Count; } int SizeDown = (size - OffsetDown) - OffsetTop; int SizeLeft = (size - OffsetLeft) - OffsetRight; - int x = 0; - int y = 0; - //Color BrushValue = Color.white; - float SampleBrush = 0; - float PixelPower = 0; - + float TargetHeight = Mathf.Clamp(((Invert?(128):(BrushTarget.value)) / ScmapEditor.Current.Data.size.y) / 10f, Min, Max); float BrushStrenghtValue = BrushStrength.value; - float PaintStrength = BrushStrenghtValue * 0.00005f * (Invert ? (-1) : 1); - float SizeSmooth = Mathf.Clamp01(size / 10f) * 10; + //float PaintStrength = BrushStrenghtValue * 0.00005f * (Invert ? (-1) : 1); + + float StrengthMultiplier = 1; + switch (BrushPaintType) + { + case 1: // Flatten + StrengthMultiplier = BrushGenerator.Current.HeightmapBlurStrength.Evaluate(BrushStrenghtValue) * 0.00008f; + break; + case 2: // Smooth + StrengthMultiplier = BrushGenerator.Current.HeightmapBlurStrength.Evaluate(BrushStrenghtValue) * Mathf.Clamp(size / 10f, 0, 20) * 0.01f; + break; + case 3: // Sharp + StrengthMultiplier = BrushGenerator.Current.HeightmapBlurStrength.Evaluate(BrushStrenghtValue) * 0.00008f; + break; + default: + StrengthMultiplier = BrushGenerator.Current.HeightmapPaintStrength.Evaluate(BrushStrenghtValue) * 0.00008f * (Invert ? (-1) : 1); + break; + } + + //float SizeSmooth = Mathf.Clamp01(size / 10f) * 15; + for (i = 0; i < SizeDown; i++) { @@ -754,30 +792,47 @@ void Paint(Vector3 AtPosition, int id = 0) //BrushValue = BrushGenerator.Current.GetPixel(y, x); //SambleBrush = BrushValue.r; //SampleBrush = BrushGenerator.Current.GetBrushValue(id, y, x); - SampleBrush = BrushGenerator.Current.Values[id][y + BrushGenerator.Current.PaintImageWidths[id] * x]; - if (SampleBrush >= 0.003f) + SampleBrush = Mathf.Clamp01(BrushGenerator.Current.Values[id][y + BrushGenerator.Current.PaintImageWidths[id] * x] - 0.0255f); + if (SampleBrush > 0) { switch (BrushPaintType) { - case 1: // Smooth + case 1: // Flatten + PixelPower = Mathf.Pow(Mathf.Abs(heights[i, j] - CenterHeight), 0.454545f) + 1; + PixelPower /= 2f; + + //if (PixelPower < 0.001f) + // heights[i, j] = CenterHeight; + //else { + //float FlattenStrenght = PixelPower * StrengthMultiplier * Mathf.Pow(SampleBrush, 2); + //heights[i, j] += FlattenStrenght; + heights[i, j] = MoveToValue(heights[i, j], CenterHeight, StrengthMultiplier * SampleBrush * PixelPower, 0, 128); + //} + + break; + case 2: // Smooth CenterHeight = GetNearValues(ref heights, i, j); - PixelPower = Mathf.Pow(Mathf.Abs(heights[i, j] - CenterHeight), 0.5f) * SizeSmooth; + PixelPower = Mathf.Pow(Mathf.Abs(heights[i, j] - CenterHeight), 0.454545f) + 1; + PixelPower /= 2f; //PixelPower = 10; - heights[i, j] = Mathf.Lerp(heights[i, j], CenterHeight, BrushStrenghtValue * 0.4f * Mathf.Pow(SampleBrush, 2) * PixelPower); + //heights[i, j] = Mathf.Lerp(heights[i, j], CenterHeight, BrushStrenghtValue * Mathf.Pow(SampleBrush, 2) * PixelPower); + heights[i, j] = Mathf.Lerp(heights[i, j], CenterHeight, PixelPower * StrengthMultiplier * Mathf.Pow(SampleBrush, 2)); + break; - case 2: // Sharp - PixelPower = heights[i, j] - CenterHeight; - heights[i, j] += Mathf.Lerp(PixelPower, 0, PixelPower * 10) * BrushStrenghtValue * 0.01f * Mathf.Pow(SampleBrush, 2); + case 3: // Sharp + PixelPower = Mathf.Pow(Mathf.Abs(heights[i, j] - CenterHeight), 0.454545f) + 1; + PixelPower /= 2f; + //heights[i, j] += Mathf.Lerp(PixelPower, 0, PixelPower * 10) * BrushStrenghtValue * 0.01f * Mathf.Pow(SampleBrush, 2); + heights[i, j] = MoveToValue(heights[i, j], CenterHeight, - StrengthMultiplier * SampleBrush * PixelPower, Min, Max); break; default: - heights[i, j] += SampleBrush * PaintStrength; + //heights[i, j] += SampleBrush * StrengthMultiplier; + heights[i, j] = MoveToValue(heights[i, j], TargetHeight, SampleBrush * StrengthMultiplier, Min, Max); break; } - - heights[i, j] = Mathf.Clamp(heights[i, j], Min, Max); } } } @@ -797,18 +852,34 @@ void Paint(Vector3 AtPosition, int id = 0) OnTerrainChanged(); } + float MoveToValue(float current, float target, float speed, float min, float max) + { + if(current > target) + { + return Mathf.Clamp(current - speed, target, max); + } + else if (current < target) + { + return Mathf.Clamp(current + speed, min, target); + } + return current; + } + public void OnTerrainChanged() { Markers.MarkersControler.UpdateMarkersHeights(); PropsRenderer.Current.UpdatePropsHeights(); DecalsControler.UpdateDecals(); + + if (ScmapEditor.Current.Slope) + GenerateControlTex.Current.GenerateSlopeTexture(); } float GetNearValues(ref float[,] heigths, int x, int y, int range = 1) { float ToReturn = 0f; - int Count = 0; + float Count = 0; if (x > 0) { diff --git a/Assets/Scripts/UI/Tools/WaterInfo.cs b/Assets/Scripts/UI/Tools/WaterInfo.cs index 30efce3f..bac3efc1 100644 --- a/Assets/Scripts/UI/Tools/WaterInfo.cs +++ b/Assets/Scripts/UI/Tools/WaterInfo.cs @@ -115,7 +115,7 @@ public void WaterSettingsChanged() if (Loading) return; ScmapEditor.Current.map.Water.ColorLerp.x = ColorLerpXElevation.value; - ScmapEditor.Current.map.Water.ColorLerp.y = ColorLerpXElevation.value; + ScmapEditor.Current.map.Water.ColorLerp.y = ColorLerpYElevation.value; ScmapEditor.Current.map.Water.SurfaceColor = WaterColor.GetVectorValue(); ScmapEditor.Current.map.Water.SunColor = SunColor.GetVectorValue(); diff --git a/Assets/Scripts/UI/UiElements/UiTextField.cs b/Assets/Scripts/UI/UiElements/UiTextField.cs index 65ad307f..5f7fed49 100644 --- a/Assets/Scripts/UI/UiElements/UiTextField.cs +++ b/Assets/Scripts/UI/UiElements/UiTextField.cs @@ -11,7 +11,7 @@ public class UiTextField : MonoBehaviour [Header("Config")] public FieldTypes FieldType; public float BeginValue; - public string Format = "N2"; + //public string Format = "N2"; [Header("UI")] public InputField InputFieldUi; @@ -65,7 +65,7 @@ public void OnSliderChanged() ChangingValue = true; HasValue = true; LastValue = SliderUi.value; - InputFieldUi.text = LastValue.ToString(Format); + SetTextField(); if (InputFieldUi.contentType == InputField.ContentType.IntegerNumber) SliderUi.value = int.Parse(InputFieldUi.text); if (InputFieldUi.contentType == InputField.ContentType.DecimalNumber) @@ -83,7 +83,7 @@ public void OnSliderFinished() ChangingValue = true; HasValue = true; LastValue = SliderUi.value; - InputFieldUi.text = LastValue.ToString(Format); + SetTextField(); if (InputFieldUi.contentType == InputField.ContentType.IntegerNumber) SliderUi.value = int.Parse(InputFieldUi.text); if (InputFieldUi.contentType == InputField.ContentType.DecimalNumber) @@ -113,10 +113,7 @@ void UpdateSliderValue(bool ClampText = false) if (ClampText) { - if (InputFieldUi.contentType == InputField.ContentType.IntegerNumber) - InputFieldUi.text = LastValue.ToString(); - else if (InputFieldUi.contentType == InputField.ContentType.DecimalNumber) - InputFieldUi.text = LastValue.ToString(Format); + SetTextField(); } SliderUi.value = LastValue; @@ -146,7 +143,8 @@ public void SetValue(float value, bool AllowInvoke = false) LastValue = Mathf.Clamp(LastValue, SliderUi.minValue, SliderUi.maxValue); SliderUi.value = LastValue; } - InputFieldUi.text = LastValue.ToString(Format); + + SetTextField(); ChangingValue = false; } @@ -160,9 +158,17 @@ public void SetValue(int value, bool AllowInvoke = false) LastValue = Mathf.Clamp(LastValue, SliderUi.minValue, SliderUi.maxValue); SliderUi.value = LastValue; } - InputFieldUi.text = LastValue.ToString(Format); + SetTextField(); ChangingValue = false; } + + void SetTextField() + { + if (InputFieldUi.contentType == InputField.ContentType.IntegerNumber) + InputFieldUi.text = LastValue.ToString(); + else if (InputFieldUi.contentType == InputField.ContentType.DecimalNumber) + InputFieldUi.text = LastValue.ToString("0.00"); + } #endregion #region Getters diff --git a/Assets/Scripts/UI/Windows/ResourceBrowser.cs b/Assets/Scripts/UI/Windows/ResourceBrowser.cs index 7b765d7b..d22c015a 100644 --- a/Assets/Scripts/UI/Windows/ResourceBrowser.cs +++ b/Assets/Scripts/UI/Windows/ResourceBrowser.cs @@ -35,9 +35,30 @@ public class ResourceBrowser : MonoBehaviour public Dropdown Category; public GameObject Loading; public Texture2D CursorImage; + public Texture2D CursorImage_Prop; + public Texture2D CursorImage_Decal; public LayoutGroup Layout; public ContentSizeFitter SizeFitter; + public Texture2D GetCursorImage() + { + if (Category.value == 1 || Category.value == 2) + return CursorImage_Decal; + else if (Category.value == 3) + return CursorImage_Prop; + else + return CursorImage; + } + + public static bool IsDecal() + { + return Current.Category.value == 1 || Current.Category.value == 2; + } + + public static bool IsProp() + { + return Current.Category.value == 3; + } [Header("Loaded assets")] public List LoadedTextures = new List(); diff --git a/Assets/Scripts/Undo/HistoryObjects/HistoryTerrainHeight.cs b/Assets/Scripts/Undo/HistoryObjects/HistoryTerrainHeight.cs index c3b219b2..4a04c135 100644 --- a/Assets/Scripts/Undo/HistoryObjects/HistoryTerrainHeight.cs +++ b/Assets/Scripts/Undo/HistoryObjects/HistoryTerrainHeight.cs @@ -44,5 +44,6 @@ public override void DoRedo(){ //Markers.MarkersControler.UpdateMarkersHeights(); Undo.Current.EditMenu.EditTerrain.OnTerrainChanged(); + Undo.Current.EditMenu.EditTerrain.RegenerateMaps(); } } diff --git a/FAForeverMapEditor.Editor.Plugins.csproj b/FAForeverMapEditor.Editor.Plugins.csproj index 74563f9d..5ca3d3ed 100644 --- a/FAForeverMapEditor.Editor.Plugins.csproj +++ b/FAForeverMapEditor.Editor.Plugins.csproj @@ -333,6 +333,7 @@ + diff --git a/FAForeverMapEditor.Editor.csproj b/FAForeverMapEditor.Editor.csproj index 64a3718d..bb17c8d0 100644 --- a/FAForeverMapEditor.Editor.csproj +++ b/FAForeverMapEditor.Editor.csproj @@ -358,6 +358,7 @@ + diff --git a/FAForeverMapEditor.Plugins.csproj b/FAForeverMapEditor.Plugins.csproj index ebb73ac6..21119321 100644 --- a/FAForeverMapEditor.Plugins.csproj +++ b/FAForeverMapEditor.Plugins.csproj @@ -347,6 +347,7 @@ + diff --git a/FAForeverMapEditor.csproj b/FAForeverMapEditor.csproj index 5a296c92..096218e1 100644 --- a/FAForeverMapEditor.csproj +++ b/FAForeverMapEditor.csproj @@ -295,6 +295,11 @@ + + + + + @@ -482,6 +487,7 @@ + @@ -622,6 +628,7 @@ +