Module:Rolling Stock
Appearance
Documentation for this module may be created at Module:Rolling Stock/doc
local module = {}
-- PLEASE add trailing commas to every line in a table - it makes it easier to edit in the future!
-- do not add ambiguous information or guess-work, without proper reasoning - test and confirm in-game to your best ability!
-- leave notes in the form of comments if necessary.
local page_title = mw.title.getCurrentTitle()
-- mw is a mediawiki global (i think)
local page_name = page_title.fullText
-- added: MAPLE RIDGE
-- WEIGHT IS IN TONS
module.rolling_stock = {
["14' Stake Wagon"] = {
page = "14' Stake Wagon",
type = "cargo",
image = "14StakeWagonDefault.png",
buy_price = 555,
weight = 4.3,
cargo = {
["Logs"] = 4.7,
["Rails"] = 3.1,
["Pipes"] = 4.7,
["Iron Ingots"] = 2,
["Copper Ingots"] = 2,
["Aluminium Ingots"] = 4,
["Beams"] = 2.3,
}
},
["8 Ton Ore Hopper"] = {
page = "8 Ton Ore Hopper",
type = "cargo",
image = "8TonOreHopper.png",
buy_price = 684,
weight = 4.8,
paintable = true,
cargo = {
["Copper Ore"] = 4.4,
["Bauxite Ore"] = 4.4,
["Gold Ore"] = 4.4,
["Iron Ore"] = 4.4,
["Wood Pulp"] = 4.4,
["Coal"] = 4.4,
["Clay"] = 4.4,
["Sand"] = 4.4,
["Gravel"] = 4.4,
["Grain"] = 15,
}
},
["17' Stake Wagon"] = {
page = "Stake_Wagons",
type = "cargo",
image = "Screenshot 2023-07-20 030322.png",
buy_price = 705,
weight = 6.3,
cargo = {
["Logs"] = 6,
["Rails"] = 4,
["Pipes"] = 6,
["Iron Ingots"] = 2,
["Copper Ingots"] = 2,
["Aluminium Ingots"] = 4,
["Beams"] = 3,
}
},
["20' Flat Wagon"] = {
page = "Flat_Wagon",
type = "cargo",
image = "Screenshot 2023-07-20 030655.png",
buy_price = 821,
weight = 4.8,
cargo = {
["Iron Ingots"] = 2,
["Copper Ingots"] = 2,
["Aluminium Ingots"] = 4,
["Cut Stone"] = 5,
["Food"] = 12,
["Tools"] = 5,
["Grain"] = 6,
["Lumber"] = 4,
["Leather"] = 12,
["Bricks"] = 4,
["Paper"] = 3,
}
},
["12 Ton Van"] = {
page = "Van",
type = "cargo",
image = "Screenshot 2023-07-20 030829.png",
buy_price = 837,
weight = 5,
cargo = {
["Copper Ingots"] = 4,
["Leather"] = 20,
["Uncut Gems"] = 20,
["Jewelry"] = 20,
["Food"] = 20,
["Fish"] = 20,
["Tools"] = 20,
["Textiles"] = 20,
["Grain"] = 24,
}
},
["10 Ton Ballast Wagon"] = {
page = "Ballast Wagon",
type = "cargo",
image = "Screenshot 2023-07-20 031422.png",
buy_price = 848,
weight = 5,
cargo = {
["Iron Ore"] = 5,
["Bauxite Ore"] = 5,
["Copper Ore"] = 5,
["Gold Ore"] = 5,
["Coal"] = 5,
["Gravel"] = 5,
["Sand"] = 5,
["Clay"] = 5,
["Wood Pulp"] = 5,
["Grain"] = 18,
["Rum"] = 20,
["Cordwood"] = 6,
}
},
["20' Heavy Stake Wagon"] = {
page = "Heavy_Well_Wagon",
type = "cargo",
image = "Heavywellwagon.webp",
buy_price = 1176,
weight = 13.8,
cargo = {
["Logs"] = 9.7,
["Rails"] = 8,
["Pipes"] = 8,
["Iron Ingots"] = 4.8,
["Copper Ingots"] = 5.4,
["Machinery"] = 1,
["Beams"] = 6,
}
},
["10 Ton Tank Wagon"] = {
page = "10_Ton_Tank_Wagon",
type = "cargo",
image = "10TTankThumb.png",
buy_price = 1248,
weight = 6,
cargo = {
["Grease"] = 6,
["Chemicals"] = 6,
["Crude Oil"] = 6,
["Water"] = 6,
["Kerosene"] = 28,
["Rum"] = 28,
}
},
["25' Stake Wagon"] = {
page = "Stake_Wagons",
type = "cargo",
image = "Screenshot 2023-07-20 030507.png",
buy_price = 1485,
weight = 10,
cargo = {
["Logs"] = 10.4,
["Rails"] = 8,
["Pipes"] = 12,
["Iron Ingots"] = 4,
["Copper Ingots"] = 4,
["Aluminium Ingots"] = 8,
["Beams"] = 5.2,
}
},
["16t Hopper Wagon"] = {
page = "16t_Hopper_Wagon",
type = "cargo",
image = "16tHopperThumb.jpg",
buy_price = 1646,
weight = 8.3,
cargo = {
["Iron Ore"] = 11.1,
["Bauxite Ore"] = 11.1,
["Copper Ore"] = 11.1,
["Gold Ore"] = 11.1,
["Coal"] = 11.1,
["Gravel"] = 11.1,
["Sand"] = 11.1,
["Clay"] = 11.1,
["Wood Pulp"] = 11.1,
}
},
["27' Cattle Van"] = {
page = "Cattle_Van",
type = "cargo",
image = "Screenshot 2023-07-20 031855.png",
buy_price = 1890,
weight = 15,
cargo = {
["Cattle"] = 4,
}
},
["14 Ton Open Wagon"] = {
page = "Open_Wagon",
type = "cargo",
image = "Open_wagon_default.png",
buy_price = 1973,
weight = 7.9,
paintable = true,
cargo = {
["Iron Ore"] = 8.1,
["Bauxite Ore"] = 8.1,
["Copper Ore"] = 8.1,
["Gold Ore"] = 8.1,
["Coal"] = 8.1,
["Gravel"] = 8.1,
["Sand"] = 8.1,
["Clay"] = 8.1,
["Wood Pulp"] = 8.1,
["Rum"] = 42.1,
["Grain"] = 31.2,
["Lumber"] = 5.9,
["Bricks"] = 5.9,
["Cordwood"] = 11.3,
}
},
["16 Ton Tank Wagon"] = {
page = "16_Ton_Tank_Wagon",
type = "cargo",
image = "16TonTankWagon.png",
buy_price = 1998,
weight = 6,
paintable = true,
cargo = {
["Grease"] = 12.6,
["Chemicals"] = 12.6,
["Crude Oil"] = 12.6,
["Water"] = 12.6,
["Kerosene"] = 44.2,
["Rum"] = 44.2,
}
},
["18 Ton Covered Van"] = {
page = "Covered_Van",
type = "cargo",
image = "Covered_van_default.png",
buy_price = 2037,
weight = 8.1,
paintable = true,
cargo = {
["Copper Ingots"] = 4,
["Leather"] = 33.1,
["Food"] = 33.1,
["Fish"] = 33.1,
["Tools"] = 41.4,
["Textiles"] = 33.1,
["Jewelry"] = 33.1,
["Uncut Gems"] = 33.1,
["Grain"] = 49.5,
}
},
["20t Brake Van"] = {
page = "Brake_Van",
type = "cargo",
image = nil,
buy_price = 2190,
weight = 21,
paintable = true,
description = "Holds up to 4 players.",
},
["20' Passenger Wagon"] = {
page = "20' Passenger Wagon",
type = "cargo",
image = "Passenger Wagon QV.png",
buy_price = 2037,
weight = 11.1,
paintable = true,
description = "Holds up to 8 players.",
},
["22' Flat Bulkhead"] = {
page = "Flat_Bulkhead",
type = "cargo",
image = nil,
buy_price = 2235,
weight = 13.5,
cargo = {
["Iron Ingots"] = 3,
["Copper Ingots"] = 3,
["Aluminium Ingots"] = 3,
["Cordwood"] = 23.6,
["Food"] = 21,
["Tools"] = 14,
["Cut Stone"] = 14,
["Lumber"] = 10,
["Bricks"] = 10,
["Leather"] = 21,
["Paper"] = 4,
}
},
["20 Ton Hopper Wagon"] = {
page = "20_Ton_Hopper_Wagon",
type = "cargo",
image = "HeavyHopperThumb.png",
buy_price = 2396,
weight = 9.8,
paintable = true,
cargo = {
["Iron Ore"] = 13.5,
["Bauxite Ore"] = 13.5,
["Copper Ore"] = 13.5,
["Gold Ore"] = 13.5,
["Coal"] = 13.5,
["Gravel"] = 13.5,
["Sand"] = 13.5,
["Clay"] = 13.5,
["Wood Pulp"] = 13.5,
}
},
["KdNS Type 2An'2 Class A0"] = {
page = "Class_A0",
short_name = "Class A0",
type = "locomotive",
subtype = "KdNS",
image = "Wiki image.png",
buy_price = 5114,
weight = 9.1,
locomotive = {
max_speed = 26,
max_coal = 0,
max_power = 11737
},
description = "Starter engine for [[Misty Summit]]."
},
["RSR Type B'n2st Class A1"] = {
page = "Class_A1",
short_name = "Class A1",
type = "locomotive",
subtype = "RSR",
image = "ClassA1.png",
buy_price = 6314,
weight = 12.3,
locomotive = {
max_speed = 21,
max_coal = 0,
max_power = 14671
}
},
["RSR Type B'n2 Class A1-1"] = {
page = "Class_A1",
short_name = "Class A1-1",
type = "locomotive",
subtype = "RSR",
image = "Class A1-1.png",
buy_price = nil,
weight = 21,
locomotive = {
max_speed = 21,
max_coal = 0,
max_power = 14671
},
description = "Starter engine for [[Stormy Coast]]. Identical to the [[Class A1]], but missing the saddle tank."
},
["StiG Type Dn'WT Coffeepot"] = {
page = "Coffeepot",
short_name = "Coffeepot",
type = "locomotive",
subtype = "StiG",
image = "CoffeepotMain.png",
buy_price = 7214,
weight = 14.1,
locomotive = {
max_speed = 14,
max_coal = 400,
max_power = 15539
},
},
["RSR Type 1B'n2st Class A2"] = {
page = "Class_A2",
short_name = "Class A2",
type = "locomotive",
subtype = "RSR",
image = "ClassA2.png",
buy_price = 7064,
weight = 15.8,
locomotive = {
max_speed = 26,
max_coal = 0,
max_power = 13796
},
description = "Starter engine for [[Maple Ridge]]."
},
["RSR Type 1A1t Class C"] = {
page = "Class_C",
short_name = "Class C",
type = "locomotive",
subtype = "RSR",
image = "Classc.png",
buy_price = 9462,
weight = 21.5,
locomotive = {
max_speed = 33,
max_coal = 650,
max_power = 9769
},
description = "Starter engine for most maps."
},
["RSR Type 1BST Class A"] = {
page = "Class_A",
short_name = "Class A",
type = "locomotive",
subtype = "RSR",
image = "Classa.png",
buy_price = 10197,
not_in_shop = true,
weight = 21.5,
locomotive = {
max_speed = 26,
max_coal = 320,
max_power = 15522
},
description = "Replaced with Class A1 and Class A2 on July 31st 2023. Its default color is a unique soft blue inaccessible from the shop."
},
["KdNS Type Bn'2 Class D1"] = {
page = "Class_D1",
short_name = "Class D1",
type = "locomotive",
subtype = "KdNS",
image = "ClassD1Main.png",
buy_price = 11114,
weight = 22.6,
locomotive = {
max_speed = 24,
max_coal = 0,
max_power = 23411
},
description = "Starter engine for [[Hazel Sierra]]."
},
["RSR Type C'n2 Class G"] = {
page = "Class_G",
short_name = "Class G",
type = "locomotive",
subtype = "RSR",
image = "Classg.png",
buy_price = 14152,
weight = 26.5,
locomotive = {
max_speed = 19,
max_coal = 0,
max_power = 29809
},
},
["RSR Type 1A1'N2 Class F"] = {
page = "Class_F",
short_name = "Class F",
type = "locomotive",
subtype = "RSR",
image = "F class.png",
buy_price = 17555,
weight = 25.5,
locomotive = {
max_speed = 41,
max_coal = 0,
max_power = 20684
},
},
["KdNS Type C'nt Class N"] = {
page = "Class_N",
short_name = "Class N",
type = "locomotive",
subtype = "KdNS",
image = "N class.png",
buy_price = 19602,
weight = 26.5,
locomotive = {
max_speed = 19,
max_coal = 700,
max_power = 25048
},
},
["RSR Type B1'n2t Class E"] = {
page = "Class_E",
short_name = "Class E",
type = "locomotive",
subtype = "RSR",
image = "Classe.png",
buy_price = 20817,
weight = 26,
locomotive = {
max_speed = 26,
max_coal = 1080,
max_power = 20527
},
},
["KdNS Type C'n2 Class B2"] = {
page = "Class_B2",
short_name = "Class B2",
type = "locomotive",
subtype = "KdNS",
image = "Screenshot 2023-12-21 at 12.32.15 PM.png",
buy_price = 23652,
weight = 31.5,
locomotive = {
max_speed = 29,
max_coal = 0,
max_power = 32466
},
},
["RSR Type 1B'WT Class I"] = {
page = "Class_I",
short_name = "Class I",
type = "locomotive",
subtype = "RSR",
image = "RSR Class I.png",
buy_price = 25655,
weight = 33,
locomotive = {
max_speed = 46,
max_coal = 750,
max_power = 24513
},
},
["RSR Type C'N2 Class K1"] = {
page = "Class_K1",
short_name = "Class K1",
type = "locomotive",
subtype = "RSR",
image = "ClassK1Main.png",
buy_price = 26244,
weight = 32.9,
locomotive = {
max_speed = 34,
max_coal = 0,
max_power = 34348
},
},
["KdNS Type 2'B'n2 Class B"] = {
page = "Class_B",
short_name = "Class B",
type = "locomotive",
subtype = "KdNS",
image = "ClassBSide.png",
buy_price = 26652,
weight = 31.5,
locomotive = {
max_speed = 56,
max_coal = 0,
max_power = 30653
},
},
["RSR Type B2'N2 Class J1"] = {
page = "Class_J1",
short_name = "Class J1",
type = "locomotive",
subtype = "RSR",
image = "J1.png",
buy_price = 27111,
weight = 35.5,
locomotive = {
max_speed = 32,
max_coal = 0,
max_power = 37270
},
},
["RSR Type 1C'N2 Class J2"] = {
page = "Class_J2",
short_name = "Class J2",
type = "locomotive",
subtype = "RSR",
image = "J2 Right side.png",
buy_price = 27774,
weight = 35.5,
locomotive = {
max_speed = 38,
max_coal = 0,
max_power = 39796
},
},
["KdNS Type Dn Class H"] = {
page = "Class_H",
short_name = "Class H",
type = "locomotive",
subtype = "KdNS",
image = "H class.png",
buy_price = 32652,
weight = 40.5,
locomotive = {
max_speed = 19,
max_coal = 1372,
max_power = 44478
},
},
["RSR Type C1'T Class P"] = {
page = "Class_P",
short_name = "Class P",
type = "locomotive",
subtype = "RSR",
image = "Screenshot 2025-02-27 214340.png",
buy_price = 34655,
weight = 37,
locomotive = {
max_speed = 51,
max_coal = 1440,
max_power = 30047
},
},
["RSR Type C1'NST Class K2"] = {
page = "Class_K2",
short_name = "Class K2",
type = "locomotive",
subtype = "RSR",
image = "ClassK2Main.png",
buy_price = 33744,
weight = 42.9,
locomotive = {
max_speed = 24,
max_coal = 1300,
max_power = 41991
},
},
["KdNS Type Dn Class H2"] = {
page = "Class_H2",
short_name = "Class H2",
type = "locomotive",
subtype = "KdNS",
image = "Class H2 Natasha TLR.png",
buy_price = 37152,
weight = 39.8,
locomotive = {
max_speed = 30,
max_coal = 0,
max_power = 45227
},
},
}
function numWithCommas(n) -- we love stack overflow
return tostring(math.floor(n)):reverse():gsub("(%d%d%d)","%1,")
:gsub(",(%-?)$","%1"):reverse()
end -- todo: move into a helper function
function getRollingStockPageRow(frame)
-- Stock Name|Shortened Name
local stock, short_name = frame.args[1], frame.args[2]
local out = "|-\n| style=\"text-align:center;\" |<u>[[" .. module.rolling_stock[stock].page .. "|" .. (short_name and module.rolling_stock[stock].short_name or stock) .. "]]</u>\n"
.."\n|" ..(module.rolling_stock[stock].image and ("[[File:" .. (module.rolling_stock[stock].image) .. "|thumb|link=" .. module.rolling_stock[stock].page .. "]]") or "")
.."\n|style=\"text-align:center;\"|"
if not module.rolling_stock[stock].buy_price then
out = out .. "Not available to purchase."
else
if module.rolling_stock[stock].not_in_shop then
out = out .. "No longer available to purchase. Was: "
end
out = out .. "$" .. numWithCommas(module.rolling_stock[stock].buy_price)
.."<br/><i>$" .. numWithCommas(math.ceil(module.rolling_stock[stock].buy_price * 0.8 + 10)) --[[
Trainworks multiplier and also add 10 for some reason?
]] .. " w/ Trainworks</i>"
end
out = out .. "\n| style=\"text-align:center;\" |" .. module.rolling_stock[stock].weight .. "t"
out = out .. "\n| style=\"text-align:center;\" |"
if module.rolling_stock[stock].cargo then
out = out .. "Holds cargo<br/>"
local sortable_cargo = {}
for name, amount in pairs(module.rolling_stock[stock].cargo) do
table.insert(sortable_cargo, {name = name, amount = amount})
end
table.sort(sortable_cargo, function(a, b) return a.amount > b.amount end)
for _, info in pairs(sortable_cargo) do
out = out .. info.amount .. " [[".. info.name .. "]], "
end
out = out:sub(1, out:len()-2) -- remove trailing comma
end
if module.rolling_stock[stock].locomotive then
out = out .. "Locomotive Stats:"
.."<br/>Max Power: " .. module.rolling_stock[stock].locomotive.max_power
.."<br/>Max Speed: " .. module.rolling_stock[stock].locomotive.max_speed
.."<br/>Max Coal: " .. module.rolling_stock[stock].locomotive.max_coal
end
if module.rolling_stock[stock].description then
out = out .. "<br/>" .. module.rolling_stock[stock].description
end
return out
end
function module.getRollingStockStorage(frame)
local stock = frame.args[1]
out = ""
local sortable_cargo = {}
for name, amount in pairs(module.rolling_stock[stock].cargo) do
table.insert(sortable_cargo, {name = name, amount = amount})
end
table.sort(sortable_cargo, function(a, b) return a.amount > b.amount end)
for _, info in pairs(sortable_cargo) do
out = out .. info.amount .. " [[".. info.name .. "]], "
end
out = out:sub(1, out:len()-2) -- remove trailing comma
return out
end
function module.getRollingStockPage(frame)
local stock_type, short_name = frame.args[1], frame.args[2]
short_name = short_name == "true"
local out = ""
local sortable_stock = {}
for name, info in pairs(module.rolling_stock) do
if info.type == stock_type then
info.name = name
table.insert(sortable_stock, info)
end
end
table.sort(sortable_stock, function(a, b) return (a.buy_price or math.huge) < (b.buy_price or math.huge) end)
for _, info in pairs(sortable_stock) do
out = out .. getRollingStockPageRow({args = {info.name, short_name}}) .. "\n"
end
return out
end
function module.getCargoStorage(frame)
local valid_stock = {}
for stock, info in pairs(module.rolling_stock) do
if info.cargo and info.cargo[frame.args[1]] then -- continue isnt a valid keyword :c (i blame greg)
--out = out .. stock .. ": " .. info.cargo[frame.args[1]]
-- i write these comments for nobody, nobody will even open this page
table.insert(valid_stock, {name = stock, page = info.page, amount = info.cargo[frame.args[1]]})
end
end
table.sort(valid_stock, function(a, b) return a.amount > b.amount end)
for index, info in pairs(valid_stock) do
valid_stock[index] = "[[" .. info.page .. "|" .. info.name .. "]]: " .. info.amount
end
return table.concat(valid_stock, "<br/>")
end
function module.getStringList(frame)
-- Stock Type|Formatting String|Separator
local stock_type, formatting, separator, stock_subtype = frame.args[1], (frame.args[2] or "%s"), (frame.args[3] or ""), (frame.args[4])
local out = ""
local sortable_stock = {}
for name, info in pairs(module.rolling_stock) do
if ((not stock_type) or info.type == stock_type) and ((not stock_subtype) or info.subtype == stock_subtype) then
info.name = name
table.insert(sortable_stock, info)
end
end
table.sort(sortable_stock, function(a, b) return (a.buy_price or math.huge) < (b.buy_price or math.huge) end)
for _, info in pairs(sortable_stock) do
out = out .. formatting:gsub("{name}", info.short_name or info.name):gsub("{page}", info.page or info.name) .. (separator or "")
end
out = out:sub(1, out:len()-separator:len()) -- remove trailing comma
out = out:gsub("\\([nt])", {n="\n", t="\t"}) -- fix formatting
return out
end
function module.getValue(frame)
-- Stock Name|Property
local stock, property = frame.args[1], frame.args[2]
if not stock then
stock = page_name
end
return module.rolling_stock[stock][property]
end
return module