Added signs layer
+Added SignRenderer and sign parsing. For now only the W5 sign is defined
This commit is contained in:
parent
2408fda0c9
commit
95317798e5
7
public/assets/signs/w5.svg
Normal file
7
public/assets/signs/w5.svg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="100mm" height="100mm" version="1.1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g>
|
||||||
|
<path d="m50 8c-18.73 0-34 15.27-34 34v4h68v-4c0-18.73-15.27-34-34-34zm0 8c13.036 0 23.675 9.5208 25.6 22h-51.199c1.9247-12.479 12.564-22 25.6-22z" color="#000000" fill-rule="evenodd" style="-inkscape-stroke:none"/>
|
||||||
|
<path d="m50 39a4 4 0 0 0-4 4v45a4 4 0 0 0 4 4 4 4 0 0 0 4-4v-45a4 4 0 0 0-4-4z" color="#000000"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 482 B |
@ -63,4 +63,8 @@
|
|||||||
.map svg g.signalbox text {
|
.map svg g.signalbox text {
|
||||||
fill: #eee;
|
fill: #eee;
|
||||||
font-size: 4px;
|
font-size: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.map svg g.sign path {
|
||||||
|
fill: #eee;
|
||||||
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import TrackObjectRenderer from './object-renderers/TrackObjectRenderer';
|
|||||||
import SignalRenderer from './object-renderers/SignalRenderer';
|
import SignalRenderer from './object-renderers/SignalRenderer';
|
||||||
import RouteRenderer from './object-renderers/RouteRenderer';
|
import RouteRenderer from './object-renderers/RouteRenderer';
|
||||||
import SignalBoxRenderer from './object-renderers/SignalBoxRenderer';
|
import SignalBoxRenderer from './object-renderers/SignalBoxRenderer';
|
||||||
|
import SignRenderer from './object-renderers/SignRenderer';
|
||||||
|
|
||||||
const ObjectRendererQueue = [
|
const ObjectRendererQueue = [
|
||||||
{
|
{
|
||||||
@ -26,6 +27,13 @@ const ObjectRendererQueue = [
|
|||||||
'renderer': SwitchNameRenderer,
|
'renderer': SwitchNameRenderer,
|
||||||
'cond': (layers) => layers['switches-names']
|
'cond': (layers) => layers['switches-names']
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'name': 'signs',
|
||||||
|
'category': 'track-objects',
|
||||||
|
'type': 'Sign',
|
||||||
|
'renderer': SignRenderer,
|
||||||
|
'cond': (layers) => layers['signs']
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'name': 'signals',
|
'name': 'signals',
|
||||||
'category': 'track-objects',
|
'category': 'track-objects',
|
||||||
|
|||||||
25
src/components/map/object-renderers/SignRenderer.js
Normal file
25
src/components/map/object-renderers/SignRenderer.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { ReactSVG } from 'react-svg'
|
||||||
|
|
||||||
|
export default function SignRenderer(props) {
|
||||||
|
const { object } = props;
|
||||||
|
if(!object.def) return null;
|
||||||
|
|
||||||
|
const [x, y] = object.pos.toSVGCoords();
|
||||||
|
|
||||||
|
const offX = -1.89 + (object.def.offsetX || 0);
|
||||||
|
const offY = -1.89 + (object.def.offsetY || 0);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<g className="sign" transform={`translate(${x}, ${y}) rotate(${object.rot.y}) translate(${offX}, ${offY})`}>
|
||||||
|
<ReactSVG
|
||||||
|
src={`/assets/signs/${object.def.icon}`}
|
||||||
|
wrapper='svg'
|
||||||
|
|
||||||
|
beforeInjection={(svg) => {
|
||||||
|
svg.setAttribute('width', '1mm');
|
||||||
|
svg.setAttribute('height', '1mm');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -22,6 +22,8 @@ export default function SceneryInfoView({ scenery }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function SceneryInfoViewItem({ label, value, isLink = false }) {
|
function SceneryInfoViewItem({ label, value, isLink = false }) {
|
||||||
|
if(!value) value = 'No data';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tr>
|
<tr>
|
||||||
<td className="label">{label}</td>
|
<td className="label">{label}</td>
|
||||||
|
|||||||
@ -23,6 +23,7 @@ const Constants = {
|
|||||||
switchNoModel: true,
|
switchNoModel: true,
|
||||||
signalBoxUndefinedPrefabName: true,
|
signalBoxUndefinedPrefabName: true,
|
||||||
invalidSceneryInfoVersion: true,
|
invalidSceneryInfoVersion: true,
|
||||||
|
signUndefinedPrefabName: true,
|
||||||
},
|
},
|
||||||
errors: {
|
errors: {
|
||||||
invalidSceneryInfo: true
|
invalidSceneryInfo: true
|
||||||
@ -53,6 +54,11 @@ const Constants = {
|
|||||||
name: 'Signals',
|
name: 'Signals',
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'signs',
|
||||||
|
name: 'Signs',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'signalboxes',
|
id: 'signalboxes',
|
||||||
name: 'Signal boxes',
|
name: 'Signal boxes',
|
||||||
|
|||||||
11
src/model/defined-signs.js
Normal file
11
src/model/defined-signs.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// remember to place sign_w1X before sign_w1 etc.
|
||||||
|
|
||||||
|
const DefinedSigns = {
|
||||||
|
"sign_w5": {
|
||||||
|
"name": "W5",
|
||||||
|
"icon": "w5.svg",
|
||||||
|
"offsetY": -1.4364
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DefinedSigns;
|
||||||
@ -9,6 +9,7 @@ import SceneryParserLog from './scenery-parser-log';
|
|||||||
import SignalBox from './signalbox';
|
import SignalBox from './signalbox';
|
||||||
import Constants from '../helpers/constants';
|
import Constants from '../helpers/constants';
|
||||||
import SceneryInfo from './scenery-info';
|
import SceneryInfo from './scenery-info';
|
||||||
|
import Sign from './sign';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: move parsers to another static class
|
TODO: move parsers to another static class
|
||||||
@ -164,7 +165,9 @@ export default class Scenery
|
|||||||
}
|
}
|
||||||
|
|
||||||
static _parseTrackObject(text) {
|
static _parseTrackObject(text) {
|
||||||
if(Signal.isSignal(text)) {
|
if(Sign.isSign(text)) {
|
||||||
|
return Sign.fromText(text);
|
||||||
|
} else if(Signal.isSignal(text)) {
|
||||||
return Signal.fromText(text);
|
return Signal.fromText(text);
|
||||||
} else {
|
} else {
|
||||||
return TrackObject.fromText(text);
|
return TrackObject.fromText(text);
|
||||||
|
|||||||
53
src/model/sign.js
Normal file
53
src/model/sign.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import DefinedSigns from "./defined-signs";
|
||||||
|
import SceneryParserLog from "./scenery-parser-log";
|
||||||
|
import TrackObject from "./track-object";
|
||||||
|
import Vector3 from "./vector3";
|
||||||
|
|
||||||
|
export default class Sign extends TrackObject {
|
||||||
|
type = "Sign";
|
||||||
|
def;
|
||||||
|
|
||||||
|
constructor(id, prefab_name, pos, rot, track_id, name) {
|
||||||
|
super(id, prefab_name, pos, rot, track_id, name);
|
||||||
|
|
||||||
|
this.def = Sign.getDef(name, prefab_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check if a TrackObject text is a Sign.
|
||||||
|
@param {string} text - The text representation of the TrackObject.
|
||||||
|
@returns {boolean} - Returns true if the text represents a Sign, false otherwise.
|
||||||
|
@static
|
||||||
|
@memberof Sign
|
||||||
|
*/
|
||||||
|
static isSign(text) {
|
||||||
|
const values = text.split(";");
|
||||||
|
|
||||||
|
const prefabInfo = values[2]?.trim() || "";
|
||||||
|
return prefabInfo.startsWith("sign_");
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromText(text) {
|
||||||
|
const values = text.split(";");
|
||||||
|
const sign = new Sign(
|
||||||
|
values[1], // id
|
||||||
|
values[2], // prefab_name
|
||||||
|
Vector3.fromValuesArray(values, 3), // pos
|
||||||
|
Vector3.fromValuesArray(values, 6), // rot
|
||||||
|
values[9], // track_id
|
||||||
|
values[11], // name
|
||||||
|
);
|
||||||
|
|
||||||
|
return sign;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDef(name, prefabName) {
|
||||||
|
const key = Object.keys(DefinedSigns).find(k => prefabName.startsWith(k));
|
||||||
|
if (!key) {
|
||||||
|
SceneryParserLog.warn('signUndefinedPrefabName', `Sign ${name} has an undefined prefab name ${prefabName}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefinedSigns[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user