1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-22 03:38:48 +02:00

Merge branch 'master' into master

This commit is contained in:
MewMew 2019-09-22 11:20:06 +02:00 committed by GitHub
commit 7a18032d7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 864 additions and 281 deletions

View File

@ -25,6 +25,7 @@ require "modules.floaty_chat"
---- enable modules here ----
--require "tools.cheat_mode"
--require "modules.the_floor_is_lava"
--require "modules.biters_landfill_on_death"
--require "modules.autodecon_when_depleted"
--require "modules.biter_noms_you"
--require "modules.biters_avoid_damage"
@ -51,15 +52,17 @@ require "modules.floaty_chat"
--require "modules.surrounded_by_worms"
--require "modules.more_attacks"
--require "modules.evolution_extended"
--require "modules.shopping_chests"
-----------------------------
---- enable maps here ----
--require "maps.fish_defender.main"
--require "maps.biter_battles_v2.biter_battles_v2"
--require "maps.island_troopers.main"
--require "maps.tank_conquest.tank_conquest"
--require "maps.territorial_control"
--require "maps.cave_choppy.cave_miner"
require "maps.biter_battles_v2.biter_battles_v2"
--require "maps.biter_battles.biter_battles"
--require "maps.fish_defender.fish_defender"
--require "maps.wave_of_death.WoD"
--require "maps.stone_maze.main"
--require "maps.overgrowth"

View File

