1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-09-16 09:06:21 +02:00

Mtn: fix bugs

This commit is contained in:
Gerkiz
2025-09-11 21:33:27 +02:00
parent 79412f76b1
commit dc536741b3
5 changed files with 516 additions and 486 deletions

3
.gitignore vendored
View File

@@ -16,4 +16,5 @@ tmp.lua
*.txt *.txt
# Ignore IDEA # Ignore IDEA
.idea .idea
maps/mountain_fortress_v3/stateful/_stateful_debug.lua

View File

@@ -11,56 +11,58 @@ local sqrt = math.sqrt
local max_spill = 60 local max_spill = 60
local mining_chance_weights = { local mining_chance_weights =
{ name = 'iron-plate', chance = 1000 }, {
{ name = 'iron-gear-wheel', chance = 750 }, { name = 'iron-plate', chance = 1000 },
{ name = 'copper-plate', chance = 750 }, { name = 'iron-gear-wheel', chance = 750 },
{ name = 'copper-cable', chance = 500 }, { name = 'copper-plate', chance = 750 },
{ name = 'electronic-circuit', chance = 300 }, { name = 'copper-cable', chance = 500 },
{ name = 'steel-plate', chance = 200 }, { name = 'electronic-circuit', chance = 300 },
{ name = 'solid-fuel', chance = 150 }, { name = 'steel-plate', chance = 200 },
{ name = 'pipe', chance = 100 }, { name = 'solid-fuel', chance = 150 },
{ name = 'iron-stick', chance = 50 }, { name = 'pipe', chance = 100 },
{ name = 'battery', chance = 20 }, { name = 'iron-stick', chance = 50 },
{ name = 'barrel', chance = 10 }, { name = 'battery', chance = 20 },
{ name = 'crude-oil-barrel', chance = 30 }, { name = 'barrel', chance = 10 },
{ name = 'lubricant-barrel', chance = 20 }, { name = 'crude-oil-barrel', chance = 30 },
{ name = 'petroleum-gas-barrel', chance = 15 }, { name = 'lubricant-barrel', chance = 20 },
{ name = 'sulfuric-acid-barrel', chance = 15 }, { name = 'petroleum-gas-barrel', chance = 15 },
{ name = 'heavy-oil-barrel', chance = 15 }, { name = 'sulfuric-acid-barrel', chance = 15 },
{ name = 'light-oil-barrel', chance = 15 }, { name = 'heavy-oil-barrel', chance = 15 },
{ name = 'water-barrel', chance = 10 }, { name = 'light-oil-barrel', chance = 15 },
{ name = 'explosives', chance = 5 }, { name = 'water-barrel', chance = 10 },
{ name = 'advanced-circuit', chance = 5 }, { name = 'explosives', chance = 5 },
{ name = 'nuclear-fuel', chance = 1 }, { name = 'advanced-circuit', chance = 5 },
{ name = 'pipe-to-ground', chance = 10 }, { name = 'nuclear-fuel', chance = 1 },
{ name = 'plastic-bar', chance = 5 }, { name = 'pipe-to-ground', chance = 10 },
{ name = 'processing-unit', chance = 2 }, { name = 'plastic-bar', chance = 5 },
{ name = 'depleted-uranium-fuel-cell', chance = 1 }, { name = 'processing-unit', chance = 2 },
{ name = 'uranium-fuel-cell', chance = 1 }, { name = 'depleted-uranium-fuel-cell', chance = 1 },
{ name = 'rocket-fuel', chance = 3 }, { name = 'uranium-fuel-cell', chance = 1 },
{ name = 'low-density-structure', chance = 1 }, { name = 'rocket-fuel', chance = 3 },
{ name = 'heat-pipe', chance = 1 }, { name = 'low-density-structure', chance = 1 },
{ name = 'engine-unit', chance = 4 }, { name = 'heat-pipe', chance = 1 },
{ name = 'electric-engine-unit', chance = 2 }, { name = 'engine-unit', chance = 4 },
{ name = 'logistic-robot', chance = 1 }, { name = 'electric-engine-unit', chance = 2 },
{ name = 'construction-robot', chance = 1 }, { name = 'logistic-robot', chance = 1 },
{ name = 'land-mine', chance = 3 }, { name = 'construction-robot', chance = 1 },
{ name = 'grenade', chance = 10 }, { name = 'land-mine', chance = 3 },
{ name = 'rocket', chance = 3 }, { name = 'grenade', chance = 10 },
{ name = 'explosive-rocket', chance = 3 }, { name = 'rocket', chance = 3 },
{ name = 'cannon-shell', chance = 2 }, { name = 'explosive-rocket', chance = 3 },
{ name = 'explosive-cannon-shell', chance = 2 }, { name = 'cannon-shell', chance = 2 },
{ name = 'uranium-cannon-shell', chance = 1 }, { name = 'explosive-cannon-shell', chance = 2 },
{ name = 'uranium-cannon-shell', chance = 1 },
{ name = 'explosive-uranium-cannon-shell', chance = 1 }, { name = 'explosive-uranium-cannon-shell', chance = 1 },
{ name = 'artillery-shell', chance = 1 }, { name = 'artillery-shell', chance = 1 },
{ name = 'cluster-grenade', chance = 2 }, { name = 'cluster-grenade', chance = 2 },
{ name = 'defender-capsule', chance = 5 }, { name = 'defender-capsule', chance = 5 },
{ name = 'destroyer-capsule', chance = 1 }, { name = 'destroyer-capsule', chance = 1 },
{ name = 'distractor-capsule', chance = 2 } { name = 'distractor-capsule', chance = 2 }
} }
local scrap_yield_amounts = { local scrap_yield_amounts =
{
['iron-plate'] = 16, ['iron-plate'] = 16,
['iron-gear-wheel'] = 8, ['iron-gear-wheel'] = 8,
['iron-stick'] = 16, ['iron-stick'] = 16,
@@ -109,7 +111,8 @@ local scrap_yield_amounts = {
['distractor-capsule'] = 0.3 ['distractor-capsule'] = 0.3
} }
local valid_rocks = { local valid_rocks =
{
['big-sand-rock'] = true, ['big-sand-rock'] = true,
['big-rock'] = true, ['big-rock'] = true,
['huge-rock'] = true, ['huge-rock'] = true,
@@ -122,9 +125,13 @@ local valid_rocks = {
['huge-rock-crisp-2'] = true, ['huge-rock-crisp-2'] = true,
['big-rock-crisp-2'] = true, ['big-rock-crisp-2'] = true,
['big-sand-rock-crisp-2'] = true, ['big-sand-rock-crisp-2'] = true,
['big-rock-snowy'] = true,
['huge-rock-snowy'] = true,
['big-sand-rock-snowy'] = true,
} }
local valid_trees = { local valid_trees =
{
['dead-tree-desert'] = 'wood', ['dead-tree-desert'] = 'wood',
['dead-dry-hairy-tree'] = 'wood', ['dead-dry-hairy-tree'] = 'wood',
['dry-hairy-tree'] = 'wood', ['dry-hairy-tree'] = 'wood',
@@ -138,7 +145,8 @@ local valid_trees = {
['tree-08-brown'] = 'stone' ['tree-08-brown'] = 'stone'
} }
local valid_scrap = { local valid_scrap =
{
['crash-site-spaceship-wreck-small-1'] = true, ['crash-site-spaceship-wreck-small-1'] = true,
['crash-site-spaceship-wreck-small-2'] = true, ['crash-site-spaceship-wreck-small-2'] = true,
['crash-site-spaceship-wreck-small-3'] = true, ['crash-site-spaceship-wreck-small-3'] = true,
@@ -154,7 +162,8 @@ local valid_scrap = {
['mineable-wreckages-6'] = true, ['mineable-wreckages-6'] = true,
} }
local rock_yield = { local rock_yield =
{
['big-rock'] = 1, ['big-rock'] = 1,
['huge-rock'] = 2, ['huge-rock'] = 2,
['big-sand-rock'] = 1, ['big-sand-rock'] = 1,
@@ -169,7 +178,8 @@ local rock_yield = {
['big-sand-rock-green'] = 1, ['big-sand-rock-green'] = 1,
} }
local particles = { local particles =
{
['iron-ore'] = 'iron-ore-particle', ['iron-ore'] = 'iron-ore-particle',
['copper-ore'] = 'copper-ore-particle', ['copper-ore'] = 'copper-ore-particle',
['uranium-ore'] = 'coal-particle', ['uranium-ore'] = 'coal-particle',
@@ -199,7 +209,8 @@ local function create_particles(surface, name, position, amount, cause_position)
frame_speed = 1, frame_speed = 1,
vertical_speed = 0.130, vertical_speed = 0.130,
height = 0, height = 0,
movement = { movement =
{
(m2 - (random(0, m) * 0.01)) + d1, (m2 - (random(0, m) * 0.01)) + d1,
(m2 - (random(0, m) * 0.01)) + d2 (m2 - (random(0, m) * 0.01)) + d2
} }
@@ -208,11 +219,12 @@ local function create_particles(surface, name, position, amount, cause_position)
end end
end end
local mining_chances_ores = { local mining_chances_ores =
{ name = 'iron-ore', chance = 26 }, {
{ name = 'copper-ore', chance = 21 }, { name = 'iron-ore', chance = 26 },
{ name = 'coal', chance = 17 }, { name = 'copper-ore', chance = 21 },
{ name = 'stone', chance = 6 }, { name = 'coal', chance = 17 },
{ name = 'stone', chance = 6 },
{ name = 'uranium-ore', chance = 2 } { name = 'uranium-ore', chance = 2 }
} }
@@ -455,7 +467,8 @@ function Public.on_player_mined_entity(event)
return return
end end
local data = { local data =
{
entity = entity, entity = entity,
player = player player = player
} }

View File

@@ -421,6 +421,83 @@ local function objective_frames(player, stateful, player_frame, objective, data)
data.random_objectives[#data.random_objectives + 1] = { name = objective_name, frame = objective_locale_right_label } data.random_objectives[#data.random_objectives + 1] = { name = objective_name, frame = objective_locale_right_label }
end end
local function render_buff_collection(parent_pane, buffs_source, buffs_collected_source)
local function create_section_header(parent, caption)
local label = parent.add({ type = 'label', caption = caption })
local style = label.style
style.font = 'default-semibold'
style.padding = 0
style.horizontal_align = 'left'
style.font_color = { 0.55, 0.55, 0.99 }
return label
end
local function format_force_buff_text(name, count)
local display_name = Stateful.buff_to_string[name] or name
local flat_value_buffs = { xp_level = true, xp_bonus = true, character_health_bonus = true }
if flat_value_buffs[name] then
return '[font=default-bold]' .. display_name .. ': ' .. count .. '[/font]'
else
return '[font=default-bold]' .. display_name .. ': ' .. (count * 100) .. '%[/font]'
end
end
local function format_starting_item_text(item_name, count)
return '[font=default-large] [item=' .. item_name .. '][/font]: [font=default-bold]' .. count .. '[/font]'
end
local function format_custom_buff_text(name, count)
local text_to_place = count or 'Unlocked'
return '[font=default-bold]' .. name .. ': ' .. text_to_place .. '[/font]'
end
create_section_header(parent_pane, 'Starting items')
local starting_grid = parent_pane.add({ type = 'table', column_count = 8 })
parent_pane.add({ type = 'line' })
create_section_header(parent_pane, 'Force Buffs')
local force_grid = parent_pane.add({ type = 'table', column_count = 2 })
parent_pane.add({ type = 'line' })
create_section_header(parent_pane, 'Custom Buffs')
local custom_grid = parent_pane.add({ type = 'table', column_count = 2 })
if not (buffs_source and next(buffs_source) and buffs_collected_source and next(buffs_collected_source)) then
return
end
if buffs_collected_source.starting_items then
for item_name, item_data in pairs(buffs_collected_source.starting_items) do
local text = format_starting_item_text(item_name, item_data.count)
create_input_element(starting_grid, 'label', text, nil, nil, item_data.discord, 30)
end
end
for name, buff_data in pairs(buffs_collected_source) do
if name == 'starting_items' then
goto continue
end
if type(buff_data.amount) ~= 'table' and buff_data.force then
local text = format_force_buff_text(name, buff_data.count)
create_input_element(force_grid, 'label', text, nil, nil, buff_data.discord)
elseif not buff_data.force then
if buff_data.name then
local text = format_custom_buff_text(buff_data.name, buff_data.count)
create_input_element(custom_grid, 'label', text, nil, nil, buff_data.discord)
else
for _, buff in pairs(buff_data) do
local text = format_custom_buff_text(pretty_format(buff.name), buff.count)
create_input_element(custom_grid, 'label', text, nil, nil, buff.discord)
end
end
end
::continue::
end
end
local function buff_window(player) local function buff_window(player)
local buff_frame_name, inside_table = Gui.add_main_frame_with_toolbar(player, 'center', buffs_window_name, nil, close_buffs_window_name, 'Buffs gathered') local buff_frame_name, inside_table = Gui.add_main_frame_with_toolbar(player, 'center', buffs_window_name, nil, close_buffs_window_name, 'Buffs gathered')
if not buff_frame_name then if not buff_frame_name then
@@ -452,76 +529,7 @@ local function buff_window(player)
ns.right_padding = 5 ns.right_padding = 5
ns.top_padding = 5 ns.top_padding = 5
buff_pane.add({ type = 'line' }) render_buff_collection(buff_pane, stateful.buffs, stateful.buffs_collected)
local starting_items_label = buff_pane.add({ type = 'label', caption = 'Starting items' })
local starting_items_label_style = starting_items_label.style
starting_items_label_style.font = 'default-semibold'
starting_items_label_style.padding = 0
starting_items_label_style.horizontal_align = 'left'
starting_items_label_style.font_color = { 0.55, 0.55, 0.99 }
local starting_grid = buff_pane.add({ type = 'table', column_count = 8 })
buff_pane.add({ type = 'line' })
local force_label = buff_pane.add({ type = 'label', caption = 'Force Buffs' })
local force_label_style = force_label.style
force_label_style.font = 'default-semibold'
force_label_style.padding = 0
force_label_style.horizontal_align = 'left'
force_label_style.font_color = { 0.55, 0.55, 0.99 }
local force_grid = buff_pane.add({ type = 'table', column_count = 2 })
buff_pane.add({ type = 'line' })
local custom_label = buff_pane.add({ type = 'label', caption = 'Custom Buffs' })
local custom_label_style = custom_label.style
custom_label_style.font = 'default-semibold'
custom_label_style.padding = 0
custom_label_style.horizontal_align = 'left'
custom_label_style.font_color = { 0.55, 0.55, 0.99 }
local custom_grid = buff_pane.add({ type = 'table', column_count = 2 })
if stateful.buffs and next(stateful.buffs) then
if stateful.buffs_collected and next(stateful.buffs_collected) then
if stateful.buffs_collected.starting_items then
for item_name, item_data in pairs(stateful.buffs_collected.starting_items) do
-- local text = pretty_format(item_name) .. ': [font=font-bold]' .. item_data.count
local text = '[font=default-large] [item=' .. item_name .. '][/font]' .. ': [font=default-bold]' .. item_data.count .. '[/font]'
create_input_element(starting_grid, 'label', text, nil, nil, item_data.discord, 30)
end
end
for name, buff_data in pairs(stateful.buffs_collected) do
if type(buff_data.amount) ~= 'table' and buff_data.force then
local c = buff_data.count
local text
if name == 'xp_level' or name == 'xp_bonus' or name == 'character_health_bonus' then
text = '[font=default-bold]' .. Stateful.buff_to_string[name] .. ': ' .. c .. '[/font]'
else
text = '[font=default-bold]' .. Stateful.buff_to_string[name] .. ': ' .. (c * 100) .. '%[/font]'
end
create_input_element(force_grid, 'label', text, nil, nil, buff_data.discord)
end
if name ~= 'starting_items' and not buff_data.force then
if buff_data.name then
local text_to_place = buff_data.count or 'Unlocked'
local text = '[font=default-bold]' .. buff_data.name .. ': ' .. text_to_place .. ' [/font]'
create_input_element(custom_grid, 'label', text, nil, nil, buff_data.discord)
else
for _, buff in pairs(buff_data) do
local text_to_place = buff.count or 'Unlocked'
local text = '[font=default-bold]' .. pretty_format(buff.name) .. ': ' .. text_to_place .. ' [/font]'
create_input_element(custom_grid, 'label', text, nil, nil, buff.discord)
end
end
end
end
end
end
player.opened = buff_frame_name player.opened = buff_frame_name
end end
@@ -566,75 +574,7 @@ local function permanent_buff_window(player)
ns.right_padding = 5 ns.right_padding = 5
ns.top_padding = 5 ns.top_padding = 5
buff_pane.add({ type = 'line' }) render_buff_collection(buff_pane, stateful.permanent_buffs, stateful.permanent_buffs_collected)
local starting_items_label = buff_pane.add({ type = 'label', caption = 'Starting items' })
local starting_items_label_style = starting_items_label.style
starting_items_label_style.font = 'default-semibold'
starting_items_label_style.padding = 0
starting_items_label_style.horizontal_align = 'left'
starting_items_label_style.font_color = { 0.55, 0.55, 0.99 }
local starting_grid = buff_pane.add({ type = 'table', column_count = 8 })
buff_pane.add({ type = 'line' })
local force_label = buff_pane.add({ type = 'label', caption = 'Force Buffs' })
local force_label_style = force_label.style
force_label_style.font = 'default-semibold'
force_label_style.padding = 0
force_label_style.horizontal_align = 'left'
force_label_style.font_color = { 0.55, 0.55, 0.99 }
local force_grid = buff_pane.add({ type = 'table', column_count = 2 })
buff_pane.add({ type = 'line' })
local custom_label = buff_pane.add({ type = 'label', caption = 'Custom Buffs' })
local custom_label_style = custom_label.style
custom_label_style.font = 'default-semibold'
custom_label_style.padding = 0
custom_label_style.horizontal_align = 'left'
custom_label_style.font_color = { 0.55, 0.55, 0.99 }
local custom_grid = buff_pane.add({ type = 'table', column_count = 2 })
if stateful.permanent_buffs and next(stateful.permanent_buffs) then
if stateful.permanent_buffs_collected and next(stateful.permanent_buffs_collected) then
if stateful.permanent_buffs_collected.starting_items then
for item_name, item_data in pairs(stateful.permanent_buffs_collected.starting_items) do
local text = '[font=default-large] [item=' .. item_name .. '][/font]' .. ': [font=default-bold]' .. item_data.count .. '[/font]'
create_input_element(starting_grid, 'label', text, nil, nil, item_data.discord, 30)
end
end
for name, buff_data in pairs(stateful.permanent_buffs_collected) do
if type(buff_data.amount) ~= 'table' and buff_data.force then
local c = buff_data.count
local text
if name == 'xp_level' or name == 'xp_bonus' or name == 'character_health_bonus' then
text = '[font=default-bold]' .. Stateful.buff_to_string[name] .. ': ' .. c .. '[/font]'
else
text = '[font=default-bold]' .. Stateful.buff_to_string[name] .. ': ' .. (c * 100) .. '%[/font]'
end
create_input_element(force_grid, 'label', text, nil, nil, buff_data.discord)
end
if name ~= 'starting_items' and not buff_data.force then
if buff_data.name then
local text_to_place = buff_data.count or 'Unlocked'
local text = '[font=default-bold]' .. buff_data.name .. ': ' .. text_to_place .. ' [/font]'
create_input_element(custom_grid, 'label', text, nil, nil, buff_data.discord)
else
for _, buff in pairs(buff_data) do
local text_to_place = buff.count or 'Unlocked'
local text = '[font=default-bold]' .. pretty_format(buff.name) .. ': ' .. text_to_place .. ' [/font]'
create_input_element(custom_grid, 'label', text, nil, nil, buff.discord)
end
end
end
end
end
end
player.opened = main_player_frame player.opened = main_player_frame
end end

View File

@@ -199,6 +199,7 @@ local function get_random_buff(fetch_all, only_force)
poll_name = 'Running speed', poll_name = 'Running speed',
modifier = 'force', modifier = 'force',
per_force = true, per_force = true,
limit = 25,
state = 0.05 state = 0.05
}, },
{ {
@@ -208,6 +209,7 @@ local function get_random_buff(fetch_all, only_force)
poll_name = 'Mining speed', poll_name = 'Mining speed',
modifier = 'force', modifier = 'force',
per_force = true, per_force = true,
limit = 25,
state = 0.15 state = 0.15
}, },
{ {
@@ -217,6 +219,7 @@ local function get_random_buff(fetch_all, only_force)
poll_name = 'Laboratory speed', poll_name = 'Laboratory speed',
modifier = 'force', modifier = 'force',
per_force = true, per_force = true,
limit = 30,
state = 0.15 state = 0.15
}, },
{ {
@@ -226,6 +229,7 @@ local function get_random_buff(fetch_all, only_force)
poll_name = 'Laboratory productivity', poll_name = 'Laboratory productivity',
modifier = 'force', modifier = 'force',
per_force = true, per_force = true,
limit = 30,
state = 0.15 state = 0.15
}, },
{ {
@@ -235,6 +239,7 @@ local function get_random_buff(fetch_all, only_force)
poll_name = 'Robot storage', poll_name = 'Robot storage',
modifier = 'force', modifier = 'force',
per_force = true, per_force = true,
limit = 30,
state = 1 state = 1
}, },
{ {
@@ -244,6 +249,7 @@ local function get_random_buff(fetch_all, only_force)
poll_name = 'Robot battery', poll_name = 'Robot battery',
modifier = 'force', modifier = 'force',
per_force = true, per_force = true,
limit = 30,
state = 1 state = 1
}, },
{ {
@@ -253,6 +259,7 @@ local function get_random_buff(fetch_all, only_force)
poll_name = 'Robot speed', poll_name = 'Robot speed',
modifier = 'force', modifier = 'force',
per_force = true, per_force = true,
limit = 30,
state = 0.5 state = 0.5
}, },
{ {
@@ -262,6 +269,7 @@ local function get_random_buff(fetch_all, only_force)
poll_name = 'Drill productivity', poll_name = 'Drill productivity',
modifier = 'force', modifier = 'force',
per_force = true, per_force = true,
limit = 30,
state = 0.5 state = 0.5
}, },
{ {
@@ -271,6 +279,7 @@ local function get_random_buff(fetch_all, only_force)
poll_name = 'Character health', poll_name = 'Character health',
modifier = 'force', modifier = 'force',
per_force = true, per_force = true,
limit = 50,
state = 250 state = 250
}, },
{ {
@@ -281,6 +290,7 @@ local function get_random_buff(fetch_all, only_force)
modifier = 'rpg_distance', modifier = 'rpg_distance',
per_force = true, per_force = true,
modifiers = { 'character_resource_reach_distance_bonus', 'character_item_pickup_distance_bonus', 'character_loot_pickup_distance_bonus', 'character_reach_distance_bonus' }, modifiers = { 'character_resource_reach_distance_bonus', 'character_item_pickup_distance_bonus', 'character_loot_pickup_distance_bonus', 'character_reach_distance_bonus' },
limit = 20,
state = 0.05 state = 0.05
}, },
{ {
@@ -290,6 +300,7 @@ local function get_random_buff(fetch_all, only_force)
poll_name = 'Crafting speed', poll_name = 'Crafting speed',
modifier = 'force', modifier = 'force',
per_force = true, per_force = true,
limit = 25,
state = 0.12 state = 0.12
}, },
{ {
@@ -299,6 +310,7 @@ local function get_random_buff(fetch_all, only_force)
poll_name = 'RPG XP point', poll_name = 'RPG XP point',
modifier = 'rpg', modifier = 'rpg',
per_force = true, per_force = true,
limit = 25,
state = 0.12 state = 0.12
}, },
{ {
@@ -308,6 +320,7 @@ local function get_random_buff(fetch_all, only_force)
poll_name = 'RPG XP level', poll_name = 'RPG XP level',
modifier = 'rpg', modifier = 'rpg',
per_force = true, per_force = true,
limit = 10,
state = 20 state = 20
}, },
{ {
@@ -465,7 +478,7 @@ local function get_random_buff(fetch_all, only_force)
tooltip = 'Selecting this buff will grant the team 1 extra wagon at start!', tooltip = 'Selecting this buff will grant the team 1 extra wagon at start!',
poll_name = 'Starting items (extra wagon)', poll_name = 'Starting items (extra wagon)',
modifier = 'locomotive', modifier = 'locomotive',
limit = 4, limit = 5,
state = 1 state = 1
}, },
{ {
@@ -1381,39 +1394,41 @@ local function clear_all_stats()
end end
local function migrate_buffs_generic(buffs_table) local function migrate_buffs_generic(buffs_table)
local state_buffs = get_random_buff(true) local static_buffs = get_random_buff(true)
for _, data in pairs(state_buffs) do local static_buffs_by_name = {}
for index, buff in pairs(buffs_table) do for _, static_buff in pairs(static_buffs) do
if data.name == buff.name then static_buffs_by_name[static_buff.name] = static_buff
if not Public.is_modded_pt2 and data.dlc then end
buffs_table[index] = nil
break for index, saved_buff in pairs(buffs_table) do
end local static_buff = static_buffs_by_name[saved_buff.name]
if data.add_per_buff then
buff.add_per_buff = data.add_per_buff if static_buff then
end if not Public.is_modded_pt2 and static_buff.dlc then
if buff.replaces then buffs_table[index] = nil
buff.replaces = nil else
local collected_count = saved_buff.count or 0
buffs_table[index] = {}
for key, value in pairs(static_buff) do
buffs_table[index][key] = value
end end
if buff.modifier == 'starting_items_1' then buffs_table[index].count = collected_count
buff.modifier = 'starting_items'
if buffs_table[index].modifier == 'starting_items_1' then
buffs_table[index].modifier = 'starting_items'
end end
if data.items and type(data.items) == 'table' then buffs_table[index].replaces = nil
buff.items = data.items
end
if data.limit and not buff.limit then if buffs_table[index].items == 0 then
buff.limit = data.limit
buff.name = data.name
end
if buff.items == 0 then
buffs_table[index] = nil buffs_table[index] = nil
end end
end end
else
buffs_table[index] = nil
end end
end end
end end
@@ -1426,248 +1441,225 @@ local function migrate_permanent_buffs()
migrate_buffs_generic(this.permanent_buffs) migrate_buffs_generic(this.permanent_buffs)
end end
local function apply_buffs_generic(buffs_table, collected_table, is_permanent) local function update_collected_entry(collected_table, key, name, count, discord, force_flag)
local starting_items = Public.get_func('starting_items') if not collected_table[key] then
collected_table[key] =
{
name = name,
count = count,
discord = discord,
force = force_flag
}
else
collected_table[key].count = collected_table[key].count + count
end
end
local function check_limit(limit_types, key, buff, increment)
increment = increment or 1
limit_types[key] = (limit_types[key] or 0) + increment
return buff.limit and limit_types[key] >= buff.limit
end
local function apply_force_buff(buff, collected_table)
local force = game.forces.player
force[buff.name] = force[buff.name] + buff.state
update_collected_entry(collected_table, buff.name, nil, buff.state, buff.discord, true)
end
local function apply_rpg_distance_buff(buff, collected_table)
local force = game.forces.player
for _, buff_name in pairs(buff.modifiers) do
if buff_name == 'character_reach_distance_bonus' then
buff.state = 1
end
force[buff_name] = force[buff_name] + buff.state
update_collected_entry(collected_table, buff_name, 'Extra Reach', buff.state, buff.discord, true)
end
end
local function apply_locomotive_buff(buff, collected_table, limit_types)
if check_limit(limit_types, 'locomotive', buff, buff.state) then
return true -- signal to skip this buff
end
this.extra_wagons = (this.extra_wagons or 0) + buff.state
update_collected_entry(collected_table, 'locomotive', 'Extra Wagons', buff.state, buff.discord)
return false
end
local function apply_quality_buff(buff, collected_table)
local quality_name = buff.name
local display_name = quality_name:gsub('quality_', ''):gsub('_', '-')
if quality_name == 'quality_locomotive' then
this.quality_trains.locomotive = buff.quality
elseif quality_name == 'quality_cargo_wagon' then
this.quality_trains['cargo-wagon'] = buff.quality
elseif quality_name == 'quality_buildings' then
this.quality_buildings = buff.quality
end
collected_table[quality_name] =
{
name = 'Quality ' .. display_name .. ' (' .. buff.quality .. ')!',
discord = buff.discord
}
end
local function apply_fish_buff(buff, collected_table, limit_types)
limit_types[buff.name] = true
Public.set('all_the_fish', true)
update_collected_entry(collected_table, 'fish', 'A thousand fishes', nil, buff.discord)
end
local function apply_tech_buff(buff, collected_table)
local techs = Public.get_func('techs') local techs = Public.get_func('techs')
if not collected_table['techs'] then
collected_table['techs'] = {}
end
if type(buff.techs) ~= 'table' then
return true -- signal to skip
end
for _, tech in pairs(buff.techs) do
if tech and not techs[tech.name] then
techs[tech.name] = { name = buff.name }
collected_table['techs'][tech.name] =
{
name = tech.name,
buff_type = buff.name,
discord = buff.discord
}
this.delayed_tech = this.delayed_tech or {}
this.delayed_tech[tech.name] = tech
end
end
return false
end
local function apply_rpg_buff(buff, collected_table, limit_types)
local rpg_extra = RPG.get('rpg_extra')
if check_limit(limit_types, buff.name, buff) then
return true -- signal to skip
end
if buff.name == 'xp_bonus' then
rpg_extra.difficulty = (rpg_extra.difficulty or 0) + buff.state
update_collected_entry(collected_table, 'xp_bonus', 'XP Bonus', buff.state, buff.discord)
elseif buff.name == 'xp_level' then
rpg_extra.grant_xp_level = (rpg_extra.grant_xp_level or 0) + buff.state
update_collected_entry(collected_table, 'xp_level', 'XP Level Bonus', buff.state, buff.discord)
end
return false
end
local function apply_starting_items_buff(buff, collected_table)
local starting_items = Public.get_func('starting_items')
if not collected_table['starting_items'] then
collected_table['starting_items'] = {}
end
if type(buff.items) ~= 'table' then
return true -- signal to skip
end
for _, item in pairs(buff.items) do
if item then
if starting_items[item.name] and buff.limit and
starting_items[item.name].item_limit and
starting_items[item.name].item_limit >= buff.limit then
starting_items[item.name].limit_reached = true
return true -- skip this buff
end
if starting_items[item.name] then
starting_items[item.name].count = starting_items[item.name].count + item.count
starting_items[item.name].item_limit = (starting_items[item.name].item_limit or 0) + (buff.add_per_buff or 0)
starting_items[item.name].buff_type = buff.name
else
starting_items[item.name] =
{
buff_type = buff.name,
count = item.count,
item_limit = buff.add_per_buff
}
end
if collected_table['starting_items'][item.name] then
collected_table['starting_items'][item.name].count =
collected_table['starting_items'][item.name].count + item.count
collected_table['starting_items'][item.name].buff_type = buff.name
else
collected_table['starting_items'][item.name] =
{
buff_type = buff.name,
count = item.count,
discord = buff.discord
}
end
end
end
return false
end
local function apply_buffs_generic(buffs_table, collected_table, is_permanent)
if not buffs_table or not next(buffs_table) then
return
end
-- Run migration
if is_permanent then
migrate_permanent_buffs()
else
migrate_buffs()
end
local total_buffs = 0
local limit_types = Public.get_func('limit_types') local limit_types = Public.get_func('limit_types')
if buffs_table and next(buffs_table) then for _, buff in pairs(buffs_table) do
local total_buffs = 0 if buff then
local skip_buff = false
if is_permanent then if buff.modifier == 'force' then
migrate_permanent_buffs() apply_force_buff(buff, collected_table)
else elseif buff.modifier == 'rpg_distance' then
migrate_buffs() apply_rpg_distance_buff(buff, collected_table)
end elseif buff.modifier == 'locomotive' then
skip_buff = apply_locomotive_buff(buff, collected_table, limit_types)
local force = game.forces.player elseif buff.name and buff.name:match('^quality_') then
for _, buff in pairs(buffs_table) do apply_quality_buff(buff, collected_table)
if buff then elseif buff.modifier == 'fish' then
total_buffs = total_buffs + 1 apply_fish_buff(buff, collected_table, limit_types)
if buff.modifier == 'rpg_distance' then elseif buff.modifier == 'tech' then
for _, buff_name in pairs(buff.modifiers) do skip_buff = apply_tech_buff(buff, collected_table)
if buff_name == 'character_reach_distance_bonus' then elseif buff.modifier == 'rpg' then
buff.state = 1 skip_buff = apply_rpg_buff(buff, collected_table, limit_types)
end elseif buff.modifier == 'starting_items' then
skip_buff = apply_starting_items_buff(buff, collected_table)
force[buff_name] = force[buff_name] + buff.state
if not collected_table[buff_name] then
collected_table[buff_name] =
{
name = 'Extra Reach',
count = buff.state,
discord = buff.discord,
force = true
}
else
collected_table[buff_name].count = collected_table[buff_name].count + buff.state
end
end
end
if buff.modifier == 'force' then
force[buff.name] = force[buff.name] + buff.state
if not collected_table[buff.name] then
collected_table[buff.name] =
{
count = buff.state,
discord = buff.discord,
force = true
}
else
collected_table[buff.name].count = collected_table[buff.name].count + buff.state
end
end
if buff.modifier == 'locomotive' then
if not this.extra_wagons then
this.extra_wagons = buff.state
else
this.extra_wagons = this.extra_wagons + buff.state
end
if not collected_table['locomotive'] then
collected_table['locomotive'] =
{
name = 'Extra Wagons',
count = buff.state,
discord = buff.discord
}
else
if this.extra_wagons > 5 then
collected_table['locomotive'].count = this.extra_wagons
else
collected_table['locomotive'].count = this.extra_wagons + buff.state
end
end
if this.extra_wagons > 5 then
this.extra_wagons = 5
end
end
if buff.name == 'quality_locomotive' then
this.quality_trains.locomotive = buff.quality
collected_table['quality_locomotive'] =
{
name = 'Quality locomotives (' .. buff.quality .. ')!',
discord = buff.discord
}
end
if buff.name == 'quality_cargo_wagon' then
this.quality_trains.locomotive = buff.quality
collected_table['quality_cargo_wagon'] =
{
name = 'Quality cargo-wagon (' .. buff.quality .. ')!',
discord = buff.discord
}
end
if buff.name == 'quality_buildings' then
this.quality_trains.locomotive = buff.quality
collected_table['quality_buildings'] =
{
name = 'Quality buildings (' .. buff.quality .. ')!',
discord = buff.discord
}
this.quality_buildings = buff.quality
end
if buff.modifier == 'fish' then
limit_types[buff.name] = true
Public.set('all_the_fish', true)
if not collected_table['fish'] then
collected_table['fish'] =
{
name = 'A thousand fishes',
discord = buff.discord
}
end
end
if buff.modifier == 'tech' then
if not collected_table['techs'] then
collected_table['techs'] = {}
end
if type(buff.techs) ~= 'table' then
goto cont
end
for _, tech in pairs(buff.techs) do
if tech then
if techs[tech.name] then
goto cont
end
if not techs[tech.name] then
techs[tech.name] =
{
name = buff.name
}
end
if not collected_table['techs'][tech.name] then
collected_table['techs'][tech.name] =
{
name = tech.name,
buff_type = buff.name,
discord = buff.discord
}
end
if not this.delayed_tech then
this.delayed_tech = {}
end
this.delayed_tech[tech.name] = tech
end
end
end
if buff.modifier == 'rpg' then
local rpg_extra = RPG.get('rpg_extra')
if buff.name == 'xp_bonus' then
if not rpg_extra.difficulty then
rpg_extra.difficulty = buff.state
else
rpg_extra.difficulty = rpg_extra.difficulty + buff.state
end
if not collected_table['xp_bonus'] then
collected_table['xp_bonus'] =
{
name = 'XP Bonus',
count = buff.state,
discord = buff.discord
}
else
collected_table['xp_bonus'].count = collected_table['xp_bonus'].count + buff.state
end
end
if buff.name == 'xp_level' then
if not rpg_extra.grant_xp_level then
rpg_extra.grant_xp_level = buff.state
else
rpg_extra.grant_xp_level = rpg_extra.grant_xp_level + buff.state
end
if not collected_table['xp_level'] then
collected_table['xp_level'] =
{
name = 'XP Level Bonus',
count = buff.state,
discord = buff.discord
}
else
collected_table['xp_level'].count = collected_table['xp_level'].count + buff.state
end
end
end
if buff.modifier == 'starting_items' then
if not collected_table['starting_items'] then
collected_table['starting_items'] = {}
end
if type(buff.items) ~= 'table' then
goto cont
end
for _, item in pairs(buff.items) do
if item then
if starting_items[item.name] and buff.limit and starting_items[item.name].item_limit and starting_items[item.name].item_limit >= buff.limit then
starting_items[item.name].limit_reached = true
goto cont -- break if there is a limit set
end
if starting_items[item.name] then
starting_items[item.name].count = starting_items[item.name].count + item.count
starting_items[item.name].item_limit = starting_items[item.name].item_limit and starting_items[item.name].item_limit + buff.add_per_buff or buff.add_per_buff
starting_items[item.name].buff_type = buff.name
else
starting_items[item.name] =
{
buff_type = buff.name,
count = item.count,
item_limit = buff.add_per_buff
}
end
if collected_table['starting_items'][item.name] then
collected_table['starting_items'][item.name].count = collected_table['starting_items'][item.name].count + item.count
collected_table['starting_items'][item.name].buff_type = buff.name
else
collected_table['starting_items'][item.name] =
{
buff_type = buff.name,
count = item.count,
discord = buff.discord
}
end
end
end
end
end end
::cont::
if skip_buff then
goto continue
end
total_buffs = total_buffs + 1
end end
this.total_buffs = total_buffs ::continue::
local log_message = is_permanent and 'Applied all permanent buffs.' .. ' Total buffs: ' .. total_buffs or 'Applied all buffs.' .. ' Total buffs: ' .. total_buffs
Server.output_script_data(log_message)
Server.output_script_data('Total wagons this round: ' .. this.extra_wagons)
end end
this.total_buffs = total_buffs
local log_message = is_permanent and 'Applied all permanent buffs. Total buffs: ' .. total_buffs
or 'Applied all buffs. Total buffs: ' .. total_buffs
Server.output_script_data(log_message)
Server.output_script_data('Total wagons this round: ' .. (this.extra_wagons or 0))
end end
apply_buffs = function () apply_buffs = function ()
@@ -1704,9 +1696,15 @@ local function grant_non_limit_reached_buff()
end end
end end
for limit_name, _ in pairs(limit_types) do for limit_name, limit_count in pairs(limit_types) do
if limit_name == data.name then if limit_name == data.name then
all_buffs[index] = nil if limit_count and data.limit then
if limit_count >= data.limit then
all_buffs[index] = nil
end
else
all_buffs[index] = nil
end
end end
end end
end end
@@ -1725,6 +1723,73 @@ local function grant_non_limit_reached_buff()
return all_buffs[1] return all_buffs[1]
end end
local function grant_non_limit_reached_buff_permanent()
local all_buffs = get_random_buff(true)
local permanent_buff_counts = {}
if this.permanent_buffs then
for _, permanent_buff in pairs(this.permanent_buffs) do
if permanent_buff and permanent_buff.name then
permanent_buff_counts[permanent_buff.name] = (permanent_buff_counts[permanent_buff.name] or 0) + 1
end
end
end
for index, data in pairs(all_buffs) do
local should_remove = false
if not Public.is_modded_pt2 and data.dlc then
should_remove = true
end
if not should_remove and data.limit and permanent_buff_counts[data.name] then
if permanent_buff_counts[data.name] >= data.limit then
should_remove = true
end
end
if not should_remove and data.modifier == 'tech' and data.techs then
local techs = Public.get_func('techs')
for _, tech in pairs(data.techs) do
if tech and techs[tech.name] then
should_remove = true
break
end
end
end
if not should_remove and data.modifier == 'starting_items' and data.limit then
local starting_items = Public.get_func('starting_items')
for _, item in pairs(data.items or {}) do
if item and starting_items[item.name] then
local current_limit = starting_items[item.name].item_limit or 0
if current_limit >= data.limit then
should_remove = true
break
end
end
end
end
if should_remove then
all_buffs[index] = nil
end
end
shuffle(all_buffs)
shuffle(all_buffs)
shuffle(all_buffs)
shuffle(all_buffs)
shuffle(all_buffs)
shuffle(all_buffs)
if not all_buffs[1] then
return get_random_buff(nil, true)
end
return all_buffs[1]
end
local function apply_startup_settings(settings) local function apply_startup_settings(settings)
local current_date = Server.get_current_date(false, true) local current_date = Server.get_current_date(false, true)
if not current_date then if not current_date then
@@ -1750,7 +1815,7 @@ local function apply_startup_settings(settings)
local time_to_reset = (current_date - converted_stored_date) local time_to_reset = (current_date - converted_stored_date)
this.time_to_reset = this.reset_after - time_to_reset this.time_to_reset = this.reset_after - time_to_reset
if time_to_reset and time_to_reset >= this.reset_after then if time_to_reset and time_to_reset >= this.reset_after then
local perm_buff = grant_non_limit_reached_buff() local perm_buff = grant_non_limit_reached_buff_permanent()
this.permanent_buffs[#this.permanent_buffs + 1] = perm_buff this.permanent_buffs[#this.permanent_buffs + 1] = perm_buff
Public.save_settings_before_reset() Public.save_settings_before_reset()
Public.set_season_scores() Public.set_season_scores()
@@ -1849,9 +1914,6 @@ local apply_settings_token =
settings.season = 1 settings.season = 1
end end
if not settings.best_streak then
settings.best_streak = 0
end
this.current_date = settings.current_date this.current_date = settings.current_date
this.buffs = settings.buffs or {} this.buffs = settings.buffs or {}
@@ -1859,8 +1921,8 @@ local apply_settings_token =
this.rounds_survived = settings.rounds_survived this.rounds_survived = settings.rounds_survived
this.season = settings.season this.season = settings.season
this.best_streak = settings.best_streak this.best_streak = settings.best_streak or 0
this.current_streak = settings.current_streak this.current_streak = settings.current_streak or 0
apply_startup_settings(settings) apply_startup_settings(settings)
local current_season = Public.get('current_season') local current_season = Public.get('current_season')
@@ -2219,8 +2281,8 @@ function Public.reset_stateful(refresh_gui, clear_buffs)
this.objectives = t this.objectives = t
clear_all_stats() clear_all_stats()
apply_buffs()
apply_permanent_buffs() apply_permanent_buffs()
apply_buffs()
if refresh_gui then if refresh_gui then
Public.refresh_frames() Public.refresh_frames()
end end
@@ -2521,4 +2583,16 @@ Public.grant_non_limit_reached_buff = grant_non_limit_reached_buff
Public.apply_buffs = apply_buffs Public.apply_buffs = apply_buffs
Public.apply_permanent_buffs = apply_permanent_buffs Public.apply_permanent_buffs = apply_permanent_buffs
if _DEBUG then
local settings = require 'maps.mountain_fortress_v3.stateful._stateful_debug'
Event.on_init(
function ()
local cbl = Task.get(apply_settings_token)
storage.tokens.utils_server.server_time.secs = 1187954
cbl(settings)
end
)
end
return Public return Public

View File

@@ -3516,7 +3516,7 @@ local function zone_1(x, y, data, void_or_lab, adjusted_zones)
local noise_cave_ponds = Public.get_noise('cave_rivers_2', p, seed + 28939) local noise_cave_ponds = Public.get_noise('cave_rivers_2', p, seed + 28939)
local smol_areas = Public.get_noise('smol_areas', p, seed + 3992) local smol_areas = Public.get_noise('smol_areas', p, seed + 3992)
local no_rocks_2 = Public.get_noise('no_rocks_2', p, seed + 1922) local no_rocks_2 = Public.get_noise('no_rocks_2', p, seed + 1922)
local cave_rivers = Public.get_noise('cave_rivers', p, seed) local cave_rivers = Public.get_noise('cave_rivers', p, seed + 31922)
local no_rocks = Public.get_noise('dungeon_sewer', p, seed + seed) local no_rocks = Public.get_noise('dungeon_sewer', p, seed + seed)
if smol_areas < 0.055 and smol_areas > -0.025 then if smol_areas < 0.055 and smol_areas > -0.025 then
@@ -3549,8 +3549,8 @@ local function zone_1(x, y, data, void_or_lab, adjusted_zones)
end end
--Water Ponds --Water Ponds
if noise_cave_ponds > 0.64 then if noise_cave_ponds < 0.24 and noise_cave_ponds > 0.04 then
if noise_cave_ponds > 0.74 then if noise_cave_ponds > 0.14 then
tiles[#tiles + 1] = { name = 'acid-refined-concrete', position = p } tiles[#tiles + 1] = { name = 'acid-refined-concrete', position = p }
if random(1, 4) == 1 then if random(1, 4) == 1 then
markets[#markets + 1] = p markets[#markets + 1] = p
@@ -3578,24 +3578,13 @@ local function zone_1(x, y, data, void_or_lab, adjusted_zones)
end end
end end
if noise_cave_ponds > 0.322 then
if noise_cave_ponds > 0.542 then
if cave_rivers > -0.302 then
tiles[#tiles + 1] = { name = 'refined-hazard-concrete-right', position = p }
end
end
if random(1, 64) == 1 then
entities[#entities + 1] = { name = tree_raffle[random(1, size_of_tree_raffle)], position = p }
end
return
end
--Worm oil Zones --Worm oil Zones
if no_rocks < 0.12 and no_rocks > -0.12 then if no_rocks < 0.40 and no_rocks > -0.20 then
if small_caves > 0.30 then if small_caves > 0.40 then
tiles[#tiles + 1] = { name = 'brown-refined-concrete', position = p } tiles[#tiles + 1] = { name = 'brown-refined-concrete', position = p }
if random(1, 250) == 1 then if random(1, 450) == 1 then
entities[#entities + 1] = { name = 'crude-oil', position = p, amount = get_oil_amount(p) * 2 } entities[#entities + 1] = { name = 'crude-oil', position = p, amount = get_oil_amount(p) }
end end
if random(1, 96) == 1 then if random(1, 96) == 1 then
Biters.wave_defense_set_worm_raffle(abs(p.y) * worm_level_modifier) Biters.wave_defense_set_worm_raffle(abs(p.y) * worm_level_modifier)
@@ -3617,6 +3606,19 @@ local function zone_1(x, y, data, void_or_lab, adjusted_zones)
end end
end end
if noise_cave_ponds > 0.182 then
if noise_cave_ponds > 0.542 then
if cave_rivers > -0.302 then
tiles[#tiles + 1] = { name = 'refined-hazard-concrete-right', position = p }
end
end
if random(1, 64) == 1 then
entities[#entities + 1] = { name = tree_raffle[random(1, size_of_tree_raffle)], position = p }
end
return
end
--Main Rock Terrain --Main Rock Terrain
if no_rocks_2 > 0.334 and no_rocks_2 < 0.544 then if no_rocks_2 > 0.334 and no_rocks_2 < 0.544 then
local success = place_wagon(data, adjusted_zones) local success = place_wagon(data, adjusted_zones)