mirror of
https://github.com/Refactorio/RedMew.git
synced 2024-12-12 10:04:40 +02:00
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
This commit is contained in:
parent
8f01d04862
commit
850c48bd39
@ -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
|
||||
|
||||
|
@ -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'
|
||||
|
Loading…
Reference in New Issue
Block a user