@ -64,9 +64,12 @@ function noise_vector_tile_path(surface, tile_name, position, base_vector, lengt
for _, v in pairs(brush_vectors) do
local p = {x = position.x + v[1], y = position.y + v[2]}
if whitelist then
if whitelist[surface.get_tile(p).name] then
surface.set_tiles({{name = tile_name, position = p}}, true)
tiles[#tiles + 1] = {name = tile_name, position = p}
local tile = surface.get_tile(p)
if tile.valid then
if whitelist[tile.name] then
surface.set_tiles({{name = tile_name, position = p}}, true)
tiles[#tiles + 1] = {name = tile_name, position = p}
end
end
else
surface.set_tiles({{name = tile_name, position = p}}, true)

View File

@ -21,7 +21,7 @@ bb_config = {
--TERRAIN OPTIONS--
["border_river_width"] = 29, --Approximate width of the horizontal impassable river seperating the teams. (values up to 100)
["builders_area"] = true, --Grant each side a peaceful direction with no nests and biters?
["random_scrap"] = false, --Generate harvestable scrap around worms randomly?
["random_scrap"] = true, --Generate harvestable scrap around worms randomly?
--BITER SETTINGS--
["max_active_biters"] = 2500, --Maximum total amount of attacking units per side.

View File

@ -268,10 +268,14 @@ local function ticking_work()
end
local function mirror_map()
--local limit = 32
for i, c in pairs(global.chunks_to_mirror) do
if i < game.tick then
for _, chunk in pairs(global.chunks_to_mirror[i]) do
for k, chunk in pairs(global.chunks_to_mirror[i]) do
mirror_chunk(game.surfaces["biter_battles"], chunk)
--global.chunks_to_mirror[i][k] = nil
--limit = limit - 1
--if limit == 0 then return end
end
global.chunks_to_mirror[i] = nil
end
@ -282,4 +286,4 @@ event.add(defines.events.on_chunk_generated, ocg)
-- event.add(defines.events.on_chunk_generated, on_chunk_generated)
return ticking_work
-- return mirror_map
-- return mirror_map

View File

@ -1,36 +0,0 @@
local event = require 'utils.event'
local function on_player_joined_game(event)
local player = game.players[event.player_index]
if not global.new_player_equipped then global.new_player_equipped = {} end
if not global.new_player_equipped[player.name] then
player.insert({name = "raw-fish", count = 3})
player.insert({name = "iron-plate", count = 128})
player.insert({name = "iron-gear-wheel", count = 64})
player.insert({name = "copper-plate", count = 128})
player.insert({name = "copper-cable", count = 64})
player.insert({name = "pistol", count = 1})
player.insert({name = "firearm-magazine", count = 64})
player.insert({name = "shotgun", count = 1})
player.insert({name = "shotgun-shell", count = 16})
player.insert({name = "light-armor", count = 1})
global.new_player_equipped[player.name] = true
local radius = 320
game.forces.player.chart(game.surfaces[1], {{x = -1 * radius, y = -1 * radius}, {x = radius, y = radius}})
end
end
local function on_player_created(event)
local player = game.players[event.player_index]
end
local function on_research_finished(event)
end
event.add(defines.events.on_research_finished, on_research_finished)
event.add(defines.events.on_player_joined_game, on_player_joined_game)
event.add(defines.events.on_player_created, on_player_created)

View File

@ -1,153 +0,0 @@
-- just an empty map for testing thingies
local event = require 'utils.event'
local map_functions = require "tools.map_functions"
local simplex_noise = require 'utils.simplex_noise'.d2
function dump_boom_layout()
local surface = game.surfaces["empty_map"]
game.write_file("layout.lua", "" , false)
local area = {
left_top = {x = -100, y = -100},
right_bottom = {x = 100, y = 100}
}
local entities = surface.find_entities_filtered{area = area}
local tiles = surface.find_tiles_filtered{area = area}
local str = "{"
for i = 1, #entities, 1 do
if entities[i].name ~= "character" then
str = str .. "{x = " .. math.floor(entities[i].position.x, 0)
str = str .. ", y = "
str = str .. math.floor(entities[i].position.y, 0)
str = str .. '},'
end
end
str = str .. "}"
game.write_file("layout.lua", str .. '\n' , true)
end
local function on_chunk_generated(event)
local surface = game.surfaces["empty_map"]
if event.surface.name ~= surface.name then return end
local chunk_pos_x = event.area.left_top.x
local chunk_pos_y = event.area.left_top.y
local area = {
left_top = {x = chunk_pos_x, y = chunk_pos_y},
right_bottom = {x = chunk_pos_x + 31, y = chunk_pos_y + 31}
}
surface.destroy_decoratives({area = area})
local decoratives = {}
local entities = surface.find_entities(area)
for _, e in pairs(entities) do
if e.valid then
if e.name ~= "character" then
e.destroy()
end
end
end
local tiles = {}
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local pos = {x = event.area.left_top.x + x, y = event.area.left_top.y + y}
table.insert(tiles, {name = "grass-1", position = pos})
end
end
surface.set_tiles(tiles,true)
end
local function draw_smoothed_out_ore_circle(position, name, surface, radius, richness)
if not position then return end
if not name then return end
if not surface then return end
if not radius then return end
if not richness then return end
local math_random = math.random
local noise_seed_add = 25000
local richness_part = richness / radius
for y = radius * -3, radius * 3, 1 do
for x = radius * -3, radius * 3, 1 do
local pos = {x = x + position.x, y = y + position.y}
local seed = game.surfaces[1].map_gen_settings.seed
local noise_1 = simplex_noise(pos.x * 0.0125, pos.y * 0.0125, seed)
seed = seed + noise_seed_add
local noise_2 = simplex_noise(pos.x * 0.1, pos.y * 0.1, seed)
local noise = noise_1 + noise_2 * 0.12
local distance_to_center = math.sqrt(x^2 + y^2)
local a = richness - richness_part * distance_to_center
if distance_to_center < radius - math.abs(noise * radius * 0.85) and a > 1 then
if surface.can_place_entity({name = name, position = pos, amount = a}) then
surface.create_entity{name = name, position = pos, amount = a}
local mirror_pos = {x = pos.x * -1, y = pos.y * -1}
surface.create_entity{name = name, position = mirror_pos, amount = a}
end
end
end
end
end
local function on_chunk_charted(event)
if not global.chunks_charted then global.chunks_charted = {} end
local surface = game.surfaces[event.surface_index]
local position = event.position
if global.chunks_charted[tostring(position.x) .. tostring(position.y)] then return end
global.chunks_charted[tostring(position.x) .. tostring(position.y)] = true
local force = event.force
if position.x % 4 ~= 0 then return end
if position.y % 4 ~= 0 then return end
--map_functions.draw_rainbow_patch_v2({x = position.x * 32, y = position.y * 32}, surface, 28, 1000)
--map_functions.draw_derpy_tile_circle(surface, {x = position.x * 32, y = position.y * 32}, "concrete", 20, 26)
draw_smoothed_out_ore_circle({x = position.x * 32, y = position.y * 32}, "coal", surface, 25, 3000)
end
local function on_player_joined_game(event)
local player = game.players[event.player_index]
if not global.map_init_done then
local map_gen_settings = {}
map_gen_settings.water = "none"
map_gen_settings.cliff_settings = {cliff_elevation_interval = 20, cliff_elevation_0 = 20}
map_gen_settings.autoplace_controls = {
["coal"] = {frequency = "none", size = "none", richness = "none"},
["stone"] = {frequency = "none", size = "none", richness = "none"},
["copper-ore"] = {frequency = "none", size = "none", richness = "none"},
["uranium-ore"] = {frequency = "none", size = "none", richness = "none"},
["iron-ore"] = {frequency = "none", size = "none", richness = "none"},
["crude-oil"] = {frequency = "none", size = "none", richness = "none"},
["trees"] = {frequency = "none", size = "none", richness = "none"},
["enemy-base"] = {frequency = "none", size = "none", richness = "none"}
}
game.map_settings.pollution.pollution_restored_per_tree_damage = 0
game.create_surface("empty_map", map_gen_settings)
game.forces["player"].set_spawn_position({0,0},game.surfaces["empty_map"])
local surface = game.surfaces["empty_map"]
surface.daytime = 1
surface.freeze_daytime = 1
--local radius = 512
--game.forces.player.chart(surface, {{x = -1 * radius, y = -1 * radius}, {x = radius, y = radius}})
global.map_init_done = true
end
local surface = game.surfaces["empty_map"]
if player.online_time < 5 and surface.is_chunk_generated({0,0}) then
player.teleport(surface.find_non_colliding_position("character", {0,0}, 2, 1), "empty_map")
else
if player.online_time < 5 then
player.teleport({0,0}, "empty_map")
end
end
if player.online_time < 10 then
player.insert {name = 'raw-fish', count = 3}
player.insert {name = 'light-armor', count = 1}
end
end
event.add(defines.events.on_chunk_generated, on_chunk_generated)
event.add(defines.events.on_chunk_charted, on_chunk_charted)
event.add(defines.events.on_player_joined_game, on_player_joined_game)

View File

@ -875,13 +875,15 @@ local function on_player_joined_game(event)
player.teleport(game.forces["player"].get_spawn_position(surface), "fish_defender")
end
end
create_wave_gui(player)
add_fd_stats_button(player)
if game.tick > 900 then
is_game_lost()
end
if game.tick < 5 then game.forces.player.chart(game.surfaces["fish_defender"], {{-256, -512},{768, 512}}) end
end
local function on_built_entity(event)
@ -942,7 +944,7 @@ local function on_tick()
end
if game.tick % 180 == 0 then
if game.surfaces["fish_defender"] then
game.forces.player.chart(game.surfaces["fish_defender"], {{-256, -512},{768, 512}})
game.forces.player.chart(game.surfaces["fish_defender"], {{-160, -96},{160, 64}})
if global.difficulty_vote_index then
global.wave_interval = difficulties_votes[global.difficulty_vote_index].wave_interval
end
@ -1040,7 +1042,7 @@ local function on_init(event)
map_gen_settings.height = 2048
map_gen_settings.water = 0.10
map_gen_settings.terrain_segmentation = 3
map_gen_settings.cliff_settings = {cliff_elevation_interval = 24, cliff_elevation_0 = 24}
map_gen_settings.cliff_settings = {cliff_elevation_interval = 32, cliff_elevation_0 = 32}
map_gen_settings.autoplace_controls = {
["coal"] = {frequency = 3, size = 1.5, richness = 1},
["stone"] = {frequency = 3, size = 1.5, richness = 1},
@ -1077,14 +1079,18 @@ local function on_init(event)
fish_mouth(surface)
fish_eye(surface, {x = -2150, y = -300})
--[[
server_commands.to_discord_embed("Generating chunks, this could take a while...")
print("Generating chunks, this could take a while...")
local m = 512
for x = 0, -5, -1 do
surface.request_to_generate_chunks({x = x * m, y = 0}, 32)
surface.force_generate_chunk_requests()
end
end
]]
enemy_territory(surface)
global.chunk_queue = {}
end
event.add(defines.events.on_gui_click, on_gui_click)

View File

@ -85,7 +85,7 @@ local function is_out_of_map_tile(p)
end
function generate_spawn_area(surface)
surface.request_to_generate_chunks({x = 0, y = 0}, 12)
surface.request_to_generate_chunks({x = 0, y = 0}, 8)
surface.force_generate_chunk_requests()
local spawn_position_x = -128
@ -170,6 +170,9 @@ function generate_spawn_area(surface)
end
function enemy_territory(surface)
surface.request_to_generate_chunks({x = 256, y = 0}, 16)
surface.force_generate_chunk_requests()
local area = {{160, -512},{750, 512}}
--for _, tile in pairs(surface.find_tiles_filtered({area = area})) do
-- if is_enemy_territory(tile.position) then
@ -287,12 +290,8 @@ local function plankton_territory(surface, position, seed)
return true
end
local function on_chunk_generated(event)
local function process_chunk(left_top)
local surface = game.surfaces["fish_defender"]
if not surface then return end
if surface.name ~= event.surface.name then return end
local left_top = event.area.left_top
local seed = game.surfaces[1].map_gen_settings.seed
for x = 0, 31, 1 do
@ -305,5 +304,25 @@ local function on_chunk_generated(event)
end
end
local function process_chunk_queue()
for k, left_top in pairs(global.chunk_queue) do
process_chunk(left_top)
global.chunk_queue[k] = nil
return
end
end
local function on_chunk_generated(event)
if game.surfaces["fish_defender"].index ~= event.surface.index then return end
local left_top = event.area.left_top
if game.tick == 0 then
process_chunk(left_top)
else
global.chunk_queue[#global.chunk_queue + 1] = {x = left_top.x, y = left_top.y}
end
end
local event = require 'utils.event'
event.on_nth_tick(16, process_chunk_queue)
event.add(defines.events.on_chunk_generated, on_chunk_generated)

111
maps/forest_circle.lua Normal file
View File

@ -0,0 +1,111 @@
-- forest circle -- MewMew
require 'utils.table'
require "functions.soft_reset"
local event = require 'utils.event'
global.map_gen_settings = {}
global.map_gen_settings.seed = 1024
global.map_gen_settings.water = "0.01"
global.map_gen_settings.starting_area = "2.5"
global.map_gen_settings.cliff_settings = {cliff_elevation_interval = 38, cliff_elevation_0 = 38}
global.map_gen_settings.autoplace_controls = {
["coal"] = {frequency = "2", size = "1", richness = "1"},
["stone"] = {frequency = "2", size = "1", richness = "1"},
["copper-ore"] = {frequency = "2", size = "1", richness = "1"},
["iron-ore"] = {frequency = "2.5", size = "1.1", richness = "1"},
["uranium-ore"] = {frequency = "2", size = "1", richness = "1"},
["crude-oil"] = {frequency = "2.5", size = "1", richness = "1.5"},
["trees"] = {frequency = "1.25", size = "0.6", richness = "0.5"},
["enemy-base"] = {frequency = "256", size = "0.61", richness = "1"}
}
local function init_surface()
game.create_surface("forest_circle", global.map_gen_settings)
game.map_settings.enemy_evolution.time_factor = 0
game.map_settings.enemy_evolution.destroy_factor = 0
game.map_settings.enemy_evolution.pollution_factor = 0
game.map_settings.pollution.enabled = false
game.map_settings.enemy_expansion.enabled = true
game.map_settings.enemy_expansion.settler_group_min_size = 8
game.map_settings.enemy_expansion.settler_group_max_size = 16
game.map_settings.enemy_expansion.min_expansion_cooldown = 54000
game.map_settings.enemy_expansion.max_expansion_cooldown = 108000
end
local function on_player_joined_game(event)
local surface = game.surfaces["forest_circle"]
local player = game.players[event.player_index]
if player.gui.left["map_pregen"] then player.gui.left["map_pregen"].destroy() end
if player.online_time == 0 then
if surface.is_chunk_generated({0,0}) then
player.teleport(surface.find_non_colliding_position("character", {0,0}, 3, 0.5), surface)
else
player.teleport({0,0}, surface)
end
player.character.destructible = false
game.permissions.get_group("spectator").add_player(player)
end
end
local circles = {
[1] = "tree-01",
[2] = "small-worm-turret",
[3] = "biter-spawner",
[4] = "tree-04",
[5] = "tree-05",
[6] = "tree-06",
}
local function process_position(surface, pos)
surface.set_tiles({{name = "grass-1", position = pos}}, true)
local m = 0.035
if pos.y <= math.floor(40 * math.sin(pos.x * m)) + 9 and pos.y >= math.floor(40 * math.sin(pos.x * m)) - 9 then
surface.create_entity({name = circles[1], position = pos})
return
else
return
end
local current_radius = pos.x ^ 2 + pos.y ^ 2
local index = math.floor(current_radius / 2048)
if index == 0 then return end
if index > #circles then return end
if not surface.can_place_entity({name = circles[index], position = pos}) then return end
if math.random(1,3) ~= 1 then
surface.create_entity({name = circles[index], position = pos})
end
end
local function on_chunk_generated(event)
local pos
local left_top = event.area.left_top
local surface = event.surface
for _, e in pairs(surface.find_entities_filtered({area = event.area, force = "neutral"})) do
e.destroy()
end
for x = 0.5, 31.5, 1 do
for y = 0.5, 31.5, 1 do
pos = {x = left_top.x + x, y = left_top.y + y}
process_position(surface, pos)
end
end
end
local function on_init(surface)
if game.surfaces["forest_circle"] then return end
init_surface()
end
event.on_init(on_init)
event.add(defines.events.on_player_joined_game, on_player_joined_game)
event.add(defines.events.on_chunk_generated, on_chunk_generated)

View File

@ -0,0 +1,140 @@
local difficulties_votes = {
[1] = {amount_modifier = 0.52, strength_modifier = 0.40, boss_modifier = 0.7},
[2] = {amount_modifier = 0.76, strength_modifier = 0.65, boss_modifier = 0.8},
[3] = {amount_modifier = 0.92, strength_modifier = 0.85, boss_modifier = 0.9},
[4] = {amount_modifier = 1.00, strength_modifier = 1.00, boss_modifier = 1.0},
[5] = {amount_modifier = 1.16, strength_modifier = 1.25, boss_modifier = 1.1},
[6] = {amount_modifier = 1.48, strength_modifier = 1.75, boss_modifier = 1.2},
[7] = {amount_modifier = 2.12, strength_modifier = 2.50, boss_modifier = 1.3}
}
function get_biter()
local max_chance = 0
for k, v in pairs(global.biter_chances) do
max_chance = max_chance + v
end
local r = math.random(1, max_chance)
local current_chance = 0
for k, v in pairs(global.biter_chances) do
current_chance = current_chance + v
if r <= current_chance then return k end
end
end
function get_worm()
local max_chance = 0
for k, v in pairs(global.worm_chances) do
max_chance = max_chance + v
end
local r = math.random(1, max_chance)
local current_chance = 0
for k, v in pairs(global.worm_chances) do
current_chance = current_chance + v
if r <= current_chance then return k end
end
end
function set_biter_chances(level)
global.biter_chances = {
["small-biter"] = 500 - level * 10,
["small-spitter"] = 500 - level * 10,
["medium-biter"] = level * 10,
["medium-spitter"] = level * 10,
["big-biter"] = 0,
["big-spitter"] = 0,
["behemoth-biter"] = 0,
["behemoth-spitter"] = 0,
}
if level > 25 then
global.biter_chances["big-biter"] = (level - 25) * 25
global.biter_chances["big-spitter"] = (level - 25) * 25
end
if level > 50 then
global.biter_chances["behemoth-biter"] = (level - 50) * 50
global.biter_chances["behemoth-spitter"] = (level - 50) * 50
end
for k, v in pairs(global.biter_chances) do
if global.biter_chances[k] < 0 then global.biter_chances[k] = 0 end
end
end
function set_worm_chances(level)
global.worm_chances = {
["small-worm-turret"] = 500 - level * 10,
["medium-worm-turret"] = level * 10,
["big-worm-turret"] = 0,
["behemoth-worm-turret"] = 0,
}
if level > 25 then
global.worm_chances["big-worm-turret"] = (level - 25) * 25
global.worm_chances["big-worm-turret"] = (level - 25) * 25
end
if level > 50 then
global.worm_chances["behemoth-worm-turret"] = (level - 50) * 50
global.worm_chances["behemoth-worm-turret"] = (level - 50) * 50
end
for k, v in pairs(global.worm_chances) do
if global.worm_chances[k] < 0 then global.worm_chances[k] = 0 end
end
end
local function is_boss_stage()
if global.current_stage == 1 then return false end
if global.current_stage == #global.stages - 1 then return true end
if #global.stages < 6 then return false end
if global.current_stage == math.floor(#global.stages * 0.5) then return true end
end
function add_enemies(surface, tiles)
table.shuffle_table(tiles)
if is_boss_stage() then
set_biter_chances(math.floor((global.current_level * difficulties_votes[global.difficulty_vote_index].strength_modifier) + 15))
local boss_count = math.random(1, math.floor(global.current_level * 0.5) + 1)
if boss_count > 16 then boss_count = 16 end
for k, tile in pairs(tiles) do
if surface.can_place_entity({name = "small-biter", position = tile.position, force = "enemy"}) then
local unit = surface.create_entity({name = get_biter(), position = tile.position, force = "enemy"})
unit.ai_settings.allow_destroy_when_commands_fail = false
unit.ai_settings.allow_try_return_to_spawner = false
add_boss_unit(unit, (2.5 + global.current_level * 0.1) * difficulties_votes[global.difficulty_vote_index].boss_modifier, 0.55)
global.alive_boss_enemy_count = global.alive_boss_enemy_count + 1
global.alive_boss_enemy_entities[unit.unit_number] = unit
global.alive_enemies = global.alive_enemies + 1
boss_count = boss_count - 1
if boss_count == 0 then break end
end
end
end
if math.random(1, 4) == 1 or is_boss_stage() then
set_worm_chances(global.current_level)
local worm_count = math.random(1, global.current_level)
if worm_count > 32 then worm_count = 32 end
for k, tile in pairs(tiles) do
if surface.can_place_entity({name = "big-worm-turret", position = tile.position, force = "enemy"}) then
surface.create_entity({name = get_worm(), position = tile.position, force = "enemy"})
global.alive_enemies = global.alive_enemies + 1
worm_count = worm_count - 1
if worm_count == 0 then break end
end
end
end
set_biter_chances(math.floor(global.current_level * difficulties_votes[global.difficulty_vote_index].strength_modifier) + 1)
local amount = ((global.current_level * 25) / #global.stages) * global.current_stage
amount = amount * difficulties_votes[global.difficulty_vote_index].amount_modifier
for k, tile in pairs(tiles) do
if surface.can_place_entity({name = "small-biter", position = tile.position, force = "enemy"}) then
local unit = surface.create_entity({name = get_biter(), position = tile.position, force = "enemy"})
unit.ai_settings.allow_destroy_when_commands_fail = false
unit.ai_settings.allow_try_return_to_spawner = false
global.alive_enemies = global.alive_enemies + 1
amount = amount - 1
end
if amount <= 0 then break end
end
update_stage_gui()
end

View File

@ -1,69 +1,216 @@
--map by mewmew and kyte
require "maps.island_troopers.map_intro"
require "functions.noise_vector_path"
require "functions.boss_unit"
require "modules.shopping_chests"
require "modules.no_turrets"
require "modules.dangerous_goods"
require "modules.difficulty_vote"
require "maps.island_troopers.enemies"
require "maps.island_troopers.terrain"
local function create_stage_gui(player)
if player.gui.top.stage_gui then return end
local element = player.gui.top.add({type = "frame", name = "stage_gui", caption = " "})
local style = element.style
style.minimal_height = 38
style.maximal_height = 38
style.minimal_width = 140
style.top_padding = 2
style.left_padding = 4
style.right_padding = 4
style.bottom_padding = 2
style.font_color = {r = 155, g = 85, b = 25}
style.font = "default-large-bold"
end
function update_stage_gui()
local caption = "Level: " .. global.current_level
caption = caption .. " | Stage: "
local stage = global.current_stage
if stage > #global.stages - 1 then stage = #global.stages - 1 end
caption = caption .. stage
caption = caption .. "/"
caption = caption .. #global.stages - 1
caption = caption .. " | Bugs remaining: "
caption = caption .. global.alive_enemies
for _, player in pairs(game.connected_players) do
if player.gui.top.stage_gui then
player.gui.top.stage_gui.caption = caption
end
end
end
local function bring_players()
local surface = game.surfaces[1]
for _, player in pairs(game.connected_players) do
if player.position.y < -1 then
if player.character then
if player.character.valid then
local p = surface.find_non_colliding_position("character", {0, 2}, 8, 0.5)
if not p then player.teleport({0, 2}, surface) end
player.teleport(p, surface)
end
end
end
end
end
local function drift_corpses_toward_beach()
local surface = game.surfaces[1]
for _, corpse in pairs(surface.find_entities_filtered({name = "character-corpse"})) do
if corpse.position.y < 0 then
if surface.get_tile(corpse.position).collides_with("resource-layer") then
corpse.clone{position={corpse.position.x, corpse.position.y + 1}, surface=surface, force=corpse.force.name}
corpse.destroy()
end
end
end
end
local function set_next_level()
global.alive_enemies = 0
global.alive_boss_enemy_count = 0
global.current_stage = 1
global.current_level = global.current_level + 1
if global.current_level > 1 then bring_players() end
global.path_tiles = nil
local island_size = math.random(global.current_level, global.current_level * 2) + 7
if island_size > 128 then island_size = 128 end
global.stages = {}
global.stages[1] = {
path_length = 32 + global.current_level * 5,
size = math.random(global.current_level * 2, global.current_level * 5),
}
for i = 1, global.current_level, 1 do
path_length = 24 + island_size * 2,
size = island_size,
}
local stages_amount = (global.current_level * 0.33) + 1
if stages_amount > 9 then stages_amount = 9 end
for i = 1, stages_amount, 1 do
global.stages[#global.stages + 1] = {
path_length = 24 + global.current_level * 5,
size = math.random(global.current_level * 2, global.current_level * 5),
path_length = 16 + island_size * 2,
size = island_size,
}
end
global.stages[#global.stages + 1] = {
path_length = 128 + global.current_level * 5,
path_length = 64 + island_size * 8,
size = false,
}
game.print("Level " .. global.current_level .. " has begun!")
--game.print("Level " .. global.current_level)
update_stage_gui()
global.gamestate = 2
end
local function earn_credits(amount)
for _, player in pairs(game.connected_players) do
player.play_sound{path="utility/armor_insert", volume_modifier=0.85}
end
game.print(amount .. " credits have been transfered to the factory.", {r = 255, g = 215, b = 0})
global.credits = global.credits + amount
end
local function slowmo()
if not global.slowmo then global.slowmo = 0.15 end
game.speed = global.slowmo
global.slowmo = global.slowmo + 0.01
if game.speed < 1 then return end
for _, p in pairs(game.connected_players) do
if p.gui.left["slowmo_cam"] then p.gui.left["slowmo_cam"].destroy() end
end
global.slowmo = nil
global.gamestate = 4
end
local function wait_until_stage_is_beaten()
if global.alive_enemies > 0 then return end
if global.stages[global.current_stage].size then
global.current_stage = global.current_stage + 1
global.gamestate = 2
return
end
local reward_amount = false
local gamestate = 2
game.print("Level " .. global.current_level .. " complete!!")
global.gamestate = 5
if global.stages[global.current_stage].size then
if global.current_stage < #global.stages -1 then
reward_amount = global.current_stage * global.current_level * 50
else
reward_amount = global.current_stage * global.current_level * 150
end
else
game.print("Final Stage complete!")
game.print("Level is collapsing !!", {r = 255, g = 0, b = 0})
gamestate = 5
end
if reward_amount then
earn_credits(reward_amount)
update_stage_gui()
end
global.current_stage = global.current_stage + 1
global.gamestate = gamestate
end
local function on_player_joined_game(event)
local player = game.players[event.player_index]
create_stage_gui(player)
if player.gui.left["slowmo_cam"] then player.gui.left["slowmo_cam"].destroy() end
player.insert({name = "pistol", count = 1})
player.insert({name = "uranium-rounds-magazine", count = 128})
player.insert({name = "firearm-magazine", count = 32})
end
local function on_init()
local surface = game.surfaces[1]
surface.request_to_generate_chunks({x = 0, y = 0}, 8)
surface.request_to_generate_chunks({x = 0, y = 0}, 16)
surface.force_generate_chunk_requests()
--global.level_tiles = {}
global.tree_raffle = {}
for _, e in pairs(game.entity_prototypes) do
if e.type == "tree" then
table.insert(global.tree_raffle, e.name)
end
end
global.difficulty_poll_closing_timeout = 3600 * 10
global.level_vectors = {}
global.current_level = 0
global.alive_boss_enemy_entities = {}
global.current_level = 0
global.gamestate = 1
game.forces.player.set_spawn_position({0, 2}, surface)
end
local msg = {
"We got the brainbug!",
"Good job troopers!",
"This will pay off well!",
"I'm doing my part!",
}
local function on_entity_died(event)
if not event.entity.valid then return end
if event.entity.force.name == "enemy" then global.alive_enemies = global.alive_enemies - 1 end
local entity = event.entity
if not entity.valid then return end
if entity.force.name ~= "enemy" then return end
global.alive_enemies = global.alive_enemies - 1
update_stage_gui()
if entity.type ~= "unit" then return end
if not global.alive_boss_enemy_entities[entity.unit_number] then return end
global.alive_boss_enemy_entities[entity.unit_number] = nil
global.alive_boss_enemy_count = global.alive_boss_enemy_count - 1
if global.alive_boss_enemy_count == 0 then
for _, p in pairs(game.connected_players) do
if p.gui.left["slowmo_cam"] then p.gui.left["slowmo_cam"].destroy() end
local frame = p.gui.left.add({type = "frame", name = "slowmo_cam", caption = msg[math.random(1, #msg)]})
local camera = frame.add({type = "camera", name = "mini_cam_element", position = entity.position, zoom = 1.5, surface_index = 1})
camera.style.minimal_width = 400
camera.style.minimal_height = 400
end
global.gamestate = 8
end
end
local gamestate_functions = {
@ -72,16 +219,18 @@ local gamestate_functions = {
[3] = draw_the_island,
[4] = wait_until_stage_is_beaten,
[5] = kill_the_level,
[8] = slowmo,
}
local function on_tick()
if game.tick % 2 == 0 then
gamestate_functions[global.gamestate]()
end
local function on_tick()
gamestate_functions[global.gamestate]()
if game.tick % 180 == 0 then drift_corpses_toward_beach() end
end
local event = require 'utils.event'
event.on_init(on_init)
event.add(defines.events.on_tick, on_tick)
event.add(defines.events.on_entity_died, on_entity_died)
event.add(defines.events.on_player_joined_game, on_player_joined_game)
event.add(defines.events.on_player_joined_game, on_player_joined_game)
require "functions.boss_unit"

View File

@ -0,0 +1,98 @@
local event = require 'utils.event'
local main_caption = " --Island Troopers-- "
local sub_caption = " "
local info = [[
You are stranded on this coastal planet and your mission is to get out of here.
The peaceful inhabitants live in the sea and are plagued by bugs.
They need your help!
They will send you the bugs along with the seabed to the surface.
If you eliminate the bugs, you will receive credits as a thank-you for removing the bugs.
With the credits you can buy raw materials from requirement boxes.
These can already be found on the coast.
Be careful! Over time, residents will send stronger bugs to the surface!
Turrets unfortunately malfunction in this world.
Any container bearing dangerous goods, like ammo, grenades or barrels,
causes heavy explosions when it breaks.
Maybe this can be used to our advantage.
--Good Luck Troopers--
]]
local function create_map_intro_button(player)
if player.gui.top["map_intro_button"] then return end
local b = player.gui.top.add({type = "sprite-button", caption = "?", name = "map_intro_button", tooltip = "Map Info"})
b.style.font_color = {r=0.11, g=0.8, b=0.44}
b.style.font = "heading-1"
b.style.minimal_height = 38
b.style.minimal_width = 38
b.style.top_padding = 2
b.style.left_padding = 4
b.style.right_padding = 4
b.style.bottom_padding = 2
end
local function create_map_intro(player)
if player.gui.left["map_intro_frame"] then player.gui.left["map_intro_frame"].destroy() end
local frame = player.gui.left.add {type = "frame", name = "map_intro_frame", direction = "vertical"}
local t = frame.add {type = "table", column_count = 1}
local tt = t.add {type = "table", column_count = 3}
local l = tt.add {type = "label", caption = main_caption}
l.style.font = "heading-1"
l.style.font_color = {r=0.11, g=0.8, b=0.44}
local l = tt.add {type = "label", caption = sub_caption}
l.style.font = "heading-2"
l.style.font_color = {r=0.33, g=0.66, b=0.9}
l.style.minimal_width = 385
local b = tt.add {type = "button", caption = "X", name = "close_map_intro_frame", align = "right"}
b.style.font = "heading-2"
b.style.minimal_height = 30
b.style.minimal_width = 30
b.style.top_padding = 2
b.style.left_padding = 4
b.style.right_padding = 4
b.style.bottom_padding = 2
local tt = t.add {type = "table", column_count = 1}
local frame = t.add {type = "frame"}
local l = frame.add {type = "label", caption = info}
l.style.single_line = false
l.style.font = "heading-2"
l.style.font_color = {r=0.75, g=0.8, b=0.8}
l.style.minimal_width = 480
end
local function on_gui_click(event)
if not event then return end
if not event.element then return end
if not event.element.valid then return end
local player = game.players[event.element.player_index]
if event.element.name == "close_map_intro_frame" then player.gui.left["map_intro_frame"].destroy() return end
if event.element.name == "map_intro_button" then
if player.gui.left["map_intro_frame"] then
player.gui.left["map_intro_frame"].destroy()
else
create_map_intro(player)
end
return
end
end
local function on_player_joined_game(event)
local player = game.players[event.player_index]
create_map_intro_button(player)
if player.online_time == 0 then
create_map_intro(player)
end
end
event.add(defines.events.on_player_joined_game, on_player_joined_game)
event.add(defines.events.on_gui_click, on_gui_click)

View File

@ -1,67 +1,125 @@
local map_functions = require "tools.map_functions"
local math_random = math.random
local simplex_noise = require 'utils.simplex_noise'.d2
local rock_raffle = {"sand-rock-big","sand-rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-huge"}
local function island_noise(p, seed_1, seed_2, seed_3)
local noise_1 = simplex_noise(p.x * 0.01, p.y * 0.01, seed_1)
local noise_2 = simplex_noise(p.x * 0.04, p.y * 0.04, seed_2)
local noise_3 = simplex_noise(p.x * 0.1, p.y * 0.1, seed_3)
return math.abs(noise_1 + noise_2 * 0.5 + noise_3 * 0.2)
end
local function process_island_position(position, radius, noise, distance)
if distance + noise * radius * 1.7 <= radius then
return {name = "grass-1", position = position}
end
if distance + noise * radius * 0.4 <= radius then
return {name = "sand-1", position = position}
end
if distance + noise * radius * 0.2 <= radius then
return {name = "water", position = position}
end
end
local function draw_island_tiles(surface, position, radius)
local seed_1 = math.random(1, 9999999)
local seed_2 = math.random(1, 9999999)
local seed_3 = math.random(1, 9999999)
local tiles = {}
for y = radius * -2, radius * 2, 1 do
for x = radius * -2, radius * 2, 1 do
local p = {x = x + position.x, y = y + position.y}
if surface.get_tile(p).name == "deepwater" then
local noise = island_noise(p, seed_1, seed_2, seed_3)
local distance = math.sqrt(x^2 + y^2)
local tile = process_island_position(p, radius, noise, distance)
if tile then tiles[#tiles + 1] = tile end
end
end
end
surface.set_tiles(tiles, true)
return tiles
end
local function get_vector()
if global.current_stage == 1 then return {0, -1} end
if global.current_stage == #global.stages then return {0, 1} end
return {1, 0}
end
local function add_enemies(surface, position)
local radius = global.stages[global.current_stage].size
local amount = math.ceil(((global.current_level * 10) / #global.stages) * global.current_stage)
for a = 1, amount, 1 do
local p = {x = position.x + (radius - math.random(0, radius * 2)), y = position.y + (radius - math.random(0, radius * 2))}
if surface.can_place_entity({name = "small-biter", position = p, force = enemy}) then
surface.create_entity({name = "small-biter", position = p, force = enemy})
global.alive_enemies = global.alive_enemies + 1
end
end
if global.current_stage == #global.stages - 1 then
local unit = surface.create_entity({name = "medium-spitter", position = position, force = enemy})
add_boss_unit(unit, global.current_level * 2, 0.55)
global.alive_enemies = global.alive_enemies + 1
local position = global.path_tiles[#global.path_tiles].position
local island_size = global.stages[global.current_stage].size
local y_modifier = 0
if math.abs(position.y) < 32 + island_size * 3 then
y_modifier = math.random(50, 100) * -0.01
else
y_modifier = math.random(50, 100) * 0.01
end
return {1, y_modifier}
end
function draw_the_island()
if not global.stages[global.current_stage].size then global.gamestate = 4 return end
local surface = game.surfaces[1]
local position = global.path_tiles[#global.path_tiles].position
map_functions.draw_noise_tile_circle(position, "grass-2", surface, global.stages[global.current_stage].size)
add_enemies(surface, position)
local tiles = draw_island_tiles(surface, position, global.stages[global.current_stage].size)
--local tree = "tree-0" .. math_random(1,9)
local tree = global.tree_raffle[math.random(1, #global.tree_raffle)]
local seed = math.random(1, 1000000)
for _, t in pairs(tiles) do
if math.random(1, 32) == 1 then
local noise = simplex_noise(t.position.x * 0.02, t.position.y * 0.02, seed)
if noise > 0.75 or noise < -0.75 then
surface.create_entity({name = rock_raffle[math_random(1, #rock_raffle)], position = t.position})
end
end
if surface.can_place_entity({name = "wooden-chest", position = t.position}) then
if math.random(1, 64) == 1 then
if simplex_noise(t.position.x * 0.02, t.position.y * 0.02, seed) > 0.25 then
surface.create_entity({name = tree, position = t.position})
end
end
end
end
add_enemies(surface, tiles)
global.gamestate = 4
end
local draw_path_tile_whitelist = {
["water"] = true,
["deepwater"] = true,
}
local path_tile_names = {"grass-2", "grass-3", "grass-4", "water-shallow"}
function draw_path_to_next_stage()
local surface = game.surfaces[1]
if global.current_stage ~= #global.stages then
if global.current_stage == #global.stages - 1 then
game.print("--Final Stage--")
else
game.print("--Stage " .. global.current_stage .. "--")
end
end
--if global.current_stage ~= #global.stages then
-- if global.current_stage == #global.stages - 1 then
--game.print("--Final Stage--")
-- else
--game.print("--Stage " .. global.current_stage .. "--")
-- end
--end
local position = {x = 0, y = 0}
if global.path_tiles then position = global.path_tiles[#global.path_tiles].position end
--game.print(get_vector()[1] .. " " .. get_vector()[2])
global.path_tiles = noise_vector_tile_path(surface, "grass-1", position, get_vector(), global.stages[global.current_stage].path_length, math.random(2, 5), draw_path_tile_whitelist)
global.path_tiles = noise_vector_tile_path(surface, path_tile_names[math_random(1, #path_tile_names)], position, get_vector(), global.stages[global.current_stage].path_length, math.random(2, 4), draw_path_tile_whitelist)
--for _, t in pairs(global.path_tiles) do
-- global.level_tiles[#global.level_tiles + 1] = t
--end
if global.current_stage ~= #global.stages and global.current_stage > 2 then
if math_random(1, 3) == 1 then
noise_vector_tile_path(surface, path_tile_names[math_random(1, 3)], position, {0, 1}, global.stages[#global.stages].path_length, math.random(2, 4), draw_path_tile_whitelist)
end
end
global.gamestate = 3
end
local tile_whitelist = {"grass-1", "grass-2", "grass-3", "grass-4"}
local tile_whitelist = {"grass-1", "grass-2", "grass-3", "grass-4", "water-mud", "water-shallow", "sand-1", "water", "landfill"}
local function get_level_tiles(surface)
global.level_tiles = {}
for chunk in surface.get_chunks() do
@ -89,7 +147,7 @@ local function create_particles(surface, position)
local particle = particles[math_random(1, #particles)]
local m = math_random(10, 30)
local m2 = m * 0.005
for i = 1, 25, 1 do
for i = 1, 4, 1 do
surface.create_entity({
name = particle,
position = position,
@ -104,12 +162,13 @@ end
function kill_the_level()
local surface = game.surfaces[1]
if not global.level_tiles then get_level_tiles(surface) end
local amount = global.current_level
if not global.kill_the_level_speed then global.kill_the_level_speed = 0 end
global.kill_the_level_speed = global.kill_the_level_speed + 0.0025
local amount = global.kill_the_level_speed
for i = #global.level_tiles, 1, -1 do
if global.level_tiles[i] then
for k, tile in pairs(global.level_tiles[i]) do
surface.set_tiles({{name = "water", position = tile.position}}, true)
surface.set_tiles({{name = "deepwater", position = tile.position}}, true)
create_particles(surface, tile.position)
global.level_tiles[i][k] = nil
amount = amount - 1
@ -121,26 +180,46 @@ function kill_the_level()
if #global.level_tiles == 0 then
wipe_vision(surface)
global.kill_the_level_speed = nil
global.level_tiles = nil
global.gamestate = 1
end
end
local function process_tile(surface, position)
if position.y < 0 then surface.set_tiles({{name = "water", position = position}}, true) return end
if position.y > 4 then surface.set_tiles({{name = "water-green", position = position}}, true) return end
if position.x < -96 then surface.set_tiles({{name = "out-of-map", position = position}}, true) return end
if position.x > 8192 then surface.set_tiles({{name = "out-of-map", position = position}}, true) return end
if position.y < 0 then surface.set_tiles({{name = "deepwater", position = position}}, true) return end
if position.y > 32 then surface.set_tiles({{name = "water-green", position = position}}, true) return end
if position.y > 10 + simplex_noise(position.x * 0.010, 0, game.surfaces[1].map_gen_settings.seed) * 4 then surface.set_tiles({{name = "water-green", position = position}}, true) return end
surface.set_tiles({{name = "sand-1", position = position}}, true)
if position.y == 6 then
if position.x % 60 == 30 then
create_dump_chest(surface, {x = position.x, y = position.y - 1}, false)
create_shopping_chest(surface, position, false)
end
end
end
local function on_chunk_generated(event)
local left_top = event.area.left_top
local surface = event.surface
for k, e in pairs(surface.find_entities_filtered({area = event.area})) do
if e.force.name ~= "player" then e.destroy() end
end
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local position = {x = left_top.x + x, y = left_top.y + y}
process_tile(surface, position)
end
end
surface.destroy_decoratives(event.area)
end
local event = require 'utils.event'

View File

@ -289,6 +289,8 @@ room.maze = function(surface, cell_left_top, direction)
"enemy",
true
)
surface.spill_item_stack({x = left_top.x + grid_size * 0.5, y = left_top.y + grid_size * 0.5}, get_loot_item_stack(), true, nil, true)
end
local room_weights = {

View File

@ -303,6 +303,8 @@ room.maze = function(surface, cell_left_top, direction)
"enemy",
true
)
surface.spill_item_stack({x = left_top.x + grid_size, y = left_top.y + grid_size}, get_loot_item_stack(), true, nil, true)
end
local room_weights = {

View File

@ -61,7 +61,7 @@ local function set_collision_grid(surface)
if not global.tetris_active_grid[coord_string(math.floor(e.position.x), math.floor(e.position.y))] then
global.tetris_grid[coord_string(math.floor(e.position.x), math.floor(e.position.y))] = false
else
game.print(e.position)
--game.print(e.position)
end
end
end
@ -403,7 +403,7 @@ local function on_player_joined_game(event)
set_inventory()
player.surface.daytime = 0.22
player.surface.freeze_daytime = 1
player.print("Welcome to tetris! Use the hotbar to control the bricks.", {r=0.98, g=0.66, b=0.22})
player.print("Use 1,2, 9, 0 on your keyboard to control the bricks.", {r=0.98, g=0.66, b=0.22})
end
local function on_chunk_generated(event)
@ -445,7 +445,7 @@ local function tick()
end
end
event.on_nth_tick(2, tick)
event.on_nth_tick(4, tick)
event.on_init(on_init)
event.add(defines.events.on_player_cursor_stack_changed, on_player_cursor_stack_changed)
event.add(defines.events.on_player_joined_game, on_player_joined_game)

View File

@ -11,12 +11,20 @@ local difficulties = {
}
local function difficulty_gui()
local tooltip = "Current difficulty of the map is " .. difficulties[global.difficulty_vote_index].name
tooltip = tooltip .. "."
for _, player in pairs(game.connected_players) do
if player.gui.top["difficulty_gui"] then player.gui.top["difficulty_gui"].destroy() end
local b = player.gui.top.add { type = "button", caption = difficulties[global.difficulty_vote_index].name, tooltip = "Current difficulty of the map is " .. difficulties[global.difficulty_vote_index].name .. ".", name = "difficulty_gui" }
b.style.font = "heading-2"
b.style.font_color = difficulties[global.difficulty_vote_index].print_color
b.style.minimal_height = 38
if player.gui.top["difficulty_gui"] then
player.gui.top["difficulty_gui"].caption = difficulties[global.difficulty_vote_index].name
player.gui.top["difficulty_gui"].tooltip = tooltip
player.gui.top["difficulty_gui"].style.font_color = difficulties[global.difficulty_vote_index].print_color
else
local b = player.gui.top.add { type = "button", caption = difficulties[global.difficulty_vote_index].name, tooltip = tooltip, name = "difficulty_gui" }
b.style.font = "heading-2"
b.style.font_color = difficulties[global.difficulty_vote_index].print_color
b.style.minimal_height = 38
end
end
end
@ -85,6 +93,7 @@ local function on_player_joined_game(event)
if not global.difficulty_vote_value then global.difficulty_vote_value = 1 end
if not global.difficulty_vote_index then global.difficulty_vote_index = 4 end
if not global.difficulty_player_votes then global.difficulty_player_votes = {} end
if not global.difficulty_poll_closing_timeout then global.difficulty_poll_closing_timeout = 54000 end
if game.tick < global.difficulty_poll_closing_timeout then
if not global.difficulty_player_votes[player.name] then
poll_difficulty(player)

24
modules/no_turrets.lua Normal file
View File

@ -0,0 +1,24 @@
local turret_types = {
["ammo-turret"] = true,
["artillery-turret"] = true,
["electric-turret"] = true,
["fluid-turret"] = true,
}
local function destroy_turret(entity)
if not entity.valid then return end
if not turret_types[entity.type] then return end
entity.die()
end
local function on_built_entity(event)
destroy_turret(event.created_entity)
end
local function on_robot_built_entity(event)
destroy_turret(event.created_entity)
end
local event = require 'utils.event'
event.add(defines.events.on_built_entity, on_built_entity)
event.add(defines.events.on_robot_built_entity, on_robot_built_entity)

123
modules/shopping_chests.lua Normal file
View File

@ -0,0 +1,123 @@
local shop_list = {
["coal"] = 1,
["copper-ore"] = 1,
["crude-oil-barrel"] = 6,
["empty-barrel"] = 5,
["iron-ore"] = 1,
["landfill"] = 2.5,
["raw-fish"] = 4,
["stone"] = 1,
["uranium-ore"] = 3,
["wood"] = 0.75,
}
function create_shopping_chest(surface, position, destructible)
global.shopping_chests[#global.shopping_chests + 1] = surface.create_entity({name = "logistic-chest-requester", position = position, force = "shopping_chests"})
global.shopping_chests[#global.shopping_chests].minable = false
if not destructible then global.shopping_chests[#global.shopping_chests].destructible = false end
end
function create_dump_chest(surface, position, destructible)
global.dump_chests[#global.dump_chests + 1] = surface.create_entity({name = "logistic-chest-passive-provider", position = position, force = "shopping_chests"})
global.dump_chests[#global.dump_chests].minable = false
if not destructible then global.dump_chests[#global.dump_chests].destructible = false end
end
local function get_affordable_item_count(name, count)
if global.credits >= count * shop_list[name] then
return count
end
count = math.floor(global.credits / shop_list[name])
return count
end
local function process_shopping_chest(k, chest)
if not chest.valid then global.shopping_chests[k] = nil return end
if global.credits <= 0 then return end
local requested_item_stack = chest.get_request_slot(1)
if not requested_item_stack then return end
if not shop_list[requested_item_stack.name] then
chest.surface.create_entity({name = "flying-text", position = {chest.position.x - 2, chest.position.y}, text = requested_item_stack.name .. " is not for sale", color = {r = 200, g = 160, b = 30}})
return
end
local inventory = chest.get_inventory(defines.inventory.chest)
--if not inventory.can_insert(requested_item_stack) then return end
local current_count = inventory.get_item_count(requested_item_stack.name)
if current_count >= requested_item_stack.count then return end
local count = requested_item_stack.count - current_count
count = get_affordable_item_count(requested_item_stack.name, count)
if count < 1 then return end
local inserted_amount = inventory.insert({name = requested_item_stack.name, count = count})
if inserted_amount == 0 then return end
local spent_credits = inserted_amount * shop_list[requested_item_stack.name]
global.credits = global.credits - spent_credits
chest.surface.create_entity({name = "flying-text", position = chest.position, text = "-" .. spent_credits .. " ø", color = {r = 200, g = 160, b = 30}})
end
local function process_dump_chest(k, chest)
if not chest.valid then global.dump_chests[k] = nil return end
local inventory = chest.get_inventory(defines.inventory.chest)
if inventory.is_empty() then return end
for k, price in pairs(shop_list) do
local removed = inventory.remove(k)
if removed > 0 then
local gain = removed * shop_list[k]
global.credits = global.credits + gain
chest.surface.create_entity({name = "flying-text", position = chest.position, text = "+" .. gain .. " ø", color = {r = 200, g = 160, b = 30}})
return
end
end
end
local function gui()
local tooltip = "Trade goods: "
for k, v in pairs(shop_list) do
tooltip = tooltip .. k
tooltip = tooltip .. " "
tooltip = tooltip .. v
tooltip = tooltip .. " | "
end
for _, player in pairs(game.connected_players) do
if player.gui.top.credits_button then player.gui.top.credits_button.destroy() end
local frame = player.gui.top.add({type = "frame", name = "credits_button"})
frame.style.maximal_height = 38
frame.style.top_padding = 0
frame.style.left_padding = 0
local element = frame.add({type = "label", name = "credits", caption = global.credits .. " ø", tooltip = tooltip})
local style = element.style
style.minimal_height = 38
style.maximal_height = 38
style.minimal_width = 100
style.horizontal_align = "right"
style.top_padding = 2
style.left_padding = 2
style.right_padding = 2
style.bottom_padding = 2
style.font_color = {r = 255, g = 215, b = 0}
style.font = "default-large-bold"
end
end
local function tick()
for k, chest in pairs(global.shopping_chests) do
process_shopping_chest(k, chest)
end
for k, chest in pairs(global.dump_chests) do
process_dump_chest(k, chest)
end
gui()
end
local function on_init()
global.shopping_chests = {}
global.dump_chests = {}
global.credits = 0
game.create_force("shopping_chests")
game.forces.player.set_friend("shopping_chests", true)
game.forces.shopping_chests.set_friend("player", true)
end
local event = require 'utils.event'
event.on_nth_tick(120, tick)
event.on_init(on_init)