Add junction support

This commit is contained in:
Pyro Nicampt committed 2025-03-04 22:50:26 -06:00
1 parent a8686a08c0
commit d11a3a57b7
7 files changed
+24377 -18678

No files matched your search

+1 -1
View File
@@ -2,7 +2,7 @@
"Id":"CommunityMapTool", "Id":"CommunityMapTool",
"DisplayName":"Derail Valley Community Map Tool", "DisplayName":"Derail Valley Community Map Tool",
"Author":"PyroNicampt", "Author":"PyroNicampt",
"Version":"1.0.0", "Version":"1.1.0",
"ManagerVersion":"0.31.1.0", "ManagerVersion":"0.31.1.0",
"EntryMethod":"CommunityMapTool.Main.Load" "EntryMethod":"CommunityMapTool.Main.Load"
} }
+31 -4
View File
@@ -5,6 +5,7 @@ using System.Text;
using UnityEngine; using UnityEngine;
using UnityModManagerNet; using UnityModManagerNet;
using DV.LocoRestoration; using DV.LocoRestoration;
using DV;
namespace CommunityMapTool { namespace CommunityMapTool {
[EnableReloading] [EnableReloading]
@@ -26,6 +27,8 @@ namespace CommunityMapTool {
} }
} }
static void OnGUI(UnityModManager.ModEntry modEntry) { static void OnGUI(UnityModManager.ModEntry modEntry) {
if(PlayerManager.PlayerTransform != null) GUILayout.Label($"Player Position: {PlayerManager.PlayerTransform.AbsolutePosition()}");
GUILayout.Label($"WorldMover offset: {WorldMover.currentMove}");
if(GUILayout.Button("Dump All Tracks")) DumpAllTracks(); if(GUILayout.Button("Dump All Tracks")) DumpAllTracks();
if(GUILayout.Button("Dump Demonstrator Spawnpoints")) DemonstratorDump(); if(GUILayout.Button("Dump Demonstrator Spawnpoints")) DemonstratorDump();
if(GUILayout.Button("Copy Position To Clipboard")) ClipboardPlayerPosition(); if(GUILayout.Button("Copy Position To Clipboard")) ClipboardPlayerPosition();
@@ -38,7 +41,7 @@ namespace CommunityMapTool {
} }
static void DumpAllTracks() { static void DumpAllTracks() {
List<string> records = new List<string>(); List<string> records = new List<string>();
foreach(RailTrack railTrack in UnityEngine.Object.FindObjectsOfType<RailTrack>()) { foreach(RailTrack railTrack in WorldData.RailTracks) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
string[] baseCurveData = new[] { string[] baseCurveData = new[] {
"type", "bezier", "type", "bezier",
@@ -54,15 +57,39 @@ namespace CommunityMapTool {
for(int i = 0; i < railTrack.curve.pointCount; i++) { for(int i = 0; i < railTrack.curve.pointCount; i++) {
BezierPoint point = railTrack.curve[i]; BezierPoint point = railTrack.curve[i];
sb.Append("\n\t\t{"); sb.Append("\n\t\t{");
sb.Append($"\"position\":{{\"x\":{point.position.x},\"y\":{point.position.y},\"z\":{point.position.z}}}, "); sb.Append($"\"position\":{{\"x\":{point.position.x - WorldMover.currentMove.x},\"y\":{point.position.y - WorldMover.currentMove.y},\"z\":{point.position.z - WorldMover.currentMove.z}}}, ");
sb.Append($"\"h1\":{{\"x\":{point.globalHandle1.x},\"y\":{point.globalHandle1.y},\"z\":{point.globalHandle1.z}}}, "); sb.Append($"\"h1\":{{\"x\":{point.globalHandle1.x - WorldMover.currentMove.x},\"y\":{point.globalHandle1.y - WorldMover.currentMove.y},\"z\":{point.globalHandle1.z - WorldMover.currentMove.z}}}, ");
sb.Append($"\"h2\":{{\"x\":{point.globalHandle2.x},\"y\":{point.globalHandle2.y},\"z\":{point.globalHandle2.z}}}, "); sb.Append($"\"h2\":{{\"x\":{point.globalHandle2.x - WorldMover.currentMove.x},\"y\":{point.globalHandle2.y - WorldMover.currentMove.y},\"z\":{point.globalHandle2.z - WorldMover.currentMove.z}}}, ");
sb.Append($"\"type\":\"{point.handleStyle}\""); sb.Append($"\"type\":\"{point.handleStyle}\"");
sb.Append(i + 1 < railTrack.curve.pointCount ? "}," : "}"); sb.Append(i + 1 < railTrack.curve.pointCount ? "}," : "}");
} }
sb.Append("\n\t]\n}"); sb.Append("\n\t]\n}");
records.Add(sb.ToString()); records.Add(sb.ToString());
} }
foreach(Junction junction in WorldData.Junctions) {
StringBuilder sb = new StringBuilder();
string[] baseJunctionData = new[] {
"type", "\"junction\"",
"name", $"\"{junction.junctionData.junctionIdLong}\"",
"position", $"{{\"x\":{junction.junctionData.position.x},\"y\":{junction.junctionData.position.y},\"z\":{junction.junctionData.position.z}}}",
"excludeFromJunctionMap", junction.junctionData.excludeFromJunctionMap ? "true" : "false",
"isValid", junction.junctionData.isValid ? "true" : "false",
"linkedJunctions", $"[{string.Join(", ", junction.junctionData.linkedJunctions)}]",
"index", junction.junctionData.junctionIndex.ToString(),
"id", junction.junctionData.junctionId.ToString()
};
sb.Append("\n{");
for(int i = 0; i < baseJunctionData.Length; i++) {
if(i % 2 == 0) sb.Append($"\n\t\"{baseJunctionData[i]}\":");
else {
sb.Append($"{baseJunctionData[i]}");
if(i < baseJunctionData.Length - 1) sb.Append(",");
}
}
sb.Append("\n}");
records.Add(sb.ToString());
}
File.WriteAllText(trackOutputPath, "[" + string.Join(",", records.ToArray()) + "\n]"); File.WriteAllText(trackOutputPath, "[" + string.Join(",", records.ToArray()) + "\n]");
} }
static void DemonstratorDump() { static void DemonstratorDump() {
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.1.0.0")]
+6
View File
@@ -173,6 +173,12 @@
<use href="#speedSign"></use> <use href="#speedSign"></use>
<text class="signText" style="transform:translate(-35px, 20px)">12</text> <text class="signText" style="transform:translate(-35px, 20px)">12</text>
</g> </g>
<g id="junctionSign" transform="scale(20)" viewBox="0 0 20 20">
<g transform="translate(-10 -10)">
<rect ry="1.347" y="0.539" x="5.003" height="18.922" width="9.994" style="stroke:#ebebeb;stroke-width:0.9"></rect>
<rect ry="0.989" transform="rotate(22.53)" y="-3.763" x="12.079" height="18.335" width="1.979" style="fill:#ebebeb"></rect>
</g>
</g>
<g id="mrk_office" transform="scale(20)" viewBox="0 0 20 20"> <g id="mrk_office" transform="scale(20)" viewBox="0 0 20 20">
<circle r="10"></circle> <circle r="10"></circle>
<path transform="translate(-10 -10)" d="M10 3.8l5.56 6.03h-1.66v5.2h-2.51v-3.93h-2.78v3.93h-2.51v-5.2h-1.66z" fill="#fff"></path> <path transform="translate(-10 -10)" d="M10 3.8l5.56 6.03h-1.66v5.2h-2.51v-3.93h-2.78v3.93h-2.51v-5.2h-1.66z" fill="#fff"></path>
+45 -17
View File
@@ -293,14 +293,15 @@ function establishDimensions(){
let maxY = -Infinity; let maxY = -Infinity;
let maxAlt = -Infinity; let maxAlt = -Infinity;
for(const obj of mapData){ for(const obj of mapData){
for(const point of obj.points){ if(obj.type == 'bezier')
minX = Math.min(minX, point.position.x, point.h1.x, point.h2.x); for(const point of obj.points){
minY = Math.min(minY, point.position.z, point.h1.z, point.h2.z); minX = Math.min(minX, point.position.x, point.h1.x, point.h2.x);
minAlt = Math.min(minAlt, point.position.y, point.h1.y, point.h2.y); minY = Math.min(minY, point.position.z, point.h1.z, point.h2.z);
maxX = Math.max(maxX, point.position.x, point.h1.x, point.h2.x); minAlt = Math.min(minAlt, point.position.y, point.h1.y, point.h2.y);
maxY = Math.max(maxY, point.position.z, point.h1.z, point.h2.z); maxX = Math.max(maxX, point.position.x, point.h1.x, point.h2.x);
maxAlt = Math.max(maxAlt, point.position.y, point.h1.y, point.h2.y); maxY = Math.max(maxY, point.position.z, point.h1.z, point.h2.z);
} maxAlt = Math.max(maxAlt, point.position.y, point.h1.y, point.h2.y);
}
} }
let width = maxX-minX; let width = maxX-minX;
let height = maxY-minY; let height = maxY-minY;
@@ -331,11 +332,14 @@ function establishDimensions(){
// Flip the z coordinate so the map doesn't display upside-down // Flip the z coordinate so the map doesn't display upside-down
for(const obj of mapData){ for(const obj of mapData){
for(const point of obj.points){ if(obj.points)
point.position.z = minY+maxY-point.position.z; for(const point of obj.points){
point.h1.z = minY+maxY-point.h1.z; point.position.z = minY+maxY-point.position.z;
point.h2.z = minY+maxY-point.h2.z; point.h1.z = minY+maxY-point.h1.z;
} point.h2.z = minY+maxY-point.h2.z;
}
if(obj.position)
obj.position.z = minY+maxY-obj.position.z;
} }
} }
@@ -347,6 +351,9 @@ function fillSvg(){
drawTracks(obj); drawTracks(obj);
createTrackSignage(obj); createTrackSignage(obj);
break; break;
case 'junction':
addJunction(obj);
break;
} }
} }
createYardSignage(); createYardSignage();
@@ -567,6 +574,14 @@ function createYardSignage(){
} }
} }
function addJunction(junctionData){
if(junctionData.name.startsWith('S-') || junctionData.excludeFromJunctionMap)
junctionData.cullLevel = 4;
else if(junctionData.name.startsWith('W-'))
junctionData.cullLevel = 1;
markers.push(junctionData);
}
/** Sort the tracks and put them into the svg */ /** Sort the tracks and put them into the svg */
function sortTracks(){ function sortTracks(){
tracks.sort((a,b) => { tracks.sort((a,b) => {
@@ -660,10 +675,11 @@ export function setTrackColorMode(mode){
} }
if(modeFunction != null){ if(modeFunction != null){
for(let curve of mapData){ for(let curve of mapData){
for(let section of curve.points){ if(curve.type == 'bezier')
if(!section.element) continue; for(let section of curve.points){
modeFunction(section, curve); if(!section.element) continue;
} modeFunction(section, curve);
}
} }
} }
} }
@@ -674,16 +690,21 @@ function drawSignage(){
const gradeSigns = document.createElementNS(svgns, 'g'); const gradeSigns = document.createElementNS(svgns, 'g');
const speedSigns = document.createElementNS(svgns, 'g'); const speedSigns = document.createElementNS(svgns, 'g');
const yardSigns = document.createElementNS(svgns, 'g'); const yardSigns = document.createElementNS(svgns, 'g');
const junctionSigns = document.createElementNS(svgns, 'g');
signage_container.setAttribute('id', 'signage_container'); signage_container.setAttribute('id', 'signage_container');
gradeSigns.setAttribute('id', 'signage_grade'); gradeSigns.setAttribute('id', 'signage_grade');
speedSigns.setAttribute('id', 'signage_speed'); speedSigns.setAttribute('id', 'signage_speed');
yardSigns.setAttribute('id', 'signage_yard'); yardSigns.setAttribute('id', 'signage_yard');
junctionSigns.setAttribute('id', 'signage_junction');
map_markers.appendChild(signage_container); map_markers.appendChild(signage_container);
signage_container.appendChild(gradeSigns); signage_container.appendChild(gradeSigns);
signage_container.appendChild(speedSigns); signage_container.appendChild(speedSigns);
signage_container.appendChild(yardSigns); signage_container.appendChild(yardSigns);
signage_container.appendChild(junctionSigns);
junctionSigns.style.display = 'none';
for(const markerData of markers){ for(const markerData of markers){
let markerElement = document.createElementNS(svgns, 'g'); let markerElement = document.createElementNS(svgns, 'g');
@@ -773,6 +794,13 @@ function drawSignage(){
yardSigns.appendChild(markerElement); yardSigns.appendChild(markerElement);
break; break;
case 'junction':
markerImg.setAttribute('href', `#junctionSign`);
markerImg.setAttribute('fill', '#de2121');
markerTooltip.innerHTML = `"${markerData.name}" - #${markerData.index}\n${markerData.excludeFromJunctionMap ? 'Inv' : 'V'}isible On Map\nLinked Junctions:\n- ${markerData.linkedJunctions.join('\n- ')}`;
markerElement.setAttribute('transform', `translate(${markerData.position.x} ${markerData.position.z})`);
junctionSigns.appendChild(markerElement);
break;
default: default:
markerElement.remove(); markerElement.remove();
continue; continue;
+8
View File
@@ -54,6 +54,14 @@ let settingEntries = [
func: state =>{ func: state =>{
document.getElementById('signage_yard').style.display = state ? 'unset' : 'none'; document.getElementById('signage_yard').style.display = state ? 'unset' : 'none';
}, },
},
{
label: 'Junctions',
id: 'toggle_junctions',
state: false,
func: state =>{
document.getElementById('signage_junction').style.display = state ? 'unset' : 'none';
},
} }
], ],
}, },
+24284 -18654
View File
File diff suppressed because it is too large. Load diff