2018-11-25 17:04:57 +02:00
-- fish defender -- by mewmew --
2018-11-02 23:37:58 +02:00
local event = require ' utils.event '
2018-11-09 10:34:19 +02:00
require " maps.fish_defender_map_intro "
require " maps.fish_defender_kaboomsticks "
2018-11-07 22:48:03 +02:00
local map_functions = require " maps.tools.map_functions "
2018-11-02 23:37:58 +02:00
local math_random = math.random
local insert = table.insert
2018-11-27 08:09:49 +02:00
local wave_interval = 3600 --interval between waves in ticks
2018-12-04 01:52:07 +02:00
local biter_count_limit = 2400 --maximum biters on the east side of the map, next wave will be delayed if the maximum has been reached
2018-12-03 21:05:13 +02:00
local boss_waves = {
[ 50 ] = { { name = " big-biter " , count = 3 } } ,
[ 100 ] = { { name = " behemoth-biter " , count = 1 } } ,
2018-12-04 01:52:07 +02:00
[ 150 ] = { { name = " behemoth-spitter " , count = 4 } , { name = " big-spitter " , count = 16 } } ,
[ 200 ] = { { name = " behemoth-biter " , count = 4 } , { name = " behemoth-spitter " , count = 2 } } ,
[ 250 ] = { { name = " behemoth-biter " , count = 8 } , { name = " behemoth-spitter " , count = 4 } } ,
[ 300 ] = { { name = " behemoth-biter " , count = 12 } , { name = " behemoth-spitter " , count = 6 } } ,
[ 350 ] = { { name = " behemoth-biter " , count = 16 } , { name = " behemoth-spitter " , count = 8 } } ,
[ 400 ] = { { name = " behemoth-biter " , count = 20 } , { name = " behemoth-spitter " , count = 10 } } ,
[ 450 ] = { { name = " behemoth-biter " , count = 24 } , { name = " behemoth-spitter " , count = 12 } }
2018-12-03 21:05:13 +02:00
}
2018-11-02 23:37:58 +02:00
2018-11-03 19:16:59 +02:00
local function shuffle ( tbl )
local size = # tbl
for i = size , 1 , - 1 do
local rand = math.random ( size )
tbl [ i ] , tbl [ rand ] = tbl [ rand ] , tbl [ i ]
end
return tbl
end
2018-11-06 01:07:35 +02:00
local function create_wave_gui ( player )
if player.gui . top [ " fish_defense_waves " ] then player.gui . top [ " fish_defense_waves " ] . destroy ( ) end
2018-11-07 02:50:14 +02:00
local frame = player.gui . top.add ( { type = " frame " , name = " fish_defense_waves " } )
frame.style . maximal_height = 38
2018-11-07 21:27:42 +02:00
2018-11-07 02:50:14 +02:00
local wave_count = 0
2018-11-20 15:46:13 +02:00
if global.wave_count then wave_count = global.wave_count end
2018-11-21 14:38:48 +02:00
if not global.wave_grace_period then
local label = frame.add ( { type = " label " , caption = " Wave: " .. wave_count } )
label.style . font_color = { r = 0.88 , g = 0.88 , b = 0.88 }
label.style . font = " default-listbox "
label.style . left_padding = 4
label.style . right_padding = 4
label.style . minimal_width = 68
label.style . font_color = { r = 0.33 , g = 0.66 , b = 0.9 }
local next_level_progress = game.tick % wave_interval / wave_interval
local progressbar = frame.add ( { type = " progressbar " , value = next_level_progress } )
progressbar.style . minimal_width = 120
progressbar.style . maximal_width = 120
progressbar.style . top_padding = 10
else
local time_remaining = math.floor ( ( ( global.wave_grace_period - ( game.tick % global.wave_grace_period ) ) / 60 ) / 60 )
if time_remaining <= 0 then
global.wave_grace_period = nil
2018-11-22 22:40:17 +02:00
return
2018-11-21 14:38:48 +02:00
end
local label = frame.add ( { type = " label " , caption = " Waves will start in " .. time_remaining .. " minutes. " } )
label.style . font_color = { r = 0.88 , g = 0.88 , b = 0.88 }
label.style . font = " default-listbox "
label.style . left_padding = 4
label.style . right_padding = 4
label.style . font_color = { r = 0.33 , g = 0.66 , b = 0.9 }
end
2018-11-02 23:37:58 +02:00
end
2018-11-20 15:46:13 +02:00
local threat_values = {
[ " small_biter " ] = 1 ,
2018-11-27 08:09:49 +02:00
[ " medium_biter " ] = 3 ,
2018-12-03 19:27:19 +02:00
[ " big_biter " ] = 5 ,
[ " behemoth_biter " ] = 10 ,
2018-11-20 15:46:13 +02:00
[ " small_spitter " ] = 1 ,
2018-11-27 08:09:49 +02:00
[ " medium_spitter " ] = 3 ,
2018-12-03 19:27:19 +02:00
[ " big_spitter " ] = 5 ,
[ " behemoth_spitter " ] = 10
2018-11-20 15:46:13 +02:00
}
local function get_biter_initial_pool ( )
local biter_pool = { }
2018-11-27 08:09:49 +02:00
if global.wave_count > 2000 then
biter_pool = {
{ name = " big-biter " , threat = threat_values.big_biter , weight = 1 } ,
{ name = " behemoth-biter " , threat = threat_values.behemoth_biter , weight = 1 } ,
{ name = " behemoth-spitter " , threat = threat_values.behemoth_spitter , weight = 1 }
}
return biter_pool
end
2018-11-24 15:08:52 +02:00
if global.wave_count > 1000 then
biter_pool = {
{ name = " big-biter " , threat = threat_values.big_biter , weight = 3 } ,
{ name = " behemoth-biter " , threat = threat_values.behemoth_biter , weight = 2 } ,
{ name = " behemoth-spitter " , threat = threat_values.behemoth_spitter , weight = 1 }
}
return biter_pool
end
2018-11-20 15:46:13 +02:00
if game.forces . enemy.evolution_factor < 0.1 then
biter_pool = {
{ name = " small-biter " , threat = threat_values.small_biter , weight = 3 } ,
{ name = " small-spitter " , threat = threat_values.small_spitter , weight = 1 }
}
return biter_pool
end
2018-11-20 23:30:08 +02:00
if game.forces . enemy.evolution_factor < 0.2 then
2018-11-20 15:46:13 +02:00
biter_pool = {
{ name = " small-biter " , threat = threat_values.small_biter , weight = 10 } ,
{ name = " medium-biter " , threat = threat_values.medium_biter , weight = 2 } ,
{ name = " small-spitter " , threat = threat_values.small_spitter , weight = 5 } ,
{ name = " medium-spitter " , threat = threat_values.medium_spitter , weight = 1 }
}
return biter_pool
end
2018-11-20 23:30:08 +02:00
if game.forces . enemy.evolution_factor < 0.3 then
biter_pool = {
{ name = " small-biter " , threat = threat_values.small_biter , weight = 18 } ,
{ name = " medium-biter " , threat = threat_values.medium_biter , weight = 6 } ,
{ name = " small-spitter " , threat = threat_values.small_spitter , weight = 8 } ,
{ name = " medium-spitter " , threat = threat_values.medium_spitter , weight = 3 } ,
{ name = " big-biter " , threat = threat_values.big_biter , weight = 1 }
}
return biter_pool
end
2018-11-20 15:46:13 +02:00
if game.forces . enemy.evolution_factor < 0.4 then
biter_pool = {
{ name = " small-biter " , threat = threat_values.small_biter , weight = 2 } ,
{ name = " medium-biter " , threat = threat_values.medium_biter , weight = 8 } ,
{ name = " big-biter " , threat = threat_values.big_biter , weight = 2 } ,
{ name = " small-spitter " , threat = threat_values.small_spitter , weight = 1 } ,
{ name = " medium-spitter " , threat = threat_values.medium_spitter , weight = 4 } ,
{ name = " big-spitter " , threat = threat_values.big_spitter , weight = 1 }
}
return biter_pool
end
2018-11-20 23:30:08 +02:00
if game.forces . enemy.evolution_factor < 0.5 then
2018-11-20 15:46:13 +02:00
biter_pool = {
{ name = " small-biter " , threat = threat_values.small_biter , weight = 2 } ,
{ name = " medium-biter " , threat = threat_values.medium_biter , weight = 4 } ,
{ name = " big-biter " , threat = threat_values.big_biter , weight = 8 } ,
{ name = " small-spitter " , threat = threat_values.small_spitter , weight = 1 } ,
{ name = " medium-spitter " , threat = threat_values.medium_spitter , weight = 2 } ,
{ name = " big-spitter " , threat = threat_values.big_spitter , weight = 4 }
}
return biter_pool
end
2018-11-20 23:30:08 +02:00
if game.forces . enemy.evolution_factor < 0.6 then
biter_pool = {
{ name = " medium-biter " , threat = threat_values.medium_biter , weight = 4 } ,
{ name = " big-biter " , threat = threat_values.big_biter , weight = 8 } ,
{ name = " medium-spitter " , threat = threat_values.medium_spitter , weight = 2 } ,
{ name = " big-spitter " , threat = threat_values.big_spitter , weight = 4 }
}
return biter_pool
end
if game.forces . enemy.evolution_factor < 0.7 then
biter_pool = {
{ name = " behemoth-biter " , threat = threat_values.small_biter , weight = 2 } ,
{ name = " medium-biter " , threat = threat_values.medium_biter , weight = 12 } ,
{ name = " big-biter " , threat = threat_values.big_biter , weight = 20 } ,
{ name = " behemoth-spitter " , threat = threat_values.small_spitter , weight = 1 } ,
{ name = " medium-spitter " , threat = threat_values.medium_spitter , weight = 6 } ,
{ name = " big-spitter " , threat = threat_values.big_spitter , weight = 10 }
}
return biter_pool
end
2018-11-20 15:46:13 +02:00
if game.forces . enemy.evolution_factor < 0.8 then
biter_pool = {
{ name = " behemoth-biter " , threat = threat_values.small_biter , weight = 2 } ,
2018-11-20 23:30:08 +02:00
{ name = " medium-biter " , threat = threat_values.medium_biter , weight = 4 } ,
2018-11-20 15:46:13 +02:00
{ name = " big-biter " , threat = threat_values.big_biter , weight = 10 } ,
{ name = " behemoth-spitter " , threat = threat_values.small_spitter , weight = 1 } ,
2018-11-20 23:30:08 +02:00
{ name = " medium-spitter " , threat = threat_values.medium_spitter , weight = 2 } ,
2018-11-20 15:46:13 +02:00
{ name = " big-spitter " , threat = threat_values.big_spitter , weight = 5 }
}
return biter_pool
end
2018-11-20 23:30:08 +02:00
if game.forces . enemy.evolution_factor <= 0.9 then
biter_pool = {
{ name = " big-biter " , threat = threat_values.big_biter , weight = 12 } ,
{ name = " behemoth-biter " , threat = threat_values.behemoth_biter , weight = 2 } ,
{ name = " big-spitter " , threat = threat_values.big_spitter , weight = 6 } ,
{ name = " behemoth-spitter " , threat = threat_values.behemoth_spitter , weight = 1 }
}
return biter_pool
end
2018-11-20 15:46:13 +02:00
if game.forces . enemy.evolution_factor <= 1 then
biter_pool = {
{ name = " big-biter " , threat = threat_values.big_biter , weight = 4 } ,
{ name = " behemoth-biter " , threat = threat_values.behemoth_biter , weight = 2 } ,
{ name = " big-spitter " , threat = threat_values.big_spitter , weight = 2 } ,
{ name = " behemoth-spitter " , threat = threat_values.behemoth_spitter , weight = 1 }
}
return biter_pool
end
end
local function get_biter_pool ( )
2018-11-21 14:38:48 +02:00
local surface = game.surfaces [ " fish_defender " ]
2018-11-20 15:46:13 +02:00
local biter_pool = get_biter_initial_pool ( )
local biter_raffle = { }
for _ , biter_type in pairs ( biter_pool ) do
for x = 1 , biter_type.weight , 1 do
insert ( biter_raffle , { name = biter_type.name , threat = biter_type.threat } )
2018-11-03 19:16:59 +02:00
end
2018-11-07 21:27:42 +02:00
end
2018-11-20 15:46:13 +02:00
return biter_raffle
end
2018-11-27 08:09:49 +02:00
local function spawn_biter ( pos , biter_pool )
if global.attack_wave_threat < 1 then return false end
local surface = game.surfaces [ " fish_defender " ]
biter_pool = shuffle ( biter_pool )
global.attack_wave_threat = global.attack_wave_threat - biter_pool [ 1 ] . threat
2018-11-30 15:47:22 +02:00
local valid_pos = surface.find_non_colliding_position ( biter_pool [ 1 ] . name , pos , 100 , 2 )
2018-11-27 08:09:49 +02:00
local biter = surface.create_entity ( { name = biter_pool [ 1 ] . name , position = valid_pos } )
return biter
end
local attack_group_count_thresholds = {
{ 0 , 1 } ,
2018-11-28 22:43:32 +02:00
{ 50 , 2 } ,
{ 100 , 3 } ,
{ 150 , 4 } ,
{ 200 , 5 } ,
{ 1000 , 6 } ,
{ 2000 , 7 } ,
{ 3000 , 8 }
2018-11-27 08:09:49 +02:00
}
local function get_number_of_attack_groups ( )
local n = 1
for _ , entry in pairs ( attack_group_count_thresholds ) do
if global.wave_count >= entry [ 1 ] then
n = entry [ 2 ]
end
end
return n
end
2018-12-03 19:02:20 +02:00
local function clear_corpses ( surface )
local area = { { x = - 256 , y = - 256 } , { x = 256 , y = 256 } }
for _ , entity in pairs ( surface.find_entities_filtered { area = area , type = " corpse " } ) do
if math_random ( 1 , 2 ) == 1 then
entity.destroy ( )
end
end
end
2018-12-03 21:05:13 +02:00
local function spawn_boss_units ( surface )
if not boss_waves [ global.wave_count ] then return end
if global.wave_count == 50 then game.print ( " The Big Biter Gang " , { r = 0.7 , g = 0.1 , b = 0.1 } ) end
if global.wave_count == 100 then game.print ( " Biterzilla " , { r = 0.7 , g = 0.1 , b = 0.1 } ) end
2018-12-04 01:52:07 +02:00
if global.wave_count == 150 then game.print ( " The Spitter Squad " , { r = 0.7 , g = 0.1 , b = 0.1 } ) end
2018-12-03 21:05:13 +02:00
local position = { x = 216 , y = 0 }
local biter_group = surface.create_unit_group ( { position = position } )
for _ , entry in pairs ( boss_waves [ global.wave_count ] ) do
for x = 1 , entry.count , 1 do
local pos = surface.find_non_colliding_position ( entry.name , position , 64 , 3 )
if pos then
local biter = surface.create_entity ( { name = entry.name , position = pos } )
biter_group.add_member ( biter )
end
end
end
biter_group.set_command ( {
type = defines.command . compound ,
structure_type = defines.compound_command . return_last ,
commands = {
{
type = defines.command . attack_area ,
destination = { x = - 32 , y = 0 } ,
radius = 16 ,
distraction = defines.distraction . by_anything
} ,
{
type = defines.command . attack ,
target = global.market ,
distraction = defines.distraction . by_enemy
}
}
} )
end
2018-12-03 23:02:37 +02:00
local function wake_up_idle_biters ( surface )
2018-12-03 19:02:20 +02:00
surface.set_multi_command ( {
command = {
type = defines.command . attack ,
target = global.market ,
distraction = defines.distraction . by_enemy
} ,
unit_count = 500 ,
force = " enemy " ,
unit_search_distance = 64
} )
surface.set_multi_command ( {
command = {
type = defines.command . attack ,
target = global.market ,
distraction = defines.distraction . none
} ,
unit_count = 100 ,
force = " enemy " ,
unit_search_distance = 16
} )
2018-12-03 21:05:13 +02:00
local units = surface.find_entities_filtered ( { type = " unit " , area = { { 192 , - 256 } , { 360 , 256 } } } )
for _ , unit in pairs ( units ) do
unit.set_command ( {
type = defines.command . compound ,
structure_type = defines.compound_command . return_last ,
commands = {
{
type = defines.command . attack_area ,
2018-12-03 23:02:37 +02:00
destination = { x = - 160 , y = 0 } ,
2018-12-03 21:05:13 +02:00
radius = 16 ,
distraction = defines.distraction . by_anything
2018-12-03 23:02:37 +02:00
} ,
{
type = defines.command . attack_area ,
destination = { x = - 80 , y = 0 } ,
radius = 16 ,
distraction = defines.distraction . by_anything
} ,
2018-12-03 21:05:13 +02:00
{
type = defines.command . attack ,
target = global.market ,
distraction = defines.distraction . by_enemy
}
}
} )
end
2018-12-03 23:02:37 +02:00
end
local function biter_attack_wave ( )
if not global.market then return end
if global.wave_grace_period then return end
local surface = game.surfaces [ " fish_defender " ]
clear_corpses ( surface )
wake_up_idle_biters ( surface )
2018-12-03 21:05:13 +02:00
2018-11-27 08:09:49 +02:00
if surface.count_entities_filtered ( { type = " unit " , area = { { - 128 , - 256 } , { 360 , 256 } } } ) > biter_count_limit then
game.print ( " Biter limit reached, wave stalled. " , { r = 0.7 , g = 0.1 , b = 0.1 } )
return
end
2018-11-02 23:37:58 +02:00
if not global.wave_count then
2018-11-20 15:46:13 +02:00
global.wave_count = 1
2018-11-02 23:37:58 +02:00
else
2018-11-20 15:46:13 +02:00
global.wave_count = global.wave_count + 1
2018-11-02 23:37:58 +02:00
end
2018-12-03 21:05:13 +02:00
2018-12-04 01:52:07 +02:00
if global.wave_count % 50 == 0 then
2018-12-03 21:05:13 +02:00
game.print ( " Boss Wave " .. global.wave_count , { r = 0.7 , g = 0.1 , b = 0.1 } )
global.attack_wave_threat = global.wave_count * 10
spawn_boss_units ( surface )
else
global.attack_wave_threat = global.wave_count * 5
end
2018-11-21 14:38:48 +02:00
2018-12-03 21:05:13 +02:00
if global.attack_wave_threat > 35000 then global.attack_wave_threat = 35000 end
2018-11-20 15:46:13 +02:00
local evolution = global.wave_count * 0.00125
2018-11-12 05:11:06 +02:00
if evolution > 1 then evolution = 1 end
game.forces . enemy.evolution_factor = evolution
2018-11-24 15:08:52 +02:00
if game.forces . enemy.evolution_factor == 1 then
2018-11-07 21:27:42 +02:00
if not global.endgame_modifier then
2018-11-24 15:08:52 +02:00
global.endgame_modifier = 1
2018-11-07 21:27:42 +02:00
game.print ( " Endgame enemy evolution reached. Biter damage is rising... " , { r = 0.7 , g = 0.1 , b = 0.1 } )
else
2018-11-24 15:08:52 +02:00
global.endgame_modifier = global.endgame_modifier + 1
2018-11-07 21:27:42 +02:00
end
2018-12-03 21:05:13 +02:00
end
2018-11-28 22:43:32 +02:00
2018-11-24 15:08:52 +02:00
local units = surface.find_entities_filtered ( { force = " player " , area = { { 160 , - 256 } , { 360 , 256 } } } )
for _ , unit in pairs ( units ) do
if unit.health then
unit.health = unit.health - math_random ( 75 , 125 )
surface.create_entity ( { name = " water-splash " , position = unit.position } )
if unit.health <= 0 then unit.die ( " enemy " ) end
else
if unit.type == " entity-ghost " then
unit.destroy ( )
end
end
2018-11-20 23:30:08 +02:00
end
2018-11-24 15:08:52 +02:00
2018-11-11 14:04:38 +02:00
local spawn_x = 242
2018-11-29 21:30:26 +02:00
local target_x = - 32
2018-11-27 08:09:49 +02:00
local group_coords = { }
2018-11-28 22:43:32 +02:00
for a = - 80 , 80 , 16 do
2018-11-27 08:09:49 +02:00
insert ( group_coords , { spawn = { x = spawn_x , y = a * 2 } , target = { x = target_x , y = a } } )
end
2018-11-07 21:27:42 +02:00
group_coords = shuffle ( group_coords )
2018-11-20 15:46:13 +02:00
2018-11-27 08:09:49 +02:00
local unit_groups = { }
2018-11-28 22:43:32 +02:00
if global.wave_count > 100 and math_random ( 1 , 3 ) == 1 then
for i = 1 , # group_coords , 1 do
2018-11-27 08:09:49 +02:00
unit_groups [ i ] = surface.create_unit_group ( { position = group_coords [ i ] . spawn } )
end
else
for i = 1 , get_number_of_attack_groups ( ) , 1 do
unit_groups [ i ] = surface.create_unit_group ( { position = group_coords [ i ] . spawn } )
end
end
local biter_pool = get_biter_pool ( )
while global.attack_wave_threat > 0 do
for i = 1 , # unit_groups , 1 do
local biter = spawn_biter ( unit_groups [ i ] . position , biter_pool )
if biter then
unit_groups [ i ] . add_member ( biter )
else
break
end
end
end
for i = 1 , # unit_groups , 1 do
unit_groups [ i ] . set_command ( {
type = defines.command . compound ,
structure_type = defines.compound_command . return_last ,
commands = {
2018-11-29 21:30:26 +02:00
{
type = defines.command . attack_area ,
2018-12-03 19:02:20 +02:00
destination = { group_coords [ i ] . target.x + 180 , group_coords [ i ] . target.y } ,
radius = 32 ,
distraction = defines.distraction . by_anything
} ,
{
type = defines.command . attack_area ,
destination = { group_coords [ i ] . target.x + 120 , group_coords [ i ] . target.y } ,
radius = 32 ,
distraction = defines.distraction . by_anything
} ,
{
type = defines.command . attack_area ,
destination = { group_coords [ i ] . target.x + 60 , group_coords [ i ] . target.y } ,
2018-11-29 21:30:26 +02:00
radius = 32 ,
distraction = defines.distraction . by_anything
} ,
2018-11-27 08:09:49 +02:00
{
type = defines.command . attack_area ,
destination = group_coords [ i ] . target ,
2018-11-29 21:30:26 +02:00
radius = 32 ,
2018-11-27 08:09:49 +02:00
distraction = defines.distraction . by_anything
} ,
{
type = defines.command . attack ,
target = global.market ,
distraction = defines.distraction . by_enemy
}
}
} )
end
2018-11-09 10:34:19 +02:00
end
2018-11-07 21:27:42 +02:00
2018-11-20 15:46:13 +02:00
local function refresh_market_offers ( )
if not global.market then return end
for i = 1 , 100 , 1 do
local a = global.market . remove_market_item ( 1 )
if a == false then break end
end
2018-11-21 14:38:48 +02:00
local str1 = " Gun Turret Slot for " .. tostring ( global.entity_limits [ " gun-turret " ] . limit * global.entity_limits [ " gun-turret " ] . slot_price )
2018-11-20 15:46:13 +02:00
str1 = str1 .. " Coins. "
2018-11-21 14:38:48 +02:00
2018-11-20 15:46:13 +02:00
local str2 = " Laser Turret Slot for " .. tostring ( global.entity_limits [ " laser-turret " ] . limit * global.entity_limits [ " laser-turret " ] . slot_price )
str2 = str2 .. " Coins. "
2018-11-21 14:38:48 +02:00
2018-11-24 15:08:52 +02:00
local str3 = " Artillery Slot for " .. tostring ( global.entity_limits [ " artillery-turret " ] . limit * global.entity_limits [ " artillery-turret " ] . slot_price )
2018-11-20 15:46:13 +02:00
str3 = str3 .. " Coins. "
2018-11-21 14:38:48 +02:00
2018-11-24 15:08:52 +02:00
local current_limit = 1
if global.entity_limits [ " flamethrower-turret " ] . limit ~= 0 then current_limit = current_limit + global.entity_limits [ " flamethrower-turret " ] . limit end
local str4 = " Flamethrower Turret Slot for " .. tostring ( current_limit * global.entity_limits [ " flamethrower-turret " ] . slot_price )
2018-11-20 23:30:08 +02:00
str4 = str4 .. " Coins. "
2018-11-20 15:46:13 +02:00
2018-11-24 15:08:52 +02:00
local str5 = " Landmine Slot for " .. tostring ( global.entity_limits [ " land-mine " ] . limit * global.entity_limits [ " land-mine " ] . slot_price )
str5 = str5 .. " Coins. "
2018-11-20 15:46:13 +02:00
local market_items = {
{ price = { } , offer = { type = ' nothing ' , effect_description = str1 } } ,
{ price = { } , offer = { type = ' nothing ' , effect_description = str2 } } ,
{ price = { } , offer = { type = ' nothing ' , effect_description = str3 } } ,
2018-11-20 23:30:08 +02:00
{ price = { } , offer = { type = ' nothing ' , effect_description = str4 } } ,
2018-11-24 15:08:52 +02:00
{ price = { } , offer = { type = ' nothing ' , effect_description = str5 } } ,
2018-11-20 15:46:13 +02:00
{ price = { { " coin " , 3 } } , offer = { type = ' give-item ' , item = " raw-fish " , count = 1 } } ,
2018-11-24 15:08:52 +02:00
{ price = { { " coin " , 1 } } , offer = { type = ' give-item ' , item = ' raw-wood ' , count = 8 } } ,
2018-12-02 06:47:58 +02:00
{ price = { { " coin " , 8 } } , offer = { type = ' give-item ' , item = ' grenade ' , count = 1 } } ,
2018-11-24 15:08:52 +02:00
{ price = { { " coin " , 32 } } , offer = { type = ' give-item ' , item = ' cluster-grenade ' , count = 1 } } ,
2018-11-27 08:09:49 +02:00
{ price = { { " coin " , 1 } } , offer = { type = ' give-item ' , item = ' land-mine ' , count = 1 } } ,
2018-11-20 15:46:13 +02:00
{ price = { { " coin " , 80 } } , offer = { type = ' give-item ' , item = ' car ' , count = 1 } } ,
2018-11-27 08:09:49 +02:00
{ price = { { " coin " , 1200 } } , offer = { type = ' give-item ' , item = ' tank ' , count = 1 } } ,
2018-11-21 14:38:48 +02:00
{ price = { { " coin " , 3 } } , offer = { type = ' give-item ' , item = ' cannon-shell ' , count = 1 } } ,
2018-11-24 15:08:52 +02:00
{ price = { { " coin " , 7 } } , offer = { type = ' give-item ' , item = ' explosive-cannon-shell ' , count = 1 } } ,
2018-11-20 23:30:08 +02:00
{ price = { { " coin " , 50 } } , offer = { type = ' give-item ' , item = ' gun-turret ' , count = 1 } } ,
2018-12-02 18:25:31 +02:00
{ price = { { " coin " , 300 } } , offer = { type = ' give-item ' , item = ' laser-turret ' , count = 1 } } ,
{ price = { { " coin " , 450 } } , offer = { type = ' give-item ' , item = ' artillery-turret ' , count = 1 } } ,
{ price = { { " coin " , 16 } } , offer = { type = ' give-item ' , item = ' artillery-shell ' , count = 1 } } ,
2018-11-24 15:08:52 +02:00
{ price = { { " coin " , 25 } } , offer = { type = ' give-item ' , item = ' artillery-targeting-remote ' , count = 1 } } ,
2018-11-20 15:46:13 +02:00
{ price = { { " coin " , 1 } } , offer = { type = ' give-item ' , item = ' firearm-magazine ' , count = 1 } } ,
{ price = { { " coin " , 4 } } , offer = { type = ' give-item ' , item = ' piercing-rounds-magazine ' , count = 1 } } ,
2018-11-20 23:30:08 +02:00
{ price = { { " coin " , 2 } } , offer = { type = ' give-item ' , item = ' shotgun-shell ' , count = 1 } } ,
{ price = { { " coin " , 6 } } , offer = { type = ' give-item ' , item = ' piercing-shotgun-shell ' , count = 1 } } ,
2018-11-21 14:38:48 +02:00
{ price = { { " coin " , 30 } } , offer = { type = ' give-item ' , item = " submachine-gun " , count = 1 } } ,
2018-11-20 15:46:13 +02:00
{ price = { { " coin " , 250 } } , offer = { type = ' give-item ' , item = ' combat-shotgun ' , count = 1 } } ,
2018-12-03 19:02:20 +02:00
{ price = { { " coin " , 450 } } , offer = { type = ' give-item ' , item = ' flamethrower ' , count = 1 } } ,
2018-12-02 06:47:58 +02:00
{ price = { { " coin " , 25 } } , offer = { type = ' give-item ' , item = ' flamethrower-ammo ' , count = 1 } } ,
2018-11-20 15:46:13 +02:00
{ price = { { " coin " , 125 } } , offer = { type = ' give-item ' , item = ' rocket-launcher ' , count = 1 } } ,
2018-11-24 15:08:52 +02:00
{ price = { { " coin " , 2 } } , offer = { type = ' give-item ' , item = ' rocket ' , count = 1 } } ,
{ price = { { " coin " , 7 } } , offer = { type = ' give-item ' , item = ' explosive-rocket ' , count = 1 } } ,
2018-12-03 19:02:20 +02:00
{ price = { { " coin " , 5000 } } , offer = { type = ' give-item ' , item = ' atomic-bomb ' , count = 1 } } ,
2018-11-20 23:30:08 +02:00
{ price = { { " coin " , 90 } } , offer = { type = ' give-item ' , item = ' railgun ' , count = 1 } } ,
2018-11-20 15:46:13 +02:00
{ price = { { " coin " , 5 } } , offer = { type = ' give-item ' , item = ' railgun-dart ' , count = 1 } } ,
2018-11-28 22:43:32 +02:00
{ price = { { " coin " , 40 } } , offer = { type = ' give-item ' , item = ' poison-capsule ' , count = 1 } } ,
2018-12-02 06:47:58 +02:00
{ price = { { " coin " , 4 } } , offer = { type = ' give-item ' , item = ' defender-capsule ' , count = 1 } } ,
2018-11-20 15:46:13 +02:00
{ price = { { " coin " , 10 } } , offer = { type = ' give-item ' , item = ' light-armor ' , count = 1 } } ,
2018-12-02 06:47:58 +02:00
{ price = { { " coin " , 125 } } , offer = { type = ' give-item ' , item = ' heavy-armor ' , count = 1 } } ,
2018-11-20 15:46:13 +02:00
{ price = { { " coin " , 350 } } , offer = { type = ' give-item ' , item = ' modular-armor ' , count = 1 } } ,
{ price = { { " coin " , 1500 } } , offer = { type = ' give-item ' , item = ' power-armor ' , count = 1 } } ,
2018-12-02 18:25:31 +02:00
{ price = { { " coin " , 12000 } } , offer = { type = ' give-item ' , item = ' power-armor-mk2 ' , count = 1 } } ,
2018-11-24 15:08:52 +02:00
{ price = { { " coin " , 50 } } , offer = { type = ' give-item ' , item = ' solar-panel-equipment ' , count = 1 } } ,
{ price = { { " coin " , 2250 } } , offer = { type = ' give-item ' , item = ' fusion-reactor-equipment ' , count = 1 } } ,
{ price = { { " coin " , 100 } } , offer = { type = ' give-item ' , item = ' battery-equipment ' , count = 1 } } ,
2018-11-20 23:30:08 +02:00
{ price = { { " coin " , 200 } } , offer = { type = ' give-item ' , item = ' energy-shield-equipment ' , count = 1 } } ,
{ price = { { " coin " , 750 } } , offer = { type = ' give-item ' , item = ' personal-laser-defense-equipment ' , count = 1 } } ,
2018-11-20 15:46:13 +02:00
{ price = { { " coin " , 175 } } , offer = { type = ' give-item ' , item = ' exoskeleton-equipment ' , count = 1 } } ,
{ price = { { " coin " , 125 } } , offer = { type = ' give-item ' , item = ' night-vision-equipment ' , count = 1 } } ,
2018-11-29 21:30:26 +02:00
{ price = { { " coin " , 200 } } , offer = { type = ' give-item ' , item = ' belt-immunity-equipment ' , count = 1 } } ,
2018-11-20 15:46:13 +02:00
{ price = { { " coin " , 250 } } , offer = { type = ' give-item ' , item = ' personal-roboport-equipment ' , count = 1 } } ,
2018-12-02 06:47:58 +02:00
{ price = { { " coin " , 20 } } , offer = { type = ' give-item ' , item = ' construction-robot ' , count = 1 } }
2018-11-20 15:46:13 +02:00
}
for _ , item in pairs ( market_items ) do
global.market . add_market_item ( item )
end
end
2018-11-09 10:34:19 +02:00
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 ( )
if not global.score [ " player " ] then return false end
local score = global.score [ " player " ]
local score_list = { }
for _ , p in pairs ( game.players ) do
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
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-02 23:37:58 +02:00
end
local function is_game_lost ( )
if global.market then return end
2018-11-07 21:27:42 +02:00
2018-11-02 23:37:58 +02:00
for _ , player in pairs ( game.connected_players ) do
2018-11-07 02:50:14 +02:00
if player.gui . left [ " fish_defense_game_lost " ] then return end
2018-11-09 10:34:19 +02:00
local f = player.gui . left.add ( { type = " frame " , name = " fish_defense_game_lost " , caption = " The fish market was overrun! The biters are having a feast :3 " , direction = " vertical " } )
f.style . font_color = { r = 0.65 , g = 0.1 , b = 0.99 }
local t = f.add ( { type = " table " , column_count = 2 } )
local l = t.add ( { type = " label " , caption = " Survival Time >> " } )
l.style . font = " default-listbox "
l.style . font_color = { r = 0.22 , g = 0.77 , b = 0.44 }
if global.market_age >= 216000 then
local l = t.add ( { type = " label " , caption = math.floor ( ( ( global.market_age / 60 ) / 60 ) / 60 ) .. " hours " .. math.ceil ( ( global.market_age % 216000 / 60 ) / 60 ) .. " minutes " } )
l.style . font = " default-bold "
l.style . font_color = { r = 0.33 , g = 0.66 , b = 0.9 }
else
local l = t.add ( { type = " label " , caption = math.ceil ( ( global.market_age % 216000 / 60 ) / 60 ) .. " minutes " } )
l.style . font = " default-bold "
l.style . font_color = { r = 0.33 , g = 0.66 , b = 0.9 }
end
local mvp = get_mvps ( )
if mvp then
local l = t.add ( { type = " label " , caption = " MVP 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 = " MVP 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 = " MVP 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 }
end
2018-11-03 19:16:59 +02:00
for _ , player in pairs ( game.connected_players ) do
2018-11-07 02:50:14 +02:00
player.play_sound { path = " utility/game_lost " , volume_modifier = 1 }
2018-11-03 19:16:59 +02:00
end
2018-11-02 23:37:58 +02:00
end
2018-11-07 21:27:42 +02:00
game.map_settings . enemy_expansion.enabled = true
game.map_settings . enemy_expansion.max_expansion_distance = 15
game.map_settings . enemy_expansion.settler_group_min_size = 15
game.map_settings . enemy_expansion.settler_group_max_size = 30
game.map_settings . enemy_expansion.min_expansion_cooldown = 600
game.map_settings . enemy_expansion.max_expansion_cooldown = 600
2018-11-02 23:37:58 +02:00
end
2018-11-10 05:57:26 +02:00
local biter_building_inhabitants = {
[ 1 ] = { { " small-biter " , 8 , 16 } } ,
[ 2 ] = { { " small-biter " , 12 , 24 } } ,
[ 3 ] = { { " small-biter " , 8 , 16 } , { " medium-biter " , 1 , 2 } } ,
[ 4 ] = { { " small-biter " , 4 , 8 } , { " medium-biter " , 4 , 8 } } ,
[ 5 ] = { { " small-biter " , 3 , 5 } , { " medium-biter " , 8 , 12 } } ,
[ 6 ] = { { " small-biter " , 3 , 5 } , { " medium-biter " , 5 , 7 } , { " big-biter " , 1 , 2 } } ,
[ 7 ] = { { " medium-biter " , 6 , 8 } , { " big-biter " , 3 , 5 } } ,
[ 8 ] = { { " medium-biter " , 2 , 4 } , { " big-biter " , 6 , 8 } } ,
[ 9 ] = { { " medium-biter " , 2 , 3 } , { " big-biter " , 7 , 9 } } ,
[ 10 ] = { { " big-biter " , 4 , 8 } , { " behemoth-biter " , 3 , 4 } }
}
2018-11-06 01:07:35 +02:00
2018-11-07 02:50:14 +02:00
local function damage_entities_in_radius ( position , radius , damage )
2018-12-03 19:27:19 +02:00
if radius > 8 then radius = 8 end
2018-11-21 14:38:48 +02:00
local entities_to_damage = game.surfaces [ " fish_defender " ] . find_entities_filtered ( { area = { { position.x - radius , position.y - radius } , { position.x + radius , position.y + radius } } } )
2018-11-07 02:50:14 +02:00
for _ , entity in pairs ( entities_to_damage ) do
2018-12-02 17:58:17 +02:00
if entity.health and entity.name ~= " land-mine " then
2018-11-07 02:50:14 +02:00
if entity.force . name ~= " enemy " then
if entity.name == " player " then
entity.damage ( damage , " enemy " )
else
entity.health = entity.health - damage
2018-11-24 15:08:52 +02:00
entity.surface . create_entity ( { name = " explosion " , position = entity.position } )
2018-11-07 02:50:14 +02:00
if entity.health <= 0 then entity.die ( " enemy " ) end
2018-11-07 21:27:42 +02:00
end
2018-11-07 02:50:14 +02:00
end
end
end
end
2018-11-09 10:34:19 +02:00
local coin_earnings = {
[ " small-biter " ] = 1 ,
[ " medium-biter " ] = 2 ,
[ " big-biter " ] = 3 ,
[ " behemoth-biter " ] = 5 ,
[ " small-spitter " ] = 1 ,
[ " medium-spitter " ] = 2 ,
[ " big-spitter " ] = 3 ,
2018-11-26 17:50:30 +02:00
[ " behemoth-spitter " ] = 5 ,
[ " spitter-spawner " ] = 32 ,
[ " biter-spawner " ] = 32
2018-11-09 10:34:19 +02:00
}
2018-11-28 22:43:32 +02:00
local entities_that_earn_coins = {
2018-11-30 15:47:22 +02:00
[ " artillery-turret " ] = true ,
[ " gun-turret " ] = true ,
[ " laser-turret " ] = true ,
2018-12-01 15:51:10 +02:00
[ " flamethrower-turret " ] = true
2018-11-29 21:30:26 +02:00
}
2018-11-02 23:37:58 +02:00
local function on_entity_died ( event )
2018-11-03 19:16:59 +02:00
if event.entity . force.name == " enemy " then
2018-11-21 14:38:48 +02:00
local players_to_reward = { }
2018-11-26 17:50:30 +02:00
local reward_has_been_given = false
if event.cause then
if event.entity . type == " unit " or event.entity . type == " unit-spawner " then
if event.cause . name == " player " then
insert ( players_to_reward , event.cause )
reward_has_been_given = true
end
if event.cause . type == " car " then
player = event.cause . get_driver ( )
passenger = event.cause . get_passenger ( )
if player then insert ( players_to_reward , player.player ) end
if passenger then insert ( players_to_reward , passenger.player ) end
reward_has_been_given = true
end
if event.cause . type == " locomotive " then
train_passengers = event.cause . train.passengers
if train_passengers then
for _ , passenger in pairs ( train_passengers ) do
insert ( players_to_reward , passenger )
end
reward_has_been_given = true
2018-11-11 02:26:24 +02:00
end
end
2018-11-26 17:50:30 +02:00
for _ , player in pairs ( players_to_reward ) do
player.insert ( { name = " coin " , count = coin_earnings [ event.entity . name ] } )
end
2018-11-28 22:43:32 +02:00
if entities_that_earn_coins [ event.cause . name ] then
2018-11-26 17:50:30 +02:00
event.entity . surface.spill_item_stack ( event.cause . position , { name = " coin " , count = coin_earnings [ event.entity . name ] } , true )
reward_has_been_given = true
2018-12-03 19:02:20 +02:00
end
2018-11-11 02:26:24 +02:00
end
2018-11-10 05:57:26 +02:00
end
2018-11-26 17:50:30 +02:00
2018-11-28 22:43:32 +02:00
if reward_has_been_given == false and coin_earnings [ event.entity . name ] then
event.entity . surface.spill_item_stack ( event.entity . position , { name = " coin " , count = coin_earnings [ event.entity . name ] } , true )
2018-11-21 14:38:48 +02:00
end
2018-11-06 01:07:35 +02:00
if event.entity . name == " biter-spawner " or event.entity . name == " spitter-spawner " then
2018-11-07 21:27:42 +02:00
local e = math.ceil ( game.forces . enemy.evolution_factor * 10 , 0 )
for _ , t in pairs ( biter_building_inhabitants [ e ] ) do
2018-11-06 01:07:35 +02:00
for x = 1 , math.random ( t [ 2 ] , t [ 3 ] ) , 1 do
2018-11-07 21:27:42 +02:00
local p = event.entity . surface.find_non_colliding_position ( t [ 1 ] , event.entity . position , 6 , 1 )
2018-11-06 01:07:35 +02:00
if p then event.entity . surface.create_entity { name = t [ 1 ] , position = p } end
end
end
end
2018-11-07 21:27:42 +02:00
2018-11-06 01:07:35 +02:00
if event.entity . name == " medium-biter " then
event.entity . surface.create_entity ( { name = " explosion " , position = event.entity . position } )
2018-11-07 21:27:42 +02:00
local damage = 25
2018-12-03 23:02:37 +02:00
if global.endgame_modifier then damage = 25 + math.ceil ( ( global.endgame_modifier * 0.025 ) , 0 ) end
if damage > 75 then damage = 75 end
2018-11-24 15:08:52 +02:00
damage_entities_in_radius ( event.entity . position , 1 + math.floor ( global.wave_count * 0.001 ) , damage )
2018-11-06 01:07:35 +02:00
end
2018-11-07 21:27:42 +02:00
2018-11-06 01:07:35 +02:00
if event.entity . name == " big-biter " then
event.entity . surface.create_entity ( { name = " uranium-cannon-shell-explosion " , position = event.entity . position } )
2018-11-09 10:34:19 +02:00
local damage = 35
2018-12-03 23:02:37 +02:00
if global.endgame_modifier then damage = 50 + math.ceil ( ( global.endgame_modifier * 0.05 ) , 0 ) end
if damage > 150 then damage = 150 end
2018-11-24 15:08:52 +02:00
damage_entities_in_radius ( event.entity . position , 2 + math.floor ( global.wave_count * 0.001 ) , damage )
2018-11-06 01:07:35 +02:00
end
2018-11-07 21:27:42 +02:00
2018-11-24 15:08:52 +02:00
if event.entity . name == " behemoth-biter " then
local spawn_entity = false
2018-12-03 21:05:13 +02:00
if global.endgame_modifier then
if global.endgame_modifier > 500 then
spawn_entity = " big-worm-turret "
else
spawn_entity = " medium-worm-turret "
end
2018-11-24 15:08:52 +02:00
end
2018-12-03 21:05:13 +02:00
2018-11-24 15:08:52 +02:00
if spawn_entity then
local surface = event.entity . surface
2018-12-03 21:05:13 +02:00
if surface.count_entities_filtered ( { area = { { event.entity . position.x - 5 , event.entity . position.y - 5 } , { event.entity . position.x + 5 , event.entity . position.y + 5 } } , name = spawn_entity } ) == 0 then
2018-11-24 15:08:52 +02:00
surface.create_entity ( { name = " blood-explosion-huge " , position = event.entity . position } )
surface.create_entity ( { name = spawn_entity , position = event.entity . position } )
end
end
end
2018-11-03 19:16:59 +02:00
return
end
2018-11-20 23:30:08 +02:00
2018-11-02 23:37:58 +02:00
if event.entity == global.market then
global.market = nil
global.market_age = game.tick
is_game_lost ( )
end
2018-11-12 05:11:06 +02:00
if global.entity_limits [ event.entity . name ] then
global.entity_limits [ event.entity . name ] . placed = global.entity_limits [ event.entity . name ] . placed - 1
end
2018-11-02 23:37:58 +02:00
end
local function on_entity_damaged ( event )
2018-11-07 02:50:14 +02:00
if event.cause then
if event.cause . name == " big-spitter " then
local surface = event.cause . surface
local area = { { event.entity . position.x - 3 , event.entity . position.y - 3 } , { event.entity . position.x + 3 , event.entity . position.y + 3 } }
2018-11-30 15:47:22 +02:00
if surface.count_entities_filtered ( { area = area , name = " small-biter " , limit = 3 } ) < 3 then
2018-12-03 23:02:37 +02:00
local pos = surface.find_non_colliding_position ( " small-biter " , event.entity . position , 4 , 0.5 )
2018-11-30 15:47:22 +02:00
if pos then surface.create_entity ( { name = " small-biter " , position = pos } ) end
2018-11-07 02:50:14 +02:00
end
end
2018-11-07 21:27:42 +02:00
if event.cause . name == " behemoth-spitter " then
local surface = event.cause . surface
local area = { { event.entity . position.x - 3 , event.entity . position.y - 3 } , { event.entity . position.x + 3 , event.entity . position.y + 3 } }
2018-11-30 15:47:22 +02:00
if surface.count_entities_filtered ( { area = area , name = " medium-biter " , limit = 3 } ) < 3 then
2018-12-03 23:02:37 +02:00
local pos = surface.find_non_colliding_position ( " medium-biter " , event.entity . position , 4 , 0.5 )
2018-11-30 15:47:22 +02:00
if pos then surface.create_entity ( { name = " medium-biter " , position = pos } ) end
2018-11-07 21:27:42 +02:00
end
end
2018-11-07 02:50:14 +02:00
if event.cause . force.name == " enemy " then
2018-11-07 21:27:42 +02:00
if global.endgame_modifier then
2018-11-24 15:08:52 +02:00
event.entity . health = event.entity . health - ( event.final_damage_amount * global.endgame_modifier * 0.002 )
2018-11-12 05:11:06 +02:00
if event.entity . health <= 0 then event.entity . die ( ) end
2018-11-07 21:27:42 +02:00
end
2018-11-07 02:50:14 +02:00
end
end
2018-11-24 15:08:52 +02:00
if event.entity . valid then
if event.entity . name == " market " then
2018-11-26 17:50:30 +02:00
if event.cause then
if event.cause . force.name == " enemy " then return end
end
2018-11-24 15:08:52 +02:00
event.entity . health = event.entity . health + event.final_damage_amount
end
2018-11-02 23:37:58 +02:00
end
end
local function on_player_joined_game ( event )
local player = game.players [ event.player_index ]
2018-11-07 21:27:42 +02:00
2018-11-21 14:38:48 +02:00
if not global.fish_defense_init_done then
local map_gen_settings = { }
map_gen_settings.water = " small "
map_gen_settings.cliff_settings = { cliff_elevation_interval = 22 , cliff_elevation_0 = 22 }
map_gen_settings.autoplace_controls = {
2018-11-30 21:08:51 +02:00
[ " coal " ] = { frequency = " very-high " , size = " very-big " , richness = " normal " } ,
[ " stone " ] = { frequency = " very-high " , size = " very-big " , richness = " normal " } ,
[ " copper-ore " ] = { frequency = " very-high " , size = " very-big " , richness = " normal " } ,
[ " iron-ore " ] = { frequency = " very-high " , size = " very-big " , richness = " normal " } ,
[ " crude-oil " ] = { frequency = " very-high " , size = " very-big " , richness = " normal " } ,
2018-11-21 14:38:48 +02:00
[ " trees " ] = { frequency = " normal " , size = " normal " , richness = " normal " } ,
[ " enemy-base " ] = { frequency = " none " , size = " none " , richness = " none " } ,
[ " grass " ] = { frequency = " normal " , size = " normal " , richness = " normal " } ,
[ " sand " ] = { frequency = " normal " , size = " normal " , richness = " normal " } ,
[ " desert " ] = { frequency = " normal " , size = " normal " , richness = " normal " } ,
[ " dirt " ] = { frequency = " normal " , size = " normal " , richness = " normal " }
}
game.create_surface ( " fish_defender " , map_gen_settings )
local surface = game.surfaces [ " fish_defender " ]
local radius = 256
game.forces . player.chart ( surface , { { x = - 1 * radius , y = - 1 * radius } , { x = radius , y = radius } } )
2018-11-07 02:50:14 +02:00
game.map_settings . enemy_expansion.enabled = false
2018-11-12 05:11:06 +02:00
game.map_settings . enemy_evolution.destroy_factor = 0
game.map_settings . enemy_evolution.time_factor = 0
2018-11-24 15:08:52 +02:00
game.map_settings . enemy_evolution.pollution_factor = 0
2018-11-22 22:40:17 +02:00
2018-12-03 19:02:20 +02:00
--game.forces["player"].set_turret_attack_modifier("flamethrower-turret", -0.5)
game.forces [ " player " ] . technologies [ " flamethrower-damage-1 " ] . enabled = false
game.forces [ " player " ] . technologies [ " flamethrower-damage-2 " ] . enabled = false
game.forces [ " player " ] . technologies [ " flamethrower-damage-3 " ] . enabled = false
game.forces [ " player " ] . technologies [ " flamethrower-damage-4 " ] . enabled = false
game.forces [ " player " ] . technologies [ " flamethrower-damage-5 " ] . enabled = false
game.forces [ " player " ] . technologies [ " flamethrower-damage-6 " ] . enabled = false
game.forces [ " player " ] . technologies [ " flamethrower-damage-7 " ] . enabled = false
2018-12-03 21:05:13 +02:00
game.forces [ " player " ] . technologies [ " gun-turret-damage-1 " ] . enabled = false
game.forces [ " player " ] . technologies [ " gun-turret-damage-2 " ] . enabled = false
game.forces [ " player " ] . technologies [ " gun-turret-damage-3 " ] . enabled = false
game.forces [ " player " ] . technologies [ " gun-turret-damage-4 " ] . enabled = false
game.forces [ " player " ] . technologies [ " gun-turret-damage-5 " ] . enabled = false
game.forces [ " player " ] . technologies [ " gun-turret-damage-6 " ] . enabled = false
game.forces [ " player " ] . technologies [ " gun-turret-damage-7 " ] . enabled = false
2018-12-04 01:52:07 +02:00
game.forces [ " player " ] . technologies [ " laser-turret-speed-6 " ] . enabled = false
game.forces [ " player " ] . technologies [ " laser-turret-speed-7 " ] . enabled = false
2018-12-03 19:02:20 +02:00
game.forces . player.set_ammo_damage_modifier ( " shotgun-shell " , 0.5 )
2018-12-02 18:25:31 +02:00
2018-11-20 15:46:13 +02:00
global.entity_limits = {
2018-12-03 21:05:13 +02:00
[ " gun-turret " ] = { placed = 1 , limit = 1 , str = " gun turret " , slot_price = 100 } ,
2018-12-04 01:52:07 +02:00
[ " laser-turret " ] = { placed = 0 , limit = 1 , str = " laser turret " , slot_price = 300 } ,
2018-11-24 15:08:52 +02:00
[ " artillery-turret " ] = { placed = 0 , limit = 1 , str = " artillery turret " , slot_price = 500 } ,
2018-12-04 01:52:07 +02:00
[ " flamethrower-turret " ] = { placed = 0 , limit = 0 , str = " flamethrower turret " , slot_price = 35000 } ,
2018-12-03 23:02:37 +02:00
[ " land-mine " ] = { placed = 0 , limit = 1 , str = " mine " , slot_price = 1 }
2018-11-20 15:46:13 +02:00
}
2018-11-21 14:38:48 +02:00
global.wave_grace_period = wave_interval * 21
2018-11-09 10:34:19 +02:00
2018-11-02 23:37:58 +02:00
global.fish_defense_init_done = true
end
2018-11-07 21:27:42 +02:00
2018-11-02 23:37:58 +02:00
if player.online_time < 1 then
player.insert ( { name = " pistol " , count = 1 } )
2018-11-06 01:07:35 +02:00
player.insert ( { name = " iron-axe " , count = 1 } )
player.insert ( { name = " raw-fish " , count = 3 } )
2018-12-03 19:02:20 +02:00
player.insert ( { name = " firearm-magazine " , count = 16 } )
player.insert ( { name = " iron-plate " , count = 32 } )
2018-11-09 10:34:19 +02:00
if global.show_floating_killscore then global.show_floating_killscore [ player.name ] = false end
2018-11-02 23:37:58 +02:00
end
2018-11-21 14:38:48 +02:00
2018-11-22 22:40:17 +02:00
local surface = game.surfaces [ " fish_defender " ]
2018-11-29 21:30:26 +02:00
if player.online_time < 2 and surface.is_chunk_generated ( { 0 , 0 } ) then
player.teleport ( surface.find_non_colliding_position ( " player " , { - 75 , 4 } , 50 , 1 ) , " fish_defender " )
2018-11-22 22:40:17 +02:00
else
2018-11-29 21:30:26 +02:00
if player.online_time < 2 then
player.teleport ( { - 50 , 0 } , " fish_defender " )
2018-11-22 22:40:17 +02:00
end
end
2018-12-03 23:02:37 +02:00
2018-11-25 17:04:57 +02:00
create_wave_gui ( player )
if game.tick > 900 then
is_game_lost ( )
end
2018-11-02 23:37:58 +02:00
end
2018-11-29 21:30:26 +02:00
local function get_replacement_tile ( surface )
local tilename = " grass-1 "
for x = - 160 , 160 , 1 do
for y = - 96 , 90 , 1 do
local tile = surface.get_tile ( x , y )
if tile.name ~= " water " and tile.name ~= " deepwater " then
tilename = tile.name
end
end
end
return tilename
end
2018-11-02 23:37:58 +02:00
local map_height = 96
2018-11-07 22:48:03 +02:00
2018-11-02 23:37:58 +02:00
local function on_chunk_generated ( event )
2018-11-21 14:38:48 +02:00
local surface = game.surfaces [ " fish_defender " ]
2018-11-22 22:40:17 +02:00
2018-11-23 12:30:57 +02:00
if not surface then return end
if surface.name ~= event.surface . name then return end
2018-11-02 23:37:58 +02:00
local area = event.area
local left_top = area.left_top
2018-11-07 21:27:42 +02:00
2018-11-02 23:37:58 +02:00
local entities = surface.find_entities_filtered ( { area = area , force = " enemy " } )
for _ , entity in pairs ( entities ) do
entity.destroy ( )
2018-11-07 22:48:03 +02:00
end
2018-11-29 21:30:26 +02:00
if left_top.x >= 160 then
2018-11-22 22:40:17 +02:00
if not global.spawn_ores_generated then
2018-11-29 21:30:26 +02:00
local spawn_position_x = - 76
2018-11-22 22:40:17 +02:00
surface.create_entity ( { name = " electric-beam " , position = { 160 , - 95 } , source = { 160 , - 95 } , target = { 160 , 96 } } )
2018-11-29 21:30:26 +02:00
local tiles = { }
local replacement_tile = get_replacement_tile ( surface )
2018-11-22 22:40:17 +02:00
local water_tiles = surface.find_tiles_filtered ( { name = { " water " , " deepwater " } } )
for _ , tile in pairs ( water_tiles ) do
2018-11-29 21:30:26 +02:00
insert ( tiles , { name = replacement_tile , position = { tile.position . x , tile.position . y } } )
2018-11-22 22:40:17 +02:00
end
2018-11-09 10:34:19 +02:00
surface.set_tiles ( tiles , true )
2018-11-22 22:40:17 +02:00
2018-11-29 21:30:26 +02:00
local entities = surface.find_entities_filtered ( { type = " resource " , area = { { - 160 , - 96 } , { 160 , 96 } } } )
2018-11-22 22:40:17 +02:00
for _ , entity in pairs ( entities ) do
entity.destroy ( )
end
local decorative_names = { }
for k , v in pairs ( game.decorative_prototypes ) do
if v.autoplace_specification then
decorative_names [ # decorative_names + 1 ] = k
end
end
for x = - 4 , 4 , 1 do
for y = - 3 , 3 , 1 do
surface.regenerate_decorative ( decorative_names , { { x , y } } )
end
end
2018-11-29 21:30:26 +02:00
map_functions.draw_smoothed_out_ore_circle ( { x = - 128 , y = - 64 } , " copper-ore " , surface , 15 , 2500 )
map_functions.draw_smoothed_out_ore_circle ( { x = - 128 , y = - 32 } , " iron-ore " , surface , 15 , 2500 )
map_functions.draw_smoothed_out_ore_circle ( { x = - 128 , y = 32 } , " coal " , surface , 15 , 1500 )
map_functions.draw_smoothed_out_ore_circle ( { x = - 128 , y = 64 } , " stone " , surface , 15 , 1500 )
map_functions.draw_noise_tile_circle ( { x = - 96 , y = 0 } , " water " , surface , 16 )
map_functions.draw_oil_circle ( { x = - 128 , y = 0 } , " crude-oil " , surface , 8 , 200000 )
local pos = surface.find_non_colliding_position ( " market " , { spawn_position_x , 0 } , 50 , 1 )
global.market = surface.create_entity ( { name = " market " , position = pos , force = " player " } )
global.market . minable = false
refresh_market_offers ( )
local pos = surface.find_non_colliding_position ( " gun-turret " , { spawn_position_x + 5 , 1 } , 50 , 1 )
local turret = surface.create_entity ( { name = " gun-turret " , position = pos , force = " player " } )
turret.insert ( { name = " firearm-magazine " , count = 32 } )
for x = - 20 , 20 , 1 do
for y = - 20 , 20 , 1 do
local pos = { x = global.market . position.x + x , y = global.market . position.y + y }
local distance_to_center = math.sqrt ( x ^ 2 + y ^ 2 )
if distance_to_center > 8 and distance_to_center < 15 then
if math_random ( 1 , 3 ) == 1 and surface.can_place_entity ( { name = " wooden-chest " , position = pos , force = " player " } ) then
local chest = surface.create_entity ( { name = " wooden-chest " , position = pos , force = " player " } )
end
end
end
end
2018-12-03 19:02:20 +02:00
local area = { { x = - 160 , y = - 96 } , { x = 160 , y = 96 } }
for _ , tile in pairs ( surface.find_tiles_filtered ( { name = " water " , area = area } ) ) do
if math_random ( 1 , 16 ) == 1 then
surface.create_entity ( { name = " fish " , position = tile.position } )
end
end
2018-11-29 21:30:26 +02:00
local pos = surface.find_non_colliding_position ( " player " , { spawn_position_x + 1 , 4 } , 50 , 1 )
game.forces [ " player " ] . set_spawn_position ( pos , surface )
for _ , player in pairs ( game.connected_players ) do
local pos = surface.find_non_colliding_position ( " player " , { spawn_position_x + 1 , 4 } , 50 , 1 )
player.teleport ( pos , surface )
end
2018-11-07 22:48:03 +02:00
global.spawn_ores_generated = true
2018-11-25 17:04:57 +02:00
end
2018-12-03 23:02:37 +02:00
end
2018-11-07 22:48:03 +02:00
2018-11-02 23:37:58 +02:00
local tiles = { }
2018-11-07 21:27:42 +02:00
local hourglass_center_piece_length = 64
2018-11-07 22:48:03 +02:00
2018-11-07 21:27:42 +02:00
for x = 0 , 31 , 1 do
for y = 0 , 31 , 1 do
2018-11-07 02:50:14 +02:00
local pos = { x = left_top.x + x , y = left_top.y + y }
if pos.y >= map_height then
if pos.y > pos.x - hourglass_center_piece_length and pos.x > 0 then
insert ( tiles , { name = " out-of-map " , position = pos } )
end
if pos.y > ( pos.x + hourglass_center_piece_length ) * - 1 and pos.x <= 0 then
insert ( tiles , { name = " out-of-map " , position = pos } )
end
2018-11-07 21:27:42 +02:00
end
2018-11-07 02:50:14 +02:00
if pos.y < map_height * - 1 then
if pos.y < ( pos.x - hourglass_center_piece_length ) * - 1 and pos.x > 0 then
insert ( tiles , { name = " out-of-map " , position = pos } )
end
if pos.y < pos.x + hourglass_center_piece_length and pos.x <= 0 then
insert ( tiles , { name = " out-of-map " , position = pos } )
end
2018-11-02 23:37:58 +02:00
end
end
end
2018-11-07 21:27:42 +02:00
2018-11-02 23:37:58 +02:00
surface.set_tiles ( tiles , false )
2018-11-07 21:27:42 +02:00
if left_top.x < 160 then return end
2018-11-03 19:16:59 +02:00
local entities = surface.find_entities_filtered ( { area = area , type = " tree " } )
for _ , entity in pairs ( entities ) do
entity.destroy ( )
end
2018-11-07 21:27:42 +02:00
2018-11-03 19:16:59 +02:00
local entities = surface.find_entities_filtered ( { area = area , type = " cliff " } )
for _ , entity in pairs ( entities ) do
entity.destroy ( )
end
2018-11-07 21:27:42 +02:00
2018-11-07 02:50:14 +02:00
local entities = surface.find_entities_filtered ( { area = area , type = " resource " } )
for _ , entity in pairs ( entities ) do
surface.create_entity ( { name = " uranium-ore " , position = entity.position , amount = math_random ( 200 , 8000 ) } )
entity.destroy ( )
end
2018-11-07 21:27:42 +02:00
2018-11-07 02:50:14 +02:00
local tiles = { }
2018-11-29 21:30:26 +02:00
2018-11-07 21:27:42 +02:00
for x = 0 , 31 , 1 do
for y = 0 , 31 , 1 do
2018-11-02 23:37:58 +02:00
local pos = { x = left_top.x + x , y = left_top.y + y }
2018-11-07 21:27:42 +02:00
2018-11-07 02:50:14 +02:00
local tile = surface.get_tile ( pos )
if tile.name ~= " out-of-map " then
2018-11-20 15:46:13 +02:00
if pos.x > 312 then
insert ( tiles , { name = " out-of-map " , position = pos } )
else
2018-11-29 21:30:26 +02:00
--insert(tiles, {name = "dirt-7", position = pos})
2018-11-20 15:46:13 +02:00
end
2018-11-29 21:30:26 +02:00
if pos.x > 296 and pos.x < 312 and math_random ( 1 , 128 ) == 1 then
if surface.can_place_entity ( { name = " biter-spawner " , force = " enemy " , position = pos } ) then
if math_random ( 1 , 4 ) == 1 then
2018-12-03 19:02:20 +02:00
local entity = surface.create_entity ( { name = " spitter-spawner " , force = " player " , position = pos } )
2018-11-29 21:30:26 +02:00
entity.active = false
2018-12-03 19:02:20 +02:00
entity.destructible = false
2018-11-29 21:30:26 +02:00
else
2018-12-03 19:02:20 +02:00
local entity = surface.create_entity ( { name = " biter-spawner " , force = " player " , position = pos } )
2018-11-29 21:30:26 +02:00
entity.active = false
2018-12-03 19:02:20 +02:00
entity.destructible = false
2018-11-29 21:30:26 +02:00
end
2018-11-02 23:37:58 +02:00
end
end
2018-11-20 15:46:13 +02:00
end
2018-11-02 23:37:58 +02:00
end
end
2018-11-07 02:50:14 +02:00
surface.set_tiles ( tiles , true )
2018-11-07 21:27:42 +02:00
2018-11-07 02:50:14 +02:00
local decorative_names = { }
for k , v in pairs ( game.decorative_prototypes ) do
if v.autoplace_specification then
decorative_names [ # decorative_names + 1 ] = k
2018-11-06 01:07:35 +02:00
end
2018-11-07 21:27:42 +02:00
end
surface.regenerate_decorative ( decorative_names , { { x = math.floor ( event.area . left_top.x / 32 ) , y = math.floor ( event.area . left_top.y / 32 ) } } )
2018-11-02 23:37:58 +02:00
end
local function on_built_entity ( event )
2018-11-12 05:11:06 +02:00
local entity = event.created_entity
if global.entity_limits [ entity.name ] then
local surface = entity.surface
if global.entity_limits [ entity.name ] . placed < global.entity_limits [ entity.name ] . limit then
global.entity_limits [ entity.name ] . placed = global.entity_limits [ entity.name ] . placed + 1
surface.create_entity (
{ name = " flying-text " , position = entity.position , text = global.entity_limits [ entity.name ] . placed .. " / " .. global.entity_limits [ entity.name ] . limit .. " " .. global.entity_limits [ entity.name ] . str .. " s " , color = { r = 0.98 , g = 0.66 , b = 0.22 } }
)
2018-11-07 21:27:42 +02:00
else
2018-11-12 05:11:06 +02:00
surface.create_entity ( { name = " flying-text " , position = entity.position , text = global.entity_limits [ entity.name ] . str .. " limit reached. " , color = { r = 0.82 , g = 0.11 , b = 0.11 } } )
local player = game.players [ event.player_index ]
player.insert ( { name = entity.name , count = 1 } )
if global.score then
if global.score [ player.force . name ] then
if global.score [ player.force . name ] . players [ player.name ] then
global.score [ player.force . name ] . players [ player.name ] . built_entities = global.score [ player.force . name ] . players [ player.name ] . built_entities - 1
2018-11-07 02:50:14 +02:00
end
end
2018-11-12 05:11:06 +02:00
end
entity.destroy ( )
2018-11-07 02:50:14 +02:00
end
end
2018-11-12 05:11:06 +02:00
end
2018-11-07 21:27:42 +02:00
2018-11-12 05:11:06 +02:00
local function on_robot_built_entity ( event )
local entity = event.created_entity
if global.entity_limits [ entity.name ] then
2018-11-20 23:30:08 +02:00
local surface = entity.surface
2018-11-12 05:11:06 +02:00
if global.entity_limits [ entity.name ] . placed < global.entity_limits [ entity.name ] . limit then
global.entity_limits [ entity.name ] . placed = global.entity_limits [ entity.name ] . placed + 1
surface.create_entity (
{ name = " flying-text " , position = entity.position , text = global.entity_limits [ entity.name ] . placed .. " / " .. global.entity_limits [ entity.name ] . limit .. " " .. global.entity_limits [ entity.name ] . str .. " s " , color = { r = 0.98 , g = 0.66 , b = 0.22 } }
)
2018-11-07 21:27:42 +02:00
else
2018-11-12 05:11:06 +02:00
surface.create_entity ( { name = " flying-text " , position = entity.position , text = global.entity_limits [ entity.name ] . str .. " limit reached. " , color = { r = 0.82 , g = 0.11 , b = 0.11 } } )
local inventory = event.robot . get_inventory ( defines.inventory . robot_cargo )
inventory.insert ( { name = entity.name , count = 1 } )
entity.destroy ( )
2018-11-07 02:50:14 +02:00
end
2018-11-02 23:37:58 +02:00
end
end
local function on_tick ( )
2018-11-22 22:40:17 +02:00
if game.tick % 30 == 0 then
2018-11-07 02:50:14 +02:00
if global.market then
2018-11-07 21:27:42 +02:00
for _ , player in pairs ( game.connected_players ) do
create_wave_gui ( player )
2018-11-21 14:38:48 +02:00
end
end
if game.tick % 180 == 0 then
2018-11-23 12:30:57 +02:00
if game.surfaces [ " fish_defender " ] then
2018-11-29 21:30:26 +02:00
game.forces . player.chart ( game.surfaces [ " fish_defender " ] , { { x = - 64 , y = - 256 } , { x = 288 , y = 256 } } )
2018-11-23 12:30:57 +02:00
end
2018-11-07 02:50:14 +02:00
end
2018-11-21 14:38:48 +02:00
if global.market_age then
if not global.game_restart_timer then
global.game_restart_timer = 7200
else
if global.game_restart_timer < 0 then return end
global.game_restart_timer = global.game_restart_timer - 30
end
if global.game_restart_timer % 900 == 0 then
if global.game_restart_timer > 0 then game.print ( " Map will restart in " .. global.game_restart_timer / 60 .. " seconds! " , { r = 0.22 , g = 0.88 , b = 0.22 } ) end
if global.game_restart_timer == 0 then
game.print ( " Map is restarting! " , { r = 0.22 , g = 0.88 , b = 0.22 } )
game.write_file ( " commandPipe " , " :loadscenario --force " , false , 0 )
end
end
2018-11-20 15:46:13 +02:00
end
2018-11-02 23:37:58 +02:00
end
2018-11-07 21:27:42 +02:00
2018-11-07 02:50:14 +02:00
if game.tick % wave_interval == wave_interval - 1 then
2018-11-02 23:37:58 +02:00
biter_attack_wave ( )
2018-11-07 21:27:42 +02:00
end
2018-11-02 23:37:58 +02:00
end
2018-11-07 02:50:14 +02:00
local function on_player_changed_position ( event )
local player = game.players [ event.player_index ]
if player.position . x >= 160 then
2018-11-21 14:38:48 +02:00
player.teleport ( { player.position . x - 1 , player.position . y } , game.surfaces [ " fish_defender " ] )
2018-11-07 21:27:42 +02:00
if player.position . y > map_height or player.position . y < map_height * - 1 then
2018-11-21 14:38:48 +02:00
player.teleport ( { player.position . x , 0 } , game.surfaces [ " fish_defender " ] )
2018-11-07 21:27:42 +02:00
end
2018-11-07 02:50:14 +02:00
if player.character then
2018-11-07 21:27:42 +02:00
player.character . health = player.character . health - 25
player.character . surface.create_entity ( { name = " water-splash " , position = player.position } )
if player.character . health <= 0 then player.character . die ( " enemy " ) end
2018-11-07 02:50:14 +02:00
end
end
end
2018-11-12 05:11:06 +02:00
local function on_player_mined_entity ( event )
if global.entity_limits [ event.entity . name ] then
global.entity_limits [ event.entity . name ] . placed = global.entity_limits [ event.entity . name ] . placed - 1
end
end
local function on_robot_mined_entity ( event )
if global.entity_limits [ event.entity . name ] then
global.entity_limits [ event.entity . name ] . placed = global.entity_limits [ event.entity . name ] . placed - 1
end
end
2018-11-20 15:46:13 +02:00
local function on_market_item_purchased ( event )
local player = game.players [ event.player_index ]
local market = event.market
local offer_index = event.offer_index
local offers = market.get_market_items ( )
local bought_offer = offers [ offer_index ] . offer
if bought_offer.type ~= " nothing " then return end
local slot_upgrade_offers = {
[ 1 ] = { " gun-turret " , " gun turret " } ,
2018-11-21 14:38:48 +02:00
[ 2 ] = { " laser-turret " , " laser turret " } ,
2018-11-24 15:08:52 +02:00
[ 3 ] = { " artillery-turret " , " artillery turret " } ,
[ 4 ] = { " flamethrower-turret " , " flamethrower turret " } ,
[ 5 ] = { " land-mine " , " land mine " }
2018-11-20 15:46:13 +02:00
}
2018-11-24 15:08:52 +02:00
for x = 1 , 5 , 1 do
2018-11-21 14:38:48 +02:00
if offer_index == x then
2018-11-20 15:46:13 +02:00
local price = global.entity_limits [ slot_upgrade_offers [ x ] [ 1 ] ] . limit * global.entity_limits [ slot_upgrade_offers [ x ] [ 1 ] ] . slot_price
2018-11-21 14:38:48 +02:00
if slot_upgrade_offers [ x ] [ 1 ] == " flamethrower-turret " then
price = ( global.entity_limits [ slot_upgrade_offers [ x ] [ 1 ] ] . limit + 1 ) * global.entity_limits [ slot_upgrade_offers [ x ] [ 1 ] ] . slot_price
end
2018-11-20 15:46:13 +02:00
local coins_removed = player.remove_item ( { name = " coin " , count = price } )
if coins_removed ~= price then
if coins_removed > 0 then
player.insert ( { name = " coin " , count = coins_removed } )
end
player.print ( " Not enough coins. " , { r = 0.22 , g = 0.77 , b = 0.44 } )
return
end
global.entity_limits [ slot_upgrade_offers [ x ] [ 1 ] ] . limit = global.entity_limits [ slot_upgrade_offers [ x ] [ 1 ] ] . limit + 1
game.print ( player.name .. " has bought a " .. slot_upgrade_offers [ x ] [ 2 ] .. " slot for " .. price .. " coins! " , { r = 0.22 , g = 0.77 , b = 0.44 } )
refresh_market_offers ( )
end
end
end
2018-12-03 19:02:20 +02:00
local function on_research_finished ( event )
local research = event.research . name
if research ~= " tanks " then return end
game.forces [ " player " ] . technologies [ " artillery " ] . researched = true
game.forces . player.recipes [ " artillery-wagon " ] . enabled = false
end
event.add ( defines.events . on_built_entity , on_built_entity )
event.add ( defines.events . on_chunk_generated , on_chunk_generated )
event.add ( defines.events . on_entity_damaged , on_entity_damaged )
event.add ( defines.events . on_entity_died , on_entity_died )
2018-11-20 15:46:13 +02:00
event.add ( defines.events . on_market_item_purchased , on_market_item_purchased )
2018-11-07 02:50:14 +02:00
event.add ( defines.events . on_player_changed_position , on_player_changed_position )
2018-12-03 19:02:20 +02:00
event.add ( defines.events . on_player_joined_game , on_player_joined_game )
2018-11-12 05:11:06 +02:00
event.add ( defines.events . on_player_mined_entity , on_player_mined_entity )
2018-12-03 19:02:20 +02:00
event.add ( defines.events . on_research_finished , on_research_finished )
event.add ( defines.events . on_robot_built_entity , on_robot_built_entity )
2018-11-12 05:11:06 +02:00
event.add ( defines.events . on_robot_mined_entity , on_robot_mined_entity )
2018-12-03 19:02:20 +02:00
event.add ( defines.events . on_tick , on_tick )