-- Biter Battles -- mewmew made this -- --luacheck:ignore local Server = require 'utils.server' local Score = require 'utils.gui.score' local Global = require 'utils.global' require 'modules.splice_double' require 'modules.explosive_biters' require 'modules.spawners_contain_biters' require 'modules.custom_death_messages' local biter_battles_terrain = require 'maps.biter_battles.biter_battles_terrain' local event = require 'utils.event' local math_random = math.random local insert = table.insert local traps = {} Global.register( traps, function(t) traps = t end ) 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'] = 0.00000100, ['logistic-science-pack'] = 0.00000292, ['military-science-pack'] = 0.00001225, ['chemical-science-pack'] = 0.00002392, ['production-science-pack'] = 0.00008000, ['utility-science-pack'] = 0.00013875, ['space-science-pack'] = 0.00042000 } local function get_border_cords(f) local a = {{-1000, -1000}, {1000, -10}} if f == 'south' then a = {{-1000, 10}, {1000, 1000}} end local entities = game.surfaces['surface'].find_entities_filtered {area = a, force = f} if not entities then return end local x_top = entities[1].position.x local y_top = entities[1].position.y local x_bot = entities[1].position.x local y_bot = entities[1].position.y for _, e in pairs(entities) do if e.position.x < x_top then x_top = e.position.x end if e.position.y < y_top then y_top = e.position.y end if e.position.x > x_bot then x_bot = e.position.x end if e.position.y > y_bot then y_bot = e.position.y end end global.force_area[f] = {} global.force_area[f].x_top = x_top global.force_area[f].y_top = y_top global.force_area[f].x_bot = x_bot global.force_area[f].y_bot = y_bot --game.print(x_top .. " " .. y_top .. " , ".. x_bot .. " " .. y_bot) end local function create_biter_battle_sprite_button(player) if player.gui.top.biter_battle_toggle_menu_button == nil then local button = player.gui.top.add {name = 'biter_battle_toggle_menu_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 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) local get_score = Score.get_table().score_table if not get_score[force] then return false end local score = get_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) local get_score = Score.get_table().score_table if not get_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.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.to_discord_embed(message) global.results_sent_south = true end end end local function create_biter_battle_menu(player) if global.rocket_silo_destroyed then local frame = player.gui.left.add {type = 'frame', name = 'victory_popup', direction = 'vertical'} local l = frame.add {type = 'label', caption = global.rocket_silo_destroyed, single_line = false, name = 'victory_caption'} l.style.font = 'default-listbox' l.style.font_color = {r = 0.98, g = 0.66, b = 0.22} l.style.top_padding = 10 l.style.left_padding = 20 l.style.right_padding = 20 l.style.bottom_padding = 10 show_mvps(player) return end if player.gui.left['biter_battle_menu'] then player.gui.left['biter_battle_menu'].destroy() end local frame = player.gui.left.add {type = 'frame', name = 'biter_battle_menu', direction = 'vertical'} if player.force.name == 'north' or player.force.name == 'south' 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 Calorie', '3 Calories', '12 Calories', '24 Calories', '80 Calories', '138 Calories', '420 Calories', '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 if player.force.name == 'player' then 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 = '-----------------------------------------------------------'} 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 player.force.name ~= 'player' then if global.biter_battle_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 = math.round(global.team_nerf['north'] * 100, 1) .. ' '} 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 = math.round(global.biter_rage['north'], 0)} l.style.font_color = {r = 0.66, g = 0.66, b = 0.99} l.style.font = 'default-bold' l.style.minimal_width = 25 end if player.force.name == 'player' then 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.round((global.game_lobby_timeout - game.tick) / 60, 0) 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 = '-----------------------------------------------------------'} else frame.add {type = 'label', caption = '--------------------------'} end 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 player.force.name ~= 'player' then if global.biter_battle_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 = math.round(global.team_nerf['south'] * 100, 1) .. ' '} 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 = math.round(global.biter_rage['south'], 0)} l.style.font_color = {r = 0.99, g = 0.44, b = 0.44} l.style.font = 'default-bold' l.style.minimal_width = 25 end if player.force.name == 'player' then 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.round((global.game_lobby_timeout - game.tick) / 60, 0) 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 if global.team_chosen[player.name] then local t = frame.add {type = 'table', column_count = 2} if player.force.name == 'spectator' then local b = t.add {type = 'sprite-button', name = 'biter_battle_leave_spectate', caption = 'Join Team'} else local b = t.add {type = 'sprite-button', name = 'biter_battle_spectate', caption = 'Spectate'} end if global.biter_battle_view_players[player.name] == true then local b = t.add {type = 'sprite-button', name = 'biter_battle_hide_players', caption = 'Playerlist'} else local b = t.add {type = 'sprite-button', name = 'biter_battle_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 end local function refresh_gui() for _, player in pairs(game.connected_players) do local frame = player.gui.left['biter_battle_menu'] if (frame) then frame.destroy() create_biter_battle_menu(player) end end end local function join_team(player, team) local surface = game.surfaces['surface'] local enemy_team = 'south' if team == 'south' then enemy_team = 'north' end if team == 'north' or team == 'south' then if #game.forces[team].connected_players > #game.forces[enemy_team].connected_players and global.team_chosen[player.name] == nil then player.print('Team ' .. team .. ' has too many players currently.', {r = 0.98, g = 0.66, b = 0.22}) else player.teleport(surface.find_non_colliding_position('character', game.forces[team].get_spawn_position(surface), 3, 1)) player.force = game.forces[team] if global.team_chosen[player.name] then 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}) else 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.character_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.team_chosen[player.name] = team end end end if team == 'spectator' then player.teleport(surface.find_non_colliding_position('character', {0, 0}, 2, 1)) player.force = game.forces[team] game.print(player.name .. ' is spectating.', {r = 0.98, g = 0.66, b = 0.22}) local permission_group = game.permissions.get_group('spectator') if not permission_group then permission_group = game.permissions.create_group('spectator') for action_name, _ in pairs(defines.input_action) do permission_group.set_allows_action(defines.input_action[action_name], false) end permission_group.set_allows_action(defines.input_action.write_to_console, true) permission_group.set_allows_action(defines.input_action.gui_click, true) permission_group.set_allows_action(defines.input_action.gui_selection_state_changed, true) permission_group.set_allows_action(defines.input_action.start_walking, true) permission_group.set_allows_action(defines.input_action.open_kills_gui, true) permission_group.set_allows_action(defines.input_action.open_character_gui, true) --permission_group.set_allows_action(defines.input_action.open_equipment_gui, true) permission_group.set_allows_action(defines.input_action.edit_permission_group, true) permission_group.set_allows_action(defines.input_action.toggle_show_entity_info, true) end permission_group.add_player(player.name) global.spectator_spam_protection[player.name] = game.tick end refresh_gui() end local function reveal_team(f) local m = 32 if f == 'north' then game.forces['south'].chart(game.surfaces['surface'], {{x = global.force_area[f].x_top - m, y = global.force_area[f].y_top - m}, {x = global.force_area[f].x_bot + m, y = global.force_area[f].y_bot + m}}) else game.forces['north'].chart(game.surfaces['surface'], {{x = global.force_area[f].x_top - m, y = global.force_area[f].y_top - m}, {x = global.force_area[f].x_bot + m, y = global.force_area[f].y_bot + m}}) end end local function on_player_joined_game(event) local player = game.players[event.player_index] if not global.horizontal_border_width then global.horizontal_border_width = 16 end if not global.biter_battles_init_done then local map_gen_settings = {} map_gen_settings.water = 'none' 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'} } game.create_surface('surface', map_gen_settings) game.map_settings.enemy_evolution.time_factor = 0.000004 game.map_settings.enemy_evolution.destroy_factor = 0.0035 game.map_settings.enemy_evolution.pollution_factor = 0.0000025 game.map_settings.enemy_expansion.enabled = true game.map_settings.enemy_expansion.min_expansion_cooldown = 18000 game.map_settings.enemy_expansion.max_expansion_cooldown = 72000 local surface = game.surfaces['surface'] game.create_force('north') game.create_force('south') game.create_force('spectator') --game.create_force("map_pregen") global.game_lobby_active = true global.game_lobby_timeout = 599940 global.biter_battle_view_players = {} global.spectator_spam_protection = {} global.force_area = {} global.team_chosen = {} global.team_nerf = {} global.biter_rage = {} global.spy_fish_timeout = {} local force_names = {'north', 'south'} for _, name in pairs(force_names) do game.forces[name].technologies['artillery'].enabled = false game.forces[name].technologies['artillery-shell-range-1'].enabled = false game.forces[name].technologies['artillery-shell-speed-1'].enabled = false --game.forces[name].technologies["refined-flammables-1"].enabled = false --game.forces[name].technologies["refined-flammables-2"].enabled = false --game.forces[name].technologies["refined-flammables-3"].enabled = false game.forces[name].technologies['refined-flammables-4'].enabled = false game.forces[name].technologies['refined-flammables-5'].enabled = false game.forces[name].technologies['refined-flammables-6'].enabled = false game.forces[name].technologies['refined-flammables-7'].enabled = false game.forces[name].technologies['atomic-bomb'].enabled = false global.team_nerf[name] = 0 global.biter_rage[name] = 0 game.forces[name].set_turret_attack_modifier('flamethrower-turret', -0.5) --game.forces[name].set_ammo_damage_modifier("artillery-shell", -0.95) game.forces[name].set_ammo_damage_modifier('shotgun-shell', 0.5) game.forces[name].research_queue_enabled = true end game.forces['spectator'].technologies['toolbelt'].researched = true local f = game.forces['north'] f.set_cease_fire('player', true) f.set_friend('spectator', true) f.share_chart = true f.set_spawn_position({0, -26}, surface) local f = game.forces['south'] f.set_cease_fire('player', true) f.set_friend('spectator', true) f.share_chart = true f.set_spawn_position({0, 26}, surface) local f = game.forces['spectator'] f.set_spawn_position({0, 0}, surface) f.set_friend('north', true) f.set_friend('south', true) local f = game.forces['player'] f.set_spawn_position({0, 0}, surface) global.biter_battles_init_done = true end if global.game_lobby_active then if #game.connected_players > 1 then global.game_lobby_timeout = game.tick + 7200 end end if player.online_time < 5 and game.surfaces['surface'].is_chunk_generated({0, 0}) then player.teleport(game.surfaces['surface'].find_non_colliding_position('character', {0, 0}, 2, 1), 'surface') else if not global.team_chosen[player.name] then player.teleport({0, 0}, 'surface') end end global.biter_battle_view_players[player.name] = false create_biter_battle_sprite_button(player) create_biter_battle_menu(player) refresh_gui() end local function on_player_created(event) refresh_gui() end local function on_player_left_game(event) if game.connected_players == 1 and global.game_lobby_active == true then global.game_lobby_timeout = game.tick + 599940 end refresh_gui() end local function spy_fish(player) local duration_per_unit = 1800 local i2 = player.get_inventory(defines.inventory.character_main) local owned_fishes = i2.get_item_count('raw-fish') owned_fishes = owned_fishes + i2.get_item_count('raw-fish') if owned_fishes == 0 then player.print('You have no fish in your inventory.', {r = 0.98, g = 0.66, b = 0.22}) else local x = i2.remove({name = 'raw-fish', count = 1}) if x == 0 then i2.remove({name = 'raw-fish', count = 1}) end local enemy_team = 'south' if player.force.name == 'south' then enemy_team = 'north' end if global.spy_fish_timeout[player.force.name] then global.spy_fish_timeout[player.force.name] = global.spy_fish_timeout[player.force.name] + duration_per_unit player.print(math.round((global.spy_fish_timeout[player.force.name] - game.tick) / 60, 0) .. ' seconds of enemy vision left.', {r = 0.98, g = 0.66, b = 0.22}) else get_border_cords(enemy_team) game.print(player.name .. ' sent a fish to spy on ' .. enemy_team .. ' team!', {r = 0.98, g = 0.66, b = 0.22}) global.spy_fish_timeout[player.force.name] = game.tick + duration_per_unit end end end local function feed_the_biters(food_type, player) if player.force.name == 'player' then return end if player.force.name == 'spectator' then return end local surface = game.surfaces['surface'] local enemy_team = '' if player.force.name == 'south' then enemy_team = 'north' end if player.force.name == 'north' then enemy_team = 'south' end local i = player.get_main_inventory() local food_amount = i.remove(food_type) while i.get_item_count(food_type) ~= 0 do food_amount = food_amount + i.remove(food_type) end if food_amount == 0 then local str = 'You have no ' .. food_names[food_type] str = str .. ' flask in your inventory.' player.print(str, {r = 0.98, g = 0.66, b = 0.22}) else if food_amount >= 20 then local str = player.name .. ' fed ' str = str .. food_amount str = str .. ' flasks of ' str = str .. food_names[food_type] str = str .. ' juice to team ' str = str .. enemy_team str = str .. '´s biters!' game.print(str, {r = 0.98, g = 0.66, b = 0.22}) else local str = 'You fed ' str = str .. food_amount str = str .. ' flask' if food_amount > 1 then str = str .. 's' end str = str .. ' of ' str = str .. food_names[food_type] str = str .. ' juice to the enemy team´s biters.' player.print(str, {r = 0.98, g = 0.66, b = 0.22}) end end local nerf_gain = 0 local rage_gain = 0 if food_amount > 0 then nerf_gain = food_values[food_type] * food_amount --change these two numbers to your liking nerf and rage local nerf_multiplier = 1 local rage_food_value = food_values[food_type] * 12500000 --10000000 --biter rage calculation for x = 0, food_amount, 1 do local rage_diminish_multiplier = 1 / (((global.biter_rage[enemy_team] ^ 2.9) + 8000) / 500) global.biter_rage[enemy_team] = global.biter_rage[enemy_team] + (rage_food_value * rage_diminish_multiplier) end global.team_nerf[enemy_team] = global.team_nerf[enemy_team] + (nerf_gain * nerf_multiplier) local lowest_possible_modifier = -0.95 local ammo_types = {'grenade', 'bullet', 'artillery-shell', 'flamethrower', 'cannon-shell', 'shotgun-shell', 'rocket', 'electric', 'laser-turret'} local ammo_modifier = {0.2, 0.8, 0, 0.8, 0.2, 0.2, 0.2, 0.2, 1.5} local turret_types = {'flamethrower-turret', 'gun-turret'} local turret_modifier = {1, 0.8} local ammo_speed = {'bullet', 'cannon-shell', 'shotgun-shell', 'rocket', 'laser-turret'} local ammo_speed_modifier = {0.3, 0.3, 0.3, 0.3, 0.3} ------------- local f = game.forces[enemy_team] ----------- -!!!!!-------------- local m = nerf_gain local x = 1 for _, w in pairs(ammo_types) do if f.get_ammo_damage_modifier(w) - (nerf_gain * ammo_modifier[x]) < lowest_possible_modifier then m = lowest_possible_modifier else m = f.get_ammo_damage_modifier(w) - (nerf_gain * ammo_modifier[x]) end f.set_ammo_damage_modifier(w, m) x = x + 1 end local x = 1 for _, w in pairs(turret_types) do if f.get_turret_attack_modifier(w) - (nerf_gain * ammo_modifier[x]) < lowest_possible_modifier then m = lowest_possible_modifier else m = f.get_turret_attack_modifier(w) - (nerf_gain * turret_modifier[x]) end f.set_turret_attack_modifier(w, m) x = x + 1 end local x = 1 for _, w in pairs(ammo_speed) do if f.get_gun_speed_modifier(w) - (nerf_gain * ammo_speed_modifier[x]) < lowest_possible_modifier then m = lowest_possible_modifier else m = f.get_gun_speed_modifier(w) - (nerf_gain * ammo_speed_modifier[x]) end f.set_gun_speed_modifier(w, m) x = x + 1 end refresh_gui() end end local function on_gui_click(event) if not (event and event.element and event.element.valid) then return end local player = game.players[event.element.player_index] local name = event.element.name if (name == 'biter_battle_toggle_menu_button') then local frame = player.gui.left['biter_battle_menu'] if (frame) then frame.destroy() else create_biter_battle_menu(player) end end if (name == 'automation-science-pack') then feed_the_biters(name, player) end if (name == 'logistic-science-pack') then feed_the_biters(name, player) end if (name == 'military-science-pack') then feed_the_biters(name, player) end if (name == 'chemical-science-pack') then feed_the_biters(name, player) end if (name == 'production-science-pack') then feed_the_biters(name, player) end if (name == 'utility-science-pack') then feed_the_biters(name, player) end if (name == 'space-science-pack') then feed_the_biters(name, player) end if (name == 'raw-fish') then spy_fish(player) end if (name == 'biter_battle_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 if (name == 'biter_battle_leave_spectate') and game.tick - global.spectator_spam_protection[player.name] > 1800 then join_team(player, global.team_chosen[player.name]) end if (name == 'biter_battle_leave_spectate') and game.tick - global.spectator_spam_protection[player.name] < 1800 then player.print('Not ready to return to your team yet. Please wait ' .. 30 - (math.round((game.tick - global.spectator_spam_protection[player.name]) / 60, 0)) .. ' seconds.', {r = 0.98, g = 0.66, b = 0.22}) end if (name == 'biter_battle_hide_players') then global.biter_battle_view_players[player.name] = false refresh_gui() end if (name == 'biter_battle_view_players') then global.biter_battle_view_players[player.name] = true refresh_gui() end if not global.terrain_init_done then player.print('Waiting for spawn to generate.', {r = 0.98, g = 0.66, b = 0.22}) return end if (name == 'join_north_button') and global.game_lobby_active == false then join_team(player, 'north') end if (name == 'join_south_button') and global.game_lobby_active == false then join_team(player, 'south') end if (name == 'join_north_button') and global.game_lobby_active == true then player.print('Waiting for more players to join the game.', {r = 0.98, g = 0.66, b = 0.22}) end if (name == 'join_south_button') and global.game_lobby_active == true then player.print('Waiting for more players to join the game.', {r = 0.98, g = 0.66, b = 0.22}) end if (name == 'join_north_button') and global.game_lobby_active == true and player.admin == true then join_team(player, 'north') game.print('Lobby disabled, admin override.', {r = 0.98, g = 0.66, b = 0.22}) global.game_lobby_active = false end if (name == 'join_south_button') and global.game_lobby_active == true and player.admin == true then join_team(player, 'south') game.print('Lobby disabled, admin override.', {r = 0.98, g = 0.66, b = 0.22}) global.game_lobby_active = false end end local function create_fireworks_rocket(surface, position) local particles = {'coal-particle', 'copper-ore-particle', 'iron-ore-particle', 'stone-particle'} local particle = particles[math_random(1, #particles)] local m = math_random(16, 36) local m2 = m * 0.005 for i = 1, 80, 1 do surface.create_entity( { name = particle, position = position, frame_speed = 0.1, vertical_speed = 0.1, height = 0.1, movement = {m2 - (math_random(0, m) * 0.01), m2 - (math_random(0, m) * 0.01)} } ) end if math_random(1, 16) ~= 1 then return end surface.create_entity({name = 'explosion', position = position}) end local function on_entity_died(event) if not global.rocket_silo_destroyed then if event.entity == global.rocket_silo['south'] or event.entity == global.rocket_silo['north'] then if event.entity == global.rocket_silo['south'] then global.rocket_silo_destroyed = 'North Team Won!' else global.rocket_silo_destroyed = 'South Team Won!' end for _, player in pairs(game.connected_players) do player.play_sound {path = 'utility/game_won', volume_modifier = 1} end --fireworks local radius = 96 for t = 1, 18000, 1 do if not traps[game.tick + t] then traps[game.tick + t] = {} end for x = 1, 4, 1 do traps[game.tick + t][#traps[game.tick + t] + 1] = { callback = 'create_fireworks_rocket', params = {event.entity.surface, {x = radius - math_random(0, radius * 2), y = radius - math_random(0, radius * 2)}} } end t = t + 1 end refresh_gui() end end end local function get_valid_biters(requested_amount, y_modifier, pos_x, pos_y, radius_inc) if not requested_amount then return end if not y_modifier then return end if not pos_x then pos_x = 0 end if not pos_y then pos_y = 150 * y_modifier end local surface = game.surfaces['surface'] local biters_found = {} local valid_biters = {} if not radius_inc then radius_inc = 100 end for radius = radius_inc, 2000, radius_inc do biters_found = surface.find_enemy_units({pos_x, pos_y}, radius, 'player') local x = 1 if y_modifier == -1 then for _, biter in pairs(biters_found) do if biter.position.y < 0 then valid_biters[x] = biter x = x + 1 end end else for _, biter in pairs(biters_found) do if biter.position.y > 0 then valid_biters[x] = biter x = x + 1 end end end if #valid_biters >= requested_amount or radius == 2000 then --game.print("seach radius:" .. radius .. " valid biters: " .. #valid_biters) break else valid_biters = {} end end radius_inc = nil pos_x = nil pos_y = nil return valid_biters end local function biter_attack_silo(team, requested_amount, mode) if not requested_amount then return end if not team then return end local surface = game.surfaces['surface'] local y_modifier = 1 if team == 'south' then y_modifier = 1 end if team == 'north' then y_modifier = -1 end local biters_selected_for_attack = {} if not mode then --local modes = {"spread", "ball", "line"} local modes = {'spread', 'ball'} mode = modes[math_random(1, #modes)] end if mode == 'spread' then local valid_biters = get_valid_biters(requested_amount, y_modifier, 0, 150 * y_modifier, 500) if #valid_biters < requested_amount then valid_biters = get_valid_biters(requested_amount, y_modifier, 0, 1500 * y_modifier, 500) end local f = math.floor(#valid_biters / requested_amount, 0) if f < 1 then f = 1 end local x = 0 for y = f, #valid_biters, f do x = x + 1 if not valid_biters[y] then break end if #biters_selected_for_attack >= requested_amount then break end biters_selected_for_attack[x] = valid_biters[y] end if math_random(1, 6) == 1 then for _, biter in pairs(biters_selected_for_attack) do biter.set_command({type = defines.command.attack_area, destination = global.biter_attack_main_target[team], radius = 12, distraction = defines.distraction.by_anything}) end else for _, biter in pairs(biters_selected_for_attack) do biter.set_command({type = defines.command.attack_area, destination = global.biter_attack_main_target[team], radius = 12, distraction = defines.distraction.by_enemy}) end end if global.biter_battles_debug then game.players[1].print(#valid_biters .. ' valid biters found.') game.players[1].print(#biters_selected_for_attack .. ' biter going for a spread attack') end end --[[ if mode == "line" then local valid_biters = get_valid_biters(requested_amount, y_modifier, 0, 150*y_modifier, 500) if #valid_biters < requested_amount then valid_biters = get_valid_biters(requested_amount, y_modifier, 0, 1500*y_modifier, 500) end local array_start = 1 local f = math.floor(#valid_biters/requested_amount,0) if f >= 2 then array_start = requested_amount * math_random(1,f-1) if math_random(1,f) == 1 then array_start = 1 end end local x = 0 for y = array_start,#valid_biters,1 do x = x + 1 if not valid_biters[y] then break end if #biters_selected_for_attack >= requested_amount then break end biters_selected_for_attack[x] = valid_biters[y] end if math_random(1,3) == 1 then for _, biter in pairs(biters_selected_for_attack) do biter.set_command({type=defines.command.attack_area, destination=global.biter_attack_main_target[team], radius=12, distraction=defines.distraction.by_anything}) end else for _, biter in pairs(biters_selected_for_attack) do biter.set_command({type=defines.command.attack_area, destination=global.biter_attack_main_target[team], radius=12, distraction=defines.distraction.by_enemy}) end end if global.biter_battles_debug then game.players[1].print(#valid_biters .. " valid biters found.") game.players[1].print(#biters_selected_for_attack .. " going for a line attack, table start = " .. array_start) end end ]] if mode == 'ball' then local height = 0 local width = 0 local c = 0 local tolerance = 5 local distance_to_base_modifier = 2.6 local additional_empty_space_checks = 4 local additional_checks = additional_empty_space_checks local gathering_point_x = 0 local gathering_point_y = 0 local r = math_random(1, 3) --pick a random side if r == 1 or r == 2 then --- determine base height for pos_y = 0, 8192 * y_modifier, 32 * y_modifier do if y_modifier == -1 then c = surface.count_entities_filtered {area = {{-1024, pos_y - 32}, {1024, pos_y}}, force = team} else c = surface.count_entities_filtered {area = {{-1024, pos_y}, {1024, pos_y + 32}}, force = team} end if c <= tolerance then additional_checks = additional_checks - 1 if additional_checks == 0 then height = pos_y - (32 * (additional_empty_space_checks) * y_modifier) + (32 * y_modifier) break end else additional_checks = additional_empty_space_checks end end if height ~= 0 then if y_modifier == -1 then gathering_point_y = math_random(height, -32) else gathering_point_y = math_random(32, height) end else if y_modifier == -1 then gathering_point_y = math_random(-128, -32) else gathering_point_y = math_random(32, 128) end end additional_empty_space_checks = 32 if r == 1 then --west attack local additional_checks = additional_empty_space_checks for x = 0, -8192, -32 do c = surface.count_entities_filtered {area = {{x - 32, gathering_point_y - 48}, {x, gathering_point_y + 48}}, force = team} if c <= tolerance then additional_checks = additional_checks - 1 if additional_checks == 0 then gathering_point_x = x + (32 * (additional_empty_space_checks - distance_to_base_modifier)) break end else additional_checks = additional_empty_space_checks end end end if r == 2 then --east attack local additional_checks = additional_empty_space_checks for x = 32, 8192, 32 do c = surface.count_entities_filtered {area = {{x - 32, gathering_point_y - 48}, {x, gathering_point_y + 48}}, force = team} if c <= tolerance then additional_checks = additional_checks - 1 if additional_checks == 0 then gathering_point_x = x - (32 * (additional_empty_space_checks - distance_to_base_modifier)) break end else additional_checks = additional_empty_space_checks end end end end --vertical attack if r == 3 then --- determine base width additional_checks = additional_empty_space_checks local width_east = 0 for pos_x = 32, 4096, 32 do if y_modifier == -1 then c = surface.count_entities_filtered {area = {{pos_x - 32, -2048}, {pos_x, 0}}, force = team} else c = surface.count_entities_filtered {area = {{pos_x - 32, 0}, {pos_x, 2048}}, force = team} end if c <= tolerance then additional_checks = additional_checks - 1 if additional_checks == 0 then width_east = pos_x - 32 * additional_empty_space_checks break end else additional_checks = additional_empty_space_checks end end additional_checks = additional_empty_space_checks local width_west = 0 for pos_x = 0, -4096, -32 do if y_modifier == -1 then c = surface.count_entities_filtered {area = {{pos_x - 32, -2048}, {pos_x, 0}}, force = team} else c = surface.count_entities_filtered {area = {{pos_x - 32, 0}, {pos_x, 2048}}, force = team} end if c <= tolerance then additional_checks = additional_checks - 1 if additional_checks == 0 then width_west = (pos_x + 32 * additional_empty_space_checks) - 32 break end else additional_checks = additional_empty_space_checks end end if width_west ~= 0 and width_east ~= 0 then gathering_point_x = math_random(width_west, width_east) else gathering_point_x = math_random(-64, 64) end additional_empty_space_checks = 32 --vertical attack -- local c = 0 local additional_checks = additional_empty_space_checks for pos_y = 0, 8192 * y_modifier, 32 * y_modifier do c = surface.count_entities_filtered {area = {{gathering_point_x - 48, pos_y - 32}, {gathering_point_x + 48, pos_y}}, force = team} if c <= tolerance then additional_checks = additional_checks - 1 if additional_checks == 0 then gathering_point_y = pos_y - ((32 * (additional_empty_space_checks - distance_to_base_modifier)) * y_modifier) break end else additional_checks = additional_empty_space_checks end end end valid_biters = get_valid_biters(requested_amount, y_modifier, gathering_point_x, gathering_point_y) local f = math.floor(#valid_biters / requested_amount, 0) if f < 1 then f = 1 end local x = 0 for y = f, #valid_biters, f do x = x + 1 if not valid_biters[y] then break end if #biters_selected_for_attack >= requested_amount then break end biters_selected_for_attack[x] = valid_biters[y] end --alternate attack if there is water local t = surface.count_tiles_filtered { area = {{gathering_point_x - 8, gathering_point_y - 8}, {gathering_point_x + 8, gathering_point_y + 8}}, name = {'deepwater', 'water', 'water-green'} } if t > 8 then if math_random(1, 6) ~= 1 then for _, biter in pairs(biters_selected_for_attack) do biter.set_command({type = defines.command.attack_area, destination = global.biter_attack_main_target[team], radius = 12, distraction = defines.distraction.by_enemy}) end else for _, biter in pairs(biters_selected_for_attack) do biter.set_command({type = defines.command.attack_area, destination = global.biter_attack_main_target[team], radius = 12, distraction = defines.distraction.by_anything}) end end if global.biter_battles_debug then game.players[1].print('water found, doing alternate spread attack') end else local biter_attack_group = surface.create_unit_group({position = {gathering_point_x, gathering_point_y}}) for _, biter in pairs(biters_selected_for_attack) do biter_attack_group.add_member(biter) end biter_attack_group.set_command({type = defines.command.attack_area, destination = global.biter_attack_main_target[team], radius = 12, distraction = defines.distraction.by_enemy}) if global.biter_battles_debug then game.players[1].print(#valid_biters .. ' valid biters found.') game.players[1].print(#biters_selected_for_attack .. ' gathering at (x: ' .. gathering_point_x .. ' y: ' .. gathering_point_y .. ')') end end end mode = nil end local function clear_corpses() for _, entity in pairs(game.surfaces['surface'].find_entities_filtered {type = 'corpse'}) do if math_random(1, 3) == 1 then entity.destroy() end end end local function send_near_biter_to_silo() if not global.rocket_silo then return end game.surfaces['surface'].set_multi_command( { command = { type = defines.command.attack, target = global.rocket_silo['north'], distraction = defines.distraction.none }, unit_count = 8, force = 'enemy', unit_search_distance = 64 } ) game.surfaces['surface'].set_multi_command( { command = { type = defines.command.attack, target = global.rocket_silo['south'], distraction = defines.distraction.none }, unit_count = 8, force = 'enemy', unit_search_distance = 64 } ) end local function on_tick(event) if global.rocket_silo_destroyed then if not global.game_restart_timeout then global.game_restart_timeout = 7200 end if not global.game_restart_timer_completed then if game.tick % 900 == 0 then if global.game_restart_timeout > 0 then game.print('Map will restart in ' .. math.ceil(global.game_restart_timeout / 60) .. ' seconds!', {r = 0.22, g = 0.88, b = 0.22}) end global.game_restart_timeout = global.game_restart_timeout - 900 end if global.game_restart_timeout < 0 then global.game_restart_timer_completed = true game.print('Map is restarting!', {r = 0.22, g = 0.88, b = 0.22}) local message = 'Map is restarting! ' Server.to_discord_bold(table.concat {'*** ', message, ' ***'}) Server.start_scenario('Biter_Battles') end end end if not traps[game.tick] then goto continue end for _, token in pairs(traps[game.tick]) do local callback = token.callback local params = token.params if callback == 'create_fireworks_rocket' then create_fireworks_rocket(params[1], params[2]) end end traps[game.tick] = nil ::continue:: if global.spy_fish_timeout then if global.spy_fish_timeout['south'] then if (global.spy_fish_timeout['south'] - game.tick) % 300 == 0 then reveal_team('north') end if game.tick - global.spy_fish_timeout['south'] > 0 then global.spy_fish_timeout['south'] = nil end end if global.spy_fish_timeout['north'] then if (global.spy_fish_timeout['north'] - game.tick) % 300 == 0 then reveal_team('south') end if game.tick - global.spy_fish_timeout['north'] > 0 then global.spy_fish_timeout['north'] = nil end end end if game.tick % 12600 == 6300 then clear_corpses() if global.biter_rage['north'] >= 1 then local c = math.round(global.biter_rage['north'], 0) if c > 999 then c = 999 end biter_attack_silo('north', c) end send_near_biter_to_silo() refresh_gui() return end if game.tick % 12600 == 0 then if global.biter_rage['south'] >= 1 then local c = math.round(global.biter_rage['south'], 0) if c > 999 then c = 999 end biter_attack_silo('south', c) end send_near_biter_to_silo() refresh_gui() return end if global.game_lobby_active then if game.tick % 60 == 0 then if global.game_lobby_timeout - game.tick <= 0 then global.game_lobby_active = false end refresh_gui() end end --[[ ---creating a auto fire delay for south artillery--- if global.spawn_artillery["south"] then if game.tick % 300 == 0 then local i = global.spawn_artillery["south"].get_inventory(defines.inventory.turret_ammo) if i.get_item_count("artillery-shell") == 0 then global.spawn_artillery["south"].active = false global.spawn_artillery_south_activate = false else if global.spawn_artillery_south_activate == true then global.spawn_artillery["south"].active = true end global.spawn_artillery_south_activate = true end end end]] -- end local function on_chunk_generated(event) if global.terrain_init_done then return end local surface = game.surfaces['surface'] if event.surface ~= surface then return end if event.area.left_top.x > 128 then global.rocket_silo = {} global.rocket_silo['north'] = surface.create_entity {name = 'rocket-silo', position = {0, (global.horizontal_border_width * 3.8) * -1}, force = 'north'} global.rocket_silo['north'].minable = false global.rocket_silo['south'] = surface.create_entity {name = 'rocket-silo', position = {0, global.horizontal_border_width * 3.8}, force = 'south'} global.rocket_silo['south'].minable = false global.biter_attack_main_target = {} global.biter_attack_main_target['north'] = global.rocket_silo['north'].position global.biter_attack_main_target['south'] = global.rocket_silo['south'].position biter_battles_terrain.clear_spawn_ores() biter_battles_terrain.generate_spawn_water_pond() biter_battles_terrain.generate_spawn_ores('windows') biter_battles_terrain.generate_market() --biter_battles_terrain.generate_artillery() surface.regenerate_decorative() surface.regenerate_entity( { 'tree-01', 'tree-02', 'tree-03', 'tree-04', 'tree-05', 'tree-06', 'tree-07', 'tree-08', 'tree-09', 'dead-dry-hairy-tree', 'dead-grey-trunk', 'dead-tree-desert', 'dry-hairy-tree', 'dry-tree', 'rock-big', 'rock-huge' } ) --surface.regenerate_entity({"dead-dry-hairy-tree","dead-grey-trunk","dead-tree-desert","dry-hairy-tree","dry-tree","rock-big","rock-huge"}) local entities = surface.find_entities({{-10, -10}, {10, 10}}) for _, e in pairs(entities) do if e.type == 'simple-entity' or e.type == 'resource' or e.type == 'tree' then e.destroy() end end surface.destroy_decoratives({area = {{-10, -10}, {10, 10}}}) game.print('Spawn generation done!', {r = 0.22, g = 0.99, b = 0.99}) global.terrain_init_done = true end end ----------share chat with player and spectator force------------------- local function on_console_chat(event) if not event.message then return end if not event.player_index then return end local player = game.players[event.player_index] local color = {} color = player.color color.r = color.r * 0.6 + 0.35 color.g = color.g * 0.6 + 0.35 color.b = color.b * 0.6 + 0.35 color.a = 1 if player.force.name == 'north' then game.forces.spectator.print(player.name .. ' (north): ' .. event.message, color) game.forces.player.print(player.name .. ' (north): ' .. event.message, color) end if player.force.name == 'south' then game.forces.spectator.print(player.name .. ' (south): ' .. event.message, color) game.forces.player.print(player.name .. ' (south): ' .. event.message, color) end if player.force.name == 'player' then game.forces.north.print(player.name .. ' (spawn): ' .. event.message, color) game.forces.south.print(player.name .. ' (spawn): ' .. event.message, color) game.forces.spectator.print(player.name .. ' (spawn): ' .. event.message, color) end if player.force.name == 'spectator' then game.forces.north.print(player.name .. ' (spectator): ' .. event.message, color) game.forces.south.print(player.name .. ' (spectator): ' .. event.message, color) game.forces.player.print(player.name .. ' (spectator): ' .. event.message, color) end end -------------------------------------- local function on_entity_damaged(event) --[[ --flamethrower turret nerf if event.cause then if event.cause.name == "flamethrower-turret" and event.entity.force.name == "enemy" then for i = 1, 2, 1 do if event.cause.fluidbox[i] then if event.cause.fluidbox[i].amount > 0.1 then local fluid_name = event.cause.fluidbox[i].name local new_amount = event.cause.fluidbox[i].amount - 0.25 if new_amount < 0 then new_amount = 0 end event.cause.fluidbox[i] = {name = fluid_name, amount = new_amount} end end end end end]] --Biter rage damage modifier if event.force.name == 'enemy' then if event.entity.force.name == 'north' then local additional_damage = event.final_damage_amount * math.round((global.biter_rage['north'] / 3) / 100, 2) event.entity.health = event.entity.health - additional_damage return end if event.entity.force.name == 'south' then local additional_damage = event.final_damage_amount * math.round((global.biter_rage['south'] / 3) / 100, 2) event.entity.health = event.entity.health - additional_damage return end end if event.entity.force.name == 'spectator' then event.entity.health = event.entity.health + event.final_damage_amount return end --Silo grief prevention if event.entity == global.rocket_silo['north'] then if event.force.name == 'north' then global.rocket_silo['north'].health = global.rocket_silo['north'].health + event.final_damage_amount return end end if event.entity == global.rocket_silo['south'] then if event.force.name == 'south' then global.rocket_silo['south'].health = global.rocket_silo['south'].health + event.final_damage_amount return end end --Biter spawner damage reduction if event.entity.name == 'biter-spawner' or event.entity.name == 'spitter-spawner' then if event.entity.health - event.final_damage_amount <= 0 then event.entity.die(event.force.name) end event.entity.health = event.entity.health + event.final_damage_amount * (game.forces['enemy'].evolution_factor * 0.8) return end end --anti construction robot cheese local function on_robot_built_entity(event) if event.robot.force.name == 'north' then if event.created_entity.position.y >= -1 * global.horizontal_border_width / 2 then local x = event.created_entity.position.x local y = event.created_entity.position.y event.created_entity.die('south') search_for_ghost = game.surfaces['surface'].find_entities({{x, y}, {x + 1, y + 1}}) for _, e in pairs(search_for_ghost) do if e.type == 'entity-ghost' then e.time_to_live = 1 end end event.robot.die('south') game.print('Team north´s drone had an accident.', {r = 0.98, g = 0.66, b = 0.22}) end end if event.robot.force.name == 'south' then if event.created_entity.position.y <= global.horizontal_border_width / 2 then local x = event.created_entity.position.x local y = event.created_entity.position.y event.created_entity.die('north') search_for_ghost = game.surfaces['surface'].find_entities({{x, y}, {x + 1, y + 1}}) for _, e in pairs(search_for_ghost) do if e.type == 'entity-ghost' then e.time_to_live = 1 end end event.robot.die('north') game.print('Team south´s drone had an accident.', {r = 0.98, g = 0.66, b = 0.22}) end end end local function on_marked_for_deconstruction(event) if event.entity.name == 'fish' then event.entity.cancel_deconstruction(game.players[event.player_index].force.name) end end local function on_rocket_launched(event) local team = ' ' if event.rocket_silo.force.name == 'south' then team = 'north' end if event.rocket_silo.force.name == 'north' then team = 'south' end biter_attack_silo(team, 250, 'ball') biter_attack_silo(team, 250, 'ball') biter_attack_silo(team, 250, 'ball') local str = 'A rocket launch scared the biters and triggered a huge attack on team ' str = str .. team str = str .. '´s silo!!' game.print(str, {r = 0.98, g = 0.01, b = 0.01}) end local function on_player_built_tile(event) local placed_tiles = event.tiles local player = game.players[event.player_index] for _, t in pairs(placed_tiles) do if t.old_tile.name == 'deepwater' and t.position.y <= global.horizontal_border_width * 2 and t.position.y >= global.horizontal_border_width * -1 * 2 then local str = 'Team ' .. player.force.name str = str .. '´s landfill vanished into the depths of the marianna trench.' game.print(str, {r = 0.98, g = 0.66, b = 0.22}) local tiles = {} table.insert(tiles, {name = 'deepwater', position = t.position}) game.surfaces['surface'].set_tiles(tiles, true) end end end local function on_robot_built_tile(event) local surface = event.robot.surface for _, t in pairs(event.tiles) do if t.old_tile.name == 'deepwater' and t.position.y <= global.horizontal_border_width * 2 and t.position.y >= global.horizontal_border_width * -1 * 2 then local str = 'Team ' .. event.robot.force.name str = str .. '´s landfill vanished into the depths of the marianna trench.' game.print(str, {r = 0.98, g = 0.66, b = 0.22}) local tiles = {} table.insert(tiles, {name = 'deepwater', position = t.position}) surface.set_tiles(tiles, true) end end end local function on_research_finished(event) --game.forces.north.recipes["flamethrower-turret"].enabled = false --game.forces.south.recipes["flamethrower-turret"].enabled = false end event.add(defines.events.on_robot_built_tile, on_robot_built_tile) event.add(defines.events.on_chunk_generated, on_chunk_generated) event.add(defines.events.on_research_finished, on_research_finished) event.add(defines.events.on_built_entity, on_built_entity) event.add(defines.events.on_player_built_tile, on_player_built_tile) event.add(defines.events.on_rocket_launched, on_rocket_launched) event.add(defines.events.on_marked_for_deconstruction, on_marked_for_deconstruction) event.add(defines.events.on_robot_built_entity, on_robot_built_entity) event.add(defines.events.on_entity_damaged, on_entity_damaged) event.add(defines.events.on_player_left_game, on_player_left_game) event.add(defines.events.on_entity_died, on_entity_died) event.add(defines.events.on_tick, on_tick) event.add(defines.events.on_player_created, on_player_created) event.add(defines.events.on_player_joined_game, on_player_joined_game) event.add(defines.events.on_gui_click, on_gui_click) event.add(defines.events.on_console_chat, on_console_chat)