diff --git a/TEMPLATE_SCENARIO/OARC/control.lua b/TEMPLATE_SCENARIO/OARC/control.lua index ec0c1b6..a0443f8 100644 --- a/TEMPLATE_SCENARIO/OARC/control.lua +++ b/TEMPLATE_SCENARIO/OARC/control.lua @@ -17,7 +17,7 @@ -- Check if the OARC mod is loaded. Other than that, it's an empty scenario! script.on_init(function(event) - if not game.active_mods["oarc-mod"] then + if not script.active_mods["oarc-mod"] then error("OARC mod not found! This scenario is intended to be run with the OARC mod!") end end) diff --git a/control.lua b/control.lua index 4d63205..ca2bdad 100644 --- a/control.lua +++ b/control.lua @@ -167,7 +167,10 @@ end) ---------------------------------------- -- This is not called when the default surface "nauvis" is created as it will always exist! script.on_event(defines.events.on_surface_created, function(event) - log("Surface created: " .. game.surfaces[event.surface_index].name) + local surface = game.surfaces[event.surface_index] + log("Surface created: " .. surface.name) + if (surface.platform) then return end -- WE IGNORE PLATFORMS! + SeparateSpawnsSurfaceCreated(event) RegrowthSurfaceCreated(event) end) @@ -183,7 +186,7 @@ end) ---------------------------------------- script.on_event(defines.events.on_built_entity, function(event) if storage.ocfg.regrowth.enable_regrowth then - RegrowthMarkAreaSafeGivenTilePos(event.created_entity.surface.name, event.created_entity.position, 2, false) + RegrowthMarkAreaSafeGivenTilePos(event.entity.surface.name, event.entity.position, 2, false) end -- For tracking spidertrons... @@ -192,7 +195,7 @@ end) script.on_event(defines.events.on_robot_built_entity, function (event) if storage.ocfg.regrowth.enable_regrowth then - RegrowthMarkAreaSafeGivenTilePos(event.created_entity.surface.name, event.created_entity.position, 2, false) + RegrowthMarkAreaSafeGivenTilePos(event.entity.surface.name, event.entity.position, 2, false) end end) diff --git a/data.lua b/data.lua index eb89716..caeecf0 100644 --- a/data.lua +++ b/data.lua @@ -6,14 +6,12 @@ oarc_linked_chest.type="linked-container" oarc_linked_chest.name="oarc-linked-chest" oarc_linked_chest.inventory_type="with_filters_and_bar" oarc_linked_chest.inventory_size=settings.startup["oarc-mod-linked-chest-size"].value --[[@as integer]] -oarc_linked_chest.picture.layers[1].filename = "__oarc-mod__/graphics/oarc-linked-chest.png" -oarc_linked_chest.picture.layers[1].hr_version.filename = "__oarc-mod__/graphics/hr-oarc-linked-chest.png" +oarc_linked_chest.picture.layers[1].filename = "__oarc-mod__/graphics/hr-oarc-linked-chest.png" local oarc_linked_power=table.deepcopy(data.raw["electric-pole"]["small-electric-pole"]) oarc_linked_power.name="oarc-linked-power" -oarc_linked_power.pictures.layers[1].filename = "__oarc-mod__/graphics/oarc-electric-pole.png" -oarc_linked_power.pictures.layers[1].hr_version.filename = "__oarc-mod__/graphics/hr-oarc-electric-pole.png" +oarc_linked_power.pictures.layers[1].filename = "__oarc-mod__/graphics/hr-oarc-electric-pole.png" data:extend({ { @@ -27,4 +25,4 @@ data:extend({ }) -- Make coins not hidden -data.raw["item"]["coin"].flags = {} \ No newline at end of file +data.raw["item"]["coin"].hidden = false \ No newline at end of file diff --git a/devplan.txt b/devplan.txt index fe896a1..25b1eef 100644 --- a/devplan.txt +++ b/devplan.txt @@ -78,6 +78,7 @@ Added LuaForce::copy_from() and copy_chart() methods. ------------------------------------------------------------------------------------------------------------------------ Other Ideas, Not Committed: +- Look into checking if a force has a chunk visible (for regrowth) - Add option to spawn on existing chunks (look for chunks with any entities in them, or use regrowth logic) - Add option for spawn pen to be on a specified surface (not sure this serves any real purpose) - Change "search for ungenerated spawn point" to be a "roll" button that the player can re-roll? Maybe it shows on the map in an icon where they might go first? diff --git a/example/example-map-gen-settings.json b/example/example-map-gen-settings.json index f451b0a..ab0693e 100644 --- a/example/example-map-gen-settings.json +++ b/example/example-map-gen-settings.json @@ -1,24 +1,12 @@ { - "_terrain_segmentation_comment": "Inverse of map scale", - "terrain_segmentation": 1, - - "_water_comment": - [ - "Multiplier for water 'coverage' - higher increases the water level.", - "Water level = 10 * log2(this value)" - ], - "water": 1, - "_comment_width+height": "Width and height of map, in tiles; 0 means infinite", - "width": 1, - "height": 1, + "width": 0, + "height": 0, "_starting_area_comment": "Multiplier for 'biter free zone radius'", "starting_area": 1, "peaceful_mode": false, - - "default_enable_all_autoplace_controls": true, "autoplace_controls": { @@ -28,22 +16,27 @@ "stone" : {"frequency" : 0.20, "richness" : 10.00, "size" : 0.20}, "uranium-ore" : {"frequency" : 0.20, "richness" : 10.00, "size" : 0.20}, "crude-oil" : {"frequency" : 0.20, "richness" : 10.00, "size" : 0.20}, - "trees" : {"frequency" : 0.30, "richness" : 1.50, "size" : 1.00}, - "enemy-base" : {"frequency" : 0.40, "richness" : 0.50, "size" : 0.50} + "water" : {"frequency": 1, "size": 1}, + "trees" : {"frequency": 1, "size": 1}, + "enemy-base" : {"frequency": 0.4, "size": 0.5} }, "cliff_settings": { "_name_comment": "Name of the cliff prototype", "name": "cliff", - + "_cliff_elevation_0_comment": "Elevation of first row of cliffs", "cliff_elevation_0": 10, - - "_cliff_elevation_interval_comment": "Elevation difference between successive rows of cliffs", - "cliff_elevation_interval": 10, - - "_richness_comment": "Multiplier for cliff continuity; 0 will result in no cliffs, 10 will make all cliff rows completely solid", + + "_cliff_elevation_interval_comment": + [ + "Elevation difference between successive rows of cliffs.", + "This is inversely proportional to 'frequency' in the map generation GUI. Specifically, when set from the GUI the value is 40 / frequency." + ], + "cliff_elevation_interval": 40, + + "_richness_comment": "Called 'cliff continuity' in the map generator GUI. 0 will result in no cliffs, 10 will make all cliff rows completely solid", "richness": 1 }, diff --git a/example/example-map-settings.json b/example/example-map-settings.json index 46e17b1..fde0bf4 100644 --- a/example/example-map-settings.json +++ b/example/example-map-settings.json @@ -1,10 +1,8 @@ { "difficulty_settings": { - "recipe_difficulty": 0, - "technology_difficulty": 0, - "technology_price_multiplier": 1, - "research_queue_setting": "always" + "technology_price_multiplier": 1, + "spoil_time_modifier" : 1 }, "pollution": { @@ -21,20 +19,19 @@ "pollution_per_tree_damage": 50, "pollution_restored_per_tree_damage": 10, "max_pollution_to_restore_trees": 20, - "enemy_attack_pollution_consumption_modifier": 0.5 + "enemy_attack_pollution_consumption_modifier": 1 }, "enemy_evolution": { "enabled": true, - "time_factor": 0.000000, + "time_factor": 0.000004, "destroy_factor": 0.002, - "pollution_factor": 0.0000002 + "pollution_factor": 0.0000009 }, "enemy_expansion": { "enabled": true, - "min_base_spacing": 3, - "max_expansion_distance": 10, + "max_expansion_distance": 7, "friendly_base_influence_radius": 2, "enemy_building_influence_radius": 2, "building_coefficient": 0.1, @@ -45,7 +42,7 @@ "settler_group_min_size": 5, "settler_group_max_size": 20, "min_expansion_cooldown": 14400, - "max_expansion_cooldown": 108000 + "max_expansion_cooldown": 216000 }, "unit_group": { @@ -84,7 +81,7 @@ { "fwd2bwd_ratio": 5, "goal_pressure_ratio": 2, - "max_steps_worked_per_tick": 100, + "max_steps_worked_per_tick": 1000, "max_work_done_per_tick": 8000, "use_path_cache": true, "short_cache_size": 5, @@ -111,10 +108,15 @@ "short_request_max_steps": 1000, "short_request_ratio": 0.5, "min_steps_to_check_path_find_termination": 2000, - "start_to_goal_cost_multiplier_to_terminate_path_find": 500.0, + "start_to_goal_cost_multiplier_to_terminate_path_find": 2000.0, "overload_levels": [0, 100, 500], "overload_multipliers": [2, 3, 4], "negative_path_cache_delay_interval": 20 }, + "asteroids": + { + "spawning_rate" : 1, + "max_ray_portals_expanded_per_tick" : 100 + }, "max_failed_behavior_count": 3 } diff --git a/graphics/oarc-electric-pole.png b/graphics/oarc-electric-pole.png deleted file mode 100644 index 1e40630..0000000 Binary files a/graphics/oarc-electric-pole.png and /dev/null differ diff --git a/graphics/oarc-linked-chest.png b/graphics/oarc-linked-chest.png deleted file mode 100644 index c249faf..0000000 Binary files a/graphics/oarc-linked-chest.png and /dev/null differ diff --git a/lib/config.lua b/lib/config.lua index 10ef80a..3547d36 100644 --- a/lib/config.lua +++ b/lib/config.lua @@ -521,6 +521,8 @@ OCFG = { -- (Ignore these surfaces completely for spawning and regrowth!) ---@type table surfaces_blacklist_match = { + -- Space Age + "platform-", -- Factorissimo Mod Surfaces "factory-power", "factory-floor", diff --git a/lib/config_parser.lua b/lib/config_parser.lua index dc66ac7..370cb63 100644 --- a/lib/config_parser.lua +++ b/lib/config_parser.lua @@ -126,7 +126,7 @@ function ValidateAndLoadConfig() if (entry.mod_key ~= "") then local mod_key = entry.mod_key local oarc_key = entry.ocfg_keys - local mod_value = game.mod_setting_prototypes[mod_key].default_value + local mod_value = prototypes.mod_setting[mod_key].default_value local oarc_value = GetGlobalOarcConfigUsingKeyTable(oarc_key) if (mod_value ~= oarc_value) then error("OCFG value does not match mod setting: " .. mod_key .. " = " .. tostring(mod_value) .. " -> " .. serpent.block(oarc_key) .. " = " .. tostring(oarc_value)) diff --git a/lib/gui_tabs/item_shop.lua b/lib/gui_tabs/item_shop.lua index db41b76..ec6b700 100644 --- a/lib/gui_tabs/item_shop.lua +++ b/lib/gui_tabs/item_shop.lua @@ -6,8 +6,16 @@ ---@return nil function CreateItemShopTab(tab_container, player) - local player_inv = player.get_main_inventory() - if (player_inv == nil) then return end + if (player.character == nil) then + AddLabel(tab_container, nil, "Player character not available right now.", my_warning_style) + return + end + + local player_inv = player.character.get_main_inventory() + if (player_inv == nil) then + AddLabel(tab_container, nil, "Player main inventory not available right now.", my_warning_style) + return + end local wallet = player_inv.get_item_count("coin") AddLabel(tab_container, @@ -29,7 +37,7 @@ function CreateItemShopTab(tab_container, player) for item_name,item in pairs(section) do -- Validate if item exists - if (not game.item_prototypes[item_name]) then + if (not prototypes.item[item_name]) then log("ERROR: Item not found in storage.ocfg.shop_items: " .. item_name) goto continue end @@ -134,8 +142,24 @@ function DropCoins(surface_index, pos, count, force) if drop_amount == 0 then return end if storage.ocfg.coin_generation.auto_decon_coins then - game.surfaces[surface_index].spill_item_stack(pos, {name="coin", count=math.floor(drop_amount)}, true, force, false) + game.surfaces[surface_index].spill_item_stack{ + position=pos, + stack={name="coin", count=math.floor(drop_amount)}, + enable_looted=true, + force=force, + -- allow_belts?=false, + -- max_radius?=…, + -- use_start_position_on_failure?=false + } else - game.surfaces[surface_index].spill_item_stack(pos, {name="coin", count=math.floor(drop_amount)}, true, nil, false) + game.surfaces[surface_index].spill_item_stack{ + position=pos, + stack={name="coin", count=math.floor(drop_amount)}, + enable_looted=true, + force=nil, + -- allow_belts?=false, + -- max_radius?=…, + -- use_start_position_on_failure?=false + } end end \ No newline at end of file diff --git a/lib/gui_tabs/player_list.lua b/lib/gui_tabs/player_list.lua index 1683972..bf8bb46 100644 --- a/lib/gui_tabs/player_list.lua +++ b/lib/gui_tabs/player_list.lua @@ -122,7 +122,7 @@ function PlayerListTabGuiClick(event) if (tags.setting == "show_location") then local player_name = tags.player_name --[[@as string]] local target_player = game.players[player_name] - - player.open_map(target_player.position, 0.05) -- TODO: Update this for spage age! + + player.set_controller{type = defines.controllers.remote, position = target_player.character.position, surface = target_player.character.surface} end end \ No newline at end of file diff --git a/lib/gui_tabs/settings_controls.lua b/lib/gui_tabs/settings_controls.lua index c576b0c..c492933 100644 --- a/lib/gui_tabs/settings_controls.lua +++ b/lib/gui_tabs/settings_controls.lua @@ -217,7 +217,7 @@ function SettingsControlsTabGuiTextconfirmed(event) elseif (entry.type == "integer") then local safe_value = GetSafeIntValueForModSetting(value, entry.mod_key) if not pcall(function() settings.global[entry.mod_key] = { value = safe_value } end) then - settings.global[entry.mod_key] = { value = game.mod_setting_prototypes[entry.mod_key].default_value } + settings.global[entry.mod_key] = { value = prototypes.mod_setting[entry.mod_key].default_value } log("Error setting value for " .. entry.mod_key .. " to " .. safe_value) end gui_elem.text = tostring(settings.global[entry.mod_key].value) @@ -229,7 +229,7 @@ function SettingsControlsTabGuiTextconfirmed(event) elseif (entry.type == "double") then local safe_value = GetSafeDoubleValueForModSetting(value, entry.mod_key) if not pcall(function() settings.global[entry.mod_key] = { value = safe_value } end) then - settings.global[entry.mod_key] = { value = game.mod_setting_prototypes[entry.mod_key].default_value } + settings.global[entry.mod_key] = { value = prototypes.mod_setting[entry.mod_key].default_value } log("Error setting value for " .. entry.mod_key .. " to " .. safe_value) end gui_elem.text = string.format("%.2f", settings.global[entry.mod_key].value) @@ -272,10 +272,10 @@ end function GetSafeIntValueForModSetting(input, mod_key) local value_num = tonumber(input) if not value_num then - value_num = tonumber(game.mod_setting_prototypes[mod_key].default_value) + value_num = tonumber(prototypes.mod_setting[mod_key].default_value) else - local minimum = game.mod_setting_prototypes[mod_key].minimum_value - local maximum = game.mod_setting_prototypes[mod_key].maximum_value + local minimum = prototypes.mod_setting[mod_key].minimum_value + local maximum = prototypes.mod_setting[mod_key].maximum_value if minimum ~= nil then value_num = math.max(value_num, minimum) end @@ -294,10 +294,10 @@ end function GetSafeDoubleValueForModSetting(input, mod_key) local value_num = tonumber(input) if not value_num then - value_num = tonumber(game.mod_setting_prototypes[mod_key].default_value) + value_num = tonumber(prototypes.mod_setting[mod_key].default_value) else - local minimum = game.mod_setting_prototypes[mod_key].minimum_value - local maximum = game.mod_setting_prototypes[mod_key].maximum_value + local minimum = prototypes.mod_setting[mod_key].minimum_value + local maximum = prototypes.mod_setting[mod_key].maximum_value if minimum ~= nil then value_num = math.max(value_num, minimum) end @@ -399,8 +399,8 @@ function AddIntegerSetting(tab_container, index, entry, enabled) local slider = horizontal_flow.add { name = "slider", type = "slider", - minimum_value = game.mod_setting_prototypes[entry.mod_key].minimum_value, - maximum_value = game.mod_setting_prototypes[entry.mod_key].maximum_value, + minimum_value = prototypes.mod_setting[entry.mod_key].minimum_value, + maximum_value = prototypes.mod_setting[entry.mod_key].maximum_value, value = GetGlobalOarcConfigUsingKeyTable(entry.ocfg_keys), enabled = enabled, tooltip = { "mod-setting-description."..entry.mod_key }, @@ -447,8 +447,8 @@ function AddDoubleSetting(tab_container, index, entry, enabled) local slider = horizontal_flow.add { name = "slider", type = "slider", - minimum_value = game.mod_setting_prototypes[entry.mod_key].minimum_value, - maximum_value = game.mod_setting_prototypes[entry.mod_key].maximum_value, + minimum_value = prototypes.mod_setting[entry.mod_key].minimum_value, + maximum_value = prototypes.mod_setting[entry.mod_key].maximum_value, value = GetGlobalOarcConfigUsingKeyTable(entry.ocfg_keys), enabled = enabled, tooltip = { "mod-setting-description."..entry.mod_key }, @@ -493,7 +493,7 @@ function AddStringListDropdownSetting(tab_container, index, entry, enabled) } dragger.style.horizontally_stretchable = true - local allowed_values = game.mod_setting_prototypes[entry.mod_key].allowed_values --[[@as string[] ]] + local allowed_values = prototypes.mod_setting[entry.mod_key].allowed_values --[[@as string[] ]] local selected_index = 1 for i,v in pairs(allowed_values) do diff --git a/lib/gui_tabs/spawn_controls.lua b/lib/gui_tabs/spawn_controls.lua index 5928d10..90cbf21 100644 --- a/lib/gui_tabs/spawn_controls.lua +++ b/lib/gui_tabs/spawn_controls.lua @@ -301,8 +301,9 @@ function SpawnCtrlTabGuiClick(event) elseif (tags.setting == "show_location") then local surface_name = tags.surface --[[@as string]] local position = tags.position --[[@as MapPosition]] - player.open_map(position, 0.05) -- TODO: Update this for spage age! - player.print({"", { "oarc-spawn-gps-location" }, GetGPStext(surface_name, position)}) + + player.set_controller{type = defines.controllers.remote, position = position, surface = surface_name} + -- player.print({"", { "oarc-spawn-gps-location" }, GetGPStext(surface_name, position)}) -- Accept or reject pending player join requests to a shared base elseif ((tags.setting == "accept_player_request") or (tags.setting == "reject_player_request")) then diff --git a/lib/gui_tabs/surface_config.lua b/lib/gui_tabs/surface_config.lua index 3855ba5..1260602 100644 --- a/lib/gui_tabs/surface_config.lua +++ b/lib/gui_tabs/surface_config.lua @@ -870,7 +870,7 @@ function SurfaceConfigTabGuiElemChanged(event) return end - if (game.entity_prototypes[new_resource_name].resource_category ~= "basic-solid") then + if (prototypes.entity[new_resource_name].resource_category ~= "basic-solid") then player.print("Resource must be a solid resource! " .. new_resource_name) event.element.elem_value = nil return @@ -918,7 +918,7 @@ function SurfaceConfigTabGuiElemChanged(event) return end - if (game.entity_prototypes[new_resource_name].resource_category ~= "basic-fluid") then + if (prototypes.entity[new_resource_name].resource_category ~= "basic-fluid") then player.print("Resource must be a fluid resource! " .. new_resource_name) event.element.elem_value = nil return diff --git a/lib/holding_pen.lua b/lib/holding_pen.lua index c981fb7..b438b22 100644 --- a/lib/holding_pen.lua +++ b/lib/holding_pen.lua @@ -12,8 +12,8 @@ function CreateHoldingPenSurface() ---@type MapGenSettings ---@diagnostic disable-next-line: missing-fields local map_settings = {} - map_settings.terrain_segmentation = "none" - map_settings.water = "none" + -- map_settings.terrain_segmentation = "none" + -- map_settings.water = "none" map_settings.starting_area = "none" map_settings.peaceful_mode = true map_settings.width = 64 @@ -25,6 +25,7 @@ function CreateHoldingPenSurface() holding_pen_surface.always_day = true holding_pen_surface.show_clouds = false holding_pen_surface.generate_with_lab_tiles = true + holding_pen_surface.localised_name = {"oarc-holding-pen-surface"} RenderPermanentGroundText(holding_pen_surface, {x=9,y=-7}, 5, "O", {0.9, 0.7, 0.3, 0.5}, "center") RenderPermanentGroundText(holding_pen_surface, {x=9,y=-4}, 5, "A", {0.9, 0.7, 0.3, 0.5}, "center") @@ -93,6 +94,11 @@ function CreateHoldingPenChunks(event) amount = 90000, position = { 0, 9 } }) + + -- Create special power pole if sharing is enabled (it will be created later when first requested otherwise) + if (storage.ocfg.gameplay.enable_shared_power) then + InitSharingPowerPoles() + end end end diff --git a/lib/oarc_gui_tabs.lua b/lib/oarc_gui_tabs.lua index bbe8ab1..3b19088 100644 --- a/lib/oarc_gui_tabs.lua +++ b/lib/oarc_gui_tabs.lua @@ -238,8 +238,20 @@ function CreateOarcGuiTabsPane(player) local subhead = inside_frame.add{ type="frame", name="sub_header", - style = "changelog_subheader_frame" + style = "subheader_frame" } + subhead.style.horizontally_stretchable = true + + -- changelog_subheader_frame = + -- { + -- type = "frame_style", + -- parent = "subheader_frame", + -- left_padding = 12, + -- right_padding = 12, + -- top_padding = 4, + -- horizontally_stretchable = "on" + -- } + AddLabel(subhead, nil, {"oarc-gui-tab-header-label"}, "subheader_caption_label") -- TABBED PANE diff --git a/lib/oarc_utils.lua b/lib/oarc_utils.lua index f5cc436..9d747df 100644 --- a/lib/oarc_utils.lua +++ b/lib/oarc_utils.lua @@ -88,7 +88,7 @@ end ---@param alignment TextAlign? ---@return nil function TemporaryHelperText(text, surface, position, ttl, alignment) - local rid = rendering.draw_text { text = text, + local render_object = rendering.draw_text { text = text, surface = surface, target = position, color = { 0.7, 0.7, 0.7, 0.7 }, @@ -97,6 +97,7 @@ function TemporaryHelperText(text, surface, position, ttl, alignment) time_to_live = ttl, alignment = alignment, draw_on_ground = false } + local rid = render_object.id table.insert(storage.oarc_renders_fadeout, rid) end @@ -121,12 +122,13 @@ end function FadeoutRenderOnTick() if (storage.oarc_renders_fadeout and (#storage.oarc_renders_fadeout > 0)) then for k, rid in pairs(storage.oarc_renders_fadeout) do - if (rendering.is_valid(rid)) then - local ttl = rendering.get_time_to_live(rid) + local render_object = rendering.get_object_by_id(rid) + if (render_object and render_object.valid) then + local ttl = render_object.time_to_live if ((ttl > 0) and (ttl < 200)) then - local color = rendering.get_color(rid) + local color = render_object.color if (color.a > 0.005) then - rendering.set_color(rid, { r = color.r, g = color.g, b = color.b, a = color.a - 0.005 }) + render_object.color = { r = color.r, g = color.g, b = color.b, a = color.a - 0.005 } end end else @@ -372,7 +374,7 @@ end ---@return nil function OarcsSaferInsert(entity, item_dict) if not (entity and entity.valid and item_dict) then return end - local items = game.item_prototypes + local items = prototypes.item local insert = entity.insert for name, count in pairs(item_dict) do if items[name] and count > 0 then @@ -389,7 +391,7 @@ end ---@return nil function OarcsSaferRemove(entity, item_dict) if not (entity and entity.valid and item_dict) then return end - local items = game.item_prototypes + local items = prototypes.item local remove = entity.remove_item for name, count in pairs(item_dict) do if items[name] and count > 0 then @@ -1374,7 +1376,7 @@ function CreateCropCircle(surface, centerPos, chunkArea, tileRadius, fillTile, m -- Fill in all unexpected water (or force grass) if (distSqr <= tile_radius_sqr) then - if (surface.get_tile(i, j).collides_with("water-tile") or + if (surface.get_tile(i, j).collides_with("water_tile") or storage.ocfg.spawn_general.force_grass) then table.insert(dirtTiles, { name = fillTile, position = { i, j } }) end @@ -1442,7 +1444,7 @@ function CreateCropOctagon(surface, centerPos, chunkArea, tileRadius, fillTile, -- Fill in all unexpected water (or force grass) if (distVar <= tileRadius) then - if (surface.get_tile(i, j).collides_with("water-tile") or + if (surface.get_tile(i, j).collides_with("water_tile") or storage.ocfg.spawn_general.force_grass) then table.insert(dirtTiles, { name = fillTile, position = { i, j } }) end @@ -1511,7 +1513,7 @@ function CreateCropSquare(surface, centerPos, chunkArea, tileRadius, fillTile, m -- Fill in all unexpected water (or force grass) if (max_distance <= tileRadius) then - if (surface.get_tile(i, j).collides_with("water-tile") or + if (surface.get_tile(i, j).collides_with("water_tile") or storage.ocfg.spawn_general.force_grass) then table.insert(dirtTiles, { name = fillTile, position = { i, j } }) end diff --git a/lib/regrowth_map.lua b/lib/regrowth_map.lua index 4404a03..67fc3dd 100644 --- a/lib/regrowth_map.lua +++ b/lib/regrowth_map.lua @@ -371,7 +371,7 @@ function RegrowthSectorScan(event) if (storage.rg[surface_name] == nil) then return end ---@type integer - local radar_range = event.radar.prototype.max_distance_of_nearby_sector_revealed --TODO: Space age quality might affect this? + local radar_range = event.radar.prototype.get_max_distance_of_nearby_sector_revealed(event.radar.quality) --TODO: Space age quality might affect this? RefreshAreaChunkPosition(surface_name, event.chunk_position, radar_range, 0) end @@ -694,7 +694,7 @@ function RegrowthOnBuiltEntity(event) log("Added spidertron to regrowth tracking") if storage.rg.spidertron_chunk_radius == nil then - storage.rg.spidertron_chunk_radius = game.entity_prototypes["spidertron"].chunk_exploration_radius + storage.rg.spidertron_chunk_radius = prototypes.entity["spidertron"].chunk_exploration_radius end end end diff --git a/lib/separate_spawns.lua b/lib/separate_spawns.lua index ba87772..91bbb4e 100644 --- a/lib/separate_spawns.lua +++ b/lib/separate_spawns.lua @@ -236,6 +236,9 @@ end ---@param event EventData.on_player_changed_surface ---@return nil function SeparateSpawnsPlayerChangedSurface(event) + + log("SeparateSpawnsPlayerChangedSurface - " .. event.surface_index) + if (not storage.ocfg.gameplay.enable_secondary_spawns) then return end local player = game.players[event.player_index] @@ -453,7 +456,7 @@ function SendPlayerToNewSpawnAndCreateIt(delayed_spawn) } -- Create shared power poles - if (ocfg.gameplay.enable_shared_power) then + if (ocfg.gameplay.enable_shared_power and delayed_spawn.primary) then local power_pole_position = { x = sharing_ref_pos.x + spawn_config.shared_power_pole_position.x_offset, y = sharing_ref_pos.y + spawn_config.shared_power_pole_position.y_offset } @@ -461,7 +464,7 @@ function SendPlayerToNewSpawnAndCreateIt(delayed_spawn) end -- Create shared chest - if (ocfg.gameplay.enable_shared_chest) then + if (ocfg.gameplay.enable_shared_chest and delayed_spawn.primary) then local chest_position = { x = sharing_ref_pos.x + spawn_config.shared_chest_position.x_offset, y = sharing_ref_pos.y + spawn_config.shared_chest_position.y_offset } @@ -501,7 +504,7 @@ function DisplayWelcomeGroundTextAtSpawn(player, surface, position) -- Render some welcoming text... local tcolor = { 0.9, 0.7, 0.3, 0.8 } local ttl = 2000 - local rid1 = rendering.draw_text { text = "Welcome", + local render_object_1 = rendering.draw_text { text = "Welcome", surface = surface, target = { x = position.x - 21, y = position.y - 15 }, color = tcolor, @@ -514,7 +517,7 @@ function DisplayWelcomeGroundTextAtSpawn(player, surface, position) -- alignment=center, scale_with_zoom = false, only_in_alt_mode = false } - local rid2 = rendering.draw_text { text = "Home", + local render_object_2 = rendering.draw_text { text = "Home", surface = surface, target = { x = position.x - 14, y = position.y - 5 }, color = tcolor, @@ -527,6 +530,8 @@ function DisplayWelcomeGroundTextAtSpawn(player, surface, position) -- alignment=center, scale_with_zoom = false, only_in_alt_mode = false } + local rid1 = render_object_1.id + local rid2 = render_object_2.id table.insert(storage.oarc_renders_fadeout, rid1) table.insert(storage.oarc_renders_fadeout, rid2) @@ -1241,15 +1246,16 @@ function QueuePlayerForDelayedSpawn(player_name, surface, spawn_position, moat_e final_chunk.y = final_chunk.y + spawn_chunk_radius ---@type OarcDelayedSpawn - local delayedSpawn = {} - delayedSpawn.playerName = player_name - delayedSpawn.surface = surface - delayedSpawn.position = spawn_position - delayedSpawn.moat = moat_enabled - delayedSpawn.delayedTick = game.tick + delay_spawn_seconds * TICKS_PER_SECOND - delayedSpawn.final_chunk_generated = final_chunk + local delayed_spawn = {} + delayed_spawn.playerName = player_name + delayed_spawn.surface = surface + delayed_spawn.position = spawn_position + delayed_spawn.moat = moat_enabled + delayed_spawn.delayedTick = game.tick + delay_spawn_seconds * TICKS_PER_SECOND + delayed_spawn.final_chunk_generated = final_chunk + delayed_spawn.primary = primary - table.insert(storage.delayed_spawns, delayedSpawn) + table.insert(storage.delayed_spawns, delayed_spawn) HideOarcGui(game.players[player_name]) DisplayPleaseWaitForSpawnDialog(game.players[player_name], delay_spawn_seconds, game.surfaces[surface], spawn_position) @@ -1259,7 +1265,7 @@ function QueuePlayerForDelayedSpawn(player_name, surface, spawn_position, moat_e -- Chart the area to be able to display the minimap while the player waits. ChartArea(game.players[player_name].force, - delayedSpawn.position, + delayed_spawn.position, spawn_chunk_radius, surface ) @@ -1434,7 +1440,6 @@ function CreatePlayerForce(force_name) new_force = game.create_force(force_name) new_force.share_chart = storage.ocfg.gameplay.enable_shared_team_vision new_force.friendly_fire = storage.ocfg.gameplay.enable_friendly_fire - new_force.research_queue_enabled = true -- SetCeaseFireBetweenAllPlayerForces() -- SetFriendlyBetweenAllPlayerForces() ConfigurePlayerForceRelationships(true, true) @@ -1508,7 +1513,15 @@ SPAWN_TEAM_CHOICE = { ---@alias OarcPlayerCooldownsTable table ---Temporary data used when spawning a player. Player needs to wait while the area is prepared. ----@alias OarcDelayedSpawn { surface: string, playerName: string, position: MapPosition, moat: boolean, delayedTick: number, final_chunk_generated: ChunkPosition } +---Temporary data used when spawning a player. Player needs to wait while the area is prepared. +---@class OarcDelayedSpawn +---@field surface string The surface on which the player will spawn. +---@field playerName string The name of the player. +---@field position MapPosition The position where the player will spawn. +---@field moat boolean Whether the spawn has a moat or not. +---@field delayedTick number The game tick when the spawn will be ready. +---@field final_chunk_generated ChunkPosition The final chunk position that needs to be generated. +---@field primary boolean Whether this is the primary spawn point for a player, this is the first surface they spawn on. All other spawns are secondary. ---Table of [OarcDelayedSpawn](lua://OarcDelayedSpawn) indexed by player name. ---@alias OarcDelayedSpawnsTable table diff --git a/lib/separate_spawns_guis.lua b/lib/separate_spawns_guis.lua index 43d0057..2ff09f7 100644 --- a/lib/separate_spawns_guis.lua +++ b/lib/separate_spawns_guis.lua @@ -58,8 +58,9 @@ function DisplayWelcomeTextGui(player) local dragger = button_flow.add { type = "empty-widget", - style = "draggable_space_with_no_left_margin", + style = "draggable_space", } + dragger.style.left_margin = 0 dragger.style.horizontally_stretchable = true dragger.style.height = 30 @@ -117,9 +118,19 @@ function CreateSpawnMenuGuiFrame(player) local subhead = inside_frame.add{ type="frame", name="sub_header", - style = "changelog_subheader_frame" + style = "subheader_frame" } subhead.style.height = 46 + subhead.style.horizontally_stretchable = true + -- changelog_subheader_frame = + -- { + -- type = "frame_style", + -- parent = "subheader_frame", + -- left_padding = 12, + -- right_padding = 12, + -- top_padding = 4, + -- horizontally_stretchable = "on" + -- } AddLabel(subhead, "warning_lbl1", { "oarc-click-info-btn-help" }, my_note_style) return inside_frame @@ -956,7 +967,8 @@ function DisplaySharedSpawnJoinWaitMenu(player) style = "back_button" } - local dragger = button_flow.add{type="empty-widget", style="draggable_space_with_no_right_margin"} + local dragger = button_flow.add{type="empty-widget", style="draggable_space"} + dragger.style.right_margin = 0 dragger.style.horizontally_stretchable = true dragger.style.height = 30 end @@ -1009,7 +1021,8 @@ function DisplayBuddySpawnWaitMenu(player) tooltip = { "oarc-return-to-previous-tooltip" }, } - local dragger = button_flow.add{type="empty-widget", style="draggable_space_with_no_right_margin"} + local dragger = button_flow.add{type="empty-widget", style="draggable_space"} + dragger.style.right_margin = 0 dragger.style.horizontally_stretchable = true dragger.style.height = 30 end diff --git a/lib/sharing.lua b/lib/sharing.lua index 3c042f2..7956c7a 100644 --- a/lib/sharing.lua +++ b/lib/sharing.lua @@ -1,9 +1,22 @@ --- This handles the shared power logic for the Oarc scenario. --- Won't work too hard on this since 2.0 might change things... +-- Lets players share electricity via a special power pole and cross surface connections. +-- Also lets players share items via a linked-chest. + +X_OFFSET_SHARING_POLE = 10 +Y_OFFSET_SHARING_POLE = 0 -STARTING_X_OFFSET_SHARING_POLE = -5 -Y_OFFSET_SHARING_POLE = 20 +function InitSharingPowerPoles() + if storage.shared_power_poles == nil then + ---@type LuaEntity[] + storage.shared_power_poles = {} + end + + if storage.shared_power_link == nil then + local link_position = { x = X_OFFSET_SHARING_POLE, y = Y_OFFSET_SHARING_POLE } + local link_pole = CreateSpecialPole(game.surfaces[HOLDING_PEN_SURFACE_NAME], link_position) + storage.shared_power_link = link_pole + end +end ---Create and connect a pair of power poles for a new base given surface and position. ---@param surface LuaSurface @@ -16,17 +29,10 @@ function CreateSharedPowerPolePair(surface, position) storage.shared_power_poles = {} end - --Get an open sharing pole from the holding pen surface if one exists, otherwise create a new one. - local hidden_pole = FindSharedPowerPole() - if not hidden_pole then - local poles_count = table_size(storage.shared_power_poles) - local new_position = { x = poles_count + STARTING_X_OFFSET_SHARING_POLE, y = Y_OFFSET_SHARING_POLE } - hidden_pole = CreateSpecialPole(game.surfaces[HOLDING_PEN_SURFACE_NAME], new_position) - if not hidden_pole then - log("ERROR - Failed to create shared power poles!? " .. serpent.block(position) .. " on " .. surface.name) - return - end - table.insert(storage.shared_power_poles, hidden_pole) + if storage.shared_power_link == nil then + local link_position = { x = X_OFFSET_SHARING_POLE, y = Y_OFFSET_SHARING_POLE } + local link_pole = CreateSpecialPole(game.surfaces[HOLDING_PEN_SURFACE_NAME], link_position) + storage.shared_power_link = link_pole end --Create the base pole on the new spawn area surface and connect it to the hidden pole. @@ -35,7 +41,9 @@ function CreateSharedPowerPolePair(surface, position) log("ERROR - Failed to create shared power poles!? " .. serpent.block(position) .. " on " .. surface.name) return end - base_pole.connect_neighbour(hidden_pole) + local base_connector = base_pole.get_wire_connector(defines.wire_connector_id.pole_copper, true) + local hidden_connector = storage.shared_power_link.get_wire_connector(defines.wire_connector_id.pole_copper, true) + base_connector.connect_to(hidden_connector, false, defines.wire_origin.script) TemporaryHelperText( { "oarc-shared-power-pole-helper-txt" }, @@ -46,21 +54,6 @@ function CreateSharedPowerPolePair(surface, position) ) end ----Find the first shared power pole that doesn't exceed the max number of connections. ----@return LuaEntity? -function FindSharedPowerPole() - if storage.shared_power_poles == nil then return nil end - - for _,pole in pairs(storage.shared_power_poles) do - -- 5 is the hard coded engine limit and we need to leave one open for the connection to the next hidden pole. - if pole.neighbours["copper"] and table_size(pole.neighbours["copper"]) < 4 then - return pole - end - end - - return nil -end - ---Creates a special pole on the surface at the given position on the neutral force. ---@param surface LuaSurface ---@param position MapPosition diff --git a/locale/en/locale.cfg b/locale/en/locale.cfg index 0495b8a..e0edf26 100644 --- a/locale/en/locale.cfg +++ b/locale/en/locale.cfg @@ -1,5 +1,7 @@ scenario-name=OARC +oarc-holding-pen-surface=[img=oarc-mod-sprite-40] New Player Holding Area + description=This mod provides a scenario that overhauls multiplayer spawning.\n[color=red][font=default-bold]Please check out the github page and discord for more information and support.[/font][/color] oarc-scenario-info-warn-msg=This scenario allows players to create their own spawn points far from the center of the map. For more information, click the OARC button in the top left corner.