1
0
mirror of https://github.com/Oarcinae/FactorioScenarioMultiplayerSpawn.git synced 2025-01-26 03:20:21 +02:00
FactorioScenarioMultiplayer.../lib/oarc_store_map_features.lua
2020-07-21 20:51:59 -04:00

311 lines
14 KiB
Lua

-- oarc_store_map_features.lua
-- May 2020
-- Adding microtransactions.
require("lib/shared_chests")
require("lib/map_features")
OARC_STORE_MAP_CATEGORIES =
{
special_chests = "Special buildings for sharing or monitoring items and energy. This will convert the closest wooden chest (to you) within 16 tiles into a special building of your choice. Make sure to leave enough space! The combinators and accumulators can take up several tiles around them.",
special_chunks = "Map features that can be built on the special empty chunks found on the map. You must be standing inside an empty special chunk to be able to build these. Each player can only build one of each type. [color=red]THESE FEATURES ARE PERMANENT AND CAN NOT BE REMOVED![/color]",
special_buttons = "Special buttons like teleporting home and placing waterfill.",
reset_buttons = "Reset your player and base. [color=red]Choose carefully! Can't be undone.[/color] If you don't own a base and your own force, some options may not be available to you."
}
-- N = number already purchased
-- Cost = initial + (additional * ( N^multiplier ))
OARC_STORE_MAP_FEATURES =
{
special_chests = {
["logistic-chest-storage"] = {
initial_cost = 200,
additional_cost = 20,
multiplier_cost = 2,
max_cost = 2000,
-- limit = 100,
text="Input chest for storing shared items."},
["logistic-chest-requester"] = {
initial_cost = 200,
additional_cost = 50,
multiplier_cost = 2,
max_cost = 4000,
-- limit = 100,
text="Output chest for requesting shared items."},
["constant-combinator"] = {
initial_cost = 50,
text="Combinator setup to monitor shared items."},
["accumulator"] = {
initial_cost = 200,
additional_cost = 50,
multiplier_cost = 2,
max_cost = 2000,
-- limit = 100,
text="INPUT for shared energy system."},
["electric-energy-interface"] = {
initial_cost = 200,
additional_cost = 100,
multiplier_cost = 2,
max_cost = 4000,
-- limit = 100,
text="OUTPUT for shared energy system."},
["deconstruction-planner"] = {
initial_cost = 0,
text="Removes the closest special building within range. NO REFUNDS!"},
},
special_chunks = {
["electric-furnace"] = {
initial_cost = 1000,
additional_cost = 1000,
multiplier_cost = 2,
-- limit = 3,
text="Build a special furnace chunk here. Contains 4 furnaces that run at very high speeds. [color=red]Requires energy from the shared storage. Modules have no effect![/color]"},
["oil-refinery"] = {
initial_cost = 1000,
additional_cost = 1000,
multiplier_cost = 2,
-- limit = 3,
text="Build a special oil refinery chunk here. Contains 2 refineries and some chemical plants that run at very high speeds. [color=red]Requires energy from the shared storage. Modules have no effect![/color]"},
["assembling-machine-3"] = {
initial_cost = 1000,
additional_cost = 1000,
multiplier_cost = 2,
-- limit = 3,
text="Build a special assembly machine chunk here. Contains 6 assembling machines that run at very high speeds. [color=red]Requires energy from the shared storage. Modules have no effect![/color]"},
["centrifuge"] = {
initial_cost = 1000,
additional_cost = 1000,
multiplier_cost = 2,
-- limit = 1,
text="Build a special centrifuge chunk here. Contains 1 centrifuge that runs at very high speeds. [color=red]Requires energy from the shared storage. Modules have no effect![/color]"},
["rocket-silo"] = {
initial_cost = 1000,
additional_cost = 0,
multiplier_cost = 2,
max_cost = 10000,
-- limit = 2,
text="Convert this special chunk into a rocket launch pad. This allows you to build a rocket silo here!"},
},
special_buttons = {
["assembling-machine-1"] = {
initial_cost = 10,
text="Teleport home."},
["offshore-pump"] = {
initial_cost = 50,
text="Converts the closest empty wooden chest into a water tile!"
}
},
reset_buttons = {
["crash-site-generator"] = {
initial_cost = 5000,
solo_force = true,
text="DESTROY your base and restart. This allows you to choose a new spawn and will completely destroy all your buildings and your force. All technology progress will be reset. You get to keep your current items and armor! [color=red]THERE IS NO CONFIRMATION PROMPT! THIS CAN NOT BE UNDONE![/color]"
},
["crash-site-lab-broken"] = {
initial_cost = 5000,
solo_force = true,
text="ABANDON your base and restart. This allows you to choose a new spawn and will move all your buildings to a neutral force. They will still be on the map and can be interacted with, but will not be owned by any player or player force. All radars will be destroyed to help trim map size. You get to keep your current items and armor! [color=red]THERE IS NO CONFIRMATION PROMPT! THIS CAN NOT BE UNDONE![/color]"
},
["crash-site-chest-1"] = {
initial_cost = 5000,
text="Restart your game. This will reset your player, your force and your base. [color=red]THERE IS NO CONFIRMATION PROMPT! THIS CAN NOT BE UNDONE![/color]"
}
}
}
function CreateMapFeatureStoreTab(tab_container, player)
local player_inv = player.get_main_inventory()
if (player_inv == nil) then return end
local wallet = player_inv.get_item_count("coin")
AddLabel(tab_container,
"map_feature_store_wallet_lbl",
"Coins Available: " .. wallet .. " [item=coin]",
{top_margin=5, bottom_margin=5})
AddLabel(tab_container, "coin_info", "Players start with some coins. Earn more coins by killing enemies.", my_note_style)
local line = tab_container.add{type="line", direction="horizontal"}
line.style.top_margin = 5
line.style.bottom_margin = 5
for category,section in pairs(OARC_STORE_MAP_FEATURES) do
AddLabel(tab_container,
nil,
OARC_STORE_MAP_CATEGORIES[category],
{bottom_margin=5, maximal_width = 400, single_line = false})
local flow = tab_container.add{name = category, type="flow", direction="horizontal"}
for item_name,item in pairs(section) do
local blocked = false
if (item.solo_force and ((player.force.name == global.ocfg.main_force) or
(not global.ocore.playerSpawns[player.name]))) then
blocked = true
end
local count = OarcMapFeaturePlayerCountGet(player, category, item_name)
local cost = OarcMapFeatureCostScaling(player, category, item_name)
local color = "[color=green]"
if ((cost > wallet) or (cost < 0) or blocked) then
color = "[color=red]"
end
local btn = flow.add{name=item_name,
type="sprite-button",
-- number=item.count,
sprite="item/"..item_name,
-- tooltip=item.text.." Cost: "..color..cost.."[/color] [item=coin]",
style=mod_gui.button_style}
if (cost < 0) then
btn.enabled = false
btn.tooltip = item.text .. "\n "..color..
"Limit: ("..count.."/"..item.limit..") [/color]"
elseif (blocked) then
btn.enabled = false
btn.tooltip = item.text .. " (This is only allowed for players on their own force that own the spawn. If you have other players on your force, they must reset first before you can use this.)" .." Cost: "..color..cost.."[/color] [item=coin]"
elseif (item.limit) then
btn.tooltip = item.text .. "\nCost: "..color..cost.."[/color] [item=coin] "..
"Limit: ("..count.."/"..item.limit..")"
else
btn.tooltip = item.text.." Cost: "..color..cost.."[/color] [item=coin]"
end
::SKIP_ITEM::
end
local line2 = tab_container.add{type="line", direction="horizontal"}
line2.style.top_margin = 5
line2.style.bottom_margin = 5
end
end
function OarcMapFeatureInitGlobalCounters()
global.oarc_store = {}
global.oarc_store.pmf_counts = {}
end
function OarcMapFeaturePlayerCreatedEvent(player)
global.oarc_store.pmf_counts[player.name] = {}
end
function OarcMapFeaturePlayerCountGet(player, category_name, feature_name)
if (not global.oarc_store.pmf_counts[player.name][feature_name]) then
global.oarc_store.pmf_counts[player.name][feature_name] = 0
return 0
end
return global.oarc_store.pmf_counts[player.name][feature_name]
end
function OarcMapFeaturePlayerCountChange(player, category_name, feature_name, change)
if (not global.oarc_store.pmf_counts[player.name][feature_name]) then
if (change < 0) then
log("ERROR - OarcMapFeaturePlayerCountChange - Removing when count is not set??")
end
global.oarc_store.pmf_counts[player.name][feature_name] = change
return
end
-- Update count
global.oarc_store.pmf_counts[player.name][feature_name] = global.oarc_store.pmf_counts[player.name][feature_name] + change
-- Make sure we don't go below 0.
if (global.oarc_store.pmf_counts[player.name][feature_name] < 0) then
global.oarc_store.pmf_counts[player.name][feature_name] = 0
end
end
-- Return cost (0 or more) or return -1 if disabled.
function OarcMapFeatureCostScaling(player, category_name, feature_name)
local map_feature = OARC_STORE_MAP_FEATURES[category_name][feature_name]
-- Check limit first.
local count = OarcMapFeaturePlayerCountGet(player, category_name, feature_name)
if (map_feature.limit and (count >= map_feature.limit)) then
return -1
end
if (map_feature.initial_cost and map_feature.additional_cost and map_feature.multiplier_cost) then
local calc_cost = (map_feature.initial_cost + (map_feature.additional_cost*(count^map_feature.multiplier_cost)))
if (map_feature.max_cost) then
return math.min(map_feature.max_cost, calc_cost)
else
return calc_cost
end
else
return map_feature.initial_cost
end
end
function OarcMapFeatureStoreButton(event)
local button = event.element
local player = game.players[event.player_index]
local player_inv = player.get_inventory(defines.inventory.character_main)
if (player_inv == nil) then return end
local wallet = player_inv.get_item_count("coin")
local map_feature = OARC_STORE_MAP_FEATURES[button.parent.name][button.name]
-- Calculate cost based on how many player has purchased?
local cost = OarcMapFeatureCostScaling(player, button.parent.name, button.name)
-- Check if we have enough money
if (wallet < cost) then
player.print("You're broke! Go kill some enemies or beg for change...")
return
end
-- Each button has a special function
local result = false
if (button.name == "logistic-chest-storage") then
result = ConvertWoodenChestToSharedChestInput(player)
elseif (button.name == "logistic-chest-requester") then
result = ConvertWoodenChestToSharedChestOutput(player)
elseif (button.name == "constant-combinator") then
result = ConvertWoodenChestToSharedChestCombinators(player)
elseif (button.name == "accumulator") then
result = ConvertWoodenChestToShareEnergyInput(player)
elseif (button.name == "electric-energy-interface") then
result = ConvertWoodenChestToShareEnergyOutput(player)
elseif (button.name == "deconstruction-planner") then
result = DestroyClosestSharedChestEntity(player)
elseif (button.name == "electric-furnace") then
result = RequestSpawnSpecialChunk(player, SpawnFurnaceChunk, button.name)
elseif (button.name == "oil-refinery") then
result = RequestSpawnSpecialChunk(player, SpawnOilRefineryChunk, button.name)
elseif (button.name == "assembling-machine-3") then
result = RequestSpawnSpecialChunk(player, SpawnAssemblyChunk, button.name)
elseif (button.name == "centrifuge") then
result = RequestSpawnSpecialChunk(player, SpawnCentrifugeChunk, button.name)
elseif (button.name == "rocket-silo") then
result = RequestSpawnSpecialChunk(player, SpawnSiloChunk, button.name)
elseif (button.name == "assembling-machine-1") then
SendPlayerToSpawn(player)
result = true
elseif (button.name == "offshore-pump") then
result = ConvertWoodenChestToWaterFill(player)
elseif (button.name == "crash-site-generator") then
ResetPlayerAndDestroyForce(player)
result = true
elseif (button.name == "crash-site-lab-broken") then
ResetPlayerAndAbandonForce(player)
result = true
elseif (button.name == "crash-site-chest-1") then
ResetPlayerAndMergeForceToNeutral(player)
result = true
end
-- On success, we deduct money
if (result) then
player_inv.remove({name = "coin", count = cost})
end
-- Refresh GUI:
FakeTabChangeEventOarcStore(player)
end