161 lines
5.4 KiB
C#
161 lines
5.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using Intrepid.Gameplay.Journey;
|
|
using UnityEditor;
|
|
|
|
namespace Editor.GON.WorldEditor
|
|
{
|
|
public static class JourneyCommitter
|
|
{
|
|
public static List<WorldValidationMessage> Commit(WorldLayoutSO layout, JGraphSO graph)
|
|
{
|
|
var messages = WorldLayoutValidator.Validate(layout);
|
|
if (WorldLayoutValidator.HasErrors(messages) || graph is null)
|
|
{
|
|
if (graph is null)
|
|
{
|
|
messages.Add(new WorldValidationMessage(WorldValidationSeverity.Error, "No target JGraphSO selected."));
|
|
}
|
|
|
|
return messages;
|
|
}
|
|
|
|
layout.EnsureDefaults();
|
|
graph.sourceWorldLayoutId = layout.id;
|
|
graph.publishedAt = DateTime.UtcNow.ToString("O");
|
|
graph.schemaVersion = 1;
|
|
graph.stages = BuildStages(layout);
|
|
graph.endpoints = BuildEndpoints(layout);
|
|
graph.connections = BuildConnections(layout);
|
|
graph.contentHash = ComputeContentHash(graph);
|
|
graph.EnsureDefaults();
|
|
|
|
EditorUtility.SetDirty(graph);
|
|
AssetDatabase.SaveAssets();
|
|
return messages;
|
|
}
|
|
|
|
private static List<JStage> BuildStages(WorldLayoutSO layout)
|
|
{
|
|
var stages = new List<JStage>();
|
|
foreach (var source in layout.stages)
|
|
{
|
|
if (source is null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
source.EnsureDefaults();
|
|
var stage = new JStage
|
|
{
|
|
id = source.id,
|
|
displayName = source.displayName,
|
|
worldLayer = source.worldLayer,
|
|
occupiedTiles = new List<JWorldTile>(source.occupiedTiles)
|
|
};
|
|
if (source.stageKind == WorldStageKind.SavePoint)
|
|
{
|
|
stage.tags.Add(WorldLayoutSO.SavePointTag);
|
|
}
|
|
|
|
stages.Add(stage);
|
|
}
|
|
|
|
return stages;
|
|
}
|
|
|
|
private static List<JEndpoint> BuildEndpoints(WorldLayoutSO layout)
|
|
{
|
|
var endpoints = new List<JEndpoint>();
|
|
foreach (var source in layout.endpoints)
|
|
{
|
|
if (source is null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
endpoints.Add(new JEndpoint
|
|
{
|
|
id = source.id,
|
|
stageId = source.stageId,
|
|
worldTile = source.worldTile,
|
|
kind = source.kind,
|
|
required = source.required,
|
|
socketFace = source.socketFace
|
|
});
|
|
}
|
|
|
|
return endpoints;
|
|
}
|
|
|
|
private static List<JConnection> BuildConnections(WorldLayoutSO layout)
|
|
{
|
|
var connections = new List<JConnection>();
|
|
foreach (var source in layout.connections)
|
|
{
|
|
if (source is null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
connections.Add(new JConnection
|
|
{
|
|
id = source.id,
|
|
endpointAId = source.endpointAId,
|
|
endpointBId = source.endpointBId,
|
|
directionality = source.directionality
|
|
});
|
|
}
|
|
|
|
return connections;
|
|
}
|
|
|
|
private static string ComputeContentHash(JGraphSO graph)
|
|
{
|
|
var builder = new StringBuilder();
|
|
builder.Append(graph.sourceWorldLayoutId).Append('|').Append(graph.schemaVersion).AppendLine();
|
|
|
|
foreach (var stage in graph.stages)
|
|
{
|
|
builder.Append("S|").Append(stage.id).Append('|').Append(stage.displayName).Append('|')
|
|
.Append(stage.worldLayer).AppendLine();
|
|
foreach (var tag in stage.tags)
|
|
{
|
|
builder.Append("G|").Append(tag).AppendLine();
|
|
}
|
|
|
|
foreach (var tile in stage.occupiedTiles)
|
|
{
|
|
builder.Append("T|").Append(tile.x).Append('|').Append(tile.y).AppendLine();
|
|
}
|
|
}
|
|
|
|
foreach (var endpoint in graph.endpoints)
|
|
{
|
|
builder.Append("E|").Append(endpoint.id).Append('|').Append(endpoint.stageId).Append('|')
|
|
.Append(endpoint.worldTile.x).Append('|').Append(endpoint.worldTile.y).Append('|')
|
|
.Append(endpoint.kind).Append('|').Append(endpoint.required).Append('|')
|
|
.Append(endpoint.socketFace).AppendLine();
|
|
}
|
|
|
|
foreach (var connection in graph.connections)
|
|
{
|
|
builder.Append("C|").Append(connection.id).Append('|').Append(connection.endpointAId).Append('|')
|
|
.Append(connection.endpointBId).Append('|').Append(connection.directionality).AppendLine();
|
|
}
|
|
|
|
using var sha = SHA256.Create();
|
|
var bytes = sha.ComputeHash(Encoding.UTF8.GetBytes(builder.ToString()));
|
|
var result = new StringBuilder(bytes.Length * 2);
|
|
foreach (var value in bytes)
|
|
{
|
|
result.Append(value.ToString("x2"));
|
|
}
|
|
|
|
return result.ToString();
|
|
}
|
|
}
|
|
}
|