Restore the stable legacy Unity project
This commit is contained in:
parent
56a156ee87
commit
7006a6b0dd
2070 changed files with 180490 additions and 169303 deletions
|
|
@ -1,22 +1,21 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using GameCult.Aetheria.State.Verse;
|
||||
using GameCult.Eve.PluginFields;
|
||||
using GameCult.Mesh;
|
||||
using MessagePack;
|
||||
using TMPro;
|
||||
using UniRx;
|
||||
using UnityEngine;
|
||||
using Unity.Mathematics;
|
||||
using Random = UnityEngine.Random;
|
||||
using static Unity.Mathematics.math;
|
||||
using static Unity.Mathematics.noise;
|
||||
using Random = UnityEngine.Random;
|
||||
using float2 = Unity.Mathematics.float2;
|
||||
|
||||
public class SectorMap : MonoBehaviour
|
||||
{
|
||||
public Camera InfluenceCamera;
|
||||
public AetheriaRenderSplatRasterizer InfluenceSplatRasterizer;
|
||||
public Prototype InfluenceRendererPrototype;
|
||||
public MeshRenderer SectorRenderer;
|
||||
public Prototype ZonePrototype;
|
||||
|
|
@ -35,7 +34,6 @@ public class SectorMap : MonoBehaviour
|
|||
public Texture2D HomeIcon;
|
||||
public Prototype LegendPrototype;
|
||||
public float IconDistance = 1;
|
||||
private AetheriaClientState _runtimeState;
|
||||
public float IconBackgroundSize = 3;
|
||||
public float LabelDistance = .4f;
|
||||
public float LinkWidth;
|
||||
|
|
@ -44,42 +42,32 @@ public class SectorMap : MonoBehaviour
|
|||
public Color PlayerLocationLabelColor;
|
||||
public float PlayerLocationIconSize = 1.25f;
|
||||
|
||||
public Subject<int> ZoneClicked = new Subject<int>();
|
||||
public Subject<GalaxyZone> ZoneClicked = new Subject<GalaxyZone>();
|
||||
|
||||
private int _currentPlayerLocation = -1;
|
||||
private readonly HashSet<int> _revealedZones = new HashSet<int>();
|
||||
private readonly HashSet<(int, int)> _revealedLinks = new HashSet<(int, int)>();
|
||||
private readonly Dictionary<int, (MeshRenderer influenceRenderer, RenderTexture influence, Material primaryMaterial, Material secondaryMaterial, Material linkMaterial)> _factionMaterials =
|
||||
new Dictionary<int, (MeshRenderer influenceRenderer, RenderTexture influence, Material primaryMaterial, Material secondaryMaterial, Material linkMaterial)>();
|
||||
private readonly Dictionary<int, SectorZoneUI> _zoneInstances = new Dictionary<int, SectorZoneUI>();
|
||||
private readonly Queue<IEnumerable<int>> _queuedZoneReveals = new Queue<IEnumerable<int>>();
|
||||
private readonly Dictionary<int, AetheriaRuntimeSectorMapZone> _zonesByIndex =
|
||||
new Dictionary<int, AetheriaRuntimeSectorMapZone>();
|
||||
private AetheriaRuntimeSectorMapDocument _sectorMap;
|
||||
private bool _sectorMapLoaded;
|
||||
private GalaxyZone _currentPlayerLocation;
|
||||
private HashSet<GalaxyZone> _revealedZones = new HashSet<GalaxyZone>();
|
||||
private HashSet<(GalaxyZone, GalaxyZone)> _revealedLinks = new HashSet<(GalaxyZone, GalaxyZone)>();
|
||||
|
||||
public bool TryMarkPlayerLocation(int zoneIndex)
|
||||
private Dictionary<Faction, (MeshRenderer influenceRenderer, RenderTexture influence, Material primaryMaterial, Material secondaryMaterial, Material linkMaterial)> _factionMaterials =
|
||||
new Dictionary<Faction, (MeshRenderer influenceRenderer, RenderTexture influence, Material primaryMaterial, Material secondaryMaterial, Material linkMaterial)>();
|
||||
|
||||
private Dictionary<GalaxyZone, SectorZoneUI> _zoneInstances = new Dictionary<GalaxyZone, SectorZoneUI>();
|
||||
private Queue<IEnumerable<GalaxyZone>> _queuedZoneReveals = new Queue<IEnumerable<GalaxyZone>>();
|
||||
|
||||
public void MarkPlayerLocation(GalaxyZone zone)
|
||||
{
|
||||
EnsureSectorMapLoaded();
|
||||
if (!_zonesByIndex.ContainsKey(zoneIndex))
|
||||
return false;
|
||||
|
||||
MarkPlayerLocation(zoneIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void MarkPlayerLocation(int zoneIndex)
|
||||
{
|
||||
if (_currentPlayerLocation >= 0 && _zoneInstances.TryGetValue(_currentPlayerLocation, out var previous))
|
||||
if (_currentPlayerLocation != null)
|
||||
{
|
||||
previous.Label.color = Color.white;
|
||||
previous.Label.fontStyle = FontStyles.Normal;
|
||||
previous.IconContainer.localScale = Vector3.one;
|
||||
_zoneInstances[_currentPlayerLocation].Label.color = Color.white;
|
||||
_zoneInstances[_currentPlayerLocation].Label.fontStyle = FontStyles.Normal;
|
||||
_zoneInstances[_currentPlayerLocation].IconContainer.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
_currentPlayerLocation = zoneIndex;
|
||||
if (_zoneInstances.TryGetValue(_currentPlayerLocation, out var zoneUI))
|
||||
MarkPlayerLocation(zoneUI);
|
||||
_currentPlayerLocation = zone;
|
||||
if(_zoneInstances.ContainsKey(_currentPlayerLocation))
|
||||
{
|
||||
MarkPlayerLocation(_zoneInstances[_currentPlayerLocation]);
|
||||
}
|
||||
}
|
||||
|
||||
private void MarkPlayerLocation(SectorZoneUI zoneUI)
|
||||
|
|
@ -89,409 +77,268 @@ public class SectorMap : MonoBehaviour
|
|||
zoneUI.IconContainer.localScale = new Vector3(PlayerLocationIconSize, PlayerLocationIconSize, 1);
|
||||
}
|
||||
|
||||
public void QueueZoneReveal(IEnumerable<int> zoneIndices)
|
||||
public void QueueZoneReveal(IEnumerable<GalaxyZone> zones)
|
||||
{
|
||||
_queuedZoneReveals.Enqueue(zoneIndices ?? Array.Empty<int>());
|
||||
_queuedZoneReveals.Enqueue(zones);
|
||||
}
|
||||
|
||||
public void StartReveal(float linkDuration, float iconDuration)
|
||||
{
|
||||
EnsureSectorMapLoaded();
|
||||
if (_queuedZoneReveals.Count > 0)
|
||||
{
|
||||
StartCoroutine(RevealZone(_queuedZoneReveals.Dequeue(), linkDuration, iconDuration));
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator RevealZone(IEnumerable<int> zoneIndices, float linkDuration, float iconDuration)
|
||||
public IEnumerator RevealZone(IEnumerable<GalaxyZone> zones, float linkDuration, float iconDuration)
|
||||
{
|
||||
var linksToReveal = new List<(float2 start, float2 end, Transform linkInstance, bool critical)>();
|
||||
var zoneTransforms = new List<Transform>();
|
||||
var zoneInstanceScale = ZonePrototype.transform.localScale;
|
||||
|
||||
foreach (var zoneIndex in zoneIndices ?? Array.Empty<int>())
|
||||
foreach (var zone in zones)
|
||||
{
|
||||
if (!_zonesByIndex.TryGetValue(zoneIndex, out var zone) || _revealedZones.Contains(zoneIndex))
|
||||
continue;
|
||||
|
||||
var zoneInstance = ZonePrototype.Instantiate<SectorZoneUI>();
|
||||
zoneInstance.Clickable.OnClick += (_, _, _, _) => ZoneClicked.OnNext(zone.ZoneIndex);
|
||||
if(zone.ZoneIndex == _currentPlayerLocation)
|
||||
MarkPlayerLocation(zoneInstance);
|
||||
_zoneInstances[zone.ZoneIndex] = zoneInstance;
|
||||
var zoneInstanceTransform = zoneInstance.transform;
|
||||
zoneTransforms.Add(zoneInstanceTransform);
|
||||
zoneInstanceTransform.localPosition = new Vector3((float)zone.X, (float)zone.Y);
|
||||
|
||||
if (zone.OwnerFactionIndex >= 0 && _factionMaterials.TryGetValue(zone.OwnerFactionIndex, out var ownerMaterials))
|
||||
if (!_revealedZones.Contains(zone))
|
||||
{
|
||||
zoneInstance.Primary.sharedMaterial = ownerMaterials.primaryMaterial;
|
||||
zoneInstance.Secondary.sharedMaterial = ownerMaterials.secondaryMaterial;
|
||||
}
|
||||
else
|
||||
{
|
||||
zoneInstance.Secondary.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
foreach (var link in LinksForZone(zone.ZoneIndex))
|
||||
{
|
||||
var adjacentIndex = link.FromZoneIndex == zone.ZoneIndex ? link.ToZoneIndex : link.FromZoneIndex;
|
||||
if (!_zonesByIndex.TryGetValue(adjacentIndex, out var adjacentZone) ||
|
||||
!_revealedZones.Contains(adjacentIndex) ||
|
||||
_revealedLinks.Contains((zone.ZoneIndex, adjacentIndex)) ||
|
||||
_revealedLinks.Contains((adjacentIndex, zone.ZoneIndex)))
|
||||
var zoneInstance = ZonePrototype.Instantiate<SectorZoneUI>();
|
||||
zoneInstance.Clickable.OnClick += (clickableCollider, data, ray, hit) => ZoneClicked.OnNext(zone);
|
||||
if(zone == _currentPlayerLocation)
|
||||
MarkPlayerLocation(zoneInstance);
|
||||
_zoneInstances[zone] = zoneInstance;
|
||||
var zoneInstanceTransform = zoneInstance.transform;
|
||||
zoneTransforms.Add(zoneInstanceTransform);
|
||||
zoneInstanceTransform.localPosition = new Vector3(zone.Position.x, zone.Position.y);
|
||||
if(zone.Owner != null)
|
||||
{
|
||||
continue;
|
||||
zoneInstance.Primary.sharedMaterial = _factionMaterials[zone.Owner].primaryMaterial;
|
||||
zoneInstance.Secondary.sharedMaterial = _factionMaterials[zone.Owner].secondaryMaterial;
|
||||
if(zone == ActionGameManager.CurrentGalaxy.HomeZones[zone.Owner])
|
||||
zoneInstance.Secondary.transform.localScale = Vector3.one * 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
zoneInstance.Secondary.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
var linkInstance = LinkPrototype.Instantiate<Transform>();
|
||||
var critical = zone.Entrance || zone.Exit || adjacentZone.Entrance || adjacentZone.Exit;
|
||||
var start = Position(zone);
|
||||
var end = Position(adjacentZone);
|
||||
linksToReveal.Add((start, end, linkInstance, critical));
|
||||
if (zone.OwnerFactionIndex >= 0 &&
|
||||
zone.OwnerFactionIndex == adjacentZone.OwnerFactionIndex &&
|
||||
_factionMaterials.TryGetValue(zone.OwnerFactionIndex, out var factionMaterials))
|
||||
var isOnCriticalPath = ActionGameManager.CurrentGalaxy.ExitPath?.Contains(zone) ?? false;
|
||||
foreach (var adjacentZone in zone.AdjacentZones)
|
||||
{
|
||||
linkInstance.GetComponent<MeshRenderer>().sharedMaterial = factionMaterials.linkMaterial;
|
||||
// If the adjacent zone is in the set already revealed, then show the link
|
||||
if (_revealedZones.Contains(adjacentZone) &&
|
||||
!(_revealedLinks.Contains((zone, adjacentZone)) ||
|
||||
_revealedLinks.Contains((adjacentZone, zone))))
|
||||
{
|
||||
var link = LinkPrototype.Instantiate<Transform>();
|
||||
var critical = isOnCriticalPath && (ActionGameManager.CurrentGalaxy.ExitPath?.Contains(adjacentZone) ?? false);
|
||||
linksToReveal.Add((zone.Position, adjacentZone.Position, link, critical));
|
||||
if (zone.Owner != null && zone.Owner == adjacentZone.Owner)
|
||||
link.GetComponent<MeshRenderer>().sharedMaterial = _factionMaterials[zone.Owner].linkMaterial;
|
||||
|
||||
var dir = normalize(zone.Position - adjacentZone.Position);
|
||||
link.rotation = Quaternion.Euler(0,0,atan2(dir.y,dir.x) * Mathf.Rad2Deg);
|
||||
|
||||
placeLink(zone.Position, adjacentZone.Position, link, 0, critical);
|
||||
}
|
||||
}
|
||||
_revealedZones.Add(zone);
|
||||
|
||||
// Determine center of mass for adjacent zone links, used for placement of label and icons
|
||||
var linkDirection = normalize(zone.AdjacentZones
|
||||
.Aggregate(float2.zero, (v, adjacentZone) => v + normalize(adjacentZone.Position - zone.Position)));
|
||||
|
||||
var zoneText = zoneInstance.Label;
|
||||
zoneText.text = zone.Name;
|
||||
var zoneTextTransform = zoneText.GetComponent<RectTransform>();
|
||||
zoneTextTransform.pivot = new Vector2(sign(linkDirection.x)/2+.5f,sign(linkDirection.y)/2+.5f);
|
||||
zoneTextTransform.localPosition = new Vector3(-linkDirection.x * LabelDistance, -linkDirection.y * LabelDistance, -1);
|
||||
|
||||
if (zone == ActionGameManager.CurrentGalaxy.Entrance)
|
||||
{
|
||||
var iconInstance = IconPrototype.Instantiate<MeshRenderer>();
|
||||
iconInstance.material.mainTexture = EntranceIcon;
|
||||
var iconTransform = iconInstance.transform;
|
||||
iconTransform.SetParent(zoneInstanceTransform);
|
||||
iconTransform.localScale = Vector3.one;
|
||||
iconTransform.localPosition = new Vector3(-linkDirection.x * IconDistance, -linkDirection.y * IconDistance);
|
||||
}
|
||||
|
||||
var dir = normalize(start - end);
|
||||
linkInstance.rotation = Quaternion.Euler(0, 0, atan2(dir.y, dir.x) * Mathf.Rad2Deg);
|
||||
placeLink(start, end, linkInstance, 0, critical);
|
||||
_revealedLinks.Add((zone.ZoneIndex, adjacentIndex));
|
||||
if (zone == ActionGameManager.CurrentGalaxy.Exit)
|
||||
{
|
||||
var iconInstance = IconPrototype.Instantiate<MeshRenderer>();
|
||||
iconInstance.material.mainTexture = ExitIcon;
|
||||
var iconTransform = iconInstance.transform;
|
||||
iconTransform.SetParent(zoneInstanceTransform);
|
||||
iconTransform.localScale = Vector3.one;
|
||||
iconTransform.localPosition = new Vector3(-linkDirection.x * IconDistance, -linkDirection.y * IconDistance);
|
||||
}
|
||||
|
||||
var homeMega = ActionGameManager.CurrentGalaxy.HomeZones.Keys
|
||||
.FirstOrDefault(m => ActionGameManager.CurrentGalaxy.HomeZones[m] == zone);
|
||||
if (homeMega != null)
|
||||
{
|
||||
var backgroundInstance = IconBackgroundPrototype.Instantiate<MeshRenderer>();
|
||||
var iconInstance = IconPrototype.Instantiate<MeshRenderer>();
|
||||
|
||||
backgroundInstance.material.SetColor("_Color", homeMega.SecondaryColor.ToColor());
|
||||
iconInstance.material.mainTexture = HomeIcon;
|
||||
iconInstance.material.SetColor("_Color", homeMega.PrimaryColor.ToColor());
|
||||
|
||||
var backgroundTransform = backgroundInstance.transform;
|
||||
var iconTransform = iconInstance.transform;
|
||||
|
||||
backgroundTransform.SetParent(zoneInstanceTransform);
|
||||
iconTransform.SetParent(zoneInstanceTransform);
|
||||
|
||||
backgroundTransform.localScale = Vector3.one * IconBackgroundSize;
|
||||
iconTransform.localScale = Vector3.one;
|
||||
|
||||
backgroundTransform.localPosition = new Vector3(-linkDirection.x * IconDistance, -linkDirection.y * IconDistance, .5f);
|
||||
iconTransform.localPosition = new Vector3(-linkDirection.x * IconDistance, -linkDirection.y * IconDistance);
|
||||
}
|
||||
|
||||
var bossMega = ActionGameManager.CurrentGalaxy.BossZones.Keys
|
||||
.FirstOrDefault(m => ActionGameManager.CurrentGalaxy.BossZones[m] == zone);
|
||||
if (bossMega != null)
|
||||
{
|
||||
var backgroundInstance = IconBackgroundPrototype.Instantiate<MeshRenderer>();
|
||||
var iconInstance = IconPrototype.Instantiate<MeshRenderer>();
|
||||
|
||||
backgroundInstance.material.SetColor("_Color", bossMega.SecondaryColor.ToColor());
|
||||
iconInstance.material.mainTexture = BossIcon;
|
||||
iconInstance.material.SetColor("_Color", bossMega.PrimaryColor.ToColor());
|
||||
|
||||
var backgroundTransform = backgroundInstance.transform;
|
||||
var iconTransform = iconInstance.transform;
|
||||
|
||||
backgroundTransform.SetParent(zoneInstanceTransform);
|
||||
iconTransform.SetParent(zoneInstanceTransform);
|
||||
|
||||
backgroundTransform.localScale = Vector3.one * IconBackgroundSize;
|
||||
iconTransform.localScale = Vector3.one;
|
||||
|
||||
if (homeMega != null)
|
||||
{
|
||||
backgroundTransform.localPosition = new Vector3(linkDirection.x * IconDistance, linkDirection.y * IconDistance, .5f);
|
||||
iconTransform.localPosition = new Vector3(linkDirection.x * IconDistance, linkDirection.y * IconDistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
backgroundTransform.localPosition = new Vector3(-linkDirection.x * IconDistance, -linkDirection.y * IconDistance, .5f);
|
||||
iconTransform.localPosition = new Vector3(-linkDirection.x * IconDistance, -linkDirection.y * IconDistance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_revealedZones.Add(zone.ZoneIndex);
|
||||
var linkDirection = ResolveLabelDirection(zone);
|
||||
var zoneText = zoneInstance.Label;
|
||||
zoneText.text = zone.Name;
|
||||
var zoneTextTransform = zoneText.GetComponent<RectTransform>();
|
||||
zoneTextTransform.pivot = new Vector2(sign(linkDirection.x) / 2 + .5f, sign(linkDirection.y) / 2 + .5f);
|
||||
zoneTextTransform.localPosition = new Vector3(-linkDirection.x * LabelDistance, -linkDirection.y * LabelDistance, -1);
|
||||
|
||||
if (zone.Entrance)
|
||||
AddZoneIcon(zoneInstanceTransform, EntranceIcon, linkDirection, -1);
|
||||
|
||||
if (zone.Exit)
|
||||
AddZoneIcon(zoneInstanceTransform, ExitIcon, linkDirection, zone.Entrance ? 1 : -1);
|
||||
}
|
||||
foreach (var tr in zoneTransforms) tr.gameObject.SetActive(false);
|
||||
|
||||
// Local function for animating the placement of a link
|
||||
void placeLink(float2 start, float2 end, Transform link, float t, bool critical)
|
||||
{
|
||||
var pos = lerp(start, end, t / 2);
|
||||
link.localPosition = new Vector3(pos.x, pos.y);
|
||||
link.localScale = new Vector3(length(start - end) * t, critical ? CriticalLinkWidth : LinkWidth, 1);
|
||||
|
||||
var localScale = link.localScale;
|
||||
localScale = new Vector3(length(start - end)*t, critical ? CriticalLinkWidth : LinkWidth, 1);
|
||||
link.localScale = localScale;
|
||||
}
|
||||
|
||||
var startTime = Time.time;
|
||||
while (Time.time - startTime < linkDuration)
|
||||
{
|
||||
var t = (Time.time - startTime) / linkDuration;
|
||||
foreach (var (start, end, link, critical) in linksToReveal)
|
||||
placeLink(end, start, link, t, critical);
|
||||
foreach (var (start, end, link, critical) in linksToReveal) placeLink(end, start, link, t, critical);
|
||||
|
||||
yield return null;
|
||||
}
|
||||
foreach (var (start, end, link, critical) in linksToReveal)
|
||||
placeLink(start, end, link, 1, critical);
|
||||
|
||||
foreach (var tr in zoneTransforms)
|
||||
tr.gameObject.SetActive(true);
|
||||
foreach (var (start, end, link, critical) in linksToReveal) placeLink(start, end, link, 1, critical);
|
||||
|
||||
foreach (var tr in zoneTransforms) tr.gameObject.SetActive(true);
|
||||
startTime = Time.time;
|
||||
while (Time.time - startTime < iconDuration)
|
||||
{
|
||||
var t = (Time.time - startTime) / iconDuration;
|
||||
foreach (var tr in zoneTransforms)
|
||||
tr.localScale = zoneInstanceScale * IconScaleAnimation.Evaluate(t);
|
||||
foreach (var tr in zoneTransforms) tr.localScale = zoneInstanceScale * IconScaleAnimation.Evaluate(t);
|
||||
RenderInfluence();
|
||||
|
||||
yield return null;
|
||||
}
|
||||
foreach (var tr in zoneTransforms)
|
||||
tr.localScale = zoneInstanceScale;
|
||||
foreach (var tr in zoneTransforms) tr.localScale = zoneInstanceScale;
|
||||
|
||||
StartReveal(linkDuration, iconDuration);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
EnsureSectorMapLoaded();
|
||||
DisableLegacyInfluenceCamera();
|
||||
}
|
||||
|
||||
private void EnsureSectorMapLoaded()
|
||||
{
|
||||
_runtimeState ??= AetheriaUnityRuntimeClientProvider.RuntimeState("unity-sector-map");
|
||||
_sectorMap = _runtimeState.SectorMap.Latest();
|
||||
|
||||
if (_sectorMapLoaded)
|
||||
return;
|
||||
|
||||
_sectorMapLoaded = true;
|
||||
|
||||
if (_sectorMap?.Zones == null || _sectorMap.Zones.Count == 0)
|
||||
if (ActionGameManager.CurrentGalaxy == null)
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
_zonesByIndex.Clear();
|
||||
foreach (var zone in _sectorMap.Zones)
|
||||
_zonesByIndex[zone.ZoneIndex] = zone;
|
||||
|
||||
foreach (var factionIndex in ResolveFactionIndices())
|
||||
AddFactionMaterials(factionIndex);
|
||||
|
||||
QueueZoneReveal(_sectorMap.DiscoveredZoneIndices);
|
||||
|
||||
if (_queuedZoneReveals.Count == 0)
|
||||
QueueZoneReveal(_sectorMap.Zones.Select(zone => zone.ZoneIndex));
|
||||
|
||||
if (_sectorMap.CurrentZoneIndex >= 0)
|
||||
TryMarkPlayerLocation(_sectorMap.CurrentZoneIndex);
|
||||
}
|
||||
|
||||
private void AddFactionMaterials(int factionIndex)
|
||||
{
|
||||
if (_factionMaterials.ContainsKey(factionIndex))
|
||||
return;
|
||||
|
||||
var primaryColor = ResolveFactionColor(factionIndex, secondary: false);
|
||||
var secondaryColor = ResolveFactionColor(factionIndex, secondary: true);
|
||||
var influenceTexture = new RenderTexture(1024, 1024, 0, RenderTextureFormat.RHalf);
|
||||
var influenceRenderer = InfluenceRendererPrototype.Instantiate<MeshRenderer>();
|
||||
influenceRenderer.material.mainTexture = influenceTexture;
|
||||
influenceRenderer.material.SetColor("_Color1", primaryColor);
|
||||
influenceRenderer.material.SetColor("_Color2", secondaryColor);
|
||||
influenceRenderer.material.SetFloat("_FillTilt", Random.value * PI);
|
||||
|
||||
var primary = Instantiate(ZonePrimaryMaterial);
|
||||
primary.SetColor("_Color", primaryColor * MegaPrimaryBoost);
|
||||
|
||||
var secondary = Instantiate(ZoneSecondaryMaterial);
|
||||
secondary.SetColor("_Color", secondaryColor * MegaSecondaryBoost);
|
||||
|
||||
var link = Instantiate(ZoneLinkMaterial);
|
||||
link.SetColor("_Color", primaryColor * MegaLinkBoost);
|
||||
|
||||
_factionMaterials.Add(factionIndex, (influenceRenderer, influenceTexture, primary, secondary, link));
|
||||
|
||||
var legendElement = LegendPrototype.Instantiate<LegendElement>();
|
||||
legendElement.Primary.color = primaryColor;
|
||||
legendElement.Secondary.color = secondaryColor;
|
||||
legendElement.Label.text = factionIndex < 0 ? "None" : $"F{factionIndex}";
|
||||
}
|
||||
|
||||
private IEnumerable<int> ResolveFactionIndices()
|
||||
{
|
||||
return (_sectorMap?.Zones ?? Array.Empty<AetheriaRuntimeSectorMapZone>())
|
||||
.SelectMany(zone => (zone.FactionIndices ?? Array.Empty<int>()).Append(zone.OwnerFactionIndex))
|
||||
.Where(index => index >= 0)
|
||||
.Distinct()
|
||||
.OrderBy(index => index);
|
||||
}
|
||||
|
||||
private Color ResolveFactionColor(int factionIndex, bool secondary)
|
||||
{
|
||||
var hue = frac((factionIndex + (secondary ? 0.37f : 0f)) * 0.173f);
|
||||
return Color.HSVToRGB(hue, secondary ? 0.48f : 0.62f, secondary ? 0.72f : 0.88f);
|
||||
}
|
||||
|
||||
private IEnumerable<AetheriaRuntimeSectorMapLink> LinksForZone(int zoneIndex)
|
||||
{
|
||||
return (_sectorMap?.Links ?? Array.Empty<AetheriaRuntimeSectorMapLink>())
|
||||
.Where(link => link.FromZoneIndex == zoneIndex || link.ToZoneIndex == zoneIndex);
|
||||
}
|
||||
|
||||
private float2 ResolveLabelDirection(AetheriaRuntimeSectorMapZone zone)
|
||||
{
|
||||
var direction = float2.zero;
|
||||
foreach (var adjacentIndex in zone.AdjacentZoneIndices ?? Array.Empty<int>())
|
||||
foreach (var mega in ActionGameManager.CurrentGalaxy.Factions)
|
||||
{
|
||||
if (_zonesByIndex.TryGetValue(adjacentIndex, out var adjacent))
|
||||
direction += normalizesafe(Position(adjacent) - Position(zone));
|
||||
var influenceTexture = new RenderTexture(1024, 1024, 0, RenderTextureFormat.RHalf);
|
||||
var influenceRenderer = InfluenceRendererPrototype.Instantiate<MeshRenderer>();
|
||||
|
||||
influenceRenderer.material.mainTexture = influenceTexture;
|
||||
influenceRenderer.material.SetColor("_Color1", mega.PrimaryColor.ToColor());
|
||||
influenceRenderer.material.SetColor("_Color2", mega.SecondaryColor.ToColor());
|
||||
influenceRenderer.material.SetFloat("_FillTilt", Random.value * PI);
|
||||
|
||||
var primary = Instantiate(ZonePrimaryMaterial);
|
||||
primary.SetColor("_Color", (mega.PrimaryColor * MegaPrimaryBoost).ToColor());
|
||||
|
||||
var secondary = Instantiate(ZoneSecondaryMaterial);
|
||||
secondary.SetColor("_Color", (mega.SecondaryColor * MegaSecondaryBoost).ToColor());
|
||||
|
||||
var link = Instantiate(ZoneLinkMaterial);
|
||||
link.SetColor("_Color", (mega.PrimaryColor * MegaLinkBoost).ToColor());
|
||||
|
||||
_factionMaterials.Add(mega, (influenceRenderer, influenceTexture, primary, secondary, link));
|
||||
|
||||
var legendElement = LegendPrototype.Instantiate<LegendElement>();
|
||||
legendElement.Primary.color = mega.PrimaryColor.ToColor();
|
||||
legendElement.Secondary.color = mega.SecondaryColor.ToColor();
|
||||
legendElement.Label.text = mega.ShortName;
|
||||
}
|
||||
|
||||
return lengthsq(direction) <= 0 ? new float2(0, 1) : normalize(direction);
|
||||
}
|
||||
|
||||
private void AddZoneIcon(
|
||||
Transform zoneInstanceTransform,
|
||||
Texture2D icon,
|
||||
float2 linkDirection,
|
||||
int side)
|
||||
{
|
||||
var iconInstance = IconPrototype.Instantiate<MeshRenderer>();
|
||||
iconInstance.material.mainTexture = icon;
|
||||
var iconTransform = iconInstance.transform;
|
||||
iconTransform.SetParent(zoneInstanceTransform);
|
||||
iconTransform.localScale = Vector3.one;
|
||||
iconTransform.localPosition = new Vector3(
|
||||
side * -linkDirection.x * IconDistance,
|
||||
side * -linkDirection.y * IconDistance);
|
||||
SectorRenderer.material.SetFloat("CloudAmplitude", ActionGameManager.CurrentGalaxy.Background.CloudAmplitude);
|
||||
SectorRenderer.material.SetFloat("CloudExponent", ActionGameManager.CurrentGalaxy.Background.CloudExponent);
|
||||
SectorRenderer.material.SetFloat("NoisePosition", ActionGameManager.CurrentGalaxy.Background.NoisePosition);
|
||||
SectorRenderer.material.SetFloat("NoiseAmplitude", ActionGameManager.CurrentGalaxy.Background.NoiseAmplitude);
|
||||
SectorRenderer.material.SetFloat("NoiseOffset", ActionGameManager.CurrentGalaxy.Background.NoiseOffset);
|
||||
SectorRenderer.material.SetFloat("NoiseGain", ActionGameManager.CurrentGalaxy.Background.NoiseGain);
|
||||
SectorRenderer.material.SetFloat("NoiseLacunarity", ActionGameManager.CurrentGalaxy.Background.NoiseLacunarity);
|
||||
SectorRenderer.material.SetFloat("NoiseFrequency", ActionGameManager.CurrentGalaxy.Background.NoiseFrequency);
|
||||
}
|
||||
|
||||
private void RenderInfluence()
|
||||
{
|
||||
DisableLegacyInfluenceCamera();
|
||||
foreach (var pair in _factionMaterials)
|
||||
// Render Influence Textures
|
||||
foreach (var mega in ActionGameManager.CurrentGalaxy.Factions)
|
||||
{
|
||||
var document = BuildInfluenceSplatDocument(pair.Key);
|
||||
ResolveInfluenceSplatRasterizer().RenderLayerToTarget(
|
||||
document,
|
||||
pair.Value.influence,
|
||||
0,
|
||||
0,
|
||||
Color.clear);
|
||||
}
|
||||
}
|
||||
|
||||
private AetheriaRenderSplatRasterizer ResolveInfluenceSplatRasterizer()
|
||||
{
|
||||
if (InfluenceSplatRasterizer != null)
|
||||
return InfluenceSplatRasterizer;
|
||||
|
||||
InfluenceSplatRasterizer = GetComponent<AetheriaRenderSplatRasterizer>();
|
||||
if (InfluenceSplatRasterizer == null)
|
||||
InfluenceSplatRasterizer = gameObject.AddComponent<AetheriaRenderSplatRasterizer>();
|
||||
return InfluenceSplatRasterizer;
|
||||
}
|
||||
|
||||
private EveFieldsSplatsDocument BuildInfluenceSplatDocument(int factionIndex)
|
||||
{
|
||||
var zones = (_sectorMap?.Zones ?? Array.Empty<AetheriaRuntimeSectorMapZone>()).ToArray();
|
||||
var minX = zones.Length > 0 ? zones.Min(zone => zone.X) : -1;
|
||||
var maxX = zones.Length > 0 ? zones.Max(zone => zone.X) : 1;
|
||||
var minY = zones.Length > 0 ? zones.Min(zone => zone.Y) : -1;
|
||||
var maxY = zones.Length > 0 ? zones.Max(zone => zone.Y) : 1;
|
||||
var padding = Math.Max(IconBackgroundSize * 2, 4);
|
||||
|
||||
var centerX = new List<double>();
|
||||
var centerY = new List<double>();
|
||||
var halfExtentX = new List<double>();
|
||||
var halfExtentY = new List<double>();
|
||||
var rotationCos = new List<double>();
|
||||
var rotationSin = new List<double>();
|
||||
var channel = new List<int>();
|
||||
var falloff = new List<int>();
|
||||
var valueR = new List<double>();
|
||||
var valueG = new List<double>();
|
||||
var valueB = new List<double>();
|
||||
var valueA = new List<double>();
|
||||
var sourceKey = new List<string>();
|
||||
var layerIndex = new List<int>();
|
||||
var sourceKind = new List<int>();
|
||||
var frequencyX = new List<double>();
|
||||
var frequencyY = new List<double>();
|
||||
var phaseX = new List<double>();
|
||||
var phaseY = new List<double>();
|
||||
var animationSpeed = new List<double>();
|
||||
var sourceFlags = new List<double>();
|
||||
|
||||
foreach (var zone in zones)
|
||||
{
|
||||
if (!_zoneInstances.ContainsKey(zone.ZoneIndex))
|
||||
continue;
|
||||
|
||||
var influence = ResolveZoneInfluence(zone, factionIndex);
|
||||
if (Math.Abs(influence) <= 0.0001f)
|
||||
continue;
|
||||
|
||||
centerX.Add(zone.X);
|
||||
centerY.Add(zone.Y);
|
||||
halfExtentX.Add(Math.Max(IconBackgroundSize, 1));
|
||||
halfExtentY.Add(Math.Max(IconBackgroundSize, 1));
|
||||
rotationCos.Add(1);
|
||||
rotationSin.Add(0);
|
||||
channel.Add(AetheriaRuntimeRenderSplatChannels.Influence);
|
||||
falloff.Add(AetheriaRuntimeRenderSplatFalloffs.Smooth);
|
||||
valueR.Add(influence);
|
||||
valueG.Add(influence);
|
||||
valueB.Add(influence);
|
||||
valueA.Add(1);
|
||||
sourceKey.Add($"sector-zone:{zone.ZoneIndex}:faction:{factionIndex}");
|
||||
layerIndex.Add(0);
|
||||
sourceKind.Add(AetheriaRuntimeRenderSplatSourceKinds.Constant);
|
||||
frequencyX.Add(0);
|
||||
frequencyY.Add(0);
|
||||
phaseX.Add(0);
|
||||
phaseY.Add(0);
|
||||
animationSpeed.Add(0);
|
||||
sourceFlags.Add(0);
|
||||
}
|
||||
|
||||
return new EveFieldsSplatsDocument
|
||||
{
|
||||
Schema = AetheriaRuntimeDaemonSchemas.RenderSplatsViewport,
|
||||
Viewport = new EveFieldsViewport
|
||||
foreach (var zone in ActionGameManager.CurrentGalaxy.Zones)
|
||||
{
|
||||
MinX = minX - padding,
|
||||
MinY = minY - padding,
|
||||
MaxX = maxX + padding,
|
||||
MaxY = maxY + padding
|
||||
},
|
||||
Layers = new[]
|
||||
{
|
||||
new EveFieldsSplatLayer
|
||||
if(_zoneInstances.ContainsKey(zone))
|
||||
{
|
||||
LayerKey = AetheriaRuntimeRenderSplatLayerKeys.Influence,
|
||||
DisplayName = "Sector Influence",
|
||||
Channel = AetheriaRuntimeRenderSplatChannels.Influence,
|
||||
BlendMode = AetheriaRuntimeRenderSplatBlendModes.Add,
|
||||
GraphicsFormat = "R16_SFloat"
|
||||
var instance = _zoneInstances[zone];
|
||||
var influence = 0f;
|
||||
if (zone.Factions.Length > 0)
|
||||
{
|
||||
if (zone.Factions.Contains(mega))
|
||||
{
|
||||
influence = 10;
|
||||
if (zone.Owner != mega)
|
||||
influence *= .5f;
|
||||
}
|
||||
else influence = -10;
|
||||
}
|
||||
|
||||
instance.Influence.material.SetFloat("_Depth", influence);
|
||||
}
|
||||
},
|
||||
Splats = new EveFieldsSplatSoa
|
||||
{
|
||||
Count = centerX.Count,
|
||||
CenterX = centerX,
|
||||
CenterY = centerY,
|
||||
HalfExtentX = halfExtentX,
|
||||
HalfExtentY = halfExtentY,
|
||||
RotationCos = rotationCos,
|
||||
RotationSin = rotationSin,
|
||||
Channel = channel,
|
||||
Falloff = falloff,
|
||||
ValueR = valueR,
|
||||
ValueG = valueG,
|
||||
ValueB = valueB,
|
||||
ValueA = valueA,
|
||||
SourceKey = sourceKey,
|
||||
LayerIndex = layerIndex,
|
||||
SourceKind = sourceKind,
|
||||
FrequencyX = frequencyX,
|
||||
FrequencyY = frequencyY,
|
||||
PhaseX = phaseX,
|
||||
PhaseY = phaseY,
|
||||
AnimationSpeed = animationSpeed,
|
||||
SourceFlags = sourceFlags
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static float ResolveZoneInfluence(AetheriaRuntimeSectorMapZone zone, int factionIndex)
|
||||
{
|
||||
if (zone.FactionIndices?.Count <= 0)
|
||||
return 0f;
|
||||
|
||||
if (!zone.FactionIndices.Contains(factionIndex))
|
||||
return -10f;
|
||||
|
||||
return zone.OwnerFactionIndex == factionIndex ? 10f : 5f;
|
||||
}
|
||||
|
||||
private void DisableLegacyInfluenceCamera()
|
||||
{
|
||||
if (InfluenceCamera == null)
|
||||
return;
|
||||
|
||||
InfluenceCamera.targetTexture = null;
|
||||
InfluenceCamera.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
private static float2 Position(AetheriaRuntimeSectorMapZone zone)
|
||||
{
|
||||
return new float2((float)zone.X, (float)zone.Y);
|
||||
InfluenceCamera.targetTexture = _factionMaterials[mega].influence;
|
||||
InfluenceCamera.Render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue