1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2024-12-30 23:17:53 +02:00

Expanse fix

This commit is contained in:
Gerkiz 2024-06-14 19:10:06 +02:00
parent 02f4569e41
commit 06e5492b60
2 changed files with 564 additions and 561 deletions

View File

@ -4,7 +4,7 @@ local Task = require 'utils.task'
local Token = require 'utils.token'
local Public = {}
local ores = {'copper-ore', 'iron-ore', 'stone', 'coal'}
local ores = { 'copper-ore', 'iron-ore', 'stone', 'coal' }
local price_modifiers = {
['unit-spawner'] = -256,
['unit'] = -16,
@ -24,13 +24,13 @@ local price_modifiers = {
--- So we solve it by delaying the creation.
local delay_infini_tree_token =
Token.register(
function(event)
local surface = event.surface
local position = event.position
function (event)
local surface = event.surface
local position = event.position
surface.create_entity({name = 'tree-0' .. math.random(1, 9), position = position})
end
)
surface.create_entity({ name = 'tree-0' .. math.random(1, 9), position = position })
end
)
local function reward_tokens(expanse, entity)
local chance = expanse.token_chance % 1
@ -39,12 +39,12 @@ local function reward_tokens(expanse, entity)
if chance > 0 then
chance = math.floor(chance * 1000)
if math.random(1, 1000) <= chance then
entity.surface.spill_item_stack(entity.position, {name = 'coin', count = 1}, true, nil, false)
entity.surface.spill_item_stack(entity.position, { name = 'coin', count = 1 }, true, nil, false)
end
end
if count > 0 then
for _ = 1, count, 1 do
entity.surface.spill_item_stack(entity.position, {name = 'coin', count = 1}, true, nil, false)
entity.surface.spill_item_stack(entity.position, { name = 'coin', count = 1 }, true, nil, false)
end
end
end
@ -55,9 +55,9 @@ local function get_cell_value(expanse, left_top)
value = value * 8
local source_surface = game.surfaces[expanse.source_surface]
local area = {{left_top.x, left_top.y}, {left_top.x + square_size, left_top.y + square_size}}
local area = { { left_top.x, left_top.y }, { left_top.x + square_size, left_top.y + square_size } }
local entities = source_surface.find_entities(area)
local tiles = source_surface.find_tiles_filtered({area = area})
local tiles = source_surface.find_tiles_filtered({ area = area })
for _, tile in pairs(tiles) do
if price_modifiers[tile.name] then
@ -96,13 +96,13 @@ local function get_cell_value(expanse, left_top)
end
local function get_left_top(expanse, position)
local vectors = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}}
local vectors = { { -1, 0 }, { 1, 0 }, { 0, 1 }, { 0, -1 } }
table.shuffle_table(vectors)
local surface = game.surfaces.expanse
for _, v in pairs(vectors) do
local tile = surface.get_tile({position.x + v[1], position.y + v[2]})
local tile = surface.get_tile({ position.x + v[1], position.y + v[2] })
if tile.name == 'out-of-map' then
local left_top = tile.position
left_top.x = left_top.x - left_top.x % expanse.square_size
@ -131,10 +131,10 @@ local function is_container_position_valid(expanse, position)
{
name = 'logistic-chest-requester',
force = 'neutral',
area = {{left_top.x - 1, left_top.y - 1}, {left_top.x + expanse.square_size + 1, left_top.y + expanse.square_size + 1}}
area = { { left_top.x - 1, left_top.y - 1 }, { left_top.x + expanse.square_size + 1, left_top.y + expanse.square_size + 1 } }
}
) > 0
then
then
return false
end
@ -144,27 +144,27 @@ end
local function create_costs_render(entity, name, offset)
local id =
rendering.draw_sprite {
sprite = 'virtual-signal/signal-grey',
surface = entity.surface,
target = entity,
x_scale = 1.1,
y_scale = 1.1,
render_layer = '190',
target_offset = {offset, -1.5},
only_in_alt_mode = true
}
sprite = 'virtual-signal/signal-grey',
surface = entity.surface,
target = entity,
x_scale = 1.1,
y_scale = 1.1,
render_layer = '190',
target_offset = { offset, -1.5 },
only_in_alt_mode = true
}
local id2 =
rendering.draw_sprite {
sprite = 'item/' .. name,
surface = entity.surface,
target = entity,
x_scale = 0.75,
y_scale = 0.75,
render_layer = '191',
target_offset = {offset, -1.5},
only_in_alt_mode = true
}
return {id, id2}
sprite = 'item/' .. name,
surface = entity.surface,
target = entity,
x_scale = 0.75,
y_scale = 0.75,
render_layer = '191',
target_offset = { offset, -1.5 },
only_in_alt_mode = true
}
return { id, id2 }
end
local function remove_one_render(container, key)
@ -187,41 +187,41 @@ function Public.spawn_units(spawner)
local position = spawner.position
for i = 1, 4 + math.floor(8 * evolution), 1 do
local biter_roll = BiterRaffle.roll('mixed', evolution)
local free_pos = spawner.surface.find_non_colliding_position(biter_roll, {x = position.x + math.random(-8, 8), y = position.y + math.random(-8, 8)}, 12, 0.05)
spawner.surface.create_entity({name = biter_roll, position = free_pos or position, force = 'enemy'})
local free_pos = spawner.surface.find_non_colliding_position(biter_roll, { x = position.x + math.random(-8, 8), y = position.y + math.random(-8, 8) }, 12, 0.05)
spawner.surface.create_entity({ name = biter_roll, position = free_pos or position, force = 'enemy' })
end
end
function Public.get_item_tooltip(name)
return {'expanse.stats_item_tooltip', game.item_prototypes[name].localised_name, Price_raffle.get_item_worth(name)}
return { 'expanse.stats_item_tooltip', game.item_prototypes[name].localised_name, Price_raffle.get_item_worth(name) }
end
function Public.invasion_numbers()
local evo = game.forces.enemy.evolution_factor
return {candidates = 3 + math.floor(evo * 10), groups = 1 + math.floor(evo * 4)}
return { candidates = 3 + math.floor(evo * 10), groups = 1 + math.floor(evo * 4) }
end
function Public.invasion_warn(event)
local seconds = (120 * 60 - (event.delay or 0)) / 60
game.print({'expanse.biters_invasion_warning', seconds, event.size}, {r = 0.88, g = 0.22, b = 0.22})
game.print({ 'expanse.biters_invasion_warning', seconds, event.size }, { r = 0.88, g = 0.22, b = 0.22 })
end
function Public.invasion_detonate(event)
local surface = event.surface
local position = event.position
local entities_close = surface.find_entities_filtered {position = position, radius = 8}
local entities_close = surface.find_entities_filtered { position = position, radius = 8 }
for _, entity in pairs(entities_close) do
if entity.valid then
entity.die('enemy')
end
end
local entities_nearby = surface.find_entities_filtered {position = position, radius = 16}
local entities_nearby = surface.find_entities_filtered { position = position, radius = 16 }
for _, entity in pairs(entities_nearby) do
if entity.valid and entity.is_entity_with_health then
entity.damage(entity.prototype.max_health * 0.75, 'enemy')
end
end
surface.create_entity({name = 'nuke-explosion', position = position})
surface.create_entity({ name = 'nuke-explosion', position = position })
end
function Public.invasion_trigger(event)
@ -232,40 +232,40 @@ function Public.invasion_trigger(event)
local biters = {}
for i = 1, 5 + math.floor(30 * evolution) + round * 5, 1 do
local biter_roll = BiterRaffle.roll('mixed', evolution)
local free_pos = surface.find_non_colliding_position(biter_roll, {x = position.x + math.random(-8, 8), y = position.y + math.random(-8, 8)}, 12, 0.05)
biters[#biters + 1] = surface.create_entity({name = biter_roll, position = free_pos or position, force = 'enemy'})
local free_pos = surface.find_non_colliding_position(biter_roll, { x = position.x + math.random(-8, 8), y = position.y + math.random(-8, 8) }, 12, 0.05)
biters[#biters + 1] = surface.create_entity({ name = biter_roll, position = free_pos or position, force = 'enemy' })
end
local group = surface.create_unit_group {position = position, force = 'enemy'}
local group = surface.create_unit_group { position = position, force = 'enemy' }
for _, biter in pairs(biters) do
group.add_member(biter)
end
group.set_command({type = defines.command.attack_area, destination = position, radius = 80, distraction = defines.distraction.by_anything})
group.set_command({ type = defines.command.attack_area, destination = position, radius = 80, distraction = defines.distraction.by_anything })
group.start_moving()
local worm_roll = BiterRaffle.roll('worm', evolution)
for i = 1, 3 + math.floor(7 * evolution), 1 do
local worm_pos = surface.find_non_colliding_position(worm_roll, {x = position.x + math.random(-12, 12), y = position.y + math.random(-12, 12)}, 12, 0.1)
local worm_pos = surface.find_non_colliding_position(worm_roll, { x = position.x + math.random(-12, 12), y = position.y + math.random(-12, 12) }, 12, 0.1)
if worm_pos then
surface.create_entity({name = worm_roll, position = worm_pos, force = 'enemy'})
surface.create_entity({ name = worm_roll, position = worm_pos, force = 'enemy' })
end
end
local nest = {'biter-spawner', 'biter-spawner', 'biter-spawner', 'spitter-spawner'}
local nest = { 'biter-spawner', 'biter-spawner', 'biter-spawner', 'spitter-spawner' }
local nest_roll = nest[math.random(1, 4)]
local nest_pos = surface.find_non_colliding_position(nest_roll, position, 12, 0.1)
if nest_pos then
surface.create_entity({name = nest_roll, position = nest_pos, force = 'enemy'})
surface.create_entity({ name = nest_roll, position = nest_pos, force = 'enemy' })
end
end
local function schedule_detonation(expanse, surface, position)
table.insert(expanse.schedule, {tick = game.tick + 120 * 60, event = 'invasion_detonate', parameters = {surface = surface, position = position}})
table.insert(expanse.schedule, { tick = game.tick + 120 * 60, event = 'invasion_detonate', parameters = { surface = surface, position = position } })
end
local function schedule_warning(expanse, size, delay)
table.insert(expanse.schedule, {tick = game.tick + 2 * 60 + delay, event = 'invasion_warn', parameters = {size = size, delay = delay}})
table.insert(expanse.schedule, { tick = game.tick + 2 * 60 + delay, event = 'invasion_warn', parameters = { size = size, delay = delay } })
end
local function schedule_biters(expanse, surface, position, delay, round)
table.insert(expanse.schedule, {tick = game.tick + delay + 120 * 60, event = 'invasion_trigger', parameters = {surface = surface, position = position, round = round}})
table.insert(expanse.schedule, { tick = game.tick + delay + 120 * 60, event = 'invasion_trigger', parameters = { surface = surface, position = position, round = round } })
end
local function plan_invasion(expanse, invasion_numbers)
@ -276,7 +276,9 @@ local function plan_invasion(expanse, invasion_numbers)
schedule_warning(expanse, invasion_numbers.groups, 90 * 60)
local rounds = 4 + math.random(1, 8)
for i = 1, invasion_numbers.groups, 1 do
local surface = candidates[i].surface
local surface_index = candidates[i].surface_index
if not surface_index then break end
local surface = game.get_surface(surface_index)
local position = candidates[i].position
schedule_detonation(expanse, surface, position)
for ii = 1, rounds, 1 do
@ -308,7 +310,7 @@ function Public.expand(expanse, left_top)
source_surface.force_generate_chunk_requests()
local square_size = expanse.square_size
local area = {{left_top.x, left_top.y}, {left_top.x + square_size, left_top.y + square_size}}
local area = { { left_top.x, left_top.y }, { left_top.x + square_size, left_top.y + square_size } }
local surface = game.surfaces.expanse
source_surface.clone_area(
@ -326,15 +328,15 @@ function Public.expand(expanse, left_top)
)
local positions = {
{x = left_top.x + math.random(1, square_size - 2), y = left_top.y},
{x = left_top.x, y = left_top.y + math.random(1, square_size - 2)},
{x = left_top.x + math.random(1, square_size - 2), y = left_top.y + (square_size - 1)},
{x = left_top.x + (square_size - 1), y = left_top.y + math.random(1, square_size - 2)}
{ x = left_top.x + math.random(1, square_size - 2), y = left_top.y },
{ x = left_top.x, y = left_top.y + math.random(1, square_size - 2) },
{ x = left_top.x + math.random(1, square_size - 2), y = left_top.y + (square_size - 1) },
{ x = left_top.x + (square_size - 1), y = left_top.y + math.random(1, square_size - 2) }
}
for _, position in pairs(positions) do
if is_container_position_valid(expanse, position) then
local e = surface.create_entity({name = 'logistic-chest-requester', position = position, force = 'neutral'})
local e = surface.create_entity({ name = 'logistic-chest-requester', position = position, force = 'neutral' })
e.destructible = false
e.minable = false
end
@ -344,20 +346,20 @@ function Public.expand(expanse, left_top)
local a = math.floor(expanse.square_size * 0.5)
for x = 1, 3, 1 do
for y = 1, 3, 1 do
surface.set_tiles({{name = 'water', position = {a + x + 2, a + y + 2}}}, true)
surface.set_tiles({ { name = 'water', position = { a + x + 2, a + y + 2 } } }, true)
end
end
surface.create_entity({name = 'crude-oil', position = {a - 4, a - 4}, amount = 1500000})
Task.set_timeout_in_ticks(30, delay_infini_tree_token, {surface = surface, position = {a - 4, a + 4}})
surface.create_entity({name = 'rock-big', position = {a + 4, a - 4}})
surface.spill_item_stack({a, a + 2}, {name = 'coin', count = 1}, false, nil, false)
surface.spill_item_stack({a + 0.5, a + 2.5}, {name = 'coin', count = 1}, false, nil, false)
surface.spill_item_stack({a - 0.5, a + 2.5}, {name = 'coin', count = 1}, false, nil, false)
surface.create_entity({ name = 'crude-oil', position = { a - 4, a - 4 }, amount = 1500000 })
Task.set_timeout_in_ticks(30, delay_infini_tree_token, { surface = surface, position = { a - 4, a + 4 } })
surface.create_entity({ name = 'rock-big', position = { a + 4, a - 4 } })
surface.spill_item_stack({ a, a + 2 }, { name = 'coin', count = 1 }, false, nil, false)
surface.spill_item_stack({ a + 0.5, a + 2.5 }, { name = 'coin', count = 1 }, false, nil, false)
surface.spill_item_stack({ a - 0.5, a + 2.5 }, { name = 'coin', count = 1 }, false, nil, false)
for x = 0, square_size, 1 do
for y = 0, square_size, 1 do
if surface.can_place_entity({name = 'wooden-chest', position = {x, y}}) and surface.can_place_entity({name = 'coal', position = {x, y}, amount = 1}) then
surface.create_entity({name = ores[(x + y) % 4 + 1], position = {x, y}, amount = 1500})
if surface.can_place_entity({ name = 'wooden-chest', position = { x, y } }) and surface.can_place_entity({ name = 'coal', position = { x, y }, amount = 1 }) then
surface.create_entity({ name = ores[(x + y) % 4 + 1], position = { x, y }, amount = 1500 })
end
end
end
@ -385,12 +387,12 @@ local function init_container(expanse, entity, budget)
local price = {}
local offset = -3
for k, v in pairs(item_stacks) do
table.insert(price, {name = k, count = v, render = create_costs_render(entity, k, offset)})
table.insert(price, { name = k, count = v, render = create_costs_render(entity, k, offset) })
offset = offset + 1
end
local containers = expanse.containers
containers[entity.unit_number] = {entity = entity, left_top = left_top, price = price}
containers[entity.unit_number] = { entity = entity, left_top = left_top, price = price }
end
local function get_remaining_budget(container)
@ -420,14 +422,14 @@ function Public.set_container(expanse, entity)
if not inventory.is_empty() then
local contents = inventory.get_contents()
if contents['coin'] then
local count_removed = inventory.remove({name = 'coin', count = 1})
local count_removed = inventory.remove({ name = 'coin', count = 1 })
if count_removed > 0 then
expanse.cost_stats['coin'] = (expanse.cost_stats['coin'] or 0) + count_removed
script.raise_event(expanse.events.gui_update, {item = 'coin'})
script.raise_event(expanse.events.gui_update, { item = 'coin' })
remove_old_renders(container)
init_container(expanse, entity, get_remaining_budget(container))
container = expanse.containers[entity.unit_number]
game.print({'expanse.chest_reset', {'expanse.gps', math.floor(entity.position.x), math.floor(entity.position.y), 'expanse'}})
game.print({ 'expanse.chest_reset', { 'expanse.gps', math.floor(entity.position.x), math.floor(entity.position.y), 'expanse' } })
end
end
if contents['infinity-chest'] then
@ -438,10 +440,10 @@ function Public.set_container(expanse, entity)
for key, item_stack in pairs(container.price) do
local name = item_stack.name
local count_removed = inventory.remove({name = name, count = item_stack.count})
local count_removed = inventory.remove({ name = name, count = item_stack.count })
container.price[key].count = container.price[key].count - count_removed
expanse.cost_stats[name] = (expanse.cost_stats[name] or 0) + count_removed
script.raise_event(expanse.events.gui_update, {item = name})
script.raise_event(expanse.events.gui_update, { item = name })
if container.price[key].count <= 0 then
remove_one_render(container, key)
table.remove(container.price, key)
@ -451,11 +453,11 @@ function Public.set_container(expanse, entity)
if #container.price == 0 then
Public.expand(expanse, container.left_top)
local a = math.floor(expanse.square_size * 0.5)
local expansion_position = {x = expanse.containers[entity.unit_number].left_top.x + a, y = expanse.containers[entity.unit_number].left_top.y + a}
local expansion_position = { x = expanse.containers[entity.unit_number].left_top.x + a, y = expanse.containers[entity.unit_number].left_top.y + a }
expanse.containers[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)
entity.surface.spill_item_stack(entity.position, { name = name, count = count }, true, nil, false)
end
end
reward_tokens(expanse, entity)

View File

@ -1,483 +1,484 @@
-- a map where you feed hungry boxes, which unlocks new territory, with even more hungry boxes by mewmew
--CONFIGS
local cell_size = 15 -- size of each territory to unlock
local chance_to_receive_token = 0.20 -- chance of a hungry chest, dropping a token after unlocking, can be above 1 for multiple
require 'modules.satellite_score'
require 'modules.backpack_research'
local Event = require 'utils.event'
local Functions = require 'maps.expanse.functions'
local GetNoise = require 'utils.get_noise'
local Global = require 'utils.global'
local Map_info = require 'modules.map_info'
local Gui = require 'utils.gui'
local format_number = require 'util'.format_number
local Random = require 'maps.chronosphere.random'
local Autostash = require 'modules.autostash'
local expanse = {
events = {
gui_update = Event.generate_event_name('expanse_gui_update'),
invasion_warn = Event.generate_event_name('invasion_warn'),
invasion_detonate = Event.generate_event_name('invasion_detonate'),
invasion_trigger = Event.generate_event_name('invasion_trigger')
}
}
Global.register(
expanse,
function(tbl)
expanse = tbl
end
)
local main_button_name = Gui.uid_name()
local main_frame_name = Gui.uid_name()
local function create_button(player)
if not player.gui.top[main_button_name] then
local b =
player.gui.top.add(
{
type = 'sprite-button',
name = main_button_name,
sprite = 'item/logistic-chest-requester',
tooltip = 'Show Expanse statistics!'
}
)
b.style.minimal_height = 38
b.style.maximal_height = 38
end
end
local function set_nauvis()
local surface = game.surfaces[1]
local map_gen_settings = surface.map_gen_settings
map_gen_settings.autoplace_controls = {
['coal'] = {frequency = 6, size = 0.7, richness = 0.5},
['stone'] = {frequency = 6, size = 0.4, richness = 0.5},
['copper-ore'] = {frequency = 6, size = 0.7, richness = 0.95},
['iron-ore'] = {frequency = 6, size = 0.7, richness = 1},
['uranium-ore'] = {frequency = 10, size = 0.7, richness = 1},
['crude-oil'] = {frequency = 20, size = 1.5, richness = 1.5},
['trees'] = {frequency = 1.75, size = 1.25, richness = 1},
['enemy-base'] = {frequency = 10, size = 10, richness = 2}
}
map_gen_settings.water = 0.25
map_gen_settings.terrain_segmentation = 12
map_gen_settings.starting_area = 0.08
surface.map_gen_settings = map_gen_settings
for chunk in surface.get_chunks() do
surface.delete_chunk({chunk.x, chunk.y})
end
end
local function reset()
expanse.grid = {}
expanse.containers = {}
expanse.cost_stats = {}
expanse.invasion_candidates = {}
expanse.schedule = {}
expanse.size = 1
expanse.acid_tank = nil
Autostash.insert_into_furnace(true)
local map_gen_settings = {
['water'] = 0,
['starting_area'] = 1,
['cliff_settings'] = {cliff_elevation_interval = 0, cliff_elevation_0 = 0},
['default_enable_all_autoplace_controls'] = false,
['autoplace_settings'] = {
['entity'] = {treat_missing_as_default = false},
['tile'] = {treat_missing_as_default = false},
['decorative'] = {treat_missing_as_default = false}
},
autoplace_controls = {
['coal'] = {frequency = 0, size = 0, richness = 0},
['stone'] = {frequency = 0, size = 0, richness = 0},
['copper-ore'] = {frequency = 0, size = 0, richness = 0},
['iron-ore'] = {frequency = 0, size = 0, richness = 0},
['uranium-ore'] = {frequency = 0, size = 0, richness = 0},
['crude-oil'] = {frequency = 0, size = 0, richness = 0},
['trees'] = {frequency = 0, size = 0, richness = 0},
['enemy-base'] = {frequency = 0, size = 0, richness = 0}
}
}
game.create_surface('expanse', map_gen_settings)
if expanse.override_nauvis then
set_nauvis()
end
local source_surface = game.surfaces[expanse.source_surface]
source_surface.request_to_generate_chunks({x = 0, y = 0}, 4)
source_surface.force_generate_chunk_requests()
local surface = game.surfaces.expanse
surface.request_to_generate_chunks({x = 0, y = 0}, 4)
surface.force_generate_chunk_requests()
for _, player in pairs(game.players) do
player.teleport({-4, -4}, source_surface)
end
Functions.expand(expanse, {x = 0, y = 0})
for _, player in pairs(game.players) do
player.teleport(surface.find_non_colliding_position('character', {expanse.square_size * 0.5, expanse.square_size * 0.5}, 8, 0.5), surface)
end
end
local ores = {'copper-ore', 'iron-ore', 'stone', 'coal', 'iron-ore', 'copper-ore', 'coal'}
local function generate_ore(surface, left_top)
local seed = game.surfaces[1].map_gen_settings.seed
local left_top_x = left_top.x
local left_top_y = left_top.y
--Draw the mixed ore patches.
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local pos = {x = left_top_x + x, y = left_top_y + y}
if surface.can_place_entity({name = 'iron-ore', position = pos}) then
local noise = GetNoise('smol_areas', pos, seed)
if math.abs(noise) > 0.78 or math.abs(noise) < 0.11 then
local amount = 500 + math.sqrt(pos.x ^ 2 + pos.y ^ 2) * 4
local i = math.floor(noise * 40 + math.abs(pos.x) * 0.05) % 7 + 1
surface.create_entity({name = ores[i], position = pos, amount = amount})
end
end
end
end
end
local function on_resource_depleted(event)
local ore = event.entity
if ore and ore.valid then
local distance = math.sqrt(ore.position.x ^ 2 + ore.position.y ^ 2)
if ore.name == 'stone' and distance > 150 then
if math.random(1, 4) == 1 then
ore.surface.create_entity({name = 'uranium-ore', position = ore.position, amount = 20 + math.floor(distance / 2)})
end
end
end
end
local function on_chunk_generated(event)
local surface = event.surface
if surface.name ~= 'expanse' then
if expanse.override_nauvis then
if surface.index == 1 then
for _, e in pairs(surface.find_entities_filtered({area = event.area, name = {'iron-ore', 'copper-ore', 'coal', 'stone', 'uranium-ore'}})) do
surface.create_entity({name = e.name, position = e.position, amount = 500 + math.sqrt(e.position.x ^ 2 + e.position.y ^ 2) * 3})
e.destroy()
end
generate_ore(surface, event.area.left_top)
for _, unit in pairs(surface.find_entities_filtered({area = event.area, type = {'unit', 'turret', 'unit-spawner', 'fish'}, force = {'enemy', 'neutral'}})) do
unit.active = false
end
end
end
return
end
local left_top = event.area.left_top
local tiles = {}
local i = 1
if left_top.x == 0 and left_top.y == 0 then
for x = 0, 31, 1 do
for y = 0, 31, 1 do
if x >= expanse.square_size or y >= expanse.square_size then
tiles[i] = {name = 'out-of-map', position = {left_top.x + x, left_top.y + y}}
i = i + 1
end
end
end
else
for x = 0, 31, 1 do
for y = 0, 31, 1 do
tiles[i] = {name = 'out-of-map', position = {left_top.x + x, left_top.y + y}}
i = i + 1
end
end
end
surface.set_tiles(tiles, true)
end
local function on_area_cloned(event)
local source_surface = event.source_surface
local dest_surface = event.destination_surface
for _, cloned_entity in pairs(dest_surface.find_entities(event.destination_area)) do
cloned_entity.active = true
if cloned_entity.type == 'unit-spawner' then
Functions.spawn_units(cloned_entity)
end
end
for _, source_entity in pairs(source_surface.find_entities(event.source_area)) do
source_entity.destroy()
end
end
local function container_opened(event)
local entity = event.entity
if not entity then
return
end
if not entity.valid then
return
end
if not entity.unit_number then
return
end
if entity.force.index ~= 3 then
return
end
local expansion_position = Functions.set_container(expanse, entity)
if expansion_position then
local player = game.players[event.player_index]
local colored_player_name = {'expanse.colored_text', player.color.r * 0.6 + 0.35, player.color.g * 0.6 + 0.35, player.color.b * 0.6 + 0.35, player.name}
game.print({'expanse.tile_unlock', colored_player_name, {'expanse.gps', math.floor(expansion_position.x), math.floor(expansion_position.y), 'expanse'}})
expanse.size = (expanse.size or 1) + 1
if math.random(1, 4) == 1 then
if player.surface.count_tiles_filtered({position = expansion_position, radius = 6, collision_mask = 'water-tile'}) > 40 then
return
end
local render = rendering.draw_sprite{
sprite = 'utility/danger_icon',
surface = player.surface,
target = expansion_position,
x_scale = 2,
y_scale = 2
}
table.insert(expanse.invasion_candidates, {surface = player.surface, position = expansion_position, render = render})
Functions.check_invasion(expanse)
end
end
end
local function on_gui_opened(event)
container_opened(event)
end
local function on_gui_closed(event)
container_opened(event)
end
local function assign_acid_tank(entity)
local tanks = entity.surface.find_entities_filtered{name = 'storage-tank', position = entity.position, radius = 8}
for _, tank in pairs(tanks) do
if tank.get_fluid_count('sulfuric-acid') > 0 then
return tank
end
end
return nil
end
local function uranium_mining(entity)
if not game.forces.player.technologies['uranium-processing'].researched then return end
if not expanse.acid_tank or not expanse.acid_tank.valid then
expanse.acid_tank = assign_acid_tank(entity)
end
local tank = expanse.acid_tank
if tank and tank.valid then
local acid = tank.get_fluid_count('sulfuric-acid')
if acid > 5 then
tank.remove_fluid{name = 'sulfuric-acid', amount = 4}
entity.surface.spill_item_stack(entity.position, {name = 'uranium-ore', count = 2}, true, nil, true)
entity.surface.create_entity{name = 'flying-text', position = tank.position, text = '-4 [fluid=sulfuric-acid]', color = {r = 0.88, g = 0.02, b = 0.02}}
end
end
end
local inf_ores = {'iron-ore', 'iron-ore', 'copper-ore', 'coal'}
local function infini_rock(entity)
if entity.type ~= 'simple-entity' then
return
end
local a = math.floor(expanse.square_size * 0.5)
if entity.position.x == a + 4 and entity.position.y == a - 4 then
entity.surface.create_entity({name = 'rock-big', position = {a + 4, a - 4}})
entity.surface.spill_item_stack(entity.position, {name = inf_ores[math.random(1, 4)], 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)
uranium_mining(entity)
end
end
local function infini_tree(entity)
if entity.type ~= 'tree' then
return
end
local a = math.floor(expanse.square_size * 0.5)
if entity.position.x == a - 4 and entity.position.y == a + 4 then
entity.surface.create_entity({name = 'tree-0' .. math.random(1, 9), position = {a - 4, a + 4}})
end
end
local function infini_resource(event)
local entity = event.entity
if not entity.valid then
return
end
infini_rock(entity)
infini_tree(entity)
end
local function on_player_joined_game(event)
local player = game.players[event.player_index]
if player.online_time == 0 then
local surface = game.surfaces.expanse
player.teleport(surface.find_non_colliding_position('character', {expanse.square_size * 0.5, expanse.square_size * 0.5}, 32, 0.5), surface)
end
create_button(player)
end
local function on_pre_player_left_game(event)
local player = game.players[event.player_index]
if not player.character then
return
end
if not player.character.valid then
return
end
local inventory = player.get_main_inventory()
if not inventory then
return
end
local removed_count = inventory.remove({name = 'coin', count = 999999})
if removed_count > 0 then
for _ = 1, removed_count, 1 do
player.surface.spill_item_stack(player.position, {name = 'coin', count = 1}, false, nil, false)
end
game.print({'expanse.tokens_dropped', player.name, {'expanse.gps', math.floor(player.position.x), math.floor(player.position.y), player.surface.name}})
end
end
local function on_init()
local T = Map_info.Pop_info()
T.localised_category = 'expanse'
T.main_caption_color = {r = 170, g = 170, b = 0}
T.sub_caption_color = {r = 120, g = 120, b = 0}
if not expanse.source_surface then
expanse.source_surface = 'nauvis'
end
if not expanse.token_chance then
expanse.token_chance = chance_to_receive_token
end
if not expanse.price_distance_modifier then
expanse.price_distance_modifier = 0.006
end
if not expanse.max_ore_price_modifier then
expanse.max_ore_price_modifier = 0.33
end
if not expanse.square_size then
expanse.square_size = cell_size
end
expanse.override_nauvis = true -- adds custom mixed ores and raises frequency of resources
game.map_settings.enemy_expansion.enabled = true
game.map_settings.enemy_expansion.max_expansion_cooldown = 1800
game.map_settings.enemy_expansion.min_expansion_cooldown = 1800
game.map_settings.enemy_expansion.settler_group_max_size = 8
game.map_settings.enemy_expansion.settler_group_min_size = 16
game.map_settings.enemy_evolution.destroy_factor = 0.003 --default game: 0.002
game.map_settings.enemy_evolution.pollution_factor = 6e-07 --default game: 9e-07
game.map_settings.enemy_evolution.time_factor = 2e-06 --default game: 4e-06
--Settings for cave miner
--[[
expanse.override_nauvis = false
expanse.token_chance = 0.75
expanse.price_distance_modifier = 0.0035
expanse.max_ore_price_modifier = 0.25
game.forces.player.technologies.landfill.researched = true
]]
reset()
end
local function on_tick()
if not next(expanse.schedule) then return end
for index, stuff in pairs(expanse.schedule) do
if game.tick >= stuff.tick then
script.raise_event(expanse.events[stuff.event], stuff.parameters)
expanse.schedule[index] = nil
end
end
end
local function resource_stats(parent, name, count)
local button = parent.add({type = 'sprite-button', name = name .. '_sprite', sprite = 'item/' .. name, enabled = false, tooltip = Functions.get_item_tooltip(name)})
local label = parent.add({type = 'label', name = name .. '_label', caption = format_number(tonumber(count), true), tooltip = count})
label.style.width = 40
return button, label
end
local function create_main_frame(player)
local frame = player.gui.screen.add({type = 'frame', name = main_frame_name, caption = {'expanse.stats_gui'}, direction = 'vertical'})
frame.location = {x = 10, y = 40}
frame.style.maximal_height = 600
local invasion_numbers = Functions.invasion_numbers()
frame.add({type = 'label', name = 'size', caption = {'expanse.stats_size', expanse.size or 1}})
frame.add({type = 'label', name = 'biters', caption = {'expanse.stats_attack', #expanse.invasion_candidates, invasion_numbers.candidates, invasion_numbers.groups}})
local scroll = frame.add({type = 'scroll-pane', name = 'scroll_pane', horizontal_scroll_policy = 'never', vertical_scroll_policy = 'auto-and-reserve-space'})
local frame_table = scroll.add({type = 'table', name = 'resource_stats', column_count = 8})
for name, count in Random.spairs(expanse.cost_stats, function(t,a,b) return t[a] > t[b] end) do
resource_stats(frame_table, name, count)
end
end
local function update_resource_gui(event)
for _, player in pairs(game.connected_players) do
if player.gui.screen[main_frame_name] then
local frame = player.gui.screen[main_frame_name]
local invasion_numbers = Functions.invasion_numbers()
frame['size'].caption = {'expanse.stats_size', expanse.size or 1}
frame['biters'].caption = {'expanse.stats_attack', #expanse.invasion_candidates, invasion_numbers.candidates, invasion_numbers.groups}
local frame_table = frame['scroll_pane']['resource_stats']
local count = expanse.cost_stats[event.item] or 0
if not frame_table[event.item .. '_label'] then
resource_stats(frame_table, event.item, count)
else
frame_table[event.item .. '_label'].caption = format_number(tonumber(count), true)
frame_table[event.item .. '_label'].tooltip = count
end
end
end
end
local function on_gui_click(event)
local element = event.element
if not element.valid then
return
end
local name = element.name
if name == main_button_name then
local player = game.players[event.player_index]
if player.gui.screen[main_frame_name] then
player.gui.screen[main_frame_name].destroy()
else
create_main_frame(player)
end
end
end
Event.on_init(on_init)
Event.on_nth_tick(60, on_tick)
Event.add(defines.events.on_chunk_generated, on_chunk_generated)
Event.add(defines.events.on_area_cloned, on_area_cloned)
Event.add(defines.events.on_resource_depleted, on_resource_depleted)
Event.add(defines.events.on_entity_died, infini_resource)
Event.add(defines.events.on_gui_closed, on_gui_closed)
Event.add(defines.events.on_gui_opened, on_gui_opened)
Event.add(defines.events.on_gui_click, on_gui_click)
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
Event.add(defines.events.on_pre_player_left_game, on_pre_player_left_game)
Event.add(defines.events.on_pre_player_mined_item, infini_resource)
Event.add(defines.events.on_robot_pre_mined, infini_resource)
Event.add(expanse.events.gui_update, update_resource_gui)
Event.add(expanse.events.invasion_warn, Functions.invasion_warn)
Event.add(expanse.events.invasion_detonate, Functions.invasion_detonate)
Event.add(expanse.events.invasion_trigger, Functions.invasion_trigger)
-- a map where you feed hungry boxes, which unlocks new territory, with even more hungry boxes by mewmew
--CONFIGS
local cell_size = 15 -- size of each territory to unlock
local chance_to_receive_token = 0.20 -- chance of a hungry chest, dropping a token after unlocking, can be above 1 for multiple
require 'modules.satellite_score'
require 'modules.backpack_research'
local Event = require 'utils.event'
local Functions = require 'maps.expanse.functions'
local GetNoise = require 'utils.get_noise'
local Global = require 'utils.global'
local Map_info = require 'modules.map_info'
local Gui = require 'utils.gui'
local format_number = require 'util'.format_number
local Random = require 'maps.chronosphere.random'
local Autostash = require 'modules.autostash'
local expanse = {
events = {
gui_update = Event.generate_event_name('expanse_gui_update'),
invasion_warn = Event.generate_event_name('invasion_warn'),
invasion_detonate = Event.generate_event_name('invasion_detonate'),
invasion_trigger = Event.generate_event_name('invasion_trigger')
}
}
Global.register(
expanse,
function (tbl)
expanse = tbl
end
)
local main_button_name = Gui.uid_name()
local main_frame_name = Gui.uid_name()
local function create_button(player)
if not player.gui.top[main_button_name] then
local b =
player.gui.top.add(
{
type = 'sprite-button',
name = main_button_name,
sprite = 'item/logistic-chest-requester',
tooltip = 'Show Expanse statistics!'
}
)
b.style.minimal_height = 38
b.style.maximal_height = 38
end
end
local function set_nauvis()
local surface = game.surfaces[1]
local map_gen_settings = surface.map_gen_settings
map_gen_settings.autoplace_controls = {
['coal'] = { frequency = 6, size = 0.7, richness = 0.5 },
['stone'] = { frequency = 6, size = 0.4, richness = 0.5 },
['copper-ore'] = { frequency = 6, size = 0.7, richness = 0.95 },
['iron-ore'] = { frequency = 6, size = 0.7, richness = 1 },
['uranium-ore'] = { frequency = 10, size = 0.7, richness = 1 },
['crude-oil'] = { frequency = 20, size = 1.5, richness = 1.5 },
['trees'] = { frequency = 1.75, size = 1.25, richness = 1 },
['enemy-base'] = { frequency = 10, size = 10, richness = 2 }
}
map_gen_settings.water = 0.25
map_gen_settings.terrain_segmentation = 12
map_gen_settings.starting_area = 0.08
surface.map_gen_settings = map_gen_settings
for chunk in surface.get_chunks() do
surface.delete_chunk({ chunk.x, chunk.y })
end
end
local function reset()
expanse.grid = {}
expanse.containers = {}
expanse.cost_stats = {}
expanse.invasion_candidates = {}
expanse.schedule = {}
expanse.size = 1
expanse.acid_tank = nil
Autostash.insert_into_furnace(true)
local map_gen_settings = {
['water'] = 0,
['starting_area'] = 1,
['cliff_settings'] = { cliff_elevation_interval = 0, cliff_elevation_0 = 0 },
['default_enable_all_autoplace_controls'] = false,
['autoplace_settings'] = {
['entity'] = { treat_missing_as_default = false },
['tile'] = { treat_missing_as_default = false },
['decorative'] = { treat_missing_as_default = false }
},
autoplace_controls = {
['coal'] = { frequency = 0, size = 0, richness = 0 },
['stone'] = { frequency = 0, size = 0, richness = 0 },
['copper-ore'] = { frequency = 0, size = 0, richness = 0 },
['iron-ore'] = { frequency = 0, size = 0, richness = 0 },
['uranium-ore'] = { frequency = 0, size = 0, richness = 0 },
['crude-oil'] = { frequency = 0, size = 0, richness = 0 },
['trees'] = { frequency = 0, size = 0, richness = 0 },
['enemy-base'] = { frequency = 0, size = 0, richness = 0 }
}
}
game.create_surface('expanse', map_gen_settings)
if expanse.override_nauvis then
set_nauvis()
end
local source_surface = game.surfaces[expanse.source_surface]
source_surface.request_to_generate_chunks({ x = 0, y = 0 }, 4)
source_surface.force_generate_chunk_requests()
local surface = game.surfaces.expanse
surface.request_to_generate_chunks({ x = 0, y = 0 }, 4)
surface.force_generate_chunk_requests()
for _, player in pairs(game.players) do
player.teleport({ -4, -4 }, source_surface)
end
Functions.expand(expanse, { x = 0, y = 0 })
for _, player in pairs(game.players) do
player.teleport(surface.find_non_colliding_position('character', { expanse.square_size * 0.5, expanse.square_size * 0.5 }, 8, 0.5), surface)
end
end
local ores = { 'copper-ore', 'iron-ore', 'stone', 'coal', 'iron-ore', 'copper-ore', 'coal' }
local function generate_ore(surface, left_top)
local seed = game.surfaces[1].map_gen_settings.seed
local left_top_x = left_top.x
local left_top_y = left_top.y
--Draw the mixed ore patches.
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local pos = { x = left_top_x + x, y = left_top_y + y }
if surface.can_place_entity({ name = 'iron-ore', position = pos }) then
local noise = GetNoise('smol_areas', pos, seed)
if math.abs(noise) > 0.78 or math.abs(noise) < 0.11 then
local amount = 500 + math.sqrt(pos.x ^ 2 + pos.y ^ 2) * 4
local i = math.floor(noise * 40 + math.abs(pos.x) * 0.05) % 7 + 1
surface.create_entity({ name = ores[i], position = pos, amount = amount })
end
end
end
end
end
local function on_resource_depleted(event)
local ore = event.entity
if ore and ore.valid then
local distance = math.sqrt(ore.position.x ^ 2 + ore.position.y ^ 2)
if ore.name == 'stone' and distance > 150 then
if math.random(1, 4) == 1 then
ore.surface.create_entity({ name = 'uranium-ore', position = ore.position, amount = 20 + math.floor(distance / 2) })
end
end
end
end
local function on_chunk_generated(event)
local surface = event.surface
if surface.name ~= 'expanse' then
if expanse.override_nauvis then
if surface.index == 1 then
for _, e in pairs(surface.find_entities_filtered({ area = event.area, name = { 'iron-ore', 'copper-ore', 'coal', 'stone', 'uranium-ore' } })) do
surface.create_entity({ name = e.name, position = e.position, amount = 500 + math.sqrt(e.position.x ^ 2 + e.position.y ^ 2) * 3 })
e.destroy()
end
generate_ore(surface, event.area.left_top)
for _, unit in pairs(surface.find_entities_filtered({ area = event.area, type = { 'unit', 'turret', 'unit-spawner', 'fish' }, force = { 'enemy', 'neutral' } })) do
unit.active = false
end
end
end
return
end
local left_top = event.area.left_top
local tiles = {}
local i = 1
if left_top.x == 0 and left_top.y == 0 then
for x = 0, 31, 1 do
for y = 0, 31, 1 do
if x >= expanse.square_size or y >= expanse.square_size then
tiles[i] = { name = 'out-of-map', position = { left_top.x + x, left_top.y + y } }
i = i + 1
end
end
end
else
for x = 0, 31, 1 do
for y = 0, 31, 1 do
tiles[i] = { name = 'out-of-map', position = { left_top.x + x, left_top.y + y } }
i = i + 1
end
end
end
surface.set_tiles(tiles, true)
end
local function on_area_cloned(event)
local source_surface = event.source_surface
local dest_surface = event.destination_surface
for _, cloned_entity in pairs(dest_surface.find_entities(event.destination_area)) do
cloned_entity.active = true
if cloned_entity.type == 'unit-spawner' then
Functions.spawn_units(cloned_entity)
end
end
for _, source_entity in pairs(source_surface.find_entities(event.source_area)) do
source_entity.destroy()
end
end
local function container_opened(event)
local entity = event.entity
if not entity then
return
end
if not entity.valid then
return
end
if not entity.unit_number then
return
end
if entity.force.index ~= 3 then
return
end
local expansion_position = Functions.set_container(expanse, entity)
if expansion_position then
local player = game.players[event.player_index]
local surface = game.get_surface(player.surface.name)
local colored_player_name = { 'expanse.colored_text', player.color.r * 0.6 + 0.35, player.color.g * 0.6 + 0.35, player.color.b * 0.6 + 0.35, player.name }
game.print({ 'expanse.tile_unlock', colored_player_name, { 'expanse.gps', math.floor(expansion_position.x), math.floor(expansion_position.y), 'expanse' } })
expanse.size = (expanse.size or 1) + 1
if math.random(1, 4) == 1 then
if surface.count_tiles_filtered({ position = expansion_position, radius = 6, collision_mask = 'water-tile' }) > 40 then
return
end
local render = rendering.draw_sprite {
sprite = 'utility/danger_icon',
surface = surface,
target = expansion_position,
x_scale = 2,
y_scale = 2
}
table.insert(expanse.invasion_candidates, { surface_index = surface.index, position = expansion_position, render = render })
Functions.check_invasion(expanse)
end
end
end
local function on_gui_opened(event)
container_opened(event)
end
local function on_gui_closed(event)
container_opened(event)
end
local function assign_acid_tank(entity)
local tanks = entity.surface.find_entities_filtered { name = 'storage-tank', position = entity.position, radius = 8 }
for _, tank in pairs(tanks) do
if tank.get_fluid_count('sulfuric-acid') > 0 then
return tank
end
end
return nil
end
local function uranium_mining(entity)
if not game.forces.player.technologies['uranium-processing'].researched then return end
if not expanse.acid_tank or not expanse.acid_tank.valid then
expanse.acid_tank = assign_acid_tank(entity)
end
local tank = expanse.acid_tank
if tank and tank.valid then
local acid = tank.get_fluid_count('sulfuric-acid')
if acid > 5 then
tank.remove_fluid { name = 'sulfuric-acid', amount = 4 }
entity.surface.spill_item_stack(entity.position, { name = 'uranium-ore', count = 2 }, true, nil, true)
entity.surface.create_entity { name = 'flying-text', position = tank.position, text = '-4 [fluid=sulfuric-acid]', color = { r = 0.88, g = 0.02, b = 0.02 } }
end
end
end
local inf_ores = { 'iron-ore', 'iron-ore', 'copper-ore', 'coal' }
local function infini_rock(entity)
if entity.type ~= 'simple-entity' then
return
end
local a = math.floor(expanse.square_size * 0.5)
if entity.position.x == a + 4 and entity.position.y == a - 4 then
entity.surface.create_entity({ name = 'rock-big', position = { a + 4, a - 4 } })
entity.surface.spill_item_stack(entity.position, { name = inf_ores[math.random(1, 4)], 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)
uranium_mining(entity)
end
end
local function infini_tree(entity)
if entity.type ~= 'tree' then
return
end
local a = math.floor(expanse.square_size * 0.5)
if entity.position.x == a - 4 and entity.position.y == a + 4 then
entity.surface.create_entity({ name = 'tree-0' .. math.random(1, 9), position = { a - 4, a + 4 } })
end
end
local function infini_resource(event)
local entity = event.entity
if not entity.valid then
return
end
infini_rock(entity)
infini_tree(entity)
end
local function on_player_joined_game(event)
local player = game.players[event.player_index]
if player.online_time == 0 then
local surface = game.surfaces.expanse
player.teleport(surface.find_non_colliding_position('character', { expanse.square_size * 0.5, expanse.square_size * 0.5 }, 32, 0.5), surface)
end
create_button(player)
end
local function on_pre_player_left_game(event)
local player = game.players[event.player_index]
if not player.character then
return
end
if not player.character.valid then
return
end
local inventory = player.get_main_inventory()
if not inventory then
return
end
local removed_count = inventory.remove({ name = 'coin', count = 999999 })
if removed_count > 0 then
for _ = 1, removed_count, 1 do
player.surface.spill_item_stack(player.position, { name = 'coin', count = 1 }, false, nil, false)
end
game.print({ 'expanse.tokens_dropped', player.name, { 'expanse.gps', math.floor(player.position.x), math.floor(player.position.y), player.surface.name } })
end
end
local function on_init()
local T = Map_info.Pop_info()
T.localised_category = 'expanse'
T.main_caption_color = { r = 170, g = 170, b = 0 }
T.sub_caption_color = { r = 120, g = 120, b = 0 }
if not expanse.source_surface then
expanse.source_surface = 'nauvis'
end
if not expanse.token_chance then
expanse.token_chance = chance_to_receive_token
end
if not expanse.price_distance_modifier then
expanse.price_distance_modifier = 0.006
end
if not expanse.max_ore_price_modifier then
expanse.max_ore_price_modifier = 0.33
end
if not expanse.square_size then
expanse.square_size = cell_size
end
expanse.override_nauvis = true -- adds custom mixed ores and raises frequency of resources
game.map_settings.enemy_expansion.enabled = true
game.map_settings.enemy_expansion.max_expansion_cooldown = 1800
game.map_settings.enemy_expansion.min_expansion_cooldown = 1800
game.map_settings.enemy_expansion.settler_group_max_size = 8
game.map_settings.enemy_expansion.settler_group_min_size = 16
game.map_settings.enemy_evolution.destroy_factor = 0.003 --default game: 0.002
game.map_settings.enemy_evolution.pollution_factor = 6e-07 --default game: 9e-07
game.map_settings.enemy_evolution.time_factor = 2e-06 --default game: 4e-06
--Settings for cave miner
--[[
expanse.override_nauvis = false
expanse.token_chance = 0.75
expanse.price_distance_modifier = 0.0035
expanse.max_ore_price_modifier = 0.25
game.forces.player.technologies.landfill.researched = true
]]
reset()
end
local function on_tick()
if not next(expanse.schedule) then return end
for index, stuff in pairs(expanse.schedule) do
if game.tick >= stuff.tick then
script.raise_event(expanse.events[stuff.event], stuff.parameters)
expanse.schedule[index] = nil
end
end
end
local function resource_stats(parent, name, count)
local button = parent.add({ type = 'sprite-button', name = name .. '_sprite', sprite = 'item/' .. name, enabled = false, tooltip = Functions.get_item_tooltip(name) })
local label = parent.add({ type = 'label', name = name .. '_label', caption = format_number(tonumber(count), true), tooltip = count })
label.style.width = 40
return button, label
end
local function create_main_frame(player)
local frame = player.gui.screen.add({ type = 'frame', name = main_frame_name, caption = { 'expanse.stats_gui' }, direction = 'vertical' })
frame.location = { x = 10, y = 40 }
frame.style.maximal_height = 600
local invasion_numbers = Functions.invasion_numbers()
frame.add({ type = 'label', name = 'size', caption = { 'expanse.stats_size', expanse.size or 1 } })
frame.add({ type = 'label', name = 'biters', caption = { 'expanse.stats_attack', #expanse.invasion_candidates, invasion_numbers.candidates, invasion_numbers.groups } })
local scroll = frame.add({ type = 'scroll-pane', name = 'scroll_pane', horizontal_scroll_policy = 'never', vertical_scroll_policy = 'auto-and-reserve-space' })
local frame_table = scroll.add({ type = 'table', name = 'resource_stats', column_count = 8 })
for name, count in Random.spairs(expanse.cost_stats, function (t, a, b) return t[a] > t[b] end) do
resource_stats(frame_table, name, count)
end
end
local function update_resource_gui(event)
for _, player in pairs(game.connected_players) do
if player.gui.screen[main_frame_name] then
local frame = player.gui.screen[main_frame_name]
local invasion_numbers = Functions.invasion_numbers()
frame['size'].caption = { 'expanse.stats_size', expanse.size or 1 }
frame['biters'].caption = { 'expanse.stats_attack', #expanse.invasion_candidates, invasion_numbers.candidates, invasion_numbers.groups }
local frame_table = frame['scroll_pane']['resource_stats']
local count = expanse.cost_stats[event.item] or 0
if not frame_table[event.item .. '_label'] then
resource_stats(frame_table, event.item, count)
else
frame_table[event.item .. '_label'].caption = format_number(tonumber(count), true)
frame_table[event.item .. '_label'].tooltip = count
end
end
end
end
local function on_gui_click(event)
local element = event.element
if not element.valid then
return
end
local name = element.name
if name == main_button_name then
local player = game.players[event.player_index]
if player.gui.screen[main_frame_name] then
player.gui.screen[main_frame_name].destroy()
else
create_main_frame(player)
end
end
end
Event.on_init(on_init)
Event.on_nth_tick(60, on_tick)
Event.add(defines.events.on_chunk_generated, on_chunk_generated)
Event.add(defines.events.on_area_cloned, on_area_cloned)
Event.add(defines.events.on_resource_depleted, on_resource_depleted)
Event.add(defines.events.on_entity_died, infini_resource)
Event.add(defines.events.on_gui_closed, on_gui_closed)
Event.add(defines.events.on_gui_opened, on_gui_opened)
Event.add(defines.events.on_gui_click, on_gui_click)
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
Event.add(defines.events.on_pre_player_left_game, on_pre_player_left_game)
Event.add(defines.events.on_pre_player_mined_item, infini_resource)
Event.add(defines.events.on_robot_pre_mined, infini_resource)
Event.add(expanse.events.gui_update, update_resource_gui)
Event.add(expanse.events.invasion_warn, Functions.invasion_warn)
Event.add(expanse.events.invasion_detonate, Functions.invasion_detonate)
Event.add(expanse.events.invasion_trigger, Functions.invasion_trigger)