2018-11-10 05:57:26 +02:00
-- Biter Battles -- mewmew made this --
2021-03-24 19:22:45 +02:00
--luacheck:ignore
2019-10-28 18:38:36 +02:00
local Server = require ' utils.server '
2022-04-05 19:28:08 +02:00
local Score = require ' utils.gui.score '
2020-06-13 10:45:04 +02:00
local Global = require ' utils.global '
2021-03-24 17:46:00 +02:00
require ' modules.splice_double '
require ' modules.explosive_biters '
require ' modules.spawners_contain_biters '
require ' modules.custom_death_messages '
2019-02-16 18:46:57 +02:00
2019-03-14 02:35:41 +02:00
local biter_battles_terrain = require ' maps.biter_battles.biter_battles_terrain '
2018-11-10 05:57:26 +02:00
local event = require ' utils.event '
local math_random = math.random
2019-02-20 20:37:35 +02:00
local insert = table.insert
2018-11-10 05:57:26 +02:00
2020-06-13 10:45:04 +02:00
local traps = { }
Global.register (
2021-03-24 17:46:00 +02:00
traps ,
function ( t )
traps = t
end
2020-06-13 10:45:04 +02:00
)
2018-11-10 05:57:26 +02:00
local food_names = {
2021-03-24 17:46:00 +02:00
[ ' 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 '
2018-11-10 05:57:26 +02:00
}
2020-06-13 10:45:04 +02:00
2018-11-10 05:57:26 +02:00
local food_values = {
2021-03-24 17:46:00 +02:00
[ ' 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
2018-11-10 05:57:26 +02:00
}
2018-09-20 23:04:01 +02:00
local function get_border_cords ( f )
2021-03-24 17:46:00 +02:00
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)
2018-09-20 23:04:01 +02:00
end
local function create_biter_battle_sprite_button ( player )
2021-03-24 17:46:00 +02:00
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
2018-09-20 23:04:01 +02:00
end
2020-06-13 10:45:04 +02:00
local function get_sorted_list ( column_name , score_list )
2021-03-24 17:46:00 +02:00
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
2018-11-18 17:14:50 +02:00
end
local function get_mvps ( force )
2021-03-24 17:46:00 +02:00
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
2018-11-18 17:14:50 +02:00
end
local function show_mvps ( player )
2021-03-24 17:46:00 +02:00
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
2018-11-18 17:14:50 +02:00
end
2018-09-20 23:04:01 +02:00
local function create_biter_battle_menu ( player )
2021-03-24 17:46:00 +02:00
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
2018-09-20 23:04:01 +02:00
end
local function refresh_gui ( )
2021-03-24 17:46:00 +02:00
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
2018-09-20 23:04:01 +02:00
end
local function join_team ( player , team )
2021-03-24 17:46:00 +02:00
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 ( )
2018-09-20 23:04:01 +02:00
end
local function reveal_team ( f )
2021-03-24 17:46:00 +02:00
local m = 32
if f == ' north ' then
2022-04-05 19:28:08 +02:00
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 } } )
2021-03-24 17:46:00 +02:00
else
2022-04-05 19:28:08 +02:00
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 } } )
2021-03-24 17:46:00 +02:00
end
2018-09-20 23:04:01 +02:00
end
local function on_player_joined_game ( event )
2021-03-24 17:46:00 +02:00
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 ( )
2018-09-20 23:04:01 +02:00
end
local function on_player_created ( event )
2021-03-24 17:46:00 +02:00
refresh_gui ( )
2018-09-20 23:04:01 +02:00
end
local function on_player_left_game ( event )
2021-03-24 17:46:00 +02:00
if game.connected_players == 1 and global.game_lobby_active == true then
global.game_lobby_timeout = game.tick + 599940
end
refresh_gui ( )
2018-09-20 23:04:01 +02:00
end
local function spy_fish ( player )
2021-03-24 17:46:00 +02:00
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
2018-09-20 23:04:01 +02:00
end
2021-03-24 17:46:00 +02:00
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
2018-09-20 23:04:01 +02:00
end
local function on_gui_click ( event )
2021-03-24 17:46:00 +02:00
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
2022-04-05 19:28:08 +02:00
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 } )
2021-03-24 17:46:00 +02:00
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
2018-09-20 23:04:01 +02:00
end
2019-03-03 03:38:29 +02:00
local function create_fireworks_rocket ( surface , position )
2021-03-24 17:46:00 +02:00
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 } )
2019-03-03 03:38:29 +02:00
end
2018-09-20 23:04:01 +02:00
local function on_entity_died ( event )
2021-03-24 17:46:00 +02:00
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
2018-09-20 23:04:01 +02:00
end
local function get_valid_biters ( requested_amount , y_modifier , pos_x , pos_y , radius_inc )
2021-03-24 17:46:00 +02:00
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
2018-09-20 23:04:01 +02:00
end
2020-06-13 10:45:04 +02:00
local function biter_attack_silo ( team , requested_amount , mode )
2021-03-24 17:46:00 +02:00
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
2022-04-05 19:28:08 +02:00
biter.set_command ( { type = defines.command . attack_area , destination = global.biter_attack_main_target [ team ] , radius = 12 , distraction = defines.distraction . by_anything } )
2021-03-24 17:46:00 +02:00
end
else
for _ , biter in pairs ( biters_selected_for_attack ) do
2022-04-05 19:28:08 +02:00
biter.set_command ( { type = defines.command . attack_area , destination = global.biter_attack_main_target [ team ] , radius = 12 , distraction = defines.distraction . by_enemy } )
2021-03-24 17:46:00 +02:00
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
--[[
2018-09-20 23:04:01 +02:00
if mode == " line " then
2020-06-13 10:45:04 +02:00
local valid_biters = get_valid_biters ( requested_amount , y_modifier , 0 , 150 * y_modifier , 500 )
2018-09-20 23:04:01 +02:00
if # valid_biters < requested_amount then
valid_biters = get_valid_biters ( requested_amount , y_modifier , 0 , 1500 * y_modifier , 500 )
2020-06-13 10:45:04 +02:00
end
2018-09-20 23:04:01 +02:00
local array_start = 1
local f = math.floor ( # valid_biters / requested_amount , 0 )
if f >= 2 then
2018-11-10 05:57:26 +02:00
array_start = requested_amount * math_random ( 1 , f - 1 )
if math_random ( 1 , f ) == 1 then array_start = 1 end
2020-06-13 10:45:04 +02:00
end
2018-09-20 23:04:01 +02:00
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
2020-06-13 10:45:04 +02:00
biters_selected_for_attack [ x ] = valid_biters [ y ]
2018-09-20 23:04:01 +02:00
end
2020-06-13 10:45:04 +02:00
2018-11-10 05:57:26 +02:00
if math_random ( 1 , 3 ) == 1 then
2020-06-13 10:45:04 +02:00
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
2018-09-20 23:04:01 +02:00
else
2020-06-13 10:45:04 +02:00
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
2018-09-20 23:04:01 +02:00
end
2020-06-13 10:45:04 +02:00
2018-09-20 23:04:01 +02:00
if global.biter_battles_debug then
game.players [ 1 ] . print ( # valid_biters .. " valid biters found. " )
2020-06-13 10:45:04 +02:00
game.players [ 1 ] . print ( # biters_selected_for_attack .. " going for a line attack, table start = " .. array_start )
2018-09-20 23:04:01 +02:00
end
2020-06-13 10:45:04 +02:00
end
2018-12-27 19:38:13 +02:00
] ]
2021-03-24 17:46:00 +02:00
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
2022-04-05 19:28:08 +02:00
biter.set_command ( { type = defines.command . attack_area , destination = global.biter_attack_main_target [ team ] , radius = 12 , distraction = defines.distraction . by_enemy } )
2021-03-24 17:46:00 +02:00
end
else
for _ , biter in pairs ( biters_selected_for_attack ) do
2022-04-05 19:28:08 +02:00
biter.set_command ( { type = defines.command . attack_area , destination = global.biter_attack_main_target [ team ] , radius = 12 , distraction = defines.distraction . by_anything } )
2021-03-24 17:46:00 +02:00
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
2022-04-05 19:28:08 +02:00
biter_attack_group.set_command ( { type = defines.command . attack_area , destination = global.biter_attack_main_target [ team ] , radius = 12 , distraction = defines.distraction . by_enemy } )
2021-03-24 17:46:00 +02:00
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
2018-09-20 23:04:01 +02:00
end
2018-12-09 04:18:34 +02:00
local function clear_corpses ( )
2021-03-24 17:46:00 +02:00
for _ , entity in pairs ( game.surfaces [ ' surface ' ] . find_entities_filtered { type = ' corpse ' } ) do
if math_random ( 1 , 3 ) == 1 then
entity.destroy ( )
end
end
2018-09-20 23:04:01 +02:00
end
2019-02-19 05:31:55 +02:00
local function send_near_biter_to_silo ( )
2021-03-24 17:46:00 +02:00
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
}
)
2019-02-19 05:31:55 +02:00
end
2020-06-13 10:45:04 +02:00
local function on_tick ( event )
2021-03-24 17:46:00 +02:00
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
--[[
2018-09-20 23:04:01 +02:00
---creating a auto fire delay for south artillery---
if global.spawn_artillery [ " south " ] then
if game.tick % 300 == 0 then
2020-06-13 10:45:04 +02:00
local i = global.spawn_artillery [ " south " ] . get_inventory ( defines.inventory . turret_ammo )
if i.get_item_count ( " artillery-shell " ) == 0 then
2018-09-20 23:04:01 +02:00
global.spawn_artillery [ " south " ] . active = false
global.spawn_artillery_south_activate = false
2020-06-13 10:45:04 +02:00
else
2018-09-20 23:04:01 +02:00
if global.spawn_artillery_south_activate == true then
global.spawn_artillery [ " south " ] . active = true
end
2020-06-13 10:45:04 +02:00
global.spawn_artillery_south_activate = true
end
2018-09-20 23:04:01 +02:00
end
2021-03-24 17:46:00 +02:00
end ] ]
--
2018-09-20 23:04:01 +02:00
end
2018-12-13 01:36:55 +02:00
local function on_chunk_generated ( event )
2021-03-24 17:46:00 +02:00
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
2018-12-13 01:36:55 +02:00
end
2018-09-20 23:04:01 +02:00
----------share chat with player and spectator force-------------------
local function on_console_chat ( event )
2021-03-24 17:46:00 +02:00
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
2018-09-20 23:04:01 +02:00
end
--------------------------------------
local function on_entity_damaged ( event )
2021-03-24 17:46:00 +02:00
--[[
2018-11-16 09:13:08 +02:00
--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
2020-06-13 10:45:04 +02:00
if event.cause . fluidbox [ i ] then
2018-11-16 09:13:08 +02:00
if event.cause . fluidbox [ i ] . amount > 0.1 then
local fluid_name = event.cause . fluidbox [ i ] . name
2018-11-18 15:46:15 +02:00
local new_amount = event.cause . fluidbox [ i ] . amount - 0.25
2018-11-16 09:13:08 +02:00
if new_amount < 0 then new_amount = 0 end
event.cause . fluidbox [ i ] = { name = fluid_name , amount = new_amount }
end
end
end
end
2018-12-03 23:02:37 +02:00
end ] ]
2021-03-24 17:46:00 +02:00
--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
2018-09-20 23:04:01 +02:00
end
--anti construction robot cheese
2020-06-13 10:45:04 +02:00
local function on_robot_built_entity ( event )
2021-03-24 17:46:00 +02:00
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
2018-09-20 23:04:01 +02:00
end
local function on_marked_for_deconstruction ( event )
2021-03-24 17:46:00 +02:00
if event.entity . name == ' fish ' then
event.entity . cancel_deconstruction ( game.players [ event.player_index ] . force.name )
end
2018-09-20 23:04:01 +02:00
end
local function on_rocket_launched ( event )
2021-03-24 17:46:00 +02:00
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 } )
2018-09-20 23:04:01 +02:00
end
local function on_player_built_tile ( event )
2021-03-24 17:46:00 +02:00
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
2018-09-20 23:04:01 +02:00
end
2019-03-14 02:00:20 +02:00
local function on_robot_built_tile ( event )
2021-03-24 17:46:00 +02:00
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
2019-03-14 02:00:20 +02:00
end
2020-06-13 10:45:04 +02:00
local function on_research_finished ( event )
2021-03-24 17:46:00 +02:00
--game.forces.north.recipes["flamethrower-turret"].enabled = false
--game.forces.south.recipes["flamethrower-turret"].enabled = false
2018-12-09 04:18:34 +02:00
end
2019-03-14 02:00:20 +02:00
event.add ( defines.events . on_robot_built_tile , on_robot_built_tile )
2018-12-13 01:36:55 +02:00
event.add ( defines.events . on_chunk_generated , on_chunk_generated )
2018-12-09 04:18:34 +02:00
event.add ( defines.events . on_research_finished , on_research_finished )
2018-11-10 05:57:26 +02:00
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 )
2020-06-13 10:45:04 +02:00
event.add ( defines.events . on_entity_died , on_entity_died )
event.add ( defines.events . on_tick , on_tick )
2018-11-10 05:57:26 +02:00
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 )
2019-02-28 22:53:06 +02:00
event.add ( defines.events . on_console_chat , on_console_chat )