From 850c48bd39593068c2725a4ecf98c1b43cb1e8d3 Mon Sep 17 00:00:00 2001 From: RedRafe <93430988+RedRafe@users.noreply.github.com> Date: Tue, 23 Apr 2024 11:57:09 +0200 Subject: [PATCH] Fixes for incorrect chest behaviors in DO:Expanse (#1410) * Fixes for incorrect chest behaviors in DO:Expanse * Code simplification & cleanup * Fix luachecks * Update spawn radius * Fix next() on empty values --- map_gen/maps/danger_ores/modules/expanse.lua | 143 ++++++++++-------- .../presets/danger_ore_expanse.lua | 6 + 2 files changed, 82 insertions(+), 67 deletions(-) diff --git a/map_gen/maps/danger_ores/modules/expanse.lua b/map_gen/maps/danger_ores/modules/expanse.lua index a9f213af..97a2d139 100644 --- a/map_gen/maps/danger_ores/modules/expanse.lua +++ b/map_gen/maps/danger_ores/modules/expanse.lua @@ -11,12 +11,13 @@ local Token = require 'utils.token' local rendering = rendering local math_abs = math.abs -local rock_resources = { +local RADIUS = 3 +local ROCK_RESOURCES = { 'iron-ore', 'iron-ore', 'iron-ore', 'iron-ore', 'iron-ore', 'copper-ore', 'copper-ore', 'copper-ore', 'coal' } -local price_modifiers = { +local PRICE_MODIFIERS = { ['cliff'] = -128, ['deepwater-green'] = -5, ['deepwater'] = -5, @@ -42,7 +43,7 @@ return function(config) local cell_size = 32 local start_size = config.start_size local chance_to_receive_token = config.chance_to_receive_token or 0.20 - local max_ore_price_modifier = config.max_ore_price_modifier or 0.33 + local max_ore_price_modifier = config.max_ore_price_modifier or 0.20 local price_distance_modifier = config.price_distance_modifier or 0.006 -- pad start_size to closest multiple of 32 for chunk alignment @@ -81,20 +82,21 @@ return function(config) end local function get_left_top(position) - local step = 3 - local vectors = { { -step, 0 }, { step, 0 }, { 0, step }, { 0, -step } } - table.shuffle_table(vectors) --left, right, down, up + return { + x = position.x - position.x % cell_size, + y = position.y - position.y % cell_size, + } + end + + local function get_empty_neighbour_left_top(entity_position) + local vectors = { { -RADIUS, 0 }, { RADIUS, 0 }, { 0, RADIUS }, { 0, -RADIUS } } + --table.shuffle_table(vectors) --left, right, down, up for _, v in pairs(vectors) do - local tile = surface.get_tile({ position.x + v[1], position.y + v[2] }) + local tile = surface.get_tile({ entity_position.x + v[1], entity_position.y + v[2] }) if tile.name == 'out-of-map' then - local left_top - left_top = { - x = position.x - position.x % cell_size, - y = position.y - position.y % cell_size, - } - return left_top + return get_left_top(tile.position) end end return @@ -106,17 +108,20 @@ return function(config) position.x == start_size/2-1 or position.y == start_size/2-1 end - local left_top = get_left_top(position) - if not left_top then - return false - end + return get_empty_neighbour_left_top(position) ~= nil + end - return surface.count_entities_filtered({ - name = 'logistic-chest-requester', - force = 'neutral', - --area = { { left_top.x - 1, left_top.y - 1 }, { left_top.x + cell_size + 1, left_top.y + cell_size + 1 } }, - area = { {left_top.x, left_top.y}, {left_top.x + cell_size - 1, left_top.y + cell_size - 1} }, - }) == 0 + local function destroy_and_spill_content(entity) + chest_data[entity.unit_number] = nil + local inventory = entity.get_inventory(defines.inventory.chest) + if not inventory.is_empty() then + for name, count in pairs(inventory.get_contents()) do + entity.surface.spill_item_stack(entity.position, { name = name, count = count }, true, nil, false) + end + end + inventory.clear() + entity.destructible = true + entity.die() end local function remove_one_render(chest, key) @@ -149,13 +154,13 @@ return function(config) local tiles = surface.find_tiles_filtered({ area = area }) for _, tile in pairs(tiles) do - if price_modifiers[tile.name] then - value = value + price_modifiers[tile.name] + if PRICE_MODIFIERS[tile.name] then + value = value + PRICE_MODIFIERS[tile.name] end end for _, entity in pairs(entities) do - if price_modifiers[entity.type] then - value = value + price_modifiers[entity.type] + if PRICE_MODIFIERS[entity.type] then + value = value + PRICE_MODIFIERS[entity.type] end end @@ -221,21 +226,27 @@ return function(config) local cell_value = budget or get_cell_budget(left_top, entity) local item_stacks = {} - local roll_count = 3 - for _ = 1, roll_count do - local value = math.floor(cell_value / roll_count) - local max_item_value = math.max(4, cell_value / (roll_count * 6)) - for _, stack in pairs(Price_raffle.roll(value, 3, nil, max_item_value)) do - if not item_stacks[stack.name] then - item_stacks[stack.name] = stack.count - else - item_stacks[stack.name] = item_stacks[stack.name] + stack.count + if _DEBUG then + item_stacks = { + ['iron-plate'] = 1, + } + else + local roll_count = 3 + for _ = 1, roll_count do + local value = math.floor(cell_value / roll_count) + local max_item_value = math.max(4, cell_value / (roll_count * 6)) + for _, stack in pairs(Price_raffle.roll(value, 3, nil, max_item_value)) do + if not item_stacks[stack.name] then + item_stacks[stack.name] = stack.count + else + item_stacks[stack.name] = item_stacks[stack.name] + stack.count + end end end end local price = {} - local offset = -3 + local offset = -table_size(item_stacks) / 2 + 0.5 for k, v in pairs(item_stacks) do table.insert(price, { name = k, count = v, render = create_costs_render(entity, k, offset) }) offset = offset + 1 @@ -257,6 +268,10 @@ return function(config) chest_data[entity.unit_number] = nil return end + if game.tick > 0 and not is_container_position_valid(entity.position) then + destroy_and_spill_content(entity) + return + end local inventory = container.entity.get_inventory(defines.inventory.chest) @@ -288,18 +303,9 @@ return function(config) end if #container.price == 0 then - chest_data[entity.unit_number] = nil - if not inventory.is_empty() then - for name, count in pairs(inventory.get_contents()) do - entity.surface.spill_item_stack(entity.position, { name = name, count = count }, true, nil, false) - end - end - inventory.clear() - -- compute new chunk to unlock local new_area - local step = 3 - local vectors = { { -step, 0 }, { step, 0 }, { 0, step }, { 0, -step } } + local vectors = { { -RADIUS, 0 }, { RADIUS, 0 }, { 0, RADIUS }, { 0, -RADIUS } } table.shuffle_table(vectors) --left, right, down, up for _, v in pairs(vectors) do @@ -323,8 +329,8 @@ return function(config) if math.random() < chance_to_receive_token then entity.surface.spill_item_stack(entity.position, { name = 'coin', count = 1 }, true, nil, false) end - entity.destructible = true - entity.die() + destroy_and_spill_content(entity) + return new_area end @@ -347,11 +353,13 @@ return function(config) surface.request_to_generate_chunks(left_top, 0) surface.force_generate_chunk_requests() + local max_side = cell_size - 1 - RADIUS + local min_side = RADIUS local positions = { - { x = left_top.x + math.random(1, cell_size - 2), y = left_top.y }, - { x = left_top.x, y = left_top.y + math.random(1, cell_size - 2) }, - { x = left_top.x + math.random(1, cell_size - 2), y = left_top.y + (cell_size - 1) }, - { x = left_top.x + (cell_size - 1), y = left_top.y + math.random(1, cell_size - 2) }, + { x = left_top.x + math.random(min_side, max_side), y = left_top.y }, -- north + { x = left_top.x, y = left_top.y + math.random(min_side, max_side) }, -- west + { x = left_top.x + math.random(min_side, max_side), y = left_top.y + (cell_size - 1) }, -- south + { x = left_top.x + (cell_size - 1), y = left_top.y + math.random(min_side, max_side) }, -- east } local chests = {} @@ -386,16 +394,7 @@ return function(config) } }} for _, entity in pairs(old_chests) do - chest_data[entity.unit_number] = nil - local inventory = entity.get_inventory(defines.inventory.chest) - if not inventory.is_empty() then - for name, count in pairs(inventory.get_contents()) do - entity.surface.spill_item_stack(entity.position, { name = name, count = count }, true, nil, false) - end - end - inventory.clear() - entity.destructible = true - entity.die() + destroy_and_spill_content(entity) end -- then generate new expansion chests @@ -406,6 +405,11 @@ return function(config) end local function on_tick() + if primitives.index ~= nil and chest_data[primitives.index] == nil then + primitives.index = nil + return + end + local idx, chest = next(chest_data, primitives.index) if not (chest and chest.entity) then primitives.index = nil @@ -435,12 +439,17 @@ return function(config) end if entity.type == 'tree' then - entity.surface.create_entity{name = 'tree-0'..math.random(9), position = entity.position} + for _, corpse in pairs(surface.find_entities_filtered{ + position = entity.position, + radius = 1, + type = 'corpse'} + ) do corpse.destroy() end + surface.create_entity{name = 'tree-0'..math.random(9), position = entity.position} elseif entity.type == 'simple-entity' then - local rock = entity.surface.create_entity{name = 'rock-huge', position = entity.position, move_stuck_players = true} + local rock = surface.create_entity{name = 'rock-huge', position = entity.position, move_stuck_players = true} rock.graphics_variation = math.random(16) - entity.surface.spill_item_stack(entity.position, {name = rock_resources[math.random(#rock_resources)], count = math.random(80, 160)}, true, nil, true) - entity.surface.spill_item_stack(entity.position, {name = 'stone', count = math.random(5, 15)}, true, nil, true) + surface.spill_item_stack(entity.position, {name = ROCK_RESOURCES[math.random(#ROCK_RESOURCES)], count = math.random(80, 160)}, true, nil, true) + surface.spill_item_stack(entity.position, {name = 'stone', count = math.random(5, 15)}, true, nil, true) end end diff --git a/map_gen/maps/danger_ores/presets/danger_ore_expanse.lua b/map_gen/maps/danger_ores/presets/danger_ore_expanse.lua index 65c86d34..37ccb940 100644 --- a/map_gen/maps/danger_ores/presets/danger_ore_expanse.lua +++ b/map_gen/maps/danger_ores/presets/danger_ore_expanse.lua @@ -40,6 +40,11 @@ ScenarioInfo.set_new_info([[ - Forked from DO/terraforming - Added DO/expanse - Lowered tech multiplier 25 > 5 +2024-04-17: + - Fixed incorrect request computation + - Fixed persistent chests on new chunk unlocks + - Added chests for each new expansion border + - Reduced pre_multiplier from 0.33 >s 0.20 ]]) ScenarioInfo.add_extra_rule({'info.rules_text_danger_ore'}) @@ -102,6 +107,7 @@ Event.on_init(function() game.forces.player.manual_mining_speed_modifier = 1 RS.get_surface().always_day = true + RS.get_surface().peaceful_mode = true end) local expanse = require 'map_gen.maps.danger_ores.modules.expanse'