236 lines
7.7 KiB
C#
236 lines
7.7 KiB
C#
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using GameCult.Aetheria.State.Verse;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using Unity.Mathematics;
|
|
using UnityEngine.UI;
|
|
using static Unity.Mathematics.math;
|
|
using int2 = Unity.Mathematics.int2;
|
|
|
|
public class MapRenderer : MonoBehaviour
|
|
{
|
|
public ZoneRenderer ZoneRenderer;
|
|
public TextMeshProUGUI Title;
|
|
public Camera MapOverlayCamera;
|
|
public Camera GravityCamera;
|
|
public Camera TintCamera;
|
|
public Camera InfluenceCamera;
|
|
public Image OverlayDisplay;
|
|
public Image GravityDisplay;
|
|
public Image TintDisplay;
|
|
public Image InfluenceDisplay;
|
|
public float Scale;
|
|
public float2 Position;
|
|
public float IconSize = 1f/128;
|
|
|
|
private RectTransform _rect;
|
|
private RenderTexture _mapTexture;
|
|
private RenderTexture _gravityTexture;
|
|
private RenderTexture _tintTexture;
|
|
private RenderTexture _influenceTexture;
|
|
private int2 _size;
|
|
private bool _init;
|
|
private AetheriaClient _client;
|
|
private string _clientStatePath = "";
|
|
private AetheriaRuntimeObjectsViewportDocument _objectsViewport;
|
|
private AetheriaRuntimeGravityViewportDocument _gravityViewport;
|
|
private float _nextViewportRefreshTime;
|
|
|
|
void Start()
|
|
{
|
|
_rect = GetComponent<RectTransform>();
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
_init = true;
|
|
MapOverlayCamera.gameObject.SetActive(true);
|
|
GravityCamera.gameObject.SetActive(true);
|
|
TintCamera.gameObject.SetActive(true);
|
|
InfluenceCamera.gameObject.SetActive(true);
|
|
RefreshViewportDocuments(force: true);
|
|
|
|
// If hiding minimap asteroids, turn them back on for the map screen
|
|
if (!ResolveShowAsteroidsInMinimap())
|
|
ZoneRenderer.ShowAsteroidUI = true;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
if (_mapTexture != null)
|
|
{
|
|
ReleaseTextures();
|
|
}
|
|
MapOverlayCamera.gameObject.SetActive(false);
|
|
GravityCamera.gameObject.SetActive(false);
|
|
TintCamera.gameObject.SetActive(false);
|
|
InfluenceCamera.gameObject.SetActive(false);
|
|
|
|
// If hiding minimap asteroids, turn them back off when leaving the map screen
|
|
if (!ResolveShowAsteroidsInMinimap())
|
|
ZoneRenderer.ShowAsteroidUI = false;
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
DisposeClient();
|
|
}
|
|
|
|
void ReleaseTextures()
|
|
{
|
|
_mapTexture.Release();
|
|
_mapTexture = null;
|
|
_gravityTexture.Release();
|
|
_gravityTexture = null;
|
|
_tintTexture.Release();
|
|
_tintTexture = null;
|
|
_influenceTexture.Release();
|
|
_influenceTexture = null;
|
|
}
|
|
|
|
void LateUpdate()
|
|
{
|
|
var size = int2(Screen.width, Screen.height);
|
|
if (_init || size.x != _size.x || size.y != _size.y)
|
|
{
|
|
_init = false;
|
|
_size = size;
|
|
if (_mapTexture != null)
|
|
{
|
|
ReleaseTextures();
|
|
}
|
|
|
|
_mapTexture = new RenderTexture(_size.x, _size.y, 0, RenderTextureFormat.Default);
|
|
MapOverlayCamera.targetTexture = _mapTexture;
|
|
OverlayDisplay.material.SetTexture("_DetailTex", _mapTexture);
|
|
|
|
_gravityTexture = new RenderTexture(_size.x, _size.y, 0, RenderTextureFormat.RFloat);
|
|
GravityCamera.targetTexture = _gravityTexture;
|
|
GravityDisplay.material.SetTexture("_DetailTex", _gravityTexture);
|
|
|
|
_tintTexture = new RenderTexture(_size.x / 2, _size.y / 2, 0, RenderTextureFormat.RGB111110Float);
|
|
TintCamera.targetTexture = _tintTexture;
|
|
TintDisplay.material.SetTexture("_DetailTex", _tintTexture);
|
|
|
|
_influenceTexture = new RenderTexture(_size.x, _size.y, 0, RenderTextureFormat.RFloat);
|
|
InfluenceCamera.targetTexture = _influenceTexture;
|
|
InfluenceDisplay.material.SetTexture("_DetailTex", _influenceTexture);
|
|
}
|
|
|
|
var pos = ((Vector2) Position).Flatland(1);
|
|
|
|
MapOverlayCamera.transform.position = pos;
|
|
MapOverlayCamera.orthographicSize = _size.y * Scale * .5f;
|
|
|
|
GravityCamera.transform.position = pos;
|
|
GravityCamera.orthographicSize = _size.y * Scale * .5f;
|
|
GravityDisplay.material.SetFloat("_Scale", Scale / 2);
|
|
|
|
TintCamera.transform.position = pos;
|
|
TintCamera.orthographicSize = _size.y * Scale * .5f;
|
|
|
|
InfluenceCamera.transform.position = pos;
|
|
InfluenceCamera.orthographicSize = _size.y * Scale * .5f;
|
|
|
|
ZoneRenderer.SetIconSize(IconSize * Scale);
|
|
RefreshViewportDocuments(force: false);
|
|
}
|
|
|
|
private void RefreshViewportDocuments(bool force)
|
|
{
|
|
if (!force && Time.unscaledTime < _nextViewportRefreshTime)
|
|
return;
|
|
|
|
_nextViewportRefreshTime = Time.unscaledTime + .5f;
|
|
try
|
|
{
|
|
var client = ResolveClient();
|
|
var viewport = ResolveViewportBounds();
|
|
_objectsViewport = client
|
|
.ObjectsViewportAsync(viewport)
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
_gravityViewport = client
|
|
.GravityViewportAsync(viewport)
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
|
|
var zoneName = string.IsNullOrWhiteSpace(_objectsViewport?.ZoneName)
|
|
? "Unknown"
|
|
: _objectsViewport.ZoneName;
|
|
Title.text = $"Zone: {zoneName}";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogWarning($"Failed to read Aetheria map viewport from local Verse state: {ex.Message}");
|
|
Title.text = "Zone: Unknown";
|
|
}
|
|
}
|
|
|
|
private AetheriaRuntimeRtsViewportBounds ResolveViewportBounds()
|
|
{
|
|
var screenHeight = _size.y <= 0 ? Math.Max(1, Screen.height) : _size.y;
|
|
var screenWidth = _size.x <= 0 ? Math.Max(1, Screen.width) : _size.x;
|
|
var halfHeight = screenHeight * Scale * .5f;
|
|
var halfWidth = screenWidth * Scale * .5f;
|
|
return new AetheriaRuntimeRtsViewportBounds
|
|
{
|
|
MinX = Position.x - halfWidth,
|
|
MinY = Position.y - halfHeight,
|
|
MaxX = Position.x + halfWidth,
|
|
MaxY = Position.y + halfHeight
|
|
};
|
|
}
|
|
|
|
private bool ResolveShowAsteroidsInMinimap()
|
|
{
|
|
try
|
|
{
|
|
return ResolveClient()
|
|
.PlayerSettingsAsync()
|
|
.GetAwaiter()
|
|
.GetResult()
|
|
?.ShowAsteroidsInMinimap ?? false;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogWarning($"Failed to read Aetheria map graphics settings from local Verse state: {ex.Message}");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private AetheriaClient ResolveClient()
|
|
{
|
|
var gameDataDirectory = new DirectoryInfo(Path.Combine(Application.dataPath, "..", "GameData"));
|
|
var stateBoot = AetheriaRuntimeStateBoot.Inspect(gameDataDirectory);
|
|
if (_client != null && string.Equals(_clientStatePath, stateBoot.StateFilePath, StringComparison.Ordinal))
|
|
return _client;
|
|
|
|
DisposeClient();
|
|
_client = AetheriaClient
|
|
.OpenLocalAsync(
|
|
gameDataDirectory,
|
|
"unity-map-renderer",
|
|
"local",
|
|
pullOnOpen: true)
|
|
.GetAwaiter()
|
|
.GetResult();
|
|
_clientStatePath = stateBoot.StateFilePath;
|
|
return _client;
|
|
}
|
|
|
|
private void DisposeClient()
|
|
{
|
|
_client?.Dispose();
|
|
_client = null;
|
|
_clientStatePath = "";
|
|
}
|
|
}
|