diff --git a/maps/biter_battles_v2/biter_battles_v2.lua b/maps/biter_battles_v2/biter_battles_v2.lua index 943ac6cf..8b6dd8a7 100644 --- a/maps/biter_battles_v2/biter_battles_v2.lua +++ b/maps/biter_battles_v2/biter_battles_v2.lua @@ -7,17 +7,18 @@ local math_random = math.random local function init_surface() if game.surfaces["biter_battles"] then return end local map_gen_settings = {} - --map_gen_settings.water = "none" - --map_gen_settings.starting_area = "5" + map_gen_settings.water = "0.5" + map_gen_settings.starting_area = "5" map_gen_settings.cliff_settings = {cliff_elevation_interval = 12, cliff_elevation_0 = 32} map_gen_settings.autoplace_controls = { - ["coal"] = {frequency = "0.8", size = "1", richness = "0.3"}, - ["stone"] = {frequency = "0.8", size = "1", richness = "0.3"}, - ["copper-ore"] = {frequency = "0.8", size = "2", richness = "0.3"}, - ["iron-ore"] = {frequency = "0.8", size = "2", richness = "0.3"}, - ["crude-oil"] = {frequency = "0.8", size = "2", richness = "0.4"}, - ["trees"] = {frequency = "0.8", size = "0.5", richness = "0.3"}, - ["enemy-base"] = {frequency = "0.8", size = "1", richness = "0.4"} + ["coal"] = {frequency = "4", size = "1", richness = "1"}, + ["stone"] = {frequency = "4", size = "1", richness = "1"}, + ["copper-ore"] = {frequency = "4", size = "1", richness = "1"}, + ["iron-ore"] = {frequency = "4", size = "1", richness = "1"}, + ["uranium-ore"] = {frequency = "2", size = "1", richness = "1"}, + ["crude-oil"] = {frequency = "3", size = "1", richness = "1"}, + ["trees"] = {frequency = "2", size = "1", richness = "1"}, + ["enemy-base"] = {frequency = "2", size = "4", richness = "1"} } game.create_surface("biter_battles", map_gen_settings) @@ -77,7 +78,9 @@ local function init_forces(surface) game.forces[force.name].technologies["artillery-shell-speed-1"].enabled = false game.forces[force.name].technologies["atomic-bomb"].enabled = false game.forces[force.name].set_ammo_damage_modifier("shotgun-shell", 1) - end + end + + global.game_lobby_active = true end local function on_player_joined_game(event) @@ -85,18 +88,20 @@ local function on_player_joined_game(event) local surface = game.surfaces["biter_battles"] init_forces(surface) - local player = game.players[event.player_index] - + 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("player", {0,0}, 3, 0.5), surface) else - player.teleport({0,-32}, surface) + player.teleport({0,0}, surface) end player.character.destructible = false end - player.character.destroy() + --player.character.destroy() end event.add(defines.events.on_player_joined_game, on_player_joined_game) @@ -105,4 +110,5 @@ require "maps.biter_battles_v2.terrain" require "maps.biter_battles_v2.mirror_terrain" require "maps.biter_battles_v2.chat" require "maps.biter_battles_v2.game_won" -require "maps.biter_battles_v2.on_tick" \ No newline at end of file +require "maps.biter_battles_v2.on_tick" +require "maps.biter_battles_v2.pregenerate_chunks" \ No newline at end of file diff --git a/maps/biter_battles_v2/game_won.lua b/maps/biter_battles_v2/game_won.lua index 72951b43..ffc97c89 100644 --- a/maps/biter_battles_v2/game_won.lua +++ b/maps/biter_battles_v2/game_won.lua @@ -35,14 +35,152 @@ local function fireworks(surface) end end +local function get_sorted_list(column_name, score_list) + for x = 1, #score_list, 1 do + for y = 1, #score_list, 1 do + if not score_list[y + 1] then break end + if score_list[y][column_name] < score_list[y + 1][column_name] then + local key = score_list[y] + score_list[y] = score_list[y + 1] + score_list[y + 1] = key + end + end + end + return score_list +end + +local function get_mvps(force) + if not global.score[force] then return false end + local score = global.score[force] + local score_list = {} + for _, p in pairs(game.players) do + if score.players[p.name] then + local killscore = 0 + if score.players[p.name].killscore then killscore = score.players[p.name].killscore end + local deaths = 0 + if score.players[p.name].deaths then deaths = score.players[p.name].deaths end + local built_entities = 0 + if score.players[p.name].built_entities then built_entities = score.players[p.name].built_entities end + local mined_entities = 0 + if score.players[p.name].mined_entities then mined_entities = score.players[p.name].mined_entities end + table.insert(score_list, {name = p.name, killscore = killscore, deaths = deaths, built_entities = built_entities, mined_entities = mined_entities}) + end + end + local mvp = {} + score_list = get_sorted_list("killscore", score_list) + mvp.killscore = {name = score_list[1].name, score = score_list[1].killscore} + score_list = get_sorted_list("deaths", score_list) + mvp.deaths = {name = score_list[1].name, score = score_list[1].deaths} + score_list = get_sorted_list("built_entities", score_list) + mvp.built_entities = {name = score_list[1].name, score = score_list[1].built_entities} + return mvp +end + +local function show_mvps(player) + if not global.score then return end + if player.gui.left["mvps"] then return end + local frame = player.gui.left.add({type = "frame", name = "mvps", direction = "vertical"}) + local l = frame.add({type = "label", caption = "MVPs - North:"}) + l.style.font = "default-listbox" + l.style.font_color = {r = 0.55, g = 0.55, b = 0.99} + + local t = frame.add({type = "table", column_count = 2}) + local mvp = get_mvps("north") + if mvp then + + local l = t.add({type = "label", caption = "Defender >> "}) + l.style.font = "default-listbox" + l.style.font_color = {r = 0.22, g = 0.77, b = 0.44} + local l = t.add({type = "label", caption = mvp.killscore.name .. " with a score of " .. mvp.killscore.score}) + l.style.font = "default-bold" + l.style.font_color = {r=0.33, g=0.66, b=0.9} + + local l = t.add({type = "label", caption = "Builder >> "}) + l.style.font = "default-listbox" + l.style.font_color = {r = 0.22, g = 0.77, b = 0.44} + local l = t.add({type = "label", caption = mvp.built_entities.name .. " built " .. mvp.built_entities.score .. " things"}) + l.style.font = "default-bold" + l.style.font_color = {r=0.33, g=0.66, b=0.9} + + local l = t.add({type = "label", caption = "Deaths >> "}) + l.style.font = "default-listbox" + l.style.font_color = {r = 0.22, g = 0.77, b = 0.44} + local l = t.add({type = "label", caption = mvp.deaths.name .. " died " .. mvp.deaths.score .. " times"}) + l.style.font = "default-bold" + l.style.font_color = {r=0.33, g=0.66, b=0.9} + + if not global.results_sent_north then + local result = {} + insert(result, 'NORTH: \\n') + insert(result, 'MVP Defender: \\n') + insert(result, mvp.killscore.name .. " with a score of " .. mvp.killscore.score .. "\\n" ) + insert(result, '\\n') + insert(result, 'MVP Builder: \\n') + insert(result, mvp.built_entities.name .. " built " .. mvp.built_entities.score .. " things\\n" ) + insert(result, '\\n') + insert(result, 'MVP Deaths: \\n') + insert(result, mvp.deaths.name .. " died " .. mvp.deaths.score .. " times" ) + local message = table.concat(result) + server_commands.to_discord_embed(message) + global.results_sent_north = true + end + end + + local l = frame.add({type = "label", caption = "MVPs - South:"}) + l.style.font = "default-listbox" + l.style.font_color = {r = 0.99, g = 0.33, b = 0.33} + + local t = frame.add({type = "table", column_count = 2}) + local mvp = get_mvps("south") + if mvp then + local l = t.add({type = "label", caption = "Defender >> "}) + l.style.font = "default-listbox" + l.style.font_color = {r = 0.22, g = 0.77, b = 0.44} + local l = t.add({type = "label", caption = mvp.killscore.name .. " with a score of " .. mvp.killscore.score}) + l.style.font = "default-bold" + l.style.font_color = {r=0.33, g=0.66, b=0.9} + + local l = t.add({type = "label", caption = "Builder >> "}) + l.style.font = "default-listbox" + l.style.font_color = {r = 0.22, g = 0.77, b = 0.44} + local l = t.add({type = "label", caption = mvp.built_entities.name .. " built " .. mvp.built_entities.score .. " things"}) + l.style.font = "default-bold" + l.style.font_color = {r=0.33, g=0.66, b=0.9} + + local l = t.add({type = "label", caption = "Deaths >> "}) + l.style.font = "default-listbox" + l.style.font_color = {r = 0.22, g = 0.77, b = 0.44} + local l = t.add({type = "label", caption = mvp.deaths.name .. " died " .. mvp.deaths.score .. " times"}) + l.style.font = "default-bold" + l.style.font_color = {r=0.33, g=0.66, b=0.9} + + if not global.results_sent_south then + local result = {} + insert(result, 'SOUTH: \\n') + insert(result, 'MVP Defender: \\n') + insert(result, mvp.killscore.name .. " with a score of " .. mvp.killscore.score .. "\\n" ) + insert(result, '\\n') + insert(result, 'MVP Builder: \\n') + insert(result, mvp.built_entities.name .. " built " .. mvp.built_entities.score .. " things\\n" ) + insert(result, '\\n') + insert(result, 'MVP Deaths: \\n') + insert(result, mvp.deaths.name .. " died " .. mvp.deaths.score .. " times" ) + local message = table.concat(result) + server_commands.to_discord_embed(message) + global.results_sent_south = true + end + end +end + local function on_entity_died(event) if not event.entity.valid then return end if event.entity.name ~= "rocket-silo" then return end if event.entity == global.rocket_silo.south or event.entity == global.rocket_silo.north then for _, player in pairs(game.connected_players) do player.play_sound{path="utility/game_won", volume_modifier=1} - end - fireworks(surface) + end + show_mvps(player) + fireworks(surface) end end diff --git a/maps/biter_battles_v2/gui.lua b/maps/biter_battles_v2/gui.lua index 99a8bcaa..85658096 100644 --- a/maps/biter_battles_v2/gui.lua +++ b/maps/biter_battles_v2/gui.lua @@ -1,7 +1,319 @@ local event = require 'utils.event' -local function on_gui_click(event) +local food_names = { + ["automation-science-pack"] = "automation science", + ["logistic-science-pack"] = "logistic science", + ["military-science-pack"] = "military science", + ["chemical-science-pack"] = "chemical science", + ["production-science-pack"] = "production science", + ["utility-science-pack"] = "utility science", + ["space-science-pack"] = "space science" +} + +local food_values = { + ["automation-science-pack"] = 100, + ["logistic-science-pack"] = 292, + ["military-science-pack"] = 1225, + ["chemical-science-pack"] = 2392, + ["production-science-pack"] = 8000, + ["utility-science-pack"] = 13875, + ["space-science-pack"] = 42000 +} + +local function create_sprite_button(player) + if player.gui.top["bb_toggle_button"] then return end + local button = player.gui.top.add { name = "bb_toggle_button", type = "sprite-button", sprite = "entity/behemoth-spitter" } + button.style.font = "default-bold" + button.style.minimal_height = 38 + button.style.minimal_width = 38 + button.style.top_padding = 2 + button.style.left_padding = 4 + button.style.right_padding = 4 + button.style.bottom_padding = 2 +end + +local function create_first_join_gui(player) + if not global.game_lobby_timeout then global.game_lobby_timeout = 5999940 end + if global.game_lobby_timeout - game.tick < 0 then global.game_lobby_active = false end + local frame = player.gui.left.add { type = "frame", name = "bb_main_gui", direction = "vertical" } + local b = frame.add{ type = "label", caption = "Defend your team´s rocket silo!" } + b.style.font = "default-bold" + b.style.font_color = { r=0.98, g=0.66, b=0.22} + local b = frame.add { type = "label", caption = "Feed the enemy team´s biters to gain advantage!" } + b.style.font = "default-bold" + b.style.font_color = { r=0.98, g=0.66, b=0.22} + frame.add { type = "label", caption = "-----------------------------------------------------------"} + local c = "JOIN NORTH" + local font_color = {r = 0.55, g = 0.55, b = 0.99} + if global.game_lobby_active then + font_color = { r=0.7, g=0.7, b=0.7} + c = c .. " (waiting for players... " + c = c .. math.ceil((global.game_lobby_timeout - game.tick)/60) + c = c .. ")" + end + local t = frame.add { type = "table", column_count = 4 } + for _, p in pairs(game.forces.north.connected_players) do + local color = {} + color = p.color + color.r = color.r * 0.6 + 0.4 + color.g = color.g * 0.6 + 0.4 + color.b = color.b * 0.6 + 0.4 + color.a = 1 + local l = t.add { type = "label", caption = p.name } + l.style.font_color = color + end + local b = frame.add { type = "sprite-button", name = "join_north_button", caption = c } + b.style.font = "default-large-bold" + b.style.font_color = font_color + b.style.minimal_width = 350 + frame.add { type = "label", caption = "-----------------------------------------------------------"} + local c = "JOIN SOUTH" + local font_color = {r = 0.99, g = 0.33, b = 0.33} + if global.game_lobby_active then + font_color = { r=0.7, g=0.7, b=0.7} + c = c .. " (waiting for players... " + c = c .. math.ceil((global.game_lobby_timeout - game.tick)/60) + c = c .. ")" + end + local t = frame.add { type = "table", column_count = 4 } + for _, p in pairs(game.forces.south.connected_players) do + local color = {} + color = p.color + color.r = color.r * 0.6 + 0.4 + color.g = color.g * 0.6 + 0.4 + color.b = color.b * 0.6 + 0.4 + color.a = 1 + local l = t.add { type = "label", caption = p.name } + l.style.font_color = color + end + local b = frame.add { type = "sprite-button", name = "join_south_button", caption = c } + b.style.font = "default-large-bold" + b.style.font_color = font_color + b.style.minimal_width = 350 +end + +local function create_main_gui(player) + if player.gui.left["bb_main_gui"] then player.gui.left["bb_main_gui"].destroy() end + if player.force.name == "player" then create_first_join_gui(player) return end + + local frame = player.gui.left.add { type = "frame", name = "bb_main_gui", direction = "vertical" } + + if player.force.name ~= "spectator" then + frame.add { type = "table", name = "biter_battle_table", column_count = 4 } + local t = frame.biter_battle_table + local foods = {"automation-science-pack","logistic-science-pack","military-science-pack","chemical-science-pack","production-science-pack","utility-science-pack","space-science-pack","raw-fish"} + local food_tooltips = {"1 Mutagen factor","3 Mutagen factor", "12 Mutagen factor", "24 Mutagen factor", "80 Mutagen factor", "138 Mutagen factor", "420 Mutagen factor", "Send spy"} + local x = 1 + for _, f in pairs(foods) do + local s = t.add { type = "sprite-button", name = f, sprite = "item/" .. f } + s.tooltip = {"",food_tooltips[x]} + x = x + 1 + end + end + + local t = frame.add { type = "table", column_count = 3 } + local l = t.add { type = "label", caption = "Team North"} + l.style.font = "default-bold" + l.style.font_color = {r = 0.55, g = 0.55, b = 0.99} + local l = t.add { type = "label", caption = " - "} + local l = t.add { type = "label", caption = #game.forces["north"].connected_players .. " Players "} + l.style.font_color = { r=0.22, g=0.88, b=0.22} + + + if global.bb_view_players[player.name] == true then + local t = frame.add { type = "table", column_count = 4 } + for _, p in pairs(game.forces.north.connected_players) do + local color = {} + color = p.color + color.r = color.r * 0.6 + 0.4 + color.g = color.g * 0.6 + 0.4 + color.b = color.b * 0.6 + 0.4 + color.a = 1 + local l = t.add { type = "label", caption = p.name } + l.style.font_color = color + end + end + + local t = frame.add { type = "table", column_count = 4 } + local l = t.add { type = "label", caption = "Nerf: "} + l.style.minimal_width = 25 + l.tooltip = "Damage nerf of the team." + local l = t.add { type = "label", caption = "NERF "} + l.style.minimal_width = 40 + l.style.font_color = {r = 0.66, g = 0.66, b = 0.99} + l.style.font = "default-bold" + local l = t.add { type = "label", caption = " Biter Rage: "} + l.style.minimal_width = 25 + l.tooltip = "Increases damage and the amount of angry biters." + local l = t.add { type = "label", caption = "RAGE"} + l.style.font_color = {r = 0.66, g = 0.66, b = 0.99} + l.style.font = "default-bold" + l.style.minimal_width = 25 + frame.add { type = "label", caption = "--------------------------"} + local t = frame.add { type = "table", column_count = 3 } + local l = t.add { type = "label", caption = "Team South"} + l.style.font = "default-bold" + l.style.font_color = {r = 0.99, g = 0.33, b = 0.33} + local l = t.add { type = "label", caption = " - "} + local l = t.add { type = "label", caption = #game.forces["south"].connected_players .. " Players "} + l.style.font_color = { r=0.22, g=0.88, b=0.22} + + + if global.bb_view_players[player.name] == true then + local t = frame.add { type = "table", column_count = 4 } + for _, p in pairs(game.forces.south.connected_players) do + local color = {} + color = p.color + color.r = color.r * 0.6 + 0.4 + color.g = color.g * 0.6 + 0.4 + color.b = color.b * 0.6 + 0.4 + color.a = 1 + local l = t.add { type = "label", caption = p.name } + l.style.font_color = color + end + end + + local t = frame.add { type = "table", column_count = 4 } + local l = t.add { type = "label", caption = "Nerf: "} + l.tooltip = "Damage nerf of the team." + l.style.minimal_width = 25 + local l = t.add { type = "label", caption = "NERF"} + l.style.minimal_width = 40 + l.style.font_color = {r = 0.99, g = 0.44, b = 0.44} + l.style.font = "default-bold" + local l = t.add { type = "label", caption = " Biter Rage: "} + l.style.minimal_width = 25 + l.tooltip = "Increases damage and the amount of angry biters." + local l = t.add { type = "label", caption = "RAGE"} + l.style.font_color = {r = 0.99, g = 0.44, b = 0.44} + l.style.font = "default-bold" + l.style.minimal_width = 25 + + local t = frame.add { type = "table", column_count = 2 } + if player.force.name == "spectator" then + local b = t.add { type = "sprite-button", name = "bb_leave_spectate", caption = "Join Team" } + else + local b = t.add { type = "sprite-button", name = "bb_spectate", caption = "Spectate" } + end + + if global.bb_view_players[player.name] == true then + local b = t.add { type = "sprite-button", name = "bb_hide_players", caption = "Playerlist" } + else + local b = t.add { type = "sprite-button", name = "bb_view_players", caption = "Playerlist" } + end + for _, b in pairs(t.children) do + b.style.font = "default-bold" + b.style.font_color = { r=0.98, g=0.66, b=0.22} + b.style.top_padding = 1 + b.style.left_padding = 1 + b.style.right_padding = 1 + b.style.bottom_padding = 1 + b.style.maximal_height = 30 + b.style.minimal_width = 86 + end +end + +local function refresh_gui() + for _, player in pairs(game.connected_players) do + if player.gui.left["bb_main_gui"] then + player.gui.left["bb_main_gui"].destroy() + create_main_gui(player) + end + end +end + +local function join_team(player, force_name) + if not global.chosen_team then global.chosen_team = {} end + local surface = player.surface + + if global.chosen_team[player.name] then + local p = surface.find_non_colliding_position("player", game.forces[global.chosen_team[player.name]].get_spawn_position(surface), 3, 1) + player.teleport(p, surface) + player.force = game.forces[force_name] + local p = game.permissions.get_group("Default") + p.add_player(player.name) + game.print("Team " .. player.force.name .. " player " .. player.name .. " is no longer spectating.", {r=0.98, g=0.66, b=0.22}) + return + end + + local enemy_team = "south" + if force_name == "south" then enemy_team = "north" end + + if #game.forces[force_name].connected_players > #game.forces[enemy_team].connected_players then + player.print("Team " .. force_name .. " has too many players currently.", {r=0.98, g=0.66, b=0.22}) + else + player.teleport(surface.find_non_colliding_position("player", game.forces[force_name].get_spawn_position(surface), 3, 1)) + player.force = game.forces[force_name] + game.print(player.name .. " has joined team " .. player.force.name .. "!", {r=0.98, g=0.66, b=0.22}) + local i = player.get_inventory(defines.inventory.player_main) + player.insert {name = 'pistol', count = 1} + player.insert {name = 'raw-fish', count = 3} + player.insert {name = 'firearm-magazine', count = 16} + player.insert {name = 'iron-gear-wheel', count = 4} + player.insert {name = 'iron-plate', count = 8} + global.chosen_team[player.name] = force_name + end +end + +local function join_gui_click(name, player) + local team = { + ["join_north_button"] = "north", + ["join_south_button"] = "south" + } + + if global.game_lobby_active then + if player.admin then + join_team(player, team[name]) + game.print("Lobby disabled, admin override.", { r=0.98, g=0.66, b=0.22}) + global.game_lobby_active = false + return + end + player.print("Waiting for more players to join the game.", { r=0.98, g=0.66, b=0.22}) + return + end + join_team(player, team[name]) +end + +local function on_gui_click(event) + if not event.element then return end + if not event.element.valid then return end + local player = game.players[event.player_index] + local name = event.element.name + if name == "bb_toggle_button" then + if player.gui.left["bb_main_gui"] then + player.gui.left["bb_main_gui"].destroy() + else + create_main_gui(player) + end + return + end + + if player.force.name == "player" then join_gui_click(name, player) return end + + --if food_names[name] then feed_the_biters(player, name) return end + + if name == "bb_spectate" then + if player.position.y < 100 and player.position.y > -100 and player.position.x < 100 and player.position.x > -100 then + --join_team(player, "spectator") + else + player.print("You are too far away from spawn to spectate.",{ r=0.98, g=0.66, b=0.22}) + end + end +end + +local function on_player_joined_game(event) + local player = game.players[event.player_index] + + if not global.bb_view_players then global.bb_view_players = {} end + global.bb_view_players[player.name] = false + + create_sprite_button(player) + if player.online_time ~= 0 then return end + create_main_gui(player) end event.add(defines.events.on_gui_click, on_gui_click) +event.add(defines.events.on_player_joined_game, on_player_joined_game) + +return refresh_gui \ No newline at end of file diff --git a/maps/biter_battles_v2/mirror_terrain.lua b/maps/biter_battles_v2/mirror_terrain.lua index fc80de0f..4cd159cd 100644 --- a/maps/biter_battles_v2/mirror_terrain.lua +++ b/maps/biter_battles_v2/mirror_terrain.lua @@ -133,8 +133,8 @@ local function on_chunk_generated(event) local y = ((event.area.left_top.y + 16) * -1) - 16 local mirror_chunk_area = {left_top = {x = x, y = y}, right_bottom = {x = x + 32, y = y + 32}} - if not global.on_tick_schedule[game.tick + 1] then global.on_tick_schedule[game.tick + 1] = {} end - global.on_tick_schedule[game.tick + 1][#global.on_tick_schedule[game.tick + 1] + 1] = { + if not global.on_tick_schedule[game.tick + 5] then global.on_tick_schedule[game.tick + 5] = {} end + global.on_tick_schedule[game.tick + 5][#global.on_tick_schedule[game.tick + 5] + 1] = { func = mirror_chunk, args = {surface, mirror_chunk_area, get_chunk_position({x = x, y = y})} } diff --git a/maps/biter_battles_v2/on_tick.lua b/maps/biter_battles_v2/on_tick.lua index c54cbaaa..d0ef54b6 100644 --- a/maps/biter_battles_v2/on_tick.lua +++ b/maps/biter_battles_v2/on_tick.lua @@ -2,12 +2,10 @@ local event = require 'utils.event' local gui = require "maps.biter_battles_v2.gui" local ai = require "maps.biter_battles_v2.ai" -local pregenerate_chunks = require "maps.biter_battles_v2.pregenerate_chunks" local function on_tick(event) - if game.tick % 5 ~= 0 then return end - pregenerate_chunks() - if game.tick % 60 ~= 0 then return end + if game.tick % 60 ~= 0 then return end + gui() end event.add(defines.events.on_tick, on_tick) diff --git a/maps/biter_battles_v2/pregenerate_chunks.lua b/maps/biter_battles_v2/pregenerate_chunks.lua index 7dd80ae5..f16993b4 100644 --- a/maps/biter_battles_v2/pregenerate_chunks.lua +++ b/maps/biter_battles_v2/pregenerate_chunks.lua @@ -1,45 +1,57 @@ -local function set_chunk_coords() +local event = require 'utils.event' + +local function set_chunk_coords(radius) global.chunk_gen_coords = {} - for r = 14, 1, -1 do + for r = radius, 1, -1 do for x = r * -1, r - 1, 1 do - table.insert(global.chunk_gen_coords, {x = x, y = r * -1}) + local pos = {x = x, y = r * -1} + if math.sqrt(pos.x ^ 2 + pos.y ^ 2) <= radius then table.insert(global.chunk_gen_coords, pos) end end for y = r * -1, r - 1, 1 do - table.insert(global.chunk_gen_coords, {x = r, y = y}) + local pos = {x = r, y = y} + if math.sqrt(pos.x ^ 2 + pos.y ^ 2) <= radius then table.insert(global.chunk_gen_coords, pos) end end for x = r, r * -1 + 1, -1 do - table.insert(global.chunk_gen_coords, {x = x, y = r}) + local pos = {x = x, y = r} + if math.sqrt(pos.x ^ 2 + pos.y ^ 2) <= radius then table.insert(global.chunk_gen_coords, pos) end end for y = r, r * -1 + 1, -1 do - table.insert(global.chunk_gen_coords, {x = r * -1, y = y}) + local pos = {x = r * -1, y = y} + if math.sqrt(pos.x ^ 2 + pos.y ^ 2) <= radius then table.insert(global.chunk_gen_coords, pos) end end end end local function draw_gui() - for _, player in pairs(game.connected_players) do - if player.gui.left["map_pregen"] then player.gui.left["map_pregen"].destroy() end - if not global.map_generation_complete then - local frame = player.gui.left.add({ - type = "frame", - caption = "Map is generating... " .. #global.chunk_gen_coords .. " chunks left.", - name = "map_pregen" - }) - frame.style.font_color = {r = 100, g = 100, b = 250} - frame.style.font = "heading-2" + for _, player in pairs(game.connected_players) do + if global.map_generation_complete then + if player.gui.left["map_pregen"] then player.gui.left["map_pregen"].destroy() end + else + local caption = "Map is generating... " .. #global.chunk_gen_coords .. " chunks left." + if player.gui.left["map_pregen"] then + player.gui.left["map_pregen"].caption = caption + else + local frame = player.gui.left.add({ + type = "frame", + caption = caption, + name = "map_pregen" + }) + frame.style.font_color = {r = 100, g = 100, b = 250} + frame.style.font = "heading-2" + frame.style.maximal_height = 36 + end end end end -local function process_chunk() - if global.map_generation_complete then draw_gui() return end - if not global.chunk_gen_coords then set_chunk_coords() end +local function process_chunk(surface) + if global.map_generation_complete then return end if #global.chunk_gen_coords == 0 then global.map_generation_complete = true draw_gui() return end - local surface = game.surfaces["biter_battles"] + for i = #global.chunk_gen_coords, 1, -1 do if surface.is_chunk_generated(global.chunk_gen_coords[i]) then global.chunk_gen_coords[i] = nil @@ -53,4 +65,19 @@ local function process_chunk() draw_gui() end -return process_chunk \ No newline at end of file +local function create_schedule(radius) + set_chunk_coords(radius) + for t = 15, #global.chunk_gen_coords * 15 + 15, 15 do + if not global.on_tick_schedule[game.tick + t] then global.on_tick_schedule[game.tick + t] = {} end + global.on_tick_schedule[game.tick + t][#global.on_tick_schedule[game.tick + t] + 1] = { + func = process_chunk, + args = {game.surfaces["biter_battles"]} + } + end +end + +local function on_player_joined_game(event) + if not global.chunk_gen_coords then create_schedule(16) end +end + +event.add(defines.events.on_player_joined_game, on_player_joined_game) \ No newline at end of file diff --git a/maps/biter_battles_v2/terrain.lua b/maps/biter_battles_v2/terrain.lua index b4dd5f82..2817ce5d 100644 --- a/maps/biter_battles_v2/terrain.lua +++ b/maps/biter_battles_v2/terrain.lua @@ -3,20 +3,7 @@ local event = require 'utils.event' local math_random = math.random local simplex_noise = require 'utils.simplex_noise'.d2 local create_tile_chain = require "functions.create_tile_chain" -local biter_territory_starting_radius = 256 local spawn_circle_size = 28 - -local worms = { - [1] = {"small-worm-turret"}, - [2] = {"medium-worm-turret", "small-worm-turret"}, - [3] = {"medium-worm-turret"}, - [4] = {"big-worm-turret", "medium-worm-turret"}, - [5] = {"big-worm-turret"}, - [6] = {"behemoth-worm-turret","big-worm-turret"}, - [7] = {"behemoth-worm-turret"} - } - -local spawners = {"biter-spawner", "biter-spawner", "spitter-spawner"} local function get_noise(name, pos) local seed = game.surfaces[1].map_gen_settings.seed @@ -33,44 +20,6 @@ local function get_noise(name, pos) end end -local function get_worm(distance_to_center) - local index = math.ceil((distance_to_center - biter_territory_starting_radius) * 0.01) - if index < 1 then index = 1 end - if index > 7 then index = 7 end - local worm = worms[index][math_random(1, #worms[index])] - return worm -end - -local function generate_biters(surface, pos, distance_to_center) - if distance_to_center < biter_territory_starting_radius then return end - if pos.y > -16 then return end - - if distance_to_center < biter_territory_starting_radius + 32 then - if math_random(1, 128) == 1 and surface.can_place_entity({name = "behemoth-worm-turret", position = pos}) then - surface.create_entity({name = get_worm(distance_to_center), position = pos, force = "north_biters"}) - end - return - end - - local noise = get_noise(1, pos) - - if noise > 0.5 or noise < -0.5 then - if math_random(1,12) == 1 and surface.can_place_entity({name = "rocket-silo", position = pos}) then - surface.create_entity({name = spawners[math_random(1,3)], position = pos, force = "north_biters"}) - end - return - end - - if noise > 0.4 or noise < -0.4 then - if math_random(1,48) == 1 then - if surface.can_place_entity({name = "behemoth-worm-turret", position = pos}) then - surface.create_entity({name = get_worm(distance_to_center), position = pos, force = "north_biters"}) - end - end - return - end -end - local function generate_horizontal_river(surface, pos) if pos.y < -32 then return false end if pos.y > -3 and pos.x > -3 and pos.x < 3 then return false end @@ -118,15 +67,9 @@ local function generate_silos(event) end end -local function on_chunk_generated(event) - if event.area.left_top.y >= 0 then return end +local function generate_river(event) + if event.area.left_top.y < -32 then return end local surface = event.surface - if surface.name ~= "biter_battles" then return end - - for _, e in pairs(surface.find_entities_filtered({area = event.area, force = "enemy"})) do - e.destroy() - end - local left_top_x = event.area.left_top.x local left_top_y = event.area.left_top.y for x = 0, 31, 1 do @@ -134,15 +77,28 @@ local function on_chunk_generated(event) local pos = {x = left_top_x + x, y = left_top_y + y} local distance_to_center = math.sqrt(pos.x ^ 2 + pos.y ^ 2) if generate_horizontal_river(surface, pos) then surface.set_tiles({{name = "deepwater", position = pos}}) end - generate_biters(surface, pos, distance_to_center) end end +end + +local function on_chunk_generated(event) + if event.area.left_top.y >= 0 then return end + local surface = event.surface + if surface.name ~= "biter_battles" then return end + for _, e in pairs(surface.find_entities_filtered({area = event.area, force = "enemy"})) do + surface.create_entity({name = e.name, position = e.position, force = "north_biters", direction = e.direction}) + e.destroy() + end + + generate_river(event) generate_circle_spawn(event) generate_silos(event) - if event.area.left_top.y == -256 and event.area.left_top.x == -256 then - global.terrain_generation_complete = true + if event.area.left_top.y == -160 and event.area.left_top.x == -160 then + for _, e in pairs(surface.find_entities_filtered({area = {{-8,-8},{8,8}}})) do + if e.name ~= "player" then e.destroy() end + end end end diff --git a/maps/biter_battles_v2/terrain_old.lua b/maps/biter_battles_v2/terrain_old.lua new file mode 100644 index 00000000..93c42cea --- /dev/null +++ b/maps/biter_battles_v2/terrain_old.lua @@ -0,0 +1,199 @@ +-- Terrain for Biter Battles -- by MewMew +local event = require 'utils.event' +local math_random = math.random +local simplex_noise = require 'utils.simplex_noise'.d2 +local create_tile_chain = require "functions.create_tile_chain" +local biter_territory_starting_radius = 1024 +local spawn_circle_size = 28 + +local worms = { + [1] = {"small-worm-turret"}, + [2] = {"medium-worm-turret", "small-worm-turret"}, + [3] = {"medium-worm-turret"}, + [4] = {"big-worm-turret", "medium-worm-turret"}, + [5] = {"big-worm-turret"}, + [6] = {"behemoth-worm-turret","big-worm-turret"}, + [7] = {"behemoth-worm-turret"} + } + +local spawners = {"biter-spawner", "biter-spawner", "spitter-spawner"} + +local function get_noise(name, pos) + local seed = game.surfaces[1].map_gen_settings.seed + local noise_seed_add = 25000 + if name == 1 then + local noise = {} + noise[1] = simplex_noise(pos.x * 0.005, pos.y * 0.005, seed) + seed = seed + noise_seed_add + noise[2] = simplex_noise(pos.x * 0.05, pos.y * 0.05, seed) + seed = seed + noise_seed_add + local noise = noise[1] + noise[2] * 0.1 + --noise = noise * 0.5 + return noise + end +end + +local function get_worm(distance_to_center) + local index = math.ceil((distance_to_center - biter_territory_starting_radius) * 0.01) + if index < 1 then index = 1 end + if index > 7 then index = 7 end + local worm = worms[index][math_random(1, #worms[index])] + return worm +end + +local function generate_biters(surface, pos, distance_to_center) + if distance_to_center < biter_territory_starting_radius then return end + if pos.y > -16 then return end + + if distance_to_center < biter_territory_starting_radius + 32 then + if math_random(1, 128) == 1 and surface.can_place_entity({name = "behemoth-worm-turret", position = pos}) then + surface.create_entity({name = get_worm(distance_to_center), position = pos, force = "north_biters"}) + end + return + end + + local noise = get_noise(1, pos) + + if noise > 0.5 or noise < -0.5 then + if math_random(1,12) == 1 and surface.can_place_entity({name = "rocket-silo", position = pos}) then + surface.create_entity({name = spawners[math_random(1,3)], position = pos, force = "north_biters"}) + end + return + end + + if noise > 0.4 or noise < -0.4 then + if math_random(1,48) == 1 then + if surface.can_place_entity({name = "behemoth-worm-turret", position = pos}) then + surface.create_entity({name = get_worm(distance_to_center), position = pos, force = "north_biters"}) + end + end + return + end +end + +local function generate_horizontal_river(surface, pos) + if pos.y < -32 then return false end + if pos.y > -3 and pos.x > -3 and pos.x < 3 then return false end + if -14 < pos.y + (get_noise(1, pos) * 5) then return true end + return false +end + +local function generate_circle_spawn(event) + if event.area.left_top.y < -64 then return end + if event.area.left_top.x < -64 then return end + if event.area.left_top.x > 64 then return end + local surface = event.surface + local left_top_x = event.area.left_top.x + local left_top_y = event.area.left_top.y + for x = 0, 31, 1 do + for y = 0, 31, 1 do + local pos = {x = left_top_x + x, y = left_top_y + y} + local distance_to_center = math.sqrt(pos.x ^ 2 + pos.y ^ 2) + + local tile = false + if distance_to_center < spawn_circle_size then tile = "deepwater" end + if distance_to_center < 9 then tile = "refined-concrete" end + if distance_to_center < 6 then tile = "sand-1" end + if tile then surface.set_tiles({{name = tile, position = pos}}, true) end + end + end +end + +local function generate_silos(event) + if global.rocket_silo then return end + if event.area.left_top.y < -128 then return end + if event.area.left_top.x < -128 then return end + if event.area.left_top.x > 128 then return end + global.rocket_silo = {} + local surface = event.surface + global.rocket_silo["north"] =surface.create_entity({ + name = "rocket-silo", + position = surface.find_non_colliding_position("rocket-silo", {0,-64}, 128, 1), + force = "north" + }) + global.rocket_silo["north"].minable = false + + for i = 1, 32, 1 do + create_tile_chain(surface, {name = "stone-path", position = global.rocket_silo["north"].position}, 32, 10) + end +end + +local function on_chunk_generated(event) + if event.area.left_top.y >= 0 then return end + local surface = event.surface + if surface.name ~= "biter_battles" then return end + + for _, e in pairs(surface.find_entities_filtered({area = event.area, force = "enemy"})) do + e.destroy() + end + + local left_top_x = event.area.left_top.x + local left_top_y = event.area.left_top.y + for x = 0, 31, 1 do + for y = 0, 31, 1 do + local pos = {x = left_top_x + x, y = left_top_y + y} + local distance_to_center = math.sqrt(pos.x ^ 2 + pos.y ^ 2) + if generate_horizontal_river(surface, pos) then surface.set_tiles({{name = "deepwater", position = pos}}) end + generate_biters(surface, pos, distance_to_center) + end + end + + generate_circle_spawn(event) + generate_silos(event) + + if event.area.left_top.y == -256 and event.area.left_top.x == -256 then + global.terrain_generation_complete = true + end +end + +--Landfill Restriction +local function restrict_landfill(surface, inventory, tiles) + for _, t in pairs(tiles) do + local distance_to_center = math.sqrt(t.position.x ^ 2 + t.position.y ^ 2) + local check_position = t.position + if check_position.y > 0 then check_position = {x = check_position.x * -1, y = (check_position.y * -1) - 1} end + if generate_horizontal_river(surface, check_position) or distance_to_center < spawn_circle_size then + surface.set_tiles({{name = t.old_tile.name, position = t.position}}, true) + inventory.insert({name = "landfill", count = 1}) + end + end +end +local function on_player_built_tile(event) + local player = game.players[event.player_index] + restrict_landfill(player.surface, player, event.tiles) +end +local function on_robot_built_tile(event) + restrict_landfill(event.robot.surface, event.robot.get_inventory(defines.inventory.robot_cargo), event.tiles) +end + +--Construction Robot Restriction +local function on_robot_built_entity(event) + local deny_building = false + local force_name = event.robot.force.name + if force_name == "north" then + if event.created_entity.position.y >= -10 then deny_building = true end + end + if force_name == "player" then + if event.created_entity.position.y <= 10 then deny_building = true end + end + if not deny_building then return end + local inventory = event.robot.get_inventory(defines.inventory.robot_cargo) + inventory.insert({name = event.created_entity.name, count = 1}) + event.robot.surface.create_entity({name = "explosion", position = event.created_entity.position}) + event.created_entity.destroy() +end + +--Prevent Players from damaging the Rocket Silo +local function on_entity_damaged(event) + if event.cause then + if event.cause.type == "unit" then return end + end + if event.entity.name ~= "rocket-silo" then return end + event.entity.health = event.entity.health + event.final_damage_amount +end + +event.add(defines.events.on_entity_damaged, on_entity_damaged) +event.add(defines.events.on_robot_built_entity, on_robot_built_entity) +event.add(defines.events.on_robot_built_tile, on_robot_built_tile) +event.add(defines.events.on_player_built_tile, on_player_built_tile) +event.add(defines.events.on_chunk_generated, on_chunk_generated) \ No newline at end of file