Module:GeneralPortOperations: Difference between revisions
From MicrasWiki
Jump to navigationJump to search
NewZimiaGov (talk | contribs) No edit summary |
NewZimiaGov (talk | contribs) No edit summary |
||
| (8 intermediate revisions by the same user not shown) | |||
| Line 34: | Line 34: | ||
-- 3) Home ports + flags | -- 3) Home ports + flags | ||
-- DO NOT ALTER: existing fixed home-city list retained exactly | |||
local cities = { | local cities = { | ||
"Aegirheim","Skýrophos","Bjornopolis","Norsolyra","Ephyra", | "Aegirheim","Skýrophos","Bjornopolis","Norsolyra","Ephyra", | ||
| Line 48: | Line 49: | ||
cityFlag[name] = string.format("[[File:%sFlag.png|20px]]", norm) | cityFlag[name] = string.format("[[File:%sFlag.png|20px]]", norm) | ||
end | end | ||
cityFlag["Skýrophos"] = "[[File:SkyrophosFlag.png|20px]]" | cityFlag["Skýrophos"] = "[[File:SkyrophosFlag.png|20px]]" | ||
cityFlag["Port of Corumia"] = "[[File:CorumiaFlag.png|20px]]" | |||
cityFlag["Port of Euranidom"] = "[[File:Euranidom.png|20px]]" | |||
cityFlag["Port of Southern Keltiania"] = "[[File:SouthKeltiania.png|20px]]" | |||
-- 3b) | local ownerOperatorFlag = { | ||
["Port of Corumia"] = "CorumiaFlag.png", | |||
["Port of Euranidom"] = "Euranidom.png", | |||
["Port of Southern Keltiania"] = "SouthKeltiania.png", | |||
} | |||
-- 3b) Hatch Ministry-aligned cluster map | |||
local cityRegion = { | local cityRegion = { | ||
["Aegirheim"] = "New South Jangsong", | ["Aegirheim"] = "New South Jangsong", | ||
| Line 58: | Line 67: | ||
["Norsolyra"] = "New South Jangsong", | ["Norsolyra"] = "New South Jangsong", | ||
["Ephyra"] = "New South Jangsong", | ["Ephyra"] = "New South Jangsong", | ||
["Symphonara"] = " | |||
["Delphica"] = " | ["Symphonara"] = "Vaeringheim", | ||
["Vaeringheim"] = " | ["Delphica"] = "Vaeringheim", | ||
["Somniumpolis"] = " | ["Vaeringheim"] = "Vaeringheim", | ||
["Somniumpolis"] = "Odiferia", | |||
["Keybir-Aviv"] = "Haifan Bassaridia", | ["Keybir-Aviv"] = "Haifan Bassaridia", | ||
["Sufriya"] = "Haifan Bassaridia", | ["Sufriya"] = "Haifan Bassaridia", | ||
["Jogi"] = "Haifan Bassaridia", | ["Jogi"] = "Haifan Bassaridia", | ||
["Ardclach"] = "Bassaridian Normark", | ["Ardclach"] = "Bassaridian Normark", | ||
["Riddersborg"] = "Bassaridian Normark", | ["Riddersborg"] = "Bassaridian Normark", | ||
["Port of Corumia"] = "Port of Corumia", | |||
["Port of Euranidom"] = "Port of Euranidom", | |||
["Port of Southern Keltiania"] = "Port of Southern Keltiania", | |||
} | |||
local regionHomeCities = { | |||
["New South Jangsong"] = {"Aegirheim","Skýrophos","Bjornopolis","Norsolyra","Ephyra"}, | |||
["Vaeringheim"] = {"Symphonara","Delphica","Vaeringheim"}, | |||
["Odiferia"] = {"Somniumpolis"}, | |||
["Haifan Bassaridia"] = {"Keybir-Aviv","Sufriya","Jogi"}, | |||
["Bassaridian Normark"]= {"Ardclach","Riddersborg"}, | |||
["Port of Corumia"] = {"Port of Corumia"}, | |||
["Port of Euranidom"] = {"Port of Euranidom"}, | |||
["Port of Southern Keltiania"] = {"Port of Southern Keltiania"}, | |||
} | |||
local allCargoRegions = { | |||
"Haifan Bassaridia", | |||
"Odiferia", | |||
"Alpazkigz", | |||
"Vaeringheim", | |||
"New South Jangsong", | |||
"Bassaridian Normark", | |||
"Ouriana", | |||
"Caledonian Dependencies" | |||
} | } | ||
local function randomHomeForRegion(region) | |||
local pool = regionHomeCities[region] | |||
if pool and #pool > 0 then return randomChoice(pool) end | |||
return randomChoice(cities) | |||
end | |||
-- 4) Vessel & cargo types | -- 4) Vessel & cargo types | ||
| Line 106: | Line 151: | ||
"Nefel Village","Diamonia Sugar Cooperatives", "Ouriana Lowlands Farmers' Association", | "Nefel Village","Diamonia Sugar Cooperatives", "Ouriana Lowlands Farmers' Association", | ||
"Nefel Village", "Ouriad River Fisheries Cooperative", "Caspazani Livestock Company", | "Nefel Village", "Ouriad River Fisheries Cooperative", "Caspazani Livestock Company", | ||
"White Ruby Communes", "Fange Velvet | "White Ruby Communes", "Fange Velvet", "Lamian Ward", "Sleva Farming Supplies Cooperative", | ||
"Hrimmanes Woolhorse Company"," King's Home Fur Trappers' Cooperative", "Caledonj Bay Fishermen’s’ Cooperatives", | "Hrimmanes Woolhorse Company"," King's Home Fur Trappers' Cooperative", "Caledonj Bay Fishermen’s’ Cooperatives", "Salain's Landing Granary Complex","Grove Synaxis of Tel-Amin", | ||
} | } | ||
local miningCompanies = { | local miningCompanies = { | ||
| Line 120: | Line 165: | ||
"Vortelin Electronics", "Thyrsiad Rubber Company","Stygium Mines of Acheron", | "Vortelin Electronics", "Thyrsiad Rubber Company","Stygium Mines of Acheron", | ||
"Trans-Rodinian Granite Agency", "Amber Ports of Slevik", "Thesean Iron Exports", | "Trans-Rodinian Granite Agency", "Amber Ports of Slevik", "Thesean Iron Exports", | ||
"Fanghorn Highland Gas Company","Gadial Oil", | "Fanghorn Highland Gas Company","Gadial Oil", "Tharsyr Shoal Salt Works", | ||
} | } | ||
local serviceCompanies = { | local serviceCompanies = { | ||
| Line 139: | Line 184: | ||
} | } | ||
-- | -- special pools | ||
local privateerCompanies = { | local privateerCompanies = { | ||
"Lake Morovia Blockade Fund", | "Lake Morovia Blockade Fund", | ||
"Baratar Corporation", | "Baratar Corporation", | ||
"Hatch Ministry", | |||
"Skyrophian Security Contractors", | |||
"Temple of Aprobelle", | |||
"Noctic Fleet", | |||
"Maritime Guild of the Cult of Maskmakers", | |||
"Merchant Caravans of the Candy Kingdom", | |||
"Haifadora Postal Service", | |||
"Fleet of Rouge Divers", | |||
"Ergonian Spy Agency", | |||
"Southern Strait Preservation Corporation", | |||
"Somniant Stock Fund" | |||
} | } | ||
| Line 149: | Line 205: | ||
} | } | ||
-- 5b) Company classification + | local portAuthorityCompanies = { | ||
"Port of Corumia", | |||
"Port of Euranidom", | |||
"Port of Southern Keltiania", | |||
} | |||
local portAuthorityLookup = {} | |||
for _, name in ipairs(portAuthorityCompanies) do | |||
portAuthorityLookup[name] = true | |||
end | |||
local function isPortAuthority(name) | |||
return portAuthorityLookup[name] == true | |||
end | |||
-- 5b) Company classification + Hatch-aligned source region metadata | |||
local companyMeta = { | local companyMeta = { | ||
-- Agriculture | -- Agriculture | ||
["Gladeseed Farmers' Union"] = {class="Agricultural", subtype="grain", region=" | ["Gladeseed Farmers' Union"] = {class="Agricultural", subtype="grain", region="Vaeringheim"}, | ||
["Atterian Cattle Drivers"] = {class="Agricultural", subtype="livestock", region="New South Jangsong"}, | ["Atterian Cattle Drivers"] = {class="Agricultural", subtype="livestock", region="New South Jangsong"}, | ||
["Jogiani Merchants of Manwine"] = {class="Agricultural", subtype="wine_spirits", region="Haifan Bassaridia"}, | ["Jogiani Merchants of Manwine"] = {class="Agricultural", subtype="wine_spirits", region="Haifan Bassaridia"}, | ||
["Keepers of the Grove of Zoe Elm"] = {class="Agricultural", subtype="forest_products", region=" | ["Keepers of the Grove of Zoe Elm"] = {class="Agricultural", subtype="forest_products", region="Vaeringheim"}, | ||
["Plains of Jogi"] = {class="Agricultural", subtype="grain", region="Haifan Bassaridia"}, | ["Plains of Jogi"] = {class="Agricultural", subtype="grain", region="Haifan Bassaridia"}, | ||
["Ale of the Night Central Brewery"] = {class="Agricultural", subtype="wine_spirits", region=" | ["Ale of the Night Central Brewery"] = {class="Agricultural", subtype="wine_spirits", region="Vaeringheim"}, | ||
["Camel Herders of the Jangsong Province"] = {class="Agricultural", subtype="livestock", region="New South Jangsong"}, | ["Camel Herders of the Jangsong Province"] = {class="Agricultural", subtype="livestock", region="New South Jangsong"}, | ||
["Anterran Imports and Services"] = {class="Agricultural", subtype="mixed_foodstuffs", region=" | ["Anterran Imports and Services"] = {class="Agricultural", subtype="mixed_foodstuffs", region="Vaeringheim"}, | ||
["Merchant Guild of the Poppy Goddess"] = {class="Agricultural", subtype="herbs", region=" | ["Merchant Guild of the Poppy Goddess"] = {class="Agricultural", subtype="herbs", region="Vaeringheim"}, | ||
["Grand Cave Bee Meadery"] = {class="Agricultural", subtype="mead_spirits", region=" | ["Grand Cave Bee Meadery"] = {class="Agricultural", subtype="mead_spirits", region="Vaeringheim"}, | ||
["Cinammon Plains of Rouge"] = {class="Agricultural", subtype="spices", region=" | ["Cinammon Plains of Rouge"] = {class="Agricultural", subtype="spices", region="Vaeringheim"}, | ||
["The Velvet Company"] = {class="Agricultural", subtype="textiles_raw", region=" | ["The Velvet Company"] = {class="Agricultural", subtype="textiles_raw", region="Vaeringheim"}, | ||
["Seamstresses of Rouge"] = {class="Agricultural", subtype="textiles_raw", region=" | ["Seamstresses of Rouge"] = {class="Agricultural", subtype="textiles_raw", region="Vaeringheim"}, | ||
["Salurian Temple of Sacred Horehound"] = {class="Agricultural", subtype="herbs", region=" | ["Salurian Temple of Sacred Horehound"] = {class="Agricultural", subtype="herbs", region="Alpazkigz"}, | ||
["Bulhanu Ranchers' Association"] = {class="Agricultural", subtype="livestock", region=" | ["Bulhanu Ranchers' Association"] = {class="Agricultural", subtype="livestock", region="Odiferia"}, | ||
["Suncliff Fisheries"] = {class="Agricultural", subtype="fish", region=" | ["Suncliff Fisheries"] = {class="Agricultural", subtype="fish", region="Vaeringheim"}, | ||
["Ministers of Mistress Mugwort"] = {class="Agricultural", subtype="herbs", region=" | ["Ministers of Mistress Mugwort"] = {class="Agricultural", subtype="herbs", region="Vaeringheim"}, | ||
["Blood Vineyards of the Far North"] = {class="Agricultural", subtype="wine_spirits", region="New South Jangsong"}, | ["Blood Vineyards of the Far North"] = {class="Agricultural", subtype="wine_spirits", region="New South Jangsong"}, | ||
["Norsolyrian Wisp Rice Farmers Association"] = {class="Agricultural", subtype="grain", region="New South Jangsong"}, | ["Norsolyrian Wisp Rice Farmers Association"] = {class="Agricultural", subtype="grain", region="New South Jangsong"}, | ||
["Giid-Lisea Ranching Import Company"] = {class="Agricultural", subtype="livestock", region=" | ["Giid-Lisea Ranching Import Company"] = {class="Agricultural", subtype="livestock", region="Vaeringheim"}, | ||
["Bird Keepers of Saluria"] = {class="Agricultural", subtype="animal_products", region=" | ["Bird Keepers of Saluria"] = {class="Agricultural", subtype="animal_products", region="Alpazkigz"}, | ||
["Hunters of the Giant Fanged Penguin"] = {class="Agricultural", subtype="animal_products", region=" | ["Hunters of the Giant Fanged Penguin"] = {class="Agricultural", subtype="animal_products", region="Caledonian Dependencies"}, | ||
["Knights Castle Reindeer Herders"] = {class="Agricultural", subtype="livestock", region="Bassaridian Normark"}, | ["Knights Castle Reindeer Herders"] = {class="Agricultural", subtype="livestock", region="Bassaridian Normark"}, | ||
["Lindley Whaling Company"] = {class="Agricultural", subtype="marine_oil", region=" | ["Lindley Whaling Company"] = {class="Agricultural", subtype="marine_oil", region="Caledonian Dependencies"}, | ||
["Aminian Coffee Company"] = {class="Agricultural", subtype="coffee", region="Haifan Bassaridia"}, | ["Aminian Coffee Company"] = {class="Agricultural", subtype="coffee", region="Haifan Bassaridia"}, | ||
["Grove Synaxis of Tel-Amin"] = {class="Agricultural", subtype="fruit", region="Haifan Bassaridia"}, | |||
["Granadita Collective"] = {class="Agricultural", subtype="fruit", region="Haifan Bassaridia"}, | ["Granadita Collective"] = {class="Agricultural", subtype="fruit", region="Haifan Bassaridia"}, | ||
["Herd Caton"] = {class="Agricultural", subtype="livestock", region=" | ["Herd Caton"] = {class="Agricultural", subtype="livestock", region="Vaeringheim"}, | ||
["Wasp Hunters of the Austral Isles"] = {class="Agricultural", subtype="animal_products", region=" | ["Wasp Hunters of the Austral Isles"] = {class="Agricultural", subtype="animal_products", region="Caledonian Dependencies"}, | ||
["Sea Elm Southern Meadery"] = {class="Agricultural", subtype="mead_spirits", region=" | ["Sea Elm Southern Meadery"] = {class="Agricultural", subtype="mead_spirits", region="Vaeringheim"}, | ||
["Nefel Village"] = {class="Agricultural", subtype="mixed_foodstuffs", region=" | ["Nefel Village"] = {class="Agricultural", subtype="mixed_foodstuffs", region="Vaeringheim"}, | ||
["Diamonia Sugar Cooperatives"] = {class="Agricultural", subtype="sugar", region="Haifan Bassaridia"}, | ["Diamonia Sugar Cooperatives"] = {class="Agricultural", subtype="sugar", region="Haifan Bassaridia"}, | ||
["Ouriana Lowlands Farmers' Association"] = {class="Agricultural", subtype="grain", region="Ouriana | ["Ouriana Lowlands Farmers' Association"] = {class="Agricultural", subtype="grain", region="Ouriana"}, | ||
["Ouriad River Fisheries Cooperative"] = {class="Agricultural", subtype="fish", region="Ouriana | ["Ouriad River Fisheries Cooperative"] = {class="Agricultural", subtype="fish", region="Ouriana"}, | ||
["Caspazani Livestock Company"] = {class="Agricultural", subtype="livestock", region="Ouriana | ["Caspazani Livestock Company"] = {class="Agricultural", subtype="livestock", region="Ouriana"}, | ||
["White Ruby Communes"] = {class="Agricultural", subtype="mixed_foodstuffs", region=" | ["White Ruby Communes"] = {class="Agricultural", subtype="mixed_foodstuffs", region="Vaeringheim"}, | ||
["Fange Velvet"] = {class="Agricultural", subtype="textiles_raw", region=" | ["Fange Velvet"] = {class="Agricultural", subtype="textiles_raw", region="Caledonian Dependencies"}, | ||
["Lamian Ward"] = {class="Agricultural", subtype="mixed_foodstuffs", region="Vaeringheim"}, | |||
["Lamian Ward"] = {class="Agricultural", subtype="mixed_foodstuffs", region=" | ["Sleva Farming Supplies Cooperative"] = {class="Agricultural", subtype="farm_inputs", region="Caledonian Dependencies"}, | ||
["Sleva Farming Supplies Cooperative"] = {class="Agricultural", subtype="farm_inputs", region=" | ["Hrimmanes Woolhorse Company"] = {class="Agricultural", subtype="livestock", region="Caledonian Dependencies"}, | ||
["Hrimmanes Woolhorse Company"] = {class="Agricultural", subtype="livestock", region=" | |||
[" King's Home Fur Trappers' Cooperative"] = {class="Agricultural", subtype="animal_products", region="Bassaridian Normark"}, | [" King's Home Fur Trappers' Cooperative"] = {class="Agricultural", subtype="animal_products", region="Bassaridian Normark"}, | ||
["Caledonj Bay Fishermen’s’ Cooperatives"] = {class="Agricultural", subtype="fish", region=" | ["Caledonj Bay Fishermen’s’ Cooperatives"] = {class="Agricultural", subtype="fish", region="Caledonian Dependencies"}, | ||
["Salain's Landing Granary Complex"] = {class="Agricultural", subtype="grain", region="Vaeringheim"}, | |||
-- Mining / Manufacturing / Energy | -- Mining / Manufacturing / Energy | ||
["Roving Wind Farm Corporation"] = {class="Mining/Manufacturing", subtype="energy", region=" | ["Roving Wind Farm Corporation"] = {class="Mining/Manufacturing", subtype="energy", region="Vaeringheim"}, | ||
["Thalassian Temple Granite Export Cooperative"] = {class="Mining/Manufacturing", subtype="stone", region=" | ["Thalassian Temple Granite Export Cooperative"] = {class="Mining/Manufacturing", subtype="stone", region="Vaeringheim"}, | ||
["East Keltian Iron Company"] = {class="Mining/Manufacturing", subtype="metals", region=" | ["East Keltian Iron Company"] = {class="Mining/Manufacturing", subtype="metals", region="Vaeringheim"}, | ||
["Mylecian Coal Ports"] = {class="Mining/Manufacturing", subtype="coal", region=" | ["Mylecian Coal Ports"] = {class="Mining/Manufacturing", subtype="coal", region="Vaeringheim"}, | ||
["Merchants of the Valley of Diamonds"] = {class="Mining/Manufacturing", subtype="gemstones", region="Haifan Bassaridia"}, | ["Merchants of the Valley of Diamonds"] = {class="Mining/Manufacturing", subtype="gemstones", region="Haifan Bassaridia"}, | ||
["East Keltian Timber Company"] = {class="Mining/Manufacturing", subtype="timber", region=" | ["East Keltian Timber Company"] = {class="Mining/Manufacturing", subtype="timber", region="Vaeringheim"}, | ||
["Onceanic Boot Company"] = {class="Mining/Manufacturing", subtype="consumer_goods", region=" | ["Onceanic Boot Company"] = {class="Mining/Manufacturing", subtype="consumer_goods", region="Vaeringheim"}, | ||
["Commune of the Garganid Apostles"] = {class="Mining/Manufacturing", subtype="stone", region=" | ["Commune of the Garganid Apostles"] = {class="Mining/Manufacturing", subtype="stone", region="Vaeringheim"}, | ||
["Shï Collective"] = {class="Mining/Manufacturing", subtype="luxury_goods", region=" | ["Shï Collective"] = {class="Mining/Manufacturing", subtype="luxury_goods", region="Vaeringheim"}, | ||
["Order of the Sphinx"] = {class="Mining/Manufacturing", subtype="luxury_goods", region="Haifan Bassaridia"}, | ["Order of the Sphinx"] = {class="Mining/Manufacturing", subtype="luxury_goods", region="Haifan Bassaridia"}, | ||
["Market Hanavusu"] = {class="Mining/Manufacturing", subtype="consumer_goods", region="New South Jangsong"}, | ["Market Hanavusu"] = {class="Mining/Manufacturing", subtype="consumer_goods", region="New South Jangsong"}, | ||
["Somniant Stock Fund"] = {class="Mining/Manufacturing", subtype="arms_industrial", region=" | ["Somniant Stock Fund"] = {class="Mining/Manufacturing", subtype="arms_industrial", region="Vaeringheim"}, | ||
["Copper Mines of Southern Jogi"] = {class="Mining/Manufacturing", subtype="metals", region="Haifan Bassaridia"}, | ["Copper Mines of Southern Jogi"] = {class="Mining/Manufacturing", subtype="metals", region="Haifan Bassaridia"}, | ||
["Horned Bear Timber Company"] = {class="Mining/Manufacturing", subtype="timber", region="New South Jangsong"}, | ["Horned Bear Timber Company"] = {class="Mining/Manufacturing", subtype="timber", region="New South Jangsong"}, | ||
["Federation of North Brabipant"] = {class="Mining/Manufacturing", subtype="consumer_goods", region=" | ["Federation of North Brabipant"] = {class="Mining/Manufacturing", subtype="consumer_goods", region="Caledonian Dependencies"}, | ||
["Southern Strait Preservation Corporation"] = {class="Mining/Manufacturing", subtype="marine_materials", region="Haifan Bassaridia"}, | ["Southern Strait Preservation Corporation"] = {class="Mining/Manufacturing", subtype="marine_materials", region="Haifan Bassaridia"}, | ||
["Eosphorus Motor Company"] = {class="Mining/Manufacturing", subtype="vehicles", region=" | ["Eosphorus Motor Company"] = {class="Mining/Manufacturing", subtype="vehicles", region="Vaeringheim"}, | ||
["Vortelin Electronics"] = {class="Mining/Manufacturing", subtype="electronics", region=" | ["Vortelin Electronics"] = {class="Mining/Manufacturing", subtype="electronics", region="Vaeringheim"}, | ||
["Thyrsiad Rubber Company"] = {class="Mining/Manufacturing", subtype="rubber", region="Haifan Bassaridia"}, | ["Thyrsiad Rubber Company"] = {class="Mining/Manufacturing", subtype="rubber", region="Haifan Bassaridia"}, | ||
["Stygium Mines of Acheron"] = {class="Mining/Manufacturing", subtype="metals", region=" | ["Stygium Mines of Acheron"] = {class="Mining/Manufacturing", subtype="metals", region="Alpazkigz"}, | ||
["Trans-Rodinian Granite Agency"] = {class="Mining/Manufacturing", subtype="stone", region=" | ["Trans-Rodinian Granite Agency"] = {class="Mining/Manufacturing", subtype="stone", region="Vaeringheim"}, | ||
["Amber Ports of Slevik"] = {class="Mining/Manufacturing", subtype="amber", region=" | ["Amber Ports of Slevik"] = {class="Mining/Manufacturing", subtype="amber", region="Caledonian Dependencies"}, | ||
["Thesean Iron Exports"] = {class="Mining/Manufacturing", subtype="metals", region="Ouriana | ["Thesean Iron Exports"] = {class="Mining/Manufacturing", subtype="metals", region="Ouriana"}, | ||
["Fanghorn Highland Gas Company"] = {class="Mining/Manufacturing", subtype="gas", region=" | ["Fanghorn Highland Gas Company"] = {class="Mining/Manufacturing", subtype="gas", region="Caledonian Dependencies"}, | ||
["Gadial Oil"] = {class="Mining/Manufacturing", subtype="oil", region=" | ["Gadial Oil"] = {class="Mining/Manufacturing", subtype="oil", region="Vaeringheim"}, | ||
["Tharsyr Shoal Salt Works"] = {class="Mining/Manufacturing", subtype="salt", region="Vaeringheim"}, | |||
-- Services | -- Services | ||
["Ergonian Spy Agency"] = {class="Services", subtype="intelligence", region=" | ["Ergonian Spy Agency"] = {class="Services", subtype="intelligence", region="Vaeringheim"}, | ||
["Temple Bank of the Reformed Stripping Path"] = {class="Services", subtype="finance", region=" | ["Temple Bank of the Reformed Stripping Path"] = {class="Services", subtype="finance", region="Vaeringheim"}, | ||
["Temple University of Delphica"] = {class="Services", subtype="education", region=" | ["Temple University of Delphica"] = {class="Services", subtype="education", region="Vaeringheim"}, | ||
["La Sái Ebile"] = {class="Services", subtype="commerce", region="Haifan Bassaridia"}, | ["La Sái Ebile"] = {class="Services", subtype="commerce", region="Haifan Bassaridia"}, | ||
["Pharmacon Sect"] = {class="Services", subtype="medical", region=" | ["Pharmacon Sect"] = {class="Services", subtype="medical", region="Alpazkigz"}, | ||
["Skyrophian Security Contractors"] = {class="Services", subtype="security", region="New South Jangsong"}, | ["Skyrophian Security Contractors"] = {class="Services", subtype="security", region="New South Jangsong"}, | ||
["Haifadora Postal Service"] = {class="Services", subtype="courier", region="Haifan Bassaridia"}, | ["Haifadora Postal Service"] = {class="Services", subtype="courier", region="Haifan Bassaridia"}, | ||
["Fleet of Rouge Divers"] = {class="Services", subtype="marine_services", region=" | ["Fleet of Rouge Divers"] = {class="Services", subtype="marine_services", region="Vaeringheim"}, | ||
["Merchant Caravans of the Candy Kingdom"] = {class="Services", subtype="logistics", region=" | ["Merchant Caravans of the Candy Kingdom"] = {class="Services", subtype="logistics", region="Vaeringheim"}, | ||
["Hellhound Breeders of Dragevik"] = {class="Services", subtype="animal_services", region="Bassaridian Normark"}, | ["Hellhound Breeders of Dragevik"] = {class="Services", subtype="animal_services", region="Bassaridian Normark"}, | ||
["Noctic Fleet"] = {class="Services", subtype="marine_services", region=" | ["Noctic Fleet"] = {class="Services", subtype="marine_services", region="Vaeringheim"}, | ||
["Maritime Guild of the Cult of Maskmakers"] = {class="Services", subtype="marine_services", region=" | ["Maritime Guild of the Cult of Maskmakers"] = {class="Services", subtype="marine_services", region="Vaeringheim"}, | ||
["Couriers of the Lizard Queen"] = {class="Services", subtype="courier", region=" | ["Couriers of the Lizard Queen"] = {class="Services", subtype="courier", region="Vaeringheim"}, | ||
["Temple of Aprobelle"] = {class="Services", subtype="security", region=" | ["Temple of Aprobelle"] = {class="Services", subtype="security", region="Vaeringheim"}, | ||
["Sårensby Depot*"] = {class="Services", subtype="logistics", region="Bassaridian Normark"}, | ["Sårensby Depot*"] = {class="Services", subtype="logistics", region="Bassaridian Normark"}, | ||
["Port of Corumia"] = {class="Services", subtype="port_authority", region="Port of Corumia"}, | |||
["Port of Euranidom"] = {class="Services", subtype="port_authority", region="Port of Euranidom"}, | |||
["Port of Southern Keltiania"] = {class="Services", subtype="port_authority", region="Port of Southern Keltiania"}, | |||
-- Special pools | -- Special pools | ||
["Lake Morovia Blockade Fund"] = {class="Services", subtype="security", region=" | ["Lake Morovia Blockade Fund"] = {class="Services", subtype="security", region="Vaeringheim"}, | ||
["Baratar Corporation"] = {class="Mining/Manufacturing", subtype="arms_industrial", region="Haifan Bassaridia"}, | ["Baratar Corporation"] = {class="Mining/Manufacturing", subtype="arms_industrial", region="Haifan Bassaridia"}, | ||
["Hatch Ministry"] = {class="Services", subtype="security", region=" | ["Hatch Ministry"] = {class="Services", subtype="security", region="Vaeringheim"}, | ||
} | } | ||
-- build a “general” pool excluding | -- build a “general” pool excluding special-only firms | ||
local generalPools = {} | local generalPools = {} | ||
for _, list in ipairs({agriCompanies, miningCompanies, serviceCompanies}) do | for _, list in ipairs({agriCompanies, miningCompanies, serviceCompanies}) do | ||
| Line 262: | Line 338: | ||
local function getCompanyMeta(name) | local function getCompanyMeta(name) | ||
return companyMeta[name] or {class="Unspecified", subtype="mixed", region=" | return companyMeta[name] or {class="Unspecified", subtype="mixed", region="Vaeringheim"} | ||
end | end | ||
| Line 303: | Line 379: | ||
local function chooseManifestProfile(vt, ct) | local function chooseManifestProfile(vt, ct) | ||
if vt == "Privateer" then | if vt == "Privateer" then | ||
local subtype = randomChoice({"security","arms_industrial","logistics","medical"}) | |||
local region = randomChoice({"Haifan Bassaridia","Odiferia","Alpazkigz","Vaeringheim","New South Jangsong","Bassaridian Normark","Ouriana"}) | |||
return subtype, region | |||
elseif vt == "Military" then | elseif vt == "Military" then | ||
local subtype = randomChoice({"security","arms_industrial","medical","logistics"}) | local subtype = randomChoice({"security","arms_industrial","medical","logistics"}) | ||
local region = randomChoice({" | local region = randomChoice({"Haifan Bassaridia","Odiferia","Alpazkigz","Vaeringheim","New South Jangsong","Bassaridian Normark","Ouriana"}) | ||
return subtype, region | return subtype, region | ||
elseif vt == "Ritual" then | elseif vt == "Ritual" then | ||
local subtype = randomChoice({"finance","medical","courier","security","education","logistics"}) | local subtype = randomChoice({"finance","medical","courier","security","education","logistics"}) | ||
local region = randomChoice({" | local region = randomChoice({"Haifan Bassaridia","Odiferia","Alpazkigz","Vaeringheim","New South Jangsong","Bassaridian Normark"}) | ||
return subtype, region | return subtype, region | ||
elseif ct == "Agricultural" then | elseif ct == "Agricultural" then | ||
| Line 318: | Line 396: | ||
"marine_oil","coffee","fruit","sugar","mixed_foodstuffs","farm_inputs" | "marine_oil","coffee","fruit","sugar","mixed_foodstuffs","farm_inputs" | ||
}) | }) | ||
local region = randomChoice( | local region = randomChoice(allCargoRegions) | ||
return subtype, region | return subtype, region | ||
elseif ct == "Mining/Manufacturing" then | |||
local subtype = randomChoice({ | |||
"energy","stone","salt","metals","coal","gemstones","timber","consumer_goods", | |||
"luxury_goods","arms_industrial","marine_materials","vehicles", | |||
"electronics","rubber","amber","gas","oil" | |||
}) | |||
local region = randomChoice( | local region = randomChoice(allCargoRegions) | ||
return subtype, region | return subtype, region | ||
elseif ct == "Services" then | |||
if math.random() < 0.20 then | |||
local port = randomChoice(portAuthorityCompanies) | |||
return "port_authority", port | |||
else | |||
local subtype = randomChoice({ | local subtype = randomChoice({ | ||
"intelligence","finance","education","commerce","medical", | "intelligence","finance","education","commerce","medical", | ||
"security","courier","marine_services","logistics","animal_services" | "security","courier","marine_services","logistics","animal_services" | ||
}) | }) | ||
local region = randomChoice( | local region = randomChoice(allCargoRegions) | ||
return subtype, region | return subtype, region | ||
end | |||
else | else | ||
local source = randomChoice(generalPools) | local source = randomChoice(generalPools) | ||
| Line 343: | Line 426: | ||
local function pickCargoCompanies(vt, owner, ct, subtype, region, count) | local function pickCargoCompanies(vt, owner, ct, subtype, region, count) | ||
if vt == "Cargo" and isPortAuthority(region) then | |||
return { region } | |||
end | |||
if vt == "Privateer" then | if vt == "Privateer" then | ||
return randomN( | local pool = {} | ||
for _, name in ipairs(privateerCompanies) do | |||
local meta = getCompanyMeta(name) | |||
if meta.region == region then | |||
if subtype == "security" and meta.subtype == "security" then | |||
table.insert(pool, name) | |||
elseif subtype == "arms_industrial" and meta.subtype == "arms_industrial" then | |||
table.insert(pool, name) | |||
elseif subtype == "logistics" and ( | |||
meta.subtype == "logistics" or | |||
meta.subtype == "courier" or | |||
meta.subtype == "marine_services" | |||
) then | |||
table.insert(pool, name) | |||
elseif subtype == "medical" and meta.subtype == "medical" then | |||
table.insert(pool, name) | |||
end | |||
end | |||
end | |||
if #pool == 0 then | |||
for _, name in ipairs(privateerCompanies) do | |||
local meta = getCompanyMeta(name) | |||
if meta.subtype == "security" | |||
or meta.subtype == "arms_industrial" | |||
or meta.subtype == "logistics" | |||
or meta.subtype == "courier" | |||
or meta.subtype == "marine_services" | |||
or meta.subtype == "medical" then | |||
table.insert(pool, name) | |||
end | |||
end | |||
end | |||
return randomN(pool, math.min(count, #pool)) | |||
elseif owner == "Hatch Ministry Division" then | elseif owner == "Hatch Ministry Division" then | ||
return randomN(hatchMinistryCompanies, | return randomN(hatchMinistryCompanies, 1) | ||
elseif ct == "Unspecified" then | elseif ct == "Unspecified" then | ||
local pool = buildGeneralPoolBySubtypeRegion(subtype, region) | local pool = buildGeneralPoolBySubtypeRegion(subtype, region) | ||
| Line 359: | Line 482: | ||
pool = fallback | pool = fallback | ||
end | end | ||
return randomN(pool, count) | return randomN(pool, math.min(count, #pool)) | ||
else | else | ||
local pool = buildPoolByClassSubtypeRegion(ct, subtype, region) | local pool = buildPoolByClassSubtypeRegion(ct, subtype, region) | ||
| Line 385: | Line 509: | ||
pool = fallback | pool = fallback | ||
end | end | ||
return randomN(pool, count) | return randomN(pool, math.min(count, #pool)) | ||
end | end | ||
end | end | ||
| Line 423: | Line 547: | ||
addLogo("Lindley Whaling Company","LindleyWhalingCompany.png") | addLogo("Lindley Whaling Company","LindleyWhalingCompany.png") | ||
addLogo("Aminian Coffee Company","Aminian421.png") | addLogo("Aminian Coffee Company","Aminian421.png") | ||
addLogo("Grove Synaxis of Tel-Amin","GroveSynaxisLogo.png") | |||
addLogo("Commune of the Garganid Apostles","Garganid421.png") | addLogo("Commune of the Garganid Apostles","Garganid421.png") | ||
addLogo("Onceanic Boot Company","OnceanicBoot421.png") | addLogo("Onceanic Boot Company","OnceanicBoot421.png") | ||
| Line 469: | Line 594: | ||
addLogo("Sårensby Depot","SårensbyDepotLogo.png") | addLogo("Sårensby Depot","SårensbyDepotLogo.png") | ||
addLogo("Amber Ports of Slevik","AmberPortsLogo2.png") | addLogo("Amber Ports of Slevik","AmberPortsLogo2.png") | ||
addLogo("Port of Corumia","PortofCorumiaLogo.png.png") | addLogo("Port of Corumia","PortofCorumiaLogo.png") | ||
addLogo("Port of Euranidom","PortofEuranidomLogo.png") | |||
addLogo("Port of Southern Keltiania","PortofSouthernKeltianiaLogo.png") | |||
addLogo("Lamian Ward","LamianWardLogo.png") | addLogo("Lamian Ward","LamianWardLogo.png") | ||
addLogo("Sleva Farming Supplies Cooperatives","SlevaFarmingLogo.png") | addLogo("Sleva Farming Supplies Cooperatives","SlevaFarmingLogo.png") | ||
| Line 508: | Line 635: | ||
addLogo("Ordo Amicitia", "OrdoFl.png") | addLogo("Ordo Amicitia", "OrdoFl.png") | ||
addLogo("Temple Illuminata", "AureumFlag.png") | addLogo("Temple Illuminata", "AureumFlag.png") | ||
addLogo("Tharsyr Shoal Salt Works","TharsyrShoalSaltWorksLogo.png") | |||
addLogo("Salain's Landing Granary Complex","SalainsLandingGranaryLogo.png") | |||
-- 7) Privateer flags + helper | -- 7) Privateer flags + helper | ||
| Line 554: | Line 683: | ||
-- 8) Determine Owner/Operator | -- 8) Determine Owner/Operator | ||
local function getOwner(vt, ct, subtype, region) | local function getOwner(vt, ct, subtype, region) | ||
if vt == "Cargo" and isPortAuthority(region) then | |||
return region | |||
end | |||
if vt == "Ritual" then | if vt == "Ritual" then | ||
return randomChoice(ritualCults) | return randomChoice(ritualCults) | ||
| Line 583: | Line 715: | ||
local y, d = p.getCurrentDate() | local y, d = p.getCurrentDate() | ||
local poolMap = { | local poolMap = { | ||
Agricultural = agriCompanies, | Agricultural = agriCompanies, | ||
| Line 589: | Line 720: | ||
Services = serviceCompanies | Services = serviceCompanies | ||
} | } | ||
local totalTonnage = 0 | local totalTonnage = 0 | ||
local ships = {} | local ships = {} | ||
for i = 1, math.random(50, 80) do | for i = 1, math.random(50, 80) do | ||
local hr, mn = math.random(0, 23), math.random(0, 59) | local hr, mn = math.random(0, 23), math.random(0, 59) | ||
local vt, ct = randomChoice(vesselTypes), randomChoice(cargoTypes) | local vt, ct = randomChoice(vesselTypes), randomChoice(cargoTypes) | ||
local subtype, sourceRegion = chooseManifestProfile(vt, ct) | local subtype, sourceRegion = chooseManifestProfile(vt, ct) | ||
local owner = getOwner(vt, ct, subtype, sourceRegion) or "Independent Consortium" | |||
local home = randomHomeForRegion(sourceRegion) | |||
local count = math.random(3, 4) | |||
local picks = pickCargoCompanies(vt, owner, ct, subtype, sourceRegion, count) | |||
-- Port authority safety lock: | |||
-- If the owner or selected company is one of the port authorities, | |||
-- force Home City, Owner/Operator, and Companies to all match. | |||
local portLock = nil | |||
if isPortAuthority(sourceRegion) then | |||
portLock = sourceRegion | |||
elseif isPortAuthority(owner) then | |||
portLock = owner | |||
else | |||
for _, nm in ipairs(picks) do | |||
if isPortAuthority(nm) then | |||
portLock = nm | |||
break | |||
end | |||
end | |||
end | |||
if portLock then | |||
vt = "Cargo" | |||
ct = "Services" | |||
subtype = "port_authority" | |||
sourceRegion = portLock | |||
home = portLock | |||
owner = portLock | |||
picks = { portLock } | |||
end | |||
local ownerLogo = ownerOperatorFlag[owner] and ("[[File:" .. ownerOperatorFlag[owner] .. "|20px]] ") | |||
or (companyLogo[owner] and ("[[File:" .. companyLogo[owner] .. "|20px]] ") or "") | |||
if #picks == 0 then | if #picks == 0 then | ||
local fallback = {} | |||
local base = (ct == "Unspecified") and generalPools or (poolMap[ct] or {}) | |||
for _, name in ipairs(base) do | |||
local meta = getCompanyMeta(name) | |||
if meta.region == sourceRegion then | |||
table.insert(fallback, name) | |||
end | end | ||
end | end | ||
picks = randomN(fallback, math.min(count, #fallback)) | |||
end | end | ||
| Line 650: | Line 787: | ||
compCell = compCell .. "</ul>" | compCell = compCell .. "</ul>" | ||
local errList = {"Cargo Mislabeling","Improper Documentation","Surveillance Anomaly","Inspection Failure","Unregistered Ritual Cargo"} | local errList = {"Cargo Mislabeling","Improper Documentation","Surveillance Anomaly","Inspection Failure","Unregistered Ritual Cargo"} | ||
local err = math.random() < 0.2 and randomChoice(errList) or "None" | local err = math.random() < 0.2 and randomChoice(errList) or "None" | ||
local rawT = math.random() * 19000 + 1000 | local rawT = math.random() * 19000 + 1000 | ||
local allowedT = math.min(rawT, MAX_DAILY_TONNAGE - totalTonnage) | local allowedT = math.min(rawT, MAX_DAILY_TONNAGE - totalTonnage) | ||
totalTonnage = totalTonnage + allowedT | totalTonnage = totalTonnage + allowedT | ||
table.insert(ships, { | table.insert(ships, { | ||
date = string.format("Day %d, Y.%d", d, y), | date = string.format("Day %d, Y.%d", d, y), | ||
| Line 678: | Line 812: | ||
}) | }) | ||
if totalTonnage >= MAX_DAILY_TONNAGE then | if totalTonnage >= MAX_DAILY_TONNAGE then | ||
break | break | ||
| Line 684: | Line 817: | ||
end | end | ||
table.sort(ships, function(a, b) return a.sort < b.sort end) | table.sort(ships, function(a, b) return a.sort < b.sort end) | ||
local out = { | local out = { | ||
'{| class="wikitable sortable"', | '{| class="wikitable sortable"', | ||
Latest revision as of 01:03, 26 May 2026
Documentation for this module may be created at Module:GeneralPortOperations/doc
-- Module:GeneralPortDailyLog
local p = {}
-- compatibility shim for unpack
local unpack = table.unpack or unpack
-- 0) Daily tonnage cap
local MAX_DAILY_TONNAGE = 1359348.096
-- 1) Date logic
function p.getCurrentDate()
local start = os.time{year=1999, month=8, day=6}
local elapsed = math.floor((os.time() - start) / 86400)
local year = math.floor(elapsed / 183)
local day = (elapsed % 183) + 1
return year, day
end
-- 2) Random helpers
local function randomChoice(tbl)
if type(tbl) ~= "table" or #tbl == 0 then return nil end
return tbl[math.random(#tbl)]
end
local function randomN(tbl, n)
if type(tbl) ~= "table" or n < 1 then return {} end
local copy, out = {unpack(tbl)}, {}
for i = 1, math.min(n, #copy) do
local idx = math.random(#copy)
table.insert(out, table.remove(copy, idx))
end
return out
end
-- 3) Home ports + flags
-- DO NOT ALTER: existing fixed home-city list retained exactly
local cities = {
"Aegirheim","Skýrophos","Bjornopolis","Norsolyra","Ephyra",
"Symphonara","Delphica","Vaeringheim","Somniumpolis",
"Keybir-Aviv","Sufriya","Jogi" , "Ardclach" , "Riddersborg"
}
local cityFlag = {}
for _, name in ipairs(cities) do
local norm = name
:gsub("[%s%-’]", "")
:gsub("[Áá]", "A"):gsub("[Éé]", "E")
:gsub("[Íí]", "I"):gsub("[Óó]", "O")
:gsub("[Úú]", "U"):gsub("[Ýý]", "Y")
cityFlag[name] = string.format("[[File:%sFlag.png|20px]]", norm)
end
cityFlag["Skýrophos"] = "[[File:SkyrophosFlag.png|20px]]"
cityFlag["Port of Corumia"] = "[[File:CorumiaFlag.png|20px]]"
cityFlag["Port of Euranidom"] = "[[File:Euranidom.png|20px]]"
cityFlag["Port of Southern Keltiania"] = "[[File:SouthKeltiania.png|20px]]"
local ownerOperatorFlag = {
["Port of Corumia"] = "CorumiaFlag.png",
["Port of Euranidom"] = "Euranidom.png",
["Port of Southern Keltiania"] = "SouthKeltiania.png",
}
-- 3b) Hatch Ministry-aligned cluster map
local cityRegion = {
["Aegirheim"] = "New South Jangsong",
["Skýrophos"] = "New South Jangsong",
["Bjornopolis"] = "New South Jangsong",
["Norsolyra"] = "New South Jangsong",
["Ephyra"] = "New South Jangsong",
["Symphonara"] = "Vaeringheim",
["Delphica"] = "Vaeringheim",
["Vaeringheim"] = "Vaeringheim",
["Somniumpolis"] = "Odiferia",
["Keybir-Aviv"] = "Haifan Bassaridia",
["Sufriya"] = "Haifan Bassaridia",
["Jogi"] = "Haifan Bassaridia",
["Ardclach"] = "Bassaridian Normark",
["Riddersborg"] = "Bassaridian Normark",
["Port of Corumia"] = "Port of Corumia",
["Port of Euranidom"] = "Port of Euranidom",
["Port of Southern Keltiania"] = "Port of Southern Keltiania",
}
local regionHomeCities = {
["New South Jangsong"] = {"Aegirheim","Skýrophos","Bjornopolis","Norsolyra","Ephyra"},
["Vaeringheim"] = {"Symphonara","Delphica","Vaeringheim"},
["Odiferia"] = {"Somniumpolis"},
["Haifan Bassaridia"] = {"Keybir-Aviv","Sufriya","Jogi"},
["Bassaridian Normark"]= {"Ardclach","Riddersborg"},
["Port of Corumia"] = {"Port of Corumia"},
["Port of Euranidom"] = {"Port of Euranidom"},
["Port of Southern Keltiania"] = {"Port of Southern Keltiania"},
}
local allCargoRegions = {
"Haifan Bassaridia",
"Odiferia",
"Alpazkigz",
"Vaeringheim",
"New South Jangsong",
"Bassaridian Normark",
"Ouriana",
"Caledonian Dependencies"
}
local function randomHomeForRegion(region)
local pool = regionHomeCities[region]
if pool and #pool > 0 then return randomChoice(pool) end
return randomChoice(cities)
end
-- 4) Vessel & cargo types
local vesselTypes = {"Cargo","Military","Ritual","Privateer"}
local cargoTypes = {"Agricultural","Mining/Manufacturing","Services","Unspecified"}
-- 5) Owner pools
local ritualCults = {
"Order of Aurora Mystica","Harmony Sanctum",
"Ignis Aeternum","Celestial Harmony Sect","Guild of Golden Shadows",
"Azure Sentinel Sect","Reverie Nebulous","Eon Fellowship",
"Order of the Umbral Oracle","Mystery of the Verdant Embrace",
"Conclave Illuminara","Sanctum Vitalis","Temple Alabaster",
"Court of the Ironclad","Accord Concordia","Mystery of the Stygian Veil",
"Sylvan Fellowship","Mystery of Red Mirth","Rex Catonis",
"Sanctum Delphica","Ordo Amicitia","Temple Illuminata"
}
local militaryDivs = {
"Alpazkigz Division","Odiferia Division","Vaeringheim Division",
"Haifa Division","Jeseri Division","Hatch Ministry Division",
"New South Jangsong Division","Haifan Bassaridia Division"
}
local agriCompanies = {
"Gladeseed Farmers' Union","Atterian Cattle Drivers",
"Jogiani Merchants of Manwine","Keepers of the Grove of Zoe Elm",
"Plains of Jogi","Ale of the Night Central Brewery",
"Camel Herders of the Jangsong Province","Anterran Imports and Services",
"Merchant Guild of the Poppy Goddess","Grand Cave Bee Meadery",
"Cinammon Plains of Rouge","The Velvet Company","Seamstresses of Rouge",
"Salurian Temple of Sacred Horehound","Bulhanu Ranchers' Association",
"Suncliff Fisheries","Ministers of Mistress Mugwort",
"Blood Vineyards of the Far North",
"Norsolyrian Wisp Rice Farmers Association",
"Giid-Lisea Ranching Import Company","Bird Keepers of Saluria",
"Hunters of the Giant Fanged Penguin","Knights Castle Reindeer Herders",
"Lindley Whaling Company","Aminian Coffee Company","Granadita Collective",
"Herd Caton","Wasp Hunters of the Austral Isles", "Sea Elm Southern Meadery",
"Nefel Village","Diamonia Sugar Cooperatives", "Ouriana Lowlands Farmers' Association",
"Nefel Village", "Ouriad River Fisheries Cooperative", "Caspazani Livestock Company",
"White Ruby Communes", "Fange Velvet", "Lamian Ward", "Sleva Farming Supplies Cooperative",
"Hrimmanes Woolhorse Company"," King's Home Fur Trappers' Cooperative", "Caledonj Bay Fishermen’s’ Cooperatives", "Salain's Landing Granary Complex","Grove Synaxis of Tel-Amin",
}
local miningCompanies = {
"Roving Wind Farm Corporation",
"Thalassian Temple Granite Export Cooperative","East Keltian Iron Company",
"Mylecian Coal Ports","Merchants of the Valley of Diamonds",
"East Keltian Timber Company","Onceanic Boot Company",
"Commune of the Garganid Apostles","Shï Collective","Order of the Sphinx",
"Market Hanavusu","Somniant Stock Fund","Copper Mines of Southern Jogi",
"Horned Bear Timber Company","Federation of North Brabipant",
"Southern Strait Preservation Corporation","Eosphorus Motor Company",
"Vortelin Electronics", "Thyrsiad Rubber Company","Stygium Mines of Acheron",
"Trans-Rodinian Granite Agency", "Amber Ports of Slevik", "Thesean Iron Exports",
"Fanghorn Highland Gas Company","Gadial Oil", "Tharsyr Shoal Salt Works",
}
local serviceCompanies = {
"Ergonian Spy Agency",
"Temple Bank of the Reformed Stripping Path",
"Temple University of Delphica","La Sái Ebile",
"Pharmacon Sect",
"Skyrophian Security Contractors",
"Haifadora Postal Service",
"Fleet of Rouge Divers",
"Merchant Caravans of the Candy Kingdom",
"Hellhound Breeders of Dragevik",
"Noctic Fleet",
"Maritime Guild of the Cult of Maskmakers",
"Couriers of the Lizard Queen",
"Temple of Aprobelle",
"Sårensby Depot*",
}
-- special pools
local privateerCompanies = {
"Lake Morovia Blockade Fund",
"Baratar Corporation",
"Hatch Ministry",
"Skyrophian Security Contractors",
"Temple of Aprobelle",
"Noctic Fleet",
"Maritime Guild of the Cult of Maskmakers",
"Merchant Caravans of the Candy Kingdom",
"Haifadora Postal Service",
"Fleet of Rouge Divers",
"Ergonian Spy Agency",
"Southern Strait Preservation Corporation",
"Somniant Stock Fund"
}
local hatchMinistryCompanies = {
"Hatch Ministry"
}
local portAuthorityCompanies = {
"Port of Corumia",
"Port of Euranidom",
"Port of Southern Keltiania",
}
local portAuthorityLookup = {}
for _, name in ipairs(portAuthorityCompanies) do
portAuthorityLookup[name] = true
end
local function isPortAuthority(name)
return portAuthorityLookup[name] == true
end
-- 5b) Company classification + Hatch-aligned source region metadata
local companyMeta = {
-- Agriculture
["Gladeseed Farmers' Union"] = {class="Agricultural", subtype="grain", region="Vaeringheim"},
["Atterian Cattle Drivers"] = {class="Agricultural", subtype="livestock", region="New South Jangsong"},
["Jogiani Merchants of Manwine"] = {class="Agricultural", subtype="wine_spirits", region="Haifan Bassaridia"},
["Keepers of the Grove of Zoe Elm"] = {class="Agricultural", subtype="forest_products", region="Vaeringheim"},
["Plains of Jogi"] = {class="Agricultural", subtype="grain", region="Haifan Bassaridia"},
["Ale of the Night Central Brewery"] = {class="Agricultural", subtype="wine_spirits", region="Vaeringheim"},
["Camel Herders of the Jangsong Province"] = {class="Agricultural", subtype="livestock", region="New South Jangsong"},
["Anterran Imports and Services"] = {class="Agricultural", subtype="mixed_foodstuffs", region="Vaeringheim"},
["Merchant Guild of the Poppy Goddess"] = {class="Agricultural", subtype="herbs", region="Vaeringheim"},
["Grand Cave Bee Meadery"] = {class="Agricultural", subtype="mead_spirits", region="Vaeringheim"},
["Cinammon Plains of Rouge"] = {class="Agricultural", subtype="spices", region="Vaeringheim"},
["The Velvet Company"] = {class="Agricultural", subtype="textiles_raw", region="Vaeringheim"},
["Seamstresses of Rouge"] = {class="Agricultural", subtype="textiles_raw", region="Vaeringheim"},
["Salurian Temple of Sacred Horehound"] = {class="Agricultural", subtype="herbs", region="Alpazkigz"},
["Bulhanu Ranchers' Association"] = {class="Agricultural", subtype="livestock", region="Odiferia"},
["Suncliff Fisheries"] = {class="Agricultural", subtype="fish", region="Vaeringheim"},
["Ministers of Mistress Mugwort"] = {class="Agricultural", subtype="herbs", region="Vaeringheim"},
["Blood Vineyards of the Far North"] = {class="Agricultural", subtype="wine_spirits", region="New South Jangsong"},
["Norsolyrian Wisp Rice Farmers Association"] = {class="Agricultural", subtype="grain", region="New South Jangsong"},
["Giid-Lisea Ranching Import Company"] = {class="Agricultural", subtype="livestock", region="Vaeringheim"},
["Bird Keepers of Saluria"] = {class="Agricultural", subtype="animal_products", region="Alpazkigz"},
["Hunters of the Giant Fanged Penguin"] = {class="Agricultural", subtype="animal_products", region="Caledonian Dependencies"},
["Knights Castle Reindeer Herders"] = {class="Agricultural", subtype="livestock", region="Bassaridian Normark"},
["Lindley Whaling Company"] = {class="Agricultural", subtype="marine_oil", region="Caledonian Dependencies"},
["Aminian Coffee Company"] = {class="Agricultural", subtype="coffee", region="Haifan Bassaridia"},
["Grove Synaxis of Tel-Amin"] = {class="Agricultural", subtype="fruit", region="Haifan Bassaridia"},
["Granadita Collective"] = {class="Agricultural", subtype="fruit", region="Haifan Bassaridia"},
["Herd Caton"] = {class="Agricultural", subtype="livestock", region="Vaeringheim"},
["Wasp Hunters of the Austral Isles"] = {class="Agricultural", subtype="animal_products", region="Caledonian Dependencies"},
["Sea Elm Southern Meadery"] = {class="Agricultural", subtype="mead_spirits", region="Vaeringheim"},
["Nefel Village"] = {class="Agricultural", subtype="mixed_foodstuffs", region="Vaeringheim"},
["Diamonia Sugar Cooperatives"] = {class="Agricultural", subtype="sugar", region="Haifan Bassaridia"},
["Ouriana Lowlands Farmers' Association"] = {class="Agricultural", subtype="grain", region="Ouriana"},
["Ouriad River Fisheries Cooperative"] = {class="Agricultural", subtype="fish", region="Ouriana"},
["Caspazani Livestock Company"] = {class="Agricultural", subtype="livestock", region="Ouriana"},
["White Ruby Communes"] = {class="Agricultural", subtype="mixed_foodstuffs", region="Vaeringheim"},
["Fange Velvet"] = {class="Agricultural", subtype="textiles_raw", region="Caledonian Dependencies"},
["Lamian Ward"] = {class="Agricultural", subtype="mixed_foodstuffs", region="Vaeringheim"},
["Sleva Farming Supplies Cooperative"] = {class="Agricultural", subtype="farm_inputs", region="Caledonian Dependencies"},
["Hrimmanes Woolhorse Company"] = {class="Agricultural", subtype="livestock", region="Caledonian Dependencies"},
[" King's Home Fur Trappers' Cooperative"] = {class="Agricultural", subtype="animal_products", region="Bassaridian Normark"},
["Caledonj Bay Fishermen’s’ Cooperatives"] = {class="Agricultural", subtype="fish", region="Caledonian Dependencies"},
["Salain's Landing Granary Complex"] = {class="Agricultural", subtype="grain", region="Vaeringheim"},
-- Mining / Manufacturing / Energy
["Roving Wind Farm Corporation"] = {class="Mining/Manufacturing", subtype="energy", region="Vaeringheim"},
["Thalassian Temple Granite Export Cooperative"] = {class="Mining/Manufacturing", subtype="stone", region="Vaeringheim"},
["East Keltian Iron Company"] = {class="Mining/Manufacturing", subtype="metals", region="Vaeringheim"},
["Mylecian Coal Ports"] = {class="Mining/Manufacturing", subtype="coal", region="Vaeringheim"},
["Merchants of the Valley of Diamonds"] = {class="Mining/Manufacturing", subtype="gemstones", region="Haifan Bassaridia"},
["East Keltian Timber Company"] = {class="Mining/Manufacturing", subtype="timber", region="Vaeringheim"},
["Onceanic Boot Company"] = {class="Mining/Manufacturing", subtype="consumer_goods", region="Vaeringheim"},
["Commune of the Garganid Apostles"] = {class="Mining/Manufacturing", subtype="stone", region="Vaeringheim"},
["Shï Collective"] = {class="Mining/Manufacturing", subtype="luxury_goods", region="Vaeringheim"},
["Order of the Sphinx"] = {class="Mining/Manufacturing", subtype="luxury_goods", region="Haifan Bassaridia"},
["Market Hanavusu"] = {class="Mining/Manufacturing", subtype="consumer_goods", region="New South Jangsong"},
["Somniant Stock Fund"] = {class="Mining/Manufacturing", subtype="arms_industrial", region="Vaeringheim"},
["Copper Mines of Southern Jogi"] = {class="Mining/Manufacturing", subtype="metals", region="Haifan Bassaridia"},
["Horned Bear Timber Company"] = {class="Mining/Manufacturing", subtype="timber", region="New South Jangsong"},
["Federation of North Brabipant"] = {class="Mining/Manufacturing", subtype="consumer_goods", region="Caledonian Dependencies"},
["Southern Strait Preservation Corporation"] = {class="Mining/Manufacturing", subtype="marine_materials", region="Haifan Bassaridia"},
["Eosphorus Motor Company"] = {class="Mining/Manufacturing", subtype="vehicles", region="Vaeringheim"},
["Vortelin Electronics"] = {class="Mining/Manufacturing", subtype="electronics", region="Vaeringheim"},
["Thyrsiad Rubber Company"] = {class="Mining/Manufacturing", subtype="rubber", region="Haifan Bassaridia"},
["Stygium Mines of Acheron"] = {class="Mining/Manufacturing", subtype="metals", region="Alpazkigz"},
["Trans-Rodinian Granite Agency"] = {class="Mining/Manufacturing", subtype="stone", region="Vaeringheim"},
["Amber Ports of Slevik"] = {class="Mining/Manufacturing", subtype="amber", region="Caledonian Dependencies"},
["Thesean Iron Exports"] = {class="Mining/Manufacturing", subtype="metals", region="Ouriana"},
["Fanghorn Highland Gas Company"] = {class="Mining/Manufacturing", subtype="gas", region="Caledonian Dependencies"},
["Gadial Oil"] = {class="Mining/Manufacturing", subtype="oil", region="Vaeringheim"},
["Tharsyr Shoal Salt Works"] = {class="Mining/Manufacturing", subtype="salt", region="Vaeringheim"},
-- Services
["Ergonian Spy Agency"] = {class="Services", subtype="intelligence", region="Vaeringheim"},
["Temple Bank of the Reformed Stripping Path"] = {class="Services", subtype="finance", region="Vaeringheim"},
["Temple University of Delphica"] = {class="Services", subtype="education", region="Vaeringheim"},
["La Sái Ebile"] = {class="Services", subtype="commerce", region="Haifan Bassaridia"},
["Pharmacon Sect"] = {class="Services", subtype="medical", region="Alpazkigz"},
["Skyrophian Security Contractors"] = {class="Services", subtype="security", region="New South Jangsong"},
["Haifadora Postal Service"] = {class="Services", subtype="courier", region="Haifan Bassaridia"},
["Fleet of Rouge Divers"] = {class="Services", subtype="marine_services", region="Vaeringheim"},
["Merchant Caravans of the Candy Kingdom"] = {class="Services", subtype="logistics", region="Vaeringheim"},
["Hellhound Breeders of Dragevik"] = {class="Services", subtype="animal_services", region="Bassaridian Normark"},
["Noctic Fleet"] = {class="Services", subtype="marine_services", region="Vaeringheim"},
["Maritime Guild of the Cult of Maskmakers"] = {class="Services", subtype="marine_services", region="Vaeringheim"},
["Couriers of the Lizard Queen"] = {class="Services", subtype="courier", region="Vaeringheim"},
["Temple of Aprobelle"] = {class="Services", subtype="security", region="Vaeringheim"},
["Sårensby Depot*"] = {class="Services", subtype="logistics", region="Bassaridian Normark"},
["Port of Corumia"] = {class="Services", subtype="port_authority", region="Port of Corumia"},
["Port of Euranidom"] = {class="Services", subtype="port_authority", region="Port of Euranidom"},
["Port of Southern Keltiania"] = {class="Services", subtype="port_authority", region="Port of Southern Keltiania"},
-- Special pools
["Lake Morovia Blockade Fund"] = {class="Services", subtype="security", region="Vaeringheim"},
["Baratar Corporation"] = {class="Mining/Manufacturing", subtype="arms_industrial", region="Haifan Bassaridia"},
["Hatch Ministry"] = {class="Services", subtype="security", region="Vaeringheim"},
}
-- build a “general” pool excluding special-only firms
local generalPools = {}
for _, list in ipairs({agriCompanies, miningCompanies, serviceCompanies}) do
for _, name in ipairs(list) do
if name ~= "Hatch Ministry" then
local isPri = false
for _, pr in ipairs(privateerCompanies) do
if name == pr then isPri = true break end
end
if not isPri then
table.insert(generalPools, name)
end
end
end
end
local function getCompanyMeta(name)
return companyMeta[name] or {class="Unspecified", subtype="mixed", region="Vaeringheim"}
end
local function buildPoolByClassSubtypeRegion(className, subtype, region)
local base = ({
Agricultural = agriCompanies,
["Mining/Manufacturing"] = miningCompanies,
Services = serviceCompanies
})[className] or {}
local pool = {}
for _, name in ipairs(base) do
if name ~= "Hatch Ministry" then
local isPri = false
for _, pr in ipairs(privateerCompanies) do
if name == pr then isPri = true break end
end
if not isPri then
local meta = getCompanyMeta(name)
if meta.class == className and meta.subtype == subtype and meta.region == region then
table.insert(pool, name)
end
end
end
end
return pool
end
local function buildGeneralPoolBySubtypeRegion(subtype, region)
local pool = {}
for _, name in ipairs(generalPools) do
local meta = getCompanyMeta(name)
if meta.subtype == subtype and meta.region == region then
table.insert(pool, name)
end
end
return pool
end
local function chooseManifestProfile(vt, ct)
if vt == "Privateer" then
local subtype = randomChoice({"security","arms_industrial","logistics","medical"})
local region = randomChoice({"Haifan Bassaridia","Odiferia","Alpazkigz","Vaeringheim","New South Jangsong","Bassaridian Normark","Ouriana"})
return subtype, region
elseif vt == "Military" then
local subtype = randomChoice({"security","arms_industrial","medical","logistics"})
local region = randomChoice({"Haifan Bassaridia","Odiferia","Alpazkigz","Vaeringheim","New South Jangsong","Bassaridian Normark","Ouriana"})
return subtype, region
elseif vt == "Ritual" then
local subtype = randomChoice({"finance","medical","courier","security","education","logistics"})
local region = randomChoice({"Haifan Bassaridia","Odiferia","Alpazkigz","Vaeringheim","New South Jangsong","Bassaridian Normark"})
return subtype, region
elseif ct == "Agricultural" then
local subtype = randomChoice({
"grain","livestock","wine_spirits","forest_products","herbs",
"mead_spirits","spices","textiles_raw","fish","animal_products",
"marine_oil","coffee","fruit","sugar","mixed_foodstuffs","farm_inputs"
})
local region = randomChoice(allCargoRegions)
return subtype, region
elseif ct == "Mining/Manufacturing" then
local subtype = randomChoice({
"energy","stone","salt","metals","coal","gemstones","timber","consumer_goods",
"luxury_goods","arms_industrial","marine_materials","vehicles",
"electronics","rubber","amber","gas","oil"
})
local region = randomChoice(allCargoRegions)
return subtype, region
elseif ct == "Services" then
if math.random() < 0.20 then
local port = randomChoice(portAuthorityCompanies)
return "port_authority", port
else
local subtype = randomChoice({
"intelligence","finance","education","commerce","medical",
"security","courier","marine_services","logistics","animal_services"
})
local region = randomChoice(allCargoRegions)
return subtype, region
end
else
local source = randomChoice(generalPools)
local meta = getCompanyMeta(source)
return meta.subtype, meta.region
end
end
local function pickCargoCompanies(vt, owner, ct, subtype, region, count)
if vt == "Cargo" and isPortAuthority(region) then
return { region }
end
if vt == "Privateer" then
local pool = {}
for _, name in ipairs(privateerCompanies) do
local meta = getCompanyMeta(name)
if meta.region == region then
if subtype == "security" and meta.subtype == "security" then
table.insert(pool, name)
elseif subtype == "arms_industrial" and meta.subtype == "arms_industrial" then
table.insert(pool, name)
elseif subtype == "logistics" and (
meta.subtype == "logistics" or
meta.subtype == "courier" or
meta.subtype == "marine_services"
) then
table.insert(pool, name)
elseif subtype == "medical" and meta.subtype == "medical" then
table.insert(pool, name)
end
end
end
if #pool == 0 then
for _, name in ipairs(privateerCompanies) do
local meta = getCompanyMeta(name)
if meta.subtype == "security"
or meta.subtype == "arms_industrial"
or meta.subtype == "logistics"
or meta.subtype == "courier"
or meta.subtype == "marine_services"
or meta.subtype == "medical" then
table.insert(pool, name)
end
end
end
return randomN(pool, math.min(count, #pool))
elseif owner == "Hatch Ministry Division" then
return randomN(hatchMinistryCompanies, 1)
elseif ct == "Unspecified" then
local pool = buildGeneralPoolBySubtypeRegion(subtype, region)
if #pool == 0 then
local fallback = {}
for _, name in ipairs(generalPools) do
local meta = getCompanyMeta(name)
if meta.region == region then
table.insert(fallback, name)
end
end
pool = fallback
end
return randomN(pool, math.min(count, #pool))
else
local pool = buildPoolByClassSubtypeRegion(ct, subtype, region)
if #pool == 0 then
local fallback = {}
local base = ({
Agricultural = agriCompanies,
["Mining/Manufacturing"] = miningCompanies,
Services = serviceCompanies
})[ct] or {}
for _, name in ipairs(base) do
if name ~= "Hatch Ministry" then
local isPri = false
for _, pr in ipairs(privateerCompanies) do
if name == pr then isPri = true break end
end
if not isPri then
local meta = getCompanyMeta(name)
if meta.region == region then
table.insert(fallback, name)
end
end
end
end
pool = fallback
end
return randomN(pool, math.min(count, #pool))
end
end
-- 6) Company logos mapping
local companyLogo = {}
local function addLogo(name,file) companyLogo[name]=file end
addLogo("Lake Morovia Blockade Fund","BlockadeFund420.png")
addLogo("Gladeseed Farmers' Union","Gladeseed420.png")
addLogo("Atterian Cattle Drivers","Atterian420.png")
addLogo("Noctic Fleet","Noctic420.png")
addLogo("Jogiani Merchants of Manwine","Jogiani420.png")
addLogo("Keepers of the Grove of Zoe Elm","KeepersoftheGrove.png")
addLogo("Plains of Jogi","PlainsofJogi.png")
addLogo("Ale of the Night Central Brewery","AleofNight420.png")
addLogo("Camel Herders of the Jangsong Province","CamelHerders420.png")
addLogo("Thalassian Temple Granite Export Cooperative","ThalassianGranite420.png")
addLogo("East Keltian Iron Company","EKIron420.png")
addLogo("Mylecian Coal Ports","CoalPorts420.png")
addLogo("Merchants of the Valley of Diamonds","ValleyofDiamonds420.png")
addLogo("Baratar Corporation","Baratar420.png")
addLogo("Roving Wind Farm Corporation","RovingWind420.png")
addLogo("Grand Cave Bee Meadery","GrandCave420.png")
addLogo("Merchant Guild of the Poppy Goddess","PoppyGoddess420.png")
addLogo("Cinammon Plains of Rouge","CinammonPlains420.png")
addLogo("The Velvet Company","VelvetHome420.png")
addLogo("Seamstresses of Rouge","Seamstresses420.png")
addLogo("Salurian Temple of Sacred Horehound","SalurianTemple421.png")
addLogo("Bulhanu Ranchers' Association","Bulhanu421.png")
addLogo("Suncliff Fisheries","Suncliff421.png")
addLogo("Ministers of Mistress Mugwort","Mugwort421.png")
addLogo("Blood Vineyards of the Far North","BloodVineyards421.png")
addLogo("Norsolyrian Wisp Rice Farmers Association","Norsolyrian421.png")
addLogo("Giid-Lisea Ranching Import Company","GiidLisea421.png")
addLogo("Bird Keepers of Saluria","SaluriaBK421.png")
addLogo("Knights Castle Reindeer Herders","KnightsCastle421.png")
addLogo("Lindley Whaling Company","LindleyWhalingCompany.png")
addLogo("Aminian Coffee Company","Aminian421.png")
addLogo("Grove Synaxis of Tel-Amin","GroveSynaxisLogo.png")
addLogo("Commune of the Garganid Apostles","Garganid421.png")
addLogo("Onceanic Boot Company","OnceanicBoot421.png")
addLogo("Maritime Guild of the Cult of Maskmakers","MaritimeGuild420.png")
addLogo("Ergonian Spy Agency","ErgonianSpy421.png")
addLogo("Temple Bank of the Reformed Stripping Path","TempleBankCrest.png")
addLogo("Couriers of the Lizard Queen","LizardQueen421.png")
addLogo("Temple University of Delphica","TempleUniversity421.png")
addLogo("Shï Collective","ShiCollective421.png")
addLogo("Order of the Sphinx","OrderofSphinx421.png")
addLogo("Market Hanavusu","MarketHanavusu421.png")
addLogo("Somniant Stock Fund","SomniantStockFund.png")
addLogo("Hatch Ministry","HatchMinistry420.png")
addLogo("Anterran Imports and Services","AnterranImports420.png")
addLogo("East Keltian Timber Company","EKTimber420.png")
addLogo("Hellhound Breeders of Dragevik","Dragevik421.png")
addLogo("La Sái Ebile","LaSie421.png")
addLogo("Hunters of the Giant Fanged Penguin","FangedPenguin421.png")
addLogo("Commune of the Garganid Apostles","Garganid421.png")
addLogo("Copper Mines of Southern Jogi","CopperMinesLogoC.png")
addLogo("Horned Bear Timber Company","HornedBearTimberLogo.png")
addLogo("Granadita Collective","GranaditaCollectiveLogo.png")
addLogo("Pharmacon Sect","PharmaconSect.png")
addLogo("Skyrophian Security Contractors","SkyrophianSecurity.png")
addLogo("Haifadora Postal Service","HaifadoraPostalLogo.png")
addLogo("Herd Caton","HerdCatonLogo.png")
addLogo("Wasp Hunters of the Austral Isles","WaspHuntersLogo.png")
addLogo("Fleet of Rouge Divers","RougeDiversLogo.png")
addLogo("Sea Elm Southern Meadery","SeaElmLogo.png")
addLogo("Candy Merchants of the Candy Kingdom","Candymerchantslogo.png")
addLogo("Federation of North Brabipant","NorthBrabipantlogo.png")
addLogo("Southern Strait Preservation Corporation","SouthernStraitPreservationLogo.png")
addLogo("Eosphorus Motor Company","EosphorusLogo.png")
addLogo("Vortelin Electronics","VortelinElectronicsLogo.png")
addLogo("Thyrsiad Rubber Company","ThyrsiadRubberLogo.png")
addLogo("Nefel Village","NefelVillageLogo.png")
addLogo("Stygium Mines of Acheron","StygiumMinesLogo.png")
addLogo("Temple of Aprobelle","TempleAprobelleLogo.png")
addLogo("Diamonia Sugar Cooperatives","DiamoniaSugarLogo.png")
addLogo("Ouriana Lowlands Farmers' Association","OurianaLowlandsLogo.png")
addLogo("Ouriad River Fisheries Cooperative","OuriadRiverLogo.png")
addLogo("Caspazani Livestock Company","CaspazaniLogo.png")
addLogo("Trans-Rodinian Granite Agency","TransRodinanLogo.png")
addLogo("White Ruby Communes","WhiteRubyLogo.png")
addLogo("Fange Velvet","FangeVelvetLogo.png")
addLogo("Sårensby Depot","SårensbyDepotLogo.png")
addLogo("Amber Ports of Slevik","AmberPortsLogo2.png")
addLogo("Port of Corumia","PortofCorumiaLogo.png")
addLogo("Port of Euranidom","PortofEuranidomLogo.png")
addLogo("Port of Southern Keltiania","PortofSouthernKeltianiaLogo.png")
addLogo("Lamian Ward","LamianWardLogo.png")
addLogo("Sleva Farming Supplies Cooperatives","SlevaFarmingLogo.png")
addLogo("Hrimmanes Woolhorse Company","HrimmanesLogoB.png.png")
addLogo("Thesean Iron Exports","TheseanIronExports.png")
addLogo("King's Home Fur Trappers' Cooperative","KingsHomeCoLogo.png.png")
addLogo("Fanghorn Highland Gas Company","FanghornGasLogo.png")
addLogo("Caledonj Bay Fishermen’s’ Cooperatives","CaledonjBayLogo.png")
addLogo("Gadial Oil","GadialOilLogoB.png")
addLogo("Alpazkigz Division", "AlpazkigzDivisionFlag.png")
addLogo("Odiferia Division", "OdiferiaFlag.png")
addLogo("Vaeringheim Division", "VaeringheimDivisionFlag.png")
addLogo("Haifa Division", "HafaanFlag.png")
addLogo("Jeseri Division", "JeseriFlag.png")
addLogo("Hatch Ministry Division", "HatchMinistryFlag.png")
addLogo("New South Jangsong Division","NewSouthJangsongFlag.png")
addLogo("Haifan Bassaridia Division", "HaifaDivisionFlag.png")
addLogo("Order of Aurora Mystica", "Auroramystica.png")
addLogo("Harmony Sanctum", "Harmonysanctum.png")
addLogo("Ignis Aeternum", "Ignis Aeternum.png")
addLogo("Celestial Harmony Sect", "HarmonySect.png")
addLogo("Guild of Golden Shadows", "GoldenShadows.png")
addLogo("Azure Sentinel Sect", "AzureSentinel.png")
addLogo("Reverie Nebulous","RevNeb.png")
addLogo("Eon Fellowship", "EonFel.png")
addLogo("Order of the Umbral Oracle", "Umbral.png")
addLogo("Mystery of the Verdant Embrace", "Verdant.png")
addLogo("Conclave Illuminara", "Conclave.png")
addLogo("Sanctum Vitalis", "Vitalis.png")
addLogo("Temple Alabaster", "Alabaster.png")
addLogo("Court of the Ironclad", "Ironclad.png")
addLogo("Accord Concordia", "Concordia.png")
addLogo("Mystery of the Stygian Veil", "StygianVe.png")
addLogo("Sylvan Fellowship", "Sylvan.png")
addLogo("Mystery of Red Mirth", "MirthFlag.png")
addLogo("Rex Catonis", "Catonis.png")
addLogo("Sanctum Delphica", "SanctumDel.png")
addLogo("Ordo Amicitia", "OrdoFl.png")
addLogo("Temple Illuminata", "AureumFlag.png")
addLogo("Tharsyr Shoal Salt Works","TharsyrShoalSaltWorksLogo.png")
addLogo("Salain's Landing Granary Complex","SalainsLandingGranaryLogo.png")
-- 7) Privateer flags + helper
local privateers = {
{first="Arion", last="Theron"},
{first="Cassius", last="Valerus"},
{first="Nefra", last="Sekeri", nick="Sekhem"},
{first="Lysander", last="Pallas"},
{first="Marwan", last="Othman"},
{first="Octavia", last="Marcellus"},
{first="Amenhotep",last="Ankhu"},
{first="Thalia", last="Chrysos"},
{first="Demetrius",last="Gravis"},
{first="Selim", last="Bey"},
{first="Julius", last="Drusus"},
{first="Leyla", last="Han"},
{first="Marcus", last="Flavianus"},
{first="Fatima", last="Pasha"},
{first="Cornelia", last="Urbanus"},
{first="Eudora", last="Merit"},
{first="Perseus", last="Phoebus"},
{first="Khepri", last="Sobek"},
{first="Lucius", last="Aurelian"},
{first="Aisha", last="Dinar"},
{first="Gaius", last="Cassianus"},
{first="Selene", last="Argus"},
{first="Arsinoe", last="Menkaure"},
{first="Omar", last="Zahir"},
{first="Dorian", last="Grimm"},
{first="Quintus", last="Nero"},
{first="Zainab", last="Sultan"},
{first="Cassian", last="Corinth"},
{first="Valeria", last="Maximus", nick="Ferox"},
{first="Thorne", last="Noctis", nick="Mainomenos"}
}
local function getRandomPrivateer()
local c = randomChoice(privateers)
local flag = string.format("[[File:%s.png|20px]] ", c.last)
if c.nick and math.random() < 0.20 then
return string.format("%sCaptain %s ‘%s’ %s", flag, c.first, c.nick, c.last)
else
return string.format("%sCaptain %s %s", flag, c.first, c.last)
end
end
-- 8) Determine Owner/Operator
local function getOwner(vt, ct, subtype, region)
if vt == "Cargo" and isPortAuthority(region) then
return region
end
if vt == "Ritual" then
return randomChoice(ritualCults)
elseif vt == "Military" then
return randomChoice(militaryDivs)
elseif vt == "Privateer" then
return getRandomPrivateer()
elseif vt == "Cargo" then
if ct == "Agricultural" then
local pool = buildPoolByClassSubtypeRegion("Agricultural", subtype, region)
return randomChoice(pool) or randomChoice(agriCompanies)
elseif ct == "Mining/Manufacturing" then
local pool = buildPoolByClassSubtypeRegion("Mining/Manufacturing", subtype, region)
return randomChoice(pool) or randomChoice(miningCompanies)
elseif ct == "Services" then
local pool = buildPoolByClassSubtypeRegion("Services", subtype, region)
return randomChoice(pool) or randomChoice(serviceCompanies)
elseif ct == "Unspecified" then
local pool = buildGeneralPoolBySubtypeRegion(subtype, region)
return randomChoice(pool) or "Independent Consortium"
end
end
return "Independent Consortium"
end
-- 9) Build the table
function p.generateShipTable()
math.randomseed(os.time())
local y, d = p.getCurrentDate()
local poolMap = {
Agricultural = agriCompanies,
["Mining/Manufacturing"] = miningCompanies,
Services = serviceCompanies
}
local totalTonnage = 0
local ships = {}
for i = 1, math.random(50, 80) do
local hr, mn = math.random(0, 23), math.random(0, 59)
local vt, ct = randomChoice(vesselTypes), randomChoice(cargoTypes)
local subtype, sourceRegion = chooseManifestProfile(vt, ct)
local owner = getOwner(vt, ct, subtype, sourceRegion) or "Independent Consortium"
local home = randomHomeForRegion(sourceRegion)
local count = math.random(3, 4)
local picks = pickCargoCompanies(vt, owner, ct, subtype, sourceRegion, count)
-- Port authority safety lock:
-- If the owner or selected company is one of the port authorities,
-- force Home City, Owner/Operator, and Companies to all match.
local portLock = nil
if isPortAuthority(sourceRegion) then
portLock = sourceRegion
elseif isPortAuthority(owner) then
portLock = owner
else
for _, nm in ipairs(picks) do
if isPortAuthority(nm) then
portLock = nm
break
end
end
end
if portLock then
vt = "Cargo"
ct = "Services"
subtype = "port_authority"
sourceRegion = portLock
home = portLock
owner = portLock
picks = { portLock }
end
local ownerLogo = ownerOperatorFlag[owner] and ("[[File:" .. ownerOperatorFlag[owner] .. "|20px]] ")
or (companyLogo[owner] and ("[[File:" .. companyLogo[owner] .. "|20px]] ") or "")
if #picks == 0 then
local fallback = {}
local base = (ct == "Unspecified") and generalPools or (poolMap[ct] or {})
for _, name in ipairs(base) do
local meta = getCompanyMeta(name)
if meta.region == sourceRegion then
table.insert(fallback, name)
end
end
picks = randomN(fallback, math.min(count, #fallback))
end
local compCell = "<ul>"
for _, nm in ipairs(picks) do
local logo = companyLogo[nm] and ("[[File:" .. companyLogo[nm] .. "|20px]] ") or ""
compCell = compCell .. string.format("<li>%s%s</li>", logo, nm)
end
compCell = compCell .. "</ul>"
local errList = {"Cargo Mislabeling","Improper Documentation","Surveillance Anomaly","Inspection Failure","Unregistered Ritual Cargo"}
local err = math.random() < 0.2 and randomChoice(errList) or "None"
local rawT = math.random() * 19000 + 1000
local allowedT = math.min(rawT, MAX_DAILY_TONNAGE - totalTonnage)
totalTonnage = totalTonnage + allowedT
table.insert(ships, {
date = string.format("Day %d, Y.%d", d, y),
time = string.format("%02d:%02d", hr, mn),
sort = hr * 60 + mn,
vid = "VM-" .. math.random(10000, 99999),
home = cityFlag[home] .. " " .. home,
typ = vt,
ownerCell = ownerLogo .. owner,
cargotype = string.format("%s / %s / %s", ct, subtype, sourceRegion),
cargoCompanies = compCell,
berth = math.random(1, 124),
teus = math.random(100, 1000),
tonnage = string.format("%.2f", allowedT),
queue = string.format("%.2f", math.random() * 5.5 + 0.5),
turnaround = string.format("%.2f", math.random() * 32 + 4),
error = err
})
if totalTonnage >= MAX_DAILY_TONNAGE then
break
end
end
table.sort(ships, function(a, b) return a.sort < b.sort end)
local out = {
'{| class="wikitable sortable"',
'! Date !! Time !! Vessel ID !! Home City !! Type !! Owner/Operator !! Cargo Type !! Companies',
'!! Berth !! TEUs !! Tonnage (t) !! Queue (hrs) !! Turnaround (hrs) !! Error'
}
for _, s in ipairs(ships) do
local row = (s.error ~= "None") and '|- bgcolor="#ffcccc"' or '|-'
table.insert(out, row)
table.insert(out, table.concat({
'|', s.date, '||', s.time, '||', s.vid, '||', s.home, '||', s.typ,
'||', s.ownerCell, '||', s.cargotype, '||', s.cargoCompanies,
'||', s.berth, '||', s.teus, '||', s.tonnage, '||', s.queue,
'||', s.turnaround, '||', s.error
}, ' '))
end
table.insert(out, '|}')
table.insert(out, "'''Error Key:'''")
table.insert(out, "* '''Cargo Mislabeling:''' Manifest ≠ actual goods")
table.insert(out, "* '''Improper Documentation:''' Missing or outdated papers")
table.insert(out, "* '''Surveillance Anomaly:''' Unexpected heat/motion")
table.insert(out, "* '''Inspection Failure:''' Customs/hatch failure")
table.insert(out, "* '''Unregistered Ritual Cargo:''' Not pre-cleared by Temple Bank")
return table.concat(out, "\n")
end
function p.dailyReport()
local y, d = p.getCurrentDate()
return string.format(
"'''General Port of Lake Morovia: Operational Log – Day %d, Year %d PSSC'''",
d, y
) .. "\n" .. p.generateShipTable()
end
return p