diff --git a/AlinasMapMod/AlinasMapMod.dll b/AlinasMapMod/AlinasMapMod.dll new file mode 100644 index 00000000..91f5e497 Binary files /dev/null and b/AlinasMapMod/AlinasMapMod.dll differ diff --git a/AlinasMapMod/AlinasMapMod.json b/AlinasMapMod/AlinasMapMod.json new file mode 100644 index 00000000..cfcee48a --- /dev/null +++ b/AlinasMapMod/AlinasMapMod.json @@ -0,0 +1,636 @@ +{ + "items": { + "AN_Sylva_Interchange_Yard": { + "identifier": "AN_Sylva_Interchange_Yard", + "name": "Sylva Interchange Yard", + "groupIds": [ + "AN_Sylva_Interchange_Yard" + ], + "description": "A yard that can be useful for organizing west bound trains and storing cars if the Interchange is filled to capacity.", + "deliveryPhases": [ + { + "cost": 2000, + "deliveries": [ + { + "carTypeFilter": "GB*", + "count": 4, + "load": "ballast", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 12, + "load": "gravel", + "direction": 0 + } + ] + }, + { + "cost": 2000, + "deliveries": [ + { + "carTypeFilter": "GB*", + "count": 2, + "load": "gravel", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 8, + "load": "ties", + "direction": 0 + }, + { + "carTypeFilter": "FM*", + "count": 6, + "load": "rails", + "direction": 0 + } + ] + } + ], + "prerequisiteSections": [ + "s1" + ], + "area": "sylva", + "trackSpans": [ + "PAN_Sylva_Interchange_Yard_00" + ], + "industryComponent": "AN_Sylva_Interchange_Yard.interchange-yard-site" + }, + "AN_Sylva_Wye": { + "identifier": "AN_Sylva_Wye", + "name": "Sylva Wye", + "groupIds": [ + "AN_Sylva_Wye" + ], + "description": "Adds a Wye at the Sylva Interchange, great for turning around those massive Berks.", + "area": "sylva", + "trackSpans": [ + "PAN_Sylva_Wye_00" + ], + "deliveryPhases": [ + { + "cost": 2000, + "deliveries": [ + { + "carTypeFilter": "FM", + "count": 1, + "load": "mow-machinery", + "direction": 0 + }, + { + "carTypeFilter": "GB", + "count": 100, + "load": "debris", + "direction": 0 + } + ] + }, + { + "cost": 2000, + "deliveries": [ + { + "carTypeFilter": "FM", + "count": 1, + "load": "mow-machinery", + "direction": 1 + }, + { + "carTypeFilter": "GB*", + "count": 6, + "load": "ballast", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 5, + "load": "gravel", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 2, + "load": "ties", + "direction": 0 + }, + { + "carTypeFilter": "FM*", + "count": 2, + "load": "rails", + "direction": 0 + } + ] + } + ], + "prerequisiteSections": [ + "s1", + "AN_Sylva_Interchange_Yard" + ], + "industryComponent": "AN_Sylva_Wye.wye-site" + }, + "AN_Sylva_Paper_Crossover": { + "identifier": "AN_Sylva_Paper_Crossover", + "name": "Sylva Paper Crossovers", + "groupIds": [ + "AN_Sylva_Paper_Crossover" + ], + "description": "Adds two Crossovers at Sylva Paperboard.", + "area": "sylva", + "trackSpans": [ + "PAN_Sylva_Paper_Crossover_00" + ], + "deliveryPhases": [ + { + "cost": 1000, + "deliveries": [ + { + "carTypeFilter": "GB*", + "count": 1, + "load": "ballast", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 1, + "load": "ties", + "direction": 0 + }, + { + "carTypeFilter": "FM*", + "count": 1, + "load": "rails", + "direction": 0 + } + ] + } + ], + "prerequisiteSections": [ + "s1" + ], + "industryComponent": "AN_Sylva_Paper_Crossover.sylva-paper-crossover-site" + }, + "AN_Sylva_Pax_Storage": { + "identifier": "AN_Sylva_Pax_Storage", + "name": "Sylva Pax Storage", + "groupIds": [ + "AN_Sylva_Pax_Storage" + ], + "description": "Adds two storage tracks to Sylva Station.", + "area": "sylva", + "trackSpans": [ + "PAN_Sylva_Pax_Storage_00" + ], + "deliveryPhases": [ + { + "cost": 2000, + "deliveries": [ + { + "carTypeFilter": "GB*", + "count": 2, + "load": "ballast", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 2, + "load": "ties", + "direction": 0 + }, + { + "carTypeFilter": "FM*", + "count": 2, + "load": "rails", + "direction": 0 + } + ] + } + ], + "prerequisiteSections": [ + "s1" + ], + "industryComponent": "AN_Sylva_Pax_Storage.sylva-station-site" + }, + "AN_Whittier_Yard_Sawmill": { + "identifier": "AN_Whittier_Yard_Sawmill", + "name": "Whittier Sawmill Connection", + "groupIds": [ + "AN_Whittier_Yard_Sawmill" + ], + "description": "Extend the sawmill track over to the interchange", + "trackSpans": [ + "PAN_Whittier_Yard_00" + ], + "area": "whittier", + "industryComponent": "AN_Whittier_Yard.sawmill-site", + "deliveryPhases": [ + { + "cost": 2000, + "deliveries": [ + { + "carTypeFilter": "GB*", + "count": 4, + "load": "ballast", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 2, + "load": "gravel", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 2, + "load": "ties", + "direction": 0 + }, + { + "carTypeFilter": "FM*", + "count": 1, + "load": "rails", + "direction": 0 + } + ] + } + ] + }, + "AN_Whittier_Yard_1": { + "identifier": "AN_Whittier_Yard_1", + "name": "Whittier Yard ", + "groupIds": [ + "AN_Whittier_Yard_Yard_Lead", + "AN_Whittier_Yard_Yard_Track_6", + "AN_Whittier_Yard_Yard_Track_7", + "AN_Whittier_Yard_Yard_Track_8" + ], + "trackSpans": [ + "PAN_Whittier_Yard_00" + ], + "industryComponent": "AN_Whittier_Yard.yard-site-1", + "area": "whittier", + "description": "A yard that can be useful for organizing trains and storing cars.", + "prerequisiteSections": [ + "AN_Whittier_Yard_Sawmill" + ], + "deliveryPhases": [ + { + "cost": 2000, + "deliveries": [ + { + "carTypeFilter": "GB*", + "count": 8, + "load": "ballast", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 12, + "load": "gravel", + "direction": 0 + } + ] + }, + { + "cost": 2000, + "deliveries": [ + { + "carTypeFilter": "GB*", + "count": 6, + "load": "gravel", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 8, + "load": "ties", + "direction": 0 + }, + { + "carTypeFilter": "FM*", + "count": 6, + "load": "rails", + "direction": 0 + } + ] + } + ] + }, + "AN_Whittier_Yard_2": { + "identifier": "AN_Whittier_Yard_2", + "name": "Whittier Yard Extension 2", + "groupIds": [ + "AN_Whittier_Yard_Yard_Track_3", + "AN_Whittier_Yard_Yard_Track_4", + "AN_Whittier_Yard_Yard_Track_5" + ], + "trackSpans": [ + "PAN_Whittier_Yard_00" + ], + "industryComponent": "AN_Whittier_Yard.yard-site-2", + "area": "whittier", + "description": "An additional 3 tracks for the Whittier yard", + "prerequisiteSections": [ + "AN_Whittier_Yard_Sawmill", + "AN_Whittier_Yard_1" + ], + "deliveryPhases": [ + { + "cost": 2000, + "deliveries": [ + { + "carTypeFilter": "GB*", + "count": 8, + "load": "ballast", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 12, + "load": "gravel", + "direction": 0 + } + ] + }, + { + "cost": 2000, + "deliveries": [ + { + "carTypeFilter": "GB*", + "count": 6, + "load": "gravel", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 8, + "load": "ties", + "direction": 0 + }, + { + "carTypeFilter": "FM*", + "count": 6, + "load": "rails", + "direction": 0 + } + ] + } + ] + }, + "AN_Whittier_Yard_3": { + "identifier": "AN_Whittier_Yard_3", + "name": "Whittier Yard Extension 3", + "groupIds": [ + "AN_Whittier_Yard_Yard_Track_0", + "AN_Whittier_Yard_Yard_Track_1", + "AN_Whittier_Yard_Yard_Track_2" + ], + "trackSpans": [ + "PAN_Whittier_Yard_00" + ], + "industryComponent": "AN_Whittier_Yard.yard-site-3", + "area": "whittier", + "description": "An additional 3 tracks for the Whittier yard", + "prerequisiteSections": [ + "AN_Whittier_Yard_Sawmill", + "AN_Whittier_Yard_1", + "AN_Whittier_Yard_2" + ], + "deliveryPhases": [ + { + "cost": 2000, + "deliveries": [ + { + "carTypeFilter": "GB*", + "count": 8, + "load": "ballast", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 12, + "load": "gravel", + "direction": 0 + } + ] + }, + { + "cost": 2000, + "deliveries": [ + { + "carTypeFilter": "GB*", + "count": 6, + "load": "gravel", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 8, + "load": "ties", + "direction": 0 + }, + { + "carTypeFilter": "FM*", + "count": 6, + "load": "rails", + "direction": 0 + } + ] + } + ] + }, + "AN_Andrews_Interchange_Yard": { + "identifier": "AN_Andrews_Interchange_Yard", + "name": "Andrews Interchange Yard", + "groupIds": [ + "AN_Andrews_Interchange_Yard" + ], + "description": "A yard that can be useful for organizing east bound trains and storing cars if the Interchange is filled to capacity.", + "trackSpans": [ + "PAN_Andrews_Interchange_Yard_00" + ], + "industryComponent": "AN_Andrews_Interchange_Yard.interchange-yard-site", + "deliveryPhases": [ + { + "cost": 2000, + "deliveries": [ + { + "carTypeFilter": "GB*", + "count": 4, + "load": "ballast", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 12, + "load": "gravel", + "direction": 0 + } + ] + }, + { + "cost": 2000, + "deliveries": [ + { + "carTypeFilter": "GB*", + "count": 2, + "load": "gravel", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 8, + "load": "ties", + "direction": 0 + }, + { + "carTypeFilter": "FM*", + "count": 6, + "load": "rails", + "direction": 0 + } + ] + } + ], + "prerequisiteSections": [ + "s6" + ], + "area": "andrews" + }, + "AN_Alarka_Jct_Additional": { + "identifier": "AN_Alarka_Jct_Additional", + "name": "Alarka Jct Additional Tracks", + "groupIds": [ + "AN_Alarka_Jct_Additional" + ], + "description": "Additional tracks in Alarka Jct, currently just a bypass around the interchange.", + "prerequisiteSections": [ + "alarka-jct" + ], + "trackSpans": [ + "Pevc" + ], + "industryComponent": "AN_Alarka_Jct_Additional.alarka-bypass-site", + "area": "alarka-jct", + "deliveryPhases": [ + { + "cost": 2000, + "deliveries": [ + { + "carTypeFilter": "GB*", + "count": 4, + "load": "ballast", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 2, + "load": "gravel", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 2, + "load": "ties", + "direction": 0 + }, + { + "carTypeFilter": "FM*", + "count": 1, + "load": "rails", + "direction": 0 + } + ] + } + ] + }, + "AN_Alarka_Pax_Storage": { + "identifier": "AN_Alarka_Pax_Storage", + "name": "Alarka Pax Storage", + "groupIds": [ + "AN_Alarka_Pax_Storage" + ], + "description": "Adds two storage tracks to Alarka Station.", + "area": "alarka", + "trackSpans": [ + "PAN_Alarka_Pax_Storage_00" + ], + "deliveryPhases": [ + { + "cost": 2000, + "deliveries": [ + { + "carTypeFilter": "GB*", + "count": 2, + "load": "ballast", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 2, + "load": "ties", + "direction": 0 + }, + { + "carTypeFilter": "FM*", + "count": 2, + "load": "rails", + "direction": 0 + } + ] + } + ], + "prerequisiteSections": [ + "alarka-branch" + ], + "industryComponent": "AN_Alarka_Pax_Storage.alarka-station-site" + }, + "AN_Alarka_Loop": { + "identifier": "AN_Alarka_Loop", + "name": "Alarka Balloon Loop", + "groupIds": [ + "AN_Alarka_Loop" + ], + "description": "Balloon loop in Alarka, no more fighting with a Wye.", + "prerequisiteSections": [ + "alarka-branch" + ], + "trackSpans": [ + "PAN_Alarka_Loop_00" + ], + "industryComponent": "AN_Alarka_Loop.alarka-bypass-site", + "area": "alarka", + "deliveryPhases": [ + { + "cost": 2000, + "deliveries": [ + { + "carTypeFilter": "GB*", + "count": 4, + "load": "ballast", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 2, + "load": "gravel", + "direction": 0 + }, + { + "carTypeFilter": "GB*", + "count": 2, + "load": "ties", + "direction": 0 + }, + { + "carTypeFilter": "FM*", + "count": 1, + "load": "rails", + "direction": 0 + } + ] + } + ] + } + } +} diff --git a/AlinasMapMod/Definition.json b/AlinasMapMod/Definition.json new file mode 100644 index 00000000..5a7eea4d --- /dev/null +++ b/AlinasMapMod/Definition.json @@ -0,0 +1,22 @@ +{ + "manifestVersion": 5, + "id": "AlinaNova21.AlinasMapMod", + "name": "Alina's Map Mod", + "version": "1.6.25167.144", + "assemblies": [ "AlinasMapMod" ], + "updateUrl": "https://railroader.alinanova.dev/update.json", + "requires": [ + { + "id": "railroader", + "notBefore": "2024.6.10" + }, + { + "id": "railloader", + "notBefore": "1.10.0.2" + }, + { + "id": "Zamu.StrangeCustoms", + "notBefore": "1.10.25017.313" + } + ] +} diff --git a/AlinasMapMod/mapeditor_integration.md b/AlinasMapMod/mapeditor_integration.md new file mode 100644 index 00000000..51e4d6ea --- /dev/null +++ b/AlinasMapMod/mapeditor_integration.md @@ -0,0 +1,8 @@ +# Map Editor Integration + +There are new classes adding in AlinasMapMod that allows +itself and other mods to register their objects in MapEditor. +This allows MapEditor to edit and save these objects. + +There not much documentation yet, but there is a few implementations in the Loaders, Map, and Station folders. The main interfaces are IEditableObject, ITransformableObject, and IObjectFactory. There is also ICustomHelper for custom helper objects. + diff --git a/AlinasMapMod/paxstations.md b/AlinasMapMod/paxstations.md new file mode 100644 index 00000000..d9735307 --- /dev/null +++ b/AlinasMapMod/paxstations.md @@ -0,0 +1,36 @@ +# Pax stations + +Industry: +```json +{ + "barkers": { + "industries": { + "barkers-station": { + "name": "Barkers Station", + "localPosition": { "x": 0, "y": 0, "z": 0}, + "usesContract": false, + "components": { + "ammBarkersStation": { + "name": "Barkers Station", + "type": "AlinasMapMod.PaxStationComponent", + "timetableCode": "BC", + // Reference values: Whittier: 30, Ela: 25, Bryson: 50 + "basePopulation": 10, + "loadId": "passengers", + "trackSpans": [ // Spans for loading/unloading + "PAN_Test_Mod_00" + ], + // Future support for custom branches, currently supported is "Main" and "Alarka Branch" + "branch": "Main", + // List of ids of other passenger stations. + // Unsure of exact impact + "neighborIds": [], + "carTypeFilter": "*", + "sharedStorage": true + } + } + } + } + } +} +``` \ No newline at end of file diff --git a/AlinasMapMod/progressions.md b/AlinasMapMod/progressions.md new file mode 100644 index 00000000..76a8ae10 --- /dev/null +++ b/AlinasMapMod/progressions.md @@ -0,0 +1,88 @@ +# Progressions + +```json +// progressions json format +{ + "mapFeatures": { + "sampleMapFeature": { + "displayName": "Sample MapFeature", + "name": "Sample MapFeature", + "description": "Description", + "prerequisites": { + "anotherMapFeature": true + }, + "areasEnableOnUnlock": { + "sampleArea": true + }, + "defaultEnableInSandbox": false, + "gameObjectsEnableOnUnlock": { + // Existing object in world, primary here for dumps. + "path://scene/world/path/to/gameObject/in/tree": true, + // Requires scenery to be defined in a game-graph + "scenery://sampleSceneryId": true + }, + "trackGroupsAvailableOnUnlock": { + "sampleGroup": true + }, + "trackGroupsEnableOnUnlock": { + "sampleGroup": true + }, + "unlockExcludeIndustries": { + "sampleIndustry": true + }, + "unlockIncludeIndustries": { + // Includes components by default + "sampleIndustry": true + }, + "unlockIncludeIndustryComponents": { + "sampleIndustryComponent": true + } + } + }, + "progressions": { + "ewh": { // ewh is the only current progression tree. + "sections": { + "sampleSection": { + "displayName": "sample milestone", + "description": "Description here", + "prerequisiteSections": { + "anotherSampleSection": true + }, + "deliveryPhases": [ + // Can have as many phases as you want here. + { + "cost": 1234, + "industryComponent": "sampleIndustryId.componentId", + "deliveries": [ + // Can be empty for cost only milestones. + { + "carTypeFilter": "GB*", + "count": 8, + "load": "ballast", + "direction": 0 // 0 = LoadToIndustry, 1 = LoadFromIndustry + }, + { + "carTypeFilter": "GB*", + "count": 12, + "load": "gravel", + "direction": 0 // 0 = LoadToIndustry, 1 = LoadFromIndustry + } + ] + } + ], + // Important note: You cannot both disable and enable the same feature, not even in seperate sections. + "disableFeaturesOnUnlock": { + "sampleMapFeature": true + }, + "enableFeaturesOnUnlock": { + "sampleMapFeature": true + }, + "enableFeaturesOnAvailable": { + "sampleMapFeature": true + } + } + } + } + } +} +``` \ No newline at end of file diff --git a/AlinasMapMod/splineys.md b/AlinasMapMod/splineys.md new file mode 100644 index 00000000..0dc67cfd --- /dev/null +++ b/AlinasMapMod/splineys.md @@ -0,0 +1,157 @@ +# Splineys + +All listed values are defaults, and may usually be omitted unless otherwise noted + +- [Prefab Formats](#prefab-formats) +- [Telegraph Poles](#telegraph-poles) +- [Turntables](#turntables) +- [Loaders](#loaders) +- [Passenger Station Agent](#passenger-station-agent-includes-building)] +- [Passenger Stations](#passenger-stations) +- [Map Labels](#map-labels) + + +## Prefab formats +All prefabs use the following formats: +- Path based: `path://scene/world/path/to/gameObject/in/tree` +- Scenery: `scenery://sampleSceneryId` +- Vanilla: `vanilla://vanillaObjectid` + This is a special one for specific structures, + as of 05/10/2025, it has the following: + - roundhouseStall + - roundhouseStart + - roundhouseEnd + - coalConveyor + - coalTower + - dieselFuelingStand + - waterTower + - waterColumn + - flagStopStation + - brysonDepot + - dillsboroStation + - southernCombinationDepot + +## Telegraph poles + +```json +{ + "handler": "AlinasMapMod.TelegraphPoleBuilder", + "polesToRaise": [1,2,3] +} +``` + +```json +{ + "handler": "AlinasMapMod.TelegraphPoleMover", + "polesToMove": [1,2,3], + "poleMovement": [ + [0,1,2], + [22,2,0], + [33,3,5], + ] +} + +``` +## Turntables + +```json +{ + "handler":"AlinasMapMod.Turntable.TurntableBuilder", + "radius": 15, + "subdivisions": 32, + "position": { "x": 0, "y": 0, "z": 0 }, + "rotation": { "x": 0, "y": 0, "z": 0 }, + "roundhouseStalls": 0, + "roundhouseTrackLength": 46, + "stallPrefab": "vanilla://roundhouseStall", + "startPrefab": "vanilla://roundhouseStart", + "endPrefab": "vanilla://roundhouseEnd" +} +``` + +## Loaders +```json +{ + "handler": "AlinasMapMod.LoaderBuilder", + "position": { "x": 0, "y": 0, "z": 0 }, + "rotation": { "x": 0, "y": 0, "z": 0 }, + // Must be set to one of the coal, diesel, or water prefabs + "prefab": "empty://", + // Required for coal and diesel, see example industry below + "industry": "", +} +``` + +Example industry: +```json +{ + "loader-industry-example": { + "name": "Example industry for loaders", + "localPosition": { "x": -271.6577, "y": 0.0, "z": -22.8286133 }, + "usesContract": false, + "components": { + "coaling": { + "type": "Model.Ops.IndustryUnloader", + "name": "Example Coaling Tower", + "trackSpans": [ "PExampleSpan" ], + "carTypeFilter": "HM,HT", + "sharedStorage": true, + "loadId": "coal", + "storageChangeRate": 0.0, + "maxStorage": 300000.0, + "orderAroundEmpties": false, + "carTransferRate": 1E+07, + "orderAroundLoaded": false + }, + "diesel": { + "type": "Model.Ops.IndustryUnloader", + "name": "Example Diesel Stand", + "trackSpans": [ "PExampleSpan" ], + "carTypeFilter": "TM", + "sharedStorage": true, + "loadId": "diesel-fuel", + "storageChangeRate": 0.0, + "maxStorage": 16000.0, + "orderAroundEmpties": false, + "carTransferRate": 32000.0, + "orderAroundLoaded": false + } + } + } +} +``` + +## Passenger Station Agent (Includes building) + +```json +{ + "handler": "AlinasMapMod.StationAgentBuilder", + "position": { + "x": 12886, + "y": 562, + "z": 4703 + }, + "rotation": { + "x": 0, + "y": 0, + "z": 0 + }, + "prefab": "vanilla://flagStopStation", + "passengerStop": "whittier" +} +``` + +## Passenger Stations + +### ***DEPRECATED: Use the industry component instead*** + +## Map Labels + +```json +{ + "handler": "AlinasMapMod.Map.MapLabelBuilder", + "position": { "x": 0, "y": 0, "z": 0 }, + "text": "Map Label", +} + +``` \ No newline at end of